Skip to content

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

Open
2409324124 wants to merge 12 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 12 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
  • preserves user-derived session titles by excluding synthetic approved-plan and internal walkthrough messages during autosave

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 Ollama CLI validation was completed locally:

  • Ollama v0.32.8 with qwen3-coder:30b (30.5B, Q4_K_M), using a 32K context and fully GPU-offloaded (49/49 layers) on an RTX 3090
  • a real interactive fixture completed Plan → approval → normal-mode implementation → Walkthrough; it generated the expected files and passed 4/4 tests
  • a fresh Plan → approval → Walkthrough → /exit autosave → --continue lifecycle run preserved all 22 messages, including the approved-plan and internal-walkthrough protocol messages, plus both artifacts, while retaining the original user request as the persisted and resumed session title
  • a separate 53-message restored-session replay preserved the complete history and artifacts and recalculated the title from the latest real user message instead of an internal protocol message
  • 3/3 forced OpenAI-compatible tool-call requests and 3/3 plain Plan JSON runs succeeded; plain runs left no temporary artifact directories

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.

@2409324124

Copy link
Copy Markdown
Contributor Author

@will-lamerton Thanks again for the detailed review. I’ve pushed the final follow-up in 2fae4224.

The original review items have been addressed. During real local-model E2E testing, I also found one related session-title issue: autosave could derive the title first from the internal walkthrough fallback and then from the synthetic <approved_plan> user message. Title derivation now skips both protocol messages while preserving the complete persisted message history.

Validation completed:

  • 21 focused AVA tests covering approved-plan, walkthrough, autosave, and restored-history behavior
  • all 11 GitHub checks are green, including unit tests, coverage, type checks, linting, formatting, build verification, Semgrep, and CodeQL
  • real NanoCoder CLI E2E against Ollama v0.32.8 with qwen3-coder:30b (30.5B Q4_K_M), 32K context, fully GPU-offloaded (49/49 layers) on an RTX 3090
  • completed an interactive Plan → approval → normal-mode implementation → Walkthrough flow; the generated fixture passed 4/4 tests
  • completed a fresh Plan → approval → Walkthrough → /exit autosave → --continue lifecycle run; the 22-message session retained both protocol messages and both artifacts while keeping the original user task
    as the persisted and resumed title
  • replayed a separate 53-message persisted session; all history and artifacts were preserved, and the title was repaired to use the latest real user message
  • 3/3 forced OpenAI-compatible tool calls and 3/3 plain Plan JSON runs succeeded, with temporary artifacts cleaned up correctly

Model compatibility note: during repeated runs, qwen3-coder:30b occasionally emitted legacy XML or redundant tool calls. NanoCoder’s correction path recovered from the syntax failures; this appeared to be model-level tool-selection behavior rather than an artifact lifecycle failure.

@akramcodez

Copy link
Copy Markdown
Collaborator

Hey @2409324124, could you please resolve the merge conflicts when you get a chance?

@github-actions

Copy link
Copy Markdown
Contributor

Hi @2409324124, thanks for this PR! It looks like a codeowner has left feedback
or review activity and there are still some outstanding items to wrap up.

Whenever you get a chance, could you take a look at the open comments?
If anything is unclear or you'd like a hand, just reply here and we'll help you get it across the line.

@2409324124

Copy link
Copy Markdown
Contributor Author

@akramcodez Thanks for the reminder! I’ve merged the latest main into the PR branch and resolved the conflicts.

A few of them involved overlapping ACP / VS Code cancellation and queued-tool changes, so I reconciled the behavior from both sides and added regression coverage rather than just choosing one version.

The PR is mergeable again, and the latest CI run has been triggered. Thanks!

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)

3 participants