feat(cli): tell an agent what init changed, and that recipes are per-task - #329
Conversation
thecodedrift
left a comment
There was a problem hiding this comment.
This should be parameterized, because if someone uses the raw recipes, this statement many not be true.
We said this so often, that honestly the agent subcommand should just add this as a header. It's specific to the agent subcommands
Agreed and done in d832a8f: the directive is rendered by — AI Coding Agent |
…task `init --no-interactive` ends with an upgrade trailer naming the directories that hold changed files and, after a version move, pointing at `update`. The --json envelope carries the same as `cliVersion`, `targets`, and `changed`. A canonical file whose bytes already match the bundle is no longer rewritten or reported, so a no-op re-install reads as one. The migration refusal names `init --no-interactive` for a piped caller, and the init recipe is rewritten for the agent that runs it. Every recipe carries a fetch-time directive on its second line, stripped with the version under `header: false`; the skill and tskl command say a recipe is fetched again for each task. Archives openspec change init-upgrade-context.
- `init` is the batch install in every context; `--no-interactive` is dropped and a bare TTY invocation calls the wizard directly. - The fetch-time directive is rendered by the `agent`, `update`, and `onboard` commands rather than written into recipe files, and now also says a session that installed or upgraded holds a stale skill. The prompts export does not carry it. - The upgrade trailer prints directly after the summary, before the reload banner. - The init recipe tells the agent to name what needs committing rather than to stage it. - The TTY-dependent refusal wording is reverted: `init` is the answer everywhere. Re-archives the change with the revised deltas.
…sources The canonical write searched the prose for the literal `npx @taskless/cli` and rewrote it for nightly/dev builds. That is whitespace-sensitive: a wrapped line or a doubled space escaped the rewrite silently. The sources now carry the recipes' token and `renderInvocationPlaceholder` substitutes it exactly at install; a source test forbids the literal. Re-archives the change with the added requirement.
873abe5 to
5b981e9
Compare
|
@claude /review |
|
Claude finished @thecodedrift's task in 7m 59s —— View job Review completeReview mode: incremental — read 28 prior review thread(s) before reviewing.
Treated as already addressed (not repeating):
New findings, both posted inline:
Everything else checked out: the |
… in the upgrade trailer Dropping --no-interactive moved the wizard launch into index.ts and left behind the CI check init used to apply: a pseudo-terminal in CI would have launched the wizard into a job nobody is watching. The guard is now a pure shouldLaunchWizard with its own tests. The upgrade trailer's update pointer uses getCliPrefix(), the convention for messages a person reads, rather than the build's fixed invocation.
taskless init --no-interactivenow tells the agent that runs it what happened and what to do next, and every recipe says it is not reusable across tasks. Two gaps from the self-healing-CLI notes: an agent thatchecksent toinitgot a write summary and an onboarding pointer, nothing about committing the rewrite or runningupdate; and an agent that fetchedagent checkonce kept using that text for the rest of the session, including after the upgrade that changed it.What an agent sees after
init. The human path prints an upgrade trailer after the install summary and before the onboarding line (which stays last): the directories that now hold changed files and that they belong in the next commit, plus, when the recorded CLI version moved, the transition and a pointer attaskless update. Nothing prints on a no-op re-install. The--jsonenvelope gains the same as fields:{ "success": true, "commandsInstalled": true, "cliVersion": { "previous": "0.10.2", "installed": "0.11.1" }, "targets": [ { "dir": ".taskless", "mode": "canonical", "writtenSkills": ["taskless"], "writtenCommands": ["tskl.md"], "removedSkills": [], "removedCommands": [] }, { "dir": ".claude", "mode": "reference", "writtenSkills": ["taskless"], "writtenCommands": ["tskl.md"], "removedSkills": [], "removedCommands": [] } ], "changed": true, "migrated": { "...": "unchanged, present only when a migration ran" } }targetsis the per-target summary that used to go to stderr under--json.cliVersion.previousisnullon a project with no recorded install.changedis true when a migration ran, any target wrote or removed something, or the version moved (a version move rewritesinstall.cliVersionin a tracked file, so it counts even when no skill bytes did).One behavior change worth reading. The canonical
.taskless/store was rewritten on every install and reported as written every time, so a no-op re-install was indistinguishable from an upgrade in the summary.writeCanonicalSkill/writeCanonicalCommandnow compare bytes and skip an identical file, returning{ path, changed }. Oneapply-install-plantest that pinned the unconditional rewrite is replaced by two: identical bytes are not reported, changed bytes are. TheSCAFFOLD_MIGRATION_REQUIREDrefusal namesinit --no-interactivewhen stdout is not a TTY, since a bareinitunder a pipe prints the topic index and migrates nothing.Recipes and the skill. Every
packages/cli/src/agent/*.mdgets a byte-identical second line saying the text was resolved at fetch time and the next task fetches again;stripHeadernow drops the block through the first blank line, soheader: falserenderings carry neither the version nor the directive and the body is unchanged. Theinitrecipe (topic v2) is rewritten for the agent: the non-interactive invocation, the envelope, then commit,updateafter a version move, and treating the current session's skills as stale.SKILL.mdgains a short section with the same directive (body at 80 lines, the cap) andtskl.mda fourth step.The OpenSpec change is archived here. Four specs were modified; I diffed requirement and scenario headings before and after the archive and nothing was dropped. The
cli-agentformat requirement also had a stale.txtspelling corrected to.mdin passing. Independent of #328.