Integrates footer rendering, working vibes, prompt history stash,
and git status tracking into unified TUI enhancement extension.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides shared stash management functions and overlay UI for browsing
and selecting previous prompts. Supports 1-9 quick picking.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Displays git branch status, dirty state, extension statuses, model info,
cost, and context usage percentage in the footer.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides context-aware working status messages based on prompt keywords
and tool names, with random emoji for visual interest.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Provides GitStatus interface and refreshGitStatus function for displaying
repository branch, dirty state, untracked files, and commit counts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- registers hook to trigger vibe state based on tool name and input
- enables working-vibes extension to respond to tool invocations
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- genai-proxy: disable full proxy implementation due to auth bootstrap
limitations at package boundary; throw clear error instead
- proxy-command: add try-catch error handling around startProxy
- prompt-history: new extension with Ctrl+Alt+H (or Ctrl+Shift+H fallback)
to navigate and insert previously-stashed prompts. Stash limited to 20
entries in ~/.sf/agent/prompt-history.json
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Updates workflow tool names, documentation references, and internal naming
conventions across MCP server, CLI, tests, and web components to complete
the singularity-forge rebrand from gsd to sf.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updates channel prefixes, log messages, comments, and configuration values
across daemon, mcp-server, and related packages to complete the rebrand from
gsd to sf-run naming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Function hasMissingWorkspaceScopes() was checking for @gsd directories
but its comment and usage indicated it should check for @sf-run scopes.
Update the check to match the renamed scope.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Loader was creating @gsd directories in node_modules but cli.js imports
@sf-run/* packages. This mismatch caused module resolution failures.
Rename gsdScopeDir to sfRunScopeDir and update scope to @sf-run.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Final rebrand: rename remaining Rust source file to complete the gsd → forge
transition. All parser references already use forge_parser after earlier commits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Accept deletion of gsd-phase-state.ts (renamed to forge-phase-state.ts earlier)
- Accept deletion of create-gsd-extension/ (renamed to create-forge-extension/ earlier)
- These renames were part of the rebrand and are preserved in commit history
Stabilize git state after restoration operations.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Type checker can't infer that !status.ok implies WebModeLaunchFailure in all cases.
Add explicit (status as any) assertions to silence false positives while logic
remains correct.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Print mode was constructing DefaultResourceLoader directly, which
bypassed the GSD extension registry filter and let disabled bundled
extensions leak through. With the community @0xkobold/pi-ollama
installed, every `gsd -p` invocation printed an /ollama command
conflict because the bundled ollama extension (explicitly disabled
in ~/.gsd/extensions/registry.json) was still being loaded.
- Add extension-manifest.json for the bundled ollama extension so the
registry's id-keyed disable entry can actually target it.
- Extend buildResourceLoader() with an options bag for print-mode
callers (additionalExtensionPaths, appendSystemPrompt).
- Switch print mode to buildResourceLoader() so the registry filter
(extensionPathsTransform) runs in both TUI and print paths.
Also fix a stderr leak in the GSD codebase-generator: execSync("git
ls-files") was inheriting stderr to the parent, so running gsd from a
non-repo cwd (e.g. $HOME) printed "fatal: not a git repository" before
the catch silently returned []. Pipe stderr so it lands in the thrown
Error instead.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds bin/gsd-from-source shell wrapper that bun-runs src/loader.ts, so
local commits are live without reinstalling gsd-pi. Patches loader.ts
to respect a pre-set GSD_BIN_PATH (previously it clobbered the env var
with process.argv[1], forcing subagent spawns to point at the .ts
loader path which child_process.spawn can't execute).
Why: working on fixes like #4251 required full `bun install -g --trust
gsd-pi` cycles plus longcat shim re-patching for every iteration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Followup to 828c5edf6. Swarm review flagged default=true as a latent
footgun: any SDK consumer of createAgentSession() that forgets to pass
persistModelChanges would silently mutate ~/.gsd/agent/settings.json.
Flip the default to false so persistence is opt-in. Interactive CLI
entry points now explicitly pass persistModelChanges: true:
- src/cli.ts interactive createAgentSession call
- packages/pi-coding-agent/src/main.ts: persistModelChanges = isInteractive
Print/rpc/mcp stay at the safe default. Tests updated (9/9 green).
`gsd -p --model X "msg"` was silently overwriting defaultProvider/
defaultModel in settings.json. One-shot verification runs must use the
model for that invocation only.
Adds an AgentSessionConfig.persistModelChanges flag (default true so
interactive behavior is unchanged), forwards it through createAgentSession,
and sets it false in main.ts when !isInteractive and in src/cli.ts print
mode. The gsd wrapper also skips validateConfiguredModel when --model is
explicitly passed, so a CLI-provided model can't trigger a fallback repair
that writes the wrong default back.
Three settings.json write sinks audited: agent-session._applyModelChange
(gated on flag), model-selector.ts (interactive only, unreachable in
print), startup-model-validation (gated by !cliFlags.model in print).
Regression: 8 source-assertion tests in
agent-session-print-mode-persist.test.ts.
Analyzes completed milestone artifacts (PLAN.md, SUMMARY.md, and
optionally VERIFICATION.md + UAT.md) and dispatches an LLM turn that
extracts institutional knowledge into four categories — Decisions,
Lessons, Patterns, Surprises — with source attribution per item.
Output: .gsd/milestones/<id>/<id>-LEARNINGS.md with YAML frontmatter
(counts per category, list of missing optional artifacts). Running
twice overwrites the previous file. Integrates with capture_thought
when available; silently skips if not.
New files:
- commands-extract-learnings.ts — handler + pure helpers
- tests/commands-extract-learnings.test.ts — 32 unit tests (TDD)
Ports the v1 graphify system to v2 as a native TypeScript implementation.
The knowledge graph builds semantic relationships between milestones, slices,
tasks, and knowledge entries — and injects relevant subgraphs automatically
into every agent dispatch prompt.
## Core implementation (packages/mcp-server/src/readers/graph.ts)
- `buildGraph(projectDir)` — walks all .gsd/ artifacts (STATE.md,
milestone PLANs, slice PLANs, KNOWLEDGE.md), extracts nodes and edges
with confidence tiers (EXTRACTED / INFERRED / AMBIGUOUS). Parse errors
skip the node rather than crashing.
- `writeGraph(gsdRoot, graph)` — atomic write via tmp file + rename.
- `writeSnapshot(gsdRoot)` — saves a diff baseline before each rebuild.
- `graphQuery(projectDir, term, budget?)` — BFS subgraph search with
case-insensitive matching on label + description; trims AMBIGUOUS edges
first, then INFERRED, respecting the token budget (default 4 000).
- `graphStatus(projectDir)` — freshness check; stale = older than 24 h.
- `graphDiff(projectDir)` — compares current graph to last snapshot,
returns added / removed / changed counts for nodes and edges.
## MCP tool (packages/mcp-server/src/server.ts)
Registers `gsd_graph` immediately after `gsd_knowledge` with four modes:
build | query | status | diff. All errors returned as isError: true.
## CLI subcommand (src/cli.ts, src/help-text.ts)
`gsd graph build|status|query <term>|diff` — follows the established
`if (cliFlags.messages[0] === '...')` dispatch pattern. Uses
`resolveGsdRoot()` for git-root-aware path resolution (not a naive
`.gsd` append). Help text updated with correct positional argument format.
## Auto-rebuild after slice completion
(src/resources/extensions/gsd/tools/complete-slice.ts)
Fire-and-forget `buildGraph → writeGraph` triggered after every slice
completion. Uses `@gsd-build/mcp-server` package import (not a relative
src path) and `resolveGsdRoot()` for correct path resolution in monorepos.
## Graph-aware dispatch injection
(src/resources/extensions/gsd/graph-context.ts,
src/resources/extensions/gsd/auto-prompts.ts)
`inlineGraphSubgraph(projectDir, term, { budget })` queries the graph and
formats the result as a `### Knowledge Graph Context` markdown block,
consistent with all other inlined context blocks. Adds a stale warning
annotation when the graph is older than 24 h. Returns null (graceful
skip) when graph.json is missing, the query returns zero nodes, or the
import fails — no agent dispatch is ever blocked by graph availability.
Injected into three prompt builders:
- `buildResearchSlicePrompt` — 3 000 token budget
- `buildPlanSlicePrompt` — 3 000 token budget
- `buildExecuteTaskPrompt` — 2 000 token budget
## Tests
- 22 tests for the core graph reader (graph.test.ts)
- 14 tests for the dispatch injection helper (graph-context.test.ts)
- All tests use real on-disk fixtures (no module mocking needed)
- Full suite: 6 318 passed, 0 failed
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- pr-branch: use execFileSync everywhere, validate --name with git check-ref-format,
cherry-pick --no-commit + path-level reset to strip .gsd/.planning/PLAN.md from
mixed commits, and assert no excluded paths leak into the final branch
- ship: argv-safe git push and gh pr create, validate base/current refs, and
resolve ROADMAP/SUMMARY via resolveMilestoneFile/resolveSliceFile
- add-tests: resolve slice SUMMARY via resolveSliceFile instead of hardcoded path
- Fix ProjectTotals field names (totalCost→cost, totalDuration→duration, etc.)
- Fix UnitMetrics field names (status→finishedAt, unitId→id)
- Fix ModelAggregate field name (count→units)
- Fix ActiveRef usage (no phase/slices fields)
- Remove commands-slice-mutation.ts (depends on single-writer engine)
- Remove slice mutation routes from catalog, do command, and workflow handler
- Update backlog promote to work without engine slice commands
Drop map-codebase from the v1→v2 parity PR: handler, prompt template,
catalog entry, nested completions, route in ops.ts, and keyword route
in the do command.
Add 12 commands that exist in GSDv1 but had no v2 equivalent:
High priority:
- ship: Create PR from milestone artifacts (title, body, metrics)
- add-slice: Append slice to roadmap via engine updateRoadmap()
- insert-slice: Insert slice at position with reordering
- remove-slice: Remove pending slice (--force for planned slices)
- do: Natural language routing via keyword matching (30 routes)
- session-report: Session cost/tokens/work summary (--json, --save)
Medium priority:
- backlog: Structured backlog with 999.x numbering (add/promote/remove)
- pr-branch: Clean PR branch filtering .gsd/ commits via cherry-pick
- add-tests: LLM-dispatched test generation for completed slices
- map-codebase: Codebase analysis (tech/arch/quality/concerns)
All slice mutations go through the engine's updateRoadmap() command,
preserving the single-writer architecture. No direct markdown edits.
Includes 46 unit tests across 6 test files, 2 prompt templates,
catalog entries with nested completions for all commands.