Skip to content

feat: add session-scoped artifact lifecycle across CLI and VS Code - #826

Open
2409324124 wants to merge 7 commits into
Nano-Collective:mainfrom
2409324124:feat/cli-artifacts
Open

feat: add session-scoped artifact lifecycle across CLI and VS Code#826
2409324124 wants to merge 7 commits into
Nano-Collective:mainfrom
2409324124:feat/cli-artifacts

Conversation

@2409324124

@2409324124 2409324124 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Description

Adds a complete session-scoped artifact lifecycle across the CLI and VS Code extension, following the planning, task tracking, and completion flow requested in #805.

The implementation:

  • persists implementation_plan.md, task.md, and walkthrough.md in isolated session artifact directories
  • keeps internal task state in tasks.json while exposing only the three user-facing lifecycle artifacts
  • adds write_walkthrough, with structured files-changed, truthful test results (or an explicit untested reason), and verification steps
  • nudges the model once if approved-plan/task work ends without the required walkthrough, without leaking the internal nudge into restored history
  • exposes unified artifact metadata and file locations through ACP
  • shows clickable Plan, Tasks, and Walkthrough shortcuts in the CLI and VS Code
  • restores artifact shortcuts when a session is resumed and clears them for a new session
  • retains the VS Code Plan Mode review flow: open the saved plan, execute it in normal mode, or revise it in Plan Mode
  • gives plain/headless runs a real session ID and working directory, so artifact tools work there too
  • removes the legacy sessionless task reset that could create .nanocoder/tasks.json in the target project
  • preserves balanced tool-call history when approval races with cancellation, preventing the transient false Internal error in later turns

Closes #805.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Changeset

  • Added a changeset (pnpm changeset) describing this change for the changelog

Testing

Automated Tests

  • New features include passing tests in .spec.ts/tsx files
  • All existing tests pass (pnpm test:all completes successfully)
  • Tests cover both success and error scenarios

Validated successfully with:

  • GitHub Actions: all 11 checks pass, including Unit Tests & Coverage Analysis
  • 290 focused AVA tests covering artifacts, ACP, interactive CLI, plain/headless CLI, prompts, task lifecycle, history replay, and tool profiles
  • 8 focused VS Code controller/plan/prompt tests
  • 7/7 built CLI integration tests
  • pnpm run test:types
  • pnpm run format:check
  • pnpm run test:lint
  • pnpm run test:knip
  • pnpm run test:audit
  • pnpm run build
  • pnpm --dir plugins/vscode run build
  • node --check plugins/vscode/media/chat-panel.js
  • pnpm exec tsc -p plugins/vscode/tsconfig.json --noEmit
  • pnpm changeset status --since=origin/main
  • pre-commit Biome checks

The complete AVA command was also run. Its assertions, including the CLI integration group, passed, but the repository's existing long-lived handle issue still makes the command time out while exiting client-factory.spec.ts and ai-sdk-client.spec.ts; the focused changed-area suites above exit cleanly.

Manual Testing

  • Tested with Ollama
  • Tested with OpenRouter
  • Tested with OpenAI-compatible API
  • Tested MCP integration (not applicable)

Real CLI and VS Code Extension Host flows were tested with an inherited API-key environment (no credentials added to the repository):

  • user manually verified CLI Plan Mode and the clickable artifact behavior
  • a real plain/headless model run created tasks, edited and tested an isolated project, wrote a walkthrough, and left no project-local .nanocoder state
  • a real VS Code run generated and opened a Plan, approved it, created live Tasks, edited files, ran npm test, and generated a Walkthrough
  • all three VS Code artifact shortcuts opened their persisted Markdown files
  • starting a new VS Code chat cleared the shortcuts; resuming the completed session restored all three
  • persisted artifact files were verified with 0600 permissions
  • an Allow → immediate Stop race was reproduced and the same session then continued without Prompt failed, a missing tool result, or an Internal error

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Documentation updated (not needed; no public API or configuration changes)
  • No breaking changes (or clearly documented)
  • Appropriate logging added using the existing VS Code OutputChannel and ACP logging conventions

Screenshots

CLI artifact lifecycle

cli-artifact-lifecycle

VS Code artifact lifecycle

vscode-artifact-lifecycle

VS Code walkthrough

vscode-walkthrough-open

@2409324124 2409324124 changed the title feat: add session-scoped AI artifacts and CLI plan mode feat: add session-scoped Plan Mode artifacts across CLI and VS Code Aug 7, 2026
@2409324124
2409324124 marked this pull request as ready for review August 7, 2026 21:33
@2409324124 2409324124 changed the title feat: add session-scoped Plan Mode artifacts across CLI and VS Code feat: add session-scoped artifact lifecycle across CLI and VS Code Aug 8, 2026
@will-lamerton

Copy link
Copy Markdown
Member

Hey @2409324124 - thanks for this - really solid work. Atomic writes at 0600, session-ID path validation, and DI on every new module so the tests use real temp dirs is exactly the standard I want to see. The withValidation options fix is a good catch too; that was silently dropping abortSignal for every validated tool.

A few things I'd want resolved before merge:

1. The walkthrough nudge is too eager. observeSuccessfulLifecycleTool sets required = true on any write_tasks with ≥1 task, and the prompt tells the model to use tasks for anything with 3+ steps. So most non-trivial turns now cost an extra round-trip. On local 7B-30B models that's a real latency tax. Can we gate it behind config (default off), or scope it to turns that actually started from an <approved_plan>?

Related: accumulatedFinalText in plain/conversation.ts concatenates across turns, so the nudge reply lands in --plain --json output. That's a contract change for scripted use and isn't in the changeset.

2. write_walkthrough's validator can throw a TypeError. validateArgsAgainstSchema deliberately skips presence checks, so a model omitting summary hits args.summary.trim() and gets "Cannot read properties of undefined" instead of a correctable validation error. Same for tests, verificationSteps, and filesChanged in renderWalkthrough. write-plan.ts guards this properly - please match it.

3. Artifact dirs leak for non-persisted sessions. deleteSessionArtifacts is only reachable from SessionManager, but plain/shell.ts mints a fresh UUID per run. Every --plain invocation that writes tasks or a walkthrough leaves an orphan directory forever.

Smaller ones:

  • ArtifactManager's session-ID regex is stricter than session-manager's. deleteSession and the retention sweep can now throw on an ID that passed their own check - the sweep runs inside withIndexLock at startup. Make deleteSessionArtifacts return early rather than throw.
  • emitPlanUpdate / emitToolCallUpdate call getArtifactPath unguarded, but loadSession takes the session ID straight from the client. listSessionArtifacts guards this already; those two should too. Same in interactive-app.tsx, where it runs during render.
  • Subagents call getToolHandler() without an execution context, so write_tasks still falls back to .nanocoder/tasks.json in plain/headless - the thing this PR set out to stop.
  • Plan review is now gated on the model actually calling write_plan. A model that writes a good plan in prose leaves the user with no review bar at all. Worth a fallback that persists the final assistant message.
  • filterAcpToolNames is return names; with a test asserting identity. Remove it or make it filter.
  • createTerminalFileLink hardcodes the label Open implementation_plan.md regardless of path (the spec passes /tmp/implementation plan.md and asserts the wrong basename). Use path.basename, and share the OSC-8 helper between the two components.

Also: the three new plugins/vscode/src/*.spec.ts files fall outside the root AVA glob, so CI never runs them. Pre-existing, but worth knowing those 8 tests aren't protecting anything yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] AI Artifact System (Implementation Plans, Tasks, Walkthroughs)

2 participants