Skip to content

fix(cli): name the field and the read failure in --from request errors #1035

fix(cli): name the field and the read failure in --from request errors

fix(cli): name the field and the read failure in --from request errors #1035

Workflow file for this run

# THIS NAME IS AN INTERFACE, NOT A LABEL. `release-cli-nightly.yml` triggers on
# `workflow_run: workflows: [Validate]`, which matches this string and not this
# file's path — a nightly is only published from a commit this workflow passed
# on. Rename it and the nightly stops firing permanently, with no error
# anywhere and nothing turning red. Rename both together, or neither.
name: Validate
on:
push:
branches: [main]
# No `branches:` filter, deliberately. Lint, typecheck, and tests have no
# interest in where a PR eventually merges, and filtering on `main` silently
# skipped this workflow on stacked PRs.
#
# The filter matches the PR's base ref, but GitHub also resolves a stacked
# PR's *eventual* target and matches on that — so `branches: [main]` did run
# on PRs based on another branch, until it stopped. Measured on the
# #71→#93→#94→#95→#100→#102→#103→#106 stack: every PR up to #102 got a
# `Validate` run, while #103 and #106 got none, across 16 `pull_request`
# events that other workflows handled fine. A filter that works for six PRs
# and quietly fails on the seventh is worse than one that never worked,
# because nobody re-checks it.
#
# `ready_for_review` is NOT in the default set (opened/synchronize/reopened)
# and must be named: without it a draft marked ready gets no fresh run until
# something happens to push again, which is exactly the state #103 sat in.
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
permissions:
contents: read
# This workflow runs the CLI this repository builds. Its telemetry is the same
# production client a user's install has, so every invocation here would count
# as adoption. Opting out is the CLI's own switch, read by the built binary.
env:
TASKLESS_TELEMETRY_DISABLED: "1"
jobs:
validate:
name: Validate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Install pnpm
uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0
- name: Setup Node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version-file: .nvmrc
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Lint
run: pnpm lint
- name: Typecheck
run: pnpm typecheck
- name: Build
run: pnpm build
- name: Test
run: pnpm test
# `test:scripts` covers .github/scripts/ AND the skill scripts under
# .agents/skills/*/scripts/, which are zero-dependency CommonJS with
# node:test suites beside them. It lives in package.json so the same
# command runs locally.
#
# Its globs are UNQUOTED on purpose. Node's own glob expansion exits 0
# when a pattern matches nothing, so a renamed or moved directory would
# report a clean pass having run no tests at all; an unmatched shell glob
# reaches node as a literal path and fails loudly with "Could not find".
# An absent check reads like a passing one, so take the loud failure.
- name: Test workflow and skill scripts
run: pnpm test:scripts
# House style, enforced rather than documented. The rules live in
# `.taskless/` and are scoped to the documents people and agents actually
# read: every README, CLAUDE.md, `.conventions/*.md`, this directory's
# workflows, and comments under `packages/cli/src/`.
#
# A step here, not a standalone `taskless.yml`. The canonical recipe
# (`taskless agent ci`) writes a separate workflow so that onboarding
# never touches a pipeline it does not own, but the two things this repo
# needs are only available inside this job. Branch protection requires
# `Validate` and nothing else, so a separate workflow would report and
# block nothing, which is the whole of what #104 asked for; and `check`
# runs this repo's own build, which the `Build` step above has already
# produced. Full scan rather than the recipe's diff scan, for the reason
# `Validate specs` gives below: rot accumulates in the files a PR does
# not touch, and the scoped corpus is small enough that a diff scan buys
# nothing.
#
# Placed after the test steps rather than immediately after `Build`, so
# that the existing signal order (lint, types, build, tests) stays intact
# for anyone used to reading these logs. It only needs to be after
# `Build`; nothing above it depends on it.
#
# `pnpm cli` is the workspace build, NOT a published release. That is a
# deliberate divergence from `ci.txt` and is ENFORCED, not requested:
# the `ci-uses-workspace-cli` rule fails this very workflow if the
# invocation is changed back, and carries the reasoning in its `note:`.
# `Build` above ran `pnpm build` on this same commit, so `dist/` here
# can be neither stale nor missing, and an absent `dist/` would fail
# this step loudly rather than pass it empty.
#
# This blocks. `check` exits non-zero on any error-severity finding and
# on an engine that failed or timed out, so an em dash added to a covered
# document turns the build red. Warning-severity rules report without
# failing, which is what `severity: warning` in a rule means.
#
# No authentication and no secrets: static rules (Vale and ast-grep) run
# unauthenticated. Runtime rules under `.taskless/rules/runtime/` are
# skipped without a token; that directory is empty today, and wiring
# `TASKLESS_TOKEN` is the separate decision to make when it is not.
- name: Check house style
run: pnpm cli check
# Repo-wide, not changed-files-only: spec rot accumulates in the specs a
# PR does not touch, so a scoped check would never surface it.
- name: Validate specs
run: pnpm openspec validate --all --strict
# `--strict` validates what the parser read, not that it read the whole
# file. A second `##` inside `## Requirements` ends the section and every
# requirement below it becomes invisible — valid, unread, and green.
- name: Check spec requirement visibility
run: node .github/scripts/openspec-visibility.cjs