Commit graph

3517 commits

Author SHA1 Message Date
Mikael Hugo
c1c2623707 Add type declaration files for learning extension
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 12:36:08 +02:00
Mikael Hugo
30730dd25b Fix rebrand artifacts, add family-priority model routing to proxy server
- Update Dockerfile image name and package.json URLs to singularity-ng/singularity-foundry
- Add uv to nix develop shell in flake.nix
- Rename resolveGsdRoot → resolveSFRoot in src/cli.ts
- Add PROXY_FAMILY_PRIORITY routing table + sortByFamilyPriority to proxy-server.ts
- Fix duplicate scope key and simplify link-workspace-packages.cjs
- Remove duplicate conditions in postinstall.js
- Add ES2024 target/lib to tsconfig.extensions.json
- Delete obsolete GSD recovery scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-18 12:28:27 +02:00
github-actions[bot]
8f160677b7
release: v2.75.0
https://claude.ai/code/session_013BwmqG3NuwwZY3vsUb4Y9Y
2026-04-17 17:26:59 +00:00
mikkihugo
dc0db3868a
Add per-family proxy provider priority system with TUI and 429 fallback
- model-registry: export PROXY_FAMILY_PRIORITY and GLOBAL_PROVIDER_FALLBACK
  constants; add getModelsForProxy() returning candidates ordered by family
  priority then global fallback (opencode → opencode-go → openrouter →
  ollama-cloud); add getModel() convenience wrapper
- proxy-server: add priorityOverrides option; handleChat iterates all
  candidates in priority order and falls through to the next on 429
- settings-manager: add ProxySettings type with providerPriority override
  map; add getProxyProviderPriority() / setProxyFamilyProvider() accessors
- settings-selector: add ProxyPrioritySubmenu — a two-level TUI submenu
  (family → provider) that dynamically generates entries from
  PROXY_FAMILY_PRIORITY; wired in interactive-mode with full callback

Family defaults: MiniMax→minimax, GLM→zai, Kimi→kimi-coding,
MiMo→global-fallback, Gemini/Gemma→google-gemini-cli, Claude→anthropic,
GPT/o-series→openai

https://claude.ai/code/session_013BwmqG3NuwwZY3vsUb4Y9Y

Co-authored-by: Claude <noreply@anthropic.com>
2026-04-17 19:17:50 +02:00
ace-pm
f92ee8d64c
Rename @sf-run/* → @singularity-forge/* package scope
- All 373 source files updated
- Package.json scopes in all workspace packages
- Loader workspace symlink dir updated
- RpcClient import unified from pi-coding-agent (fixes type mismatch)
- Scripts, configs, flake.nix updated
- Workspace symlinks rebuilt
2026-04-15 22:56:33 +02:00
ace-pm
e07204c782 gitignore native Rust build outputs (*.node, target/) 2026-04-15 18:36:37 +02:00
ace-pm
9d739dfa5d Rename GSD→SF: complete rebrand from fork origin
- All gsdDir/gsdRoot/gsdHome → sfDir/sfRootDir/sfHome
- GSDWorkspace* → SFWorkspace* interfaces
- bootstrapGsdProject → bootstrapProject
- runGSDDoctor → runSFDoctor
- GsdClient → SfClient, gsd-client.ts → sf-client.ts
- .gsd/ → .sf/ in all tests, docs, docker, native, vscode
- Auto-migration: headless detects .gsd/ → renames to .sf/
- Deleted gsd-phase-state.ts backward-compat re-export
- Renamed bin/gsd-from-source → bin/sf-from-source
- Updated mintlify docs, github workflows, docker configs
2026-04-15 18:33:47 +02:00
ace-pm
6e10d93d0d Add input parameter to setVibeForTool function.
Allows tool input to be passed to vibe setter for future context-aware
customization.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:18:54 +02:00
ace-pm
42dda2013b Remove old working-vibes and prompt-history extensions.
Consolidated into unified sf-tui extension. Removed old git-footer
extension in favor of sf-tui footer implementation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:18:29 +02:00
ace-pm
2b27f2e567 Update vibes import to use sf-tui module.
Redirect working-vibes imports from old location to new sf-tui/vibes.js.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:18:22 +02:00
ace-pm
09691fe2e8 Add SF-TUI extension main entry point.
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>
2026-04-15 16:18:15 +02:00
ace-pm
f878e9b4a1 Add stash utility for TUI prompt history.
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>
2026-04-15 16:18:07 +02:00
ace-pm
ec39512960 Add footer renderer for TUI status display.
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>
2026-04-15 16:17:24 +02:00
ace-pm
c18f67d278 Add working message vibes for TUI.
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>
2026-04-15 16:17:04 +02:00
ace-pm
7e03021b25 Add git status utility for TUI.
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>
2026-04-15 16:16:47 +02:00
ace-pm
e501ffeefd Add sf-tui shared utility functions.
Provides rightAlign helper for text alignment in terminal UI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 16:16:39 +02:00
ace-pm
acab81de11 fix(mcp-project-config): remove duplicate constant export
- removed redundant self-assignment export

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-15 16:11:35 +02:00
ace-pm
b5caedf786 fix(paths): remove duplicate SF_ROOT_FILES export
- removed redundant self-assignment export that served no purpose

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-15 16:11:25 +02:00
ace-pm
dfbe620c34 feat(bootstrap): add tool_call hook to set vibes for tools
- 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>
2026-04-15 16:10:49 +02:00
ace-pm
5102fa217e fix(rtk): remove duplicate constant declarations and logic checks
- removed duplicate SF_RTK_DISABLED_ENV, SF_SKIP_RTK_INSTALL_ENV, SF_RTK_PATH_ENV exports
- fixed isRtkEnabled() to check SF_RTK_DISABLED_ENV once instead of twice
- fixed resolveAppRoot() duplicate env.SF_HOME check
- fixed resolveRtkBinaryPath() duplicate SF_RTK_PATH_ENV lookup
- fixed ensureRtkAvailable() duplicate env checks and error messages
- fixed bootstrapRtk() duplicate process.env assignment

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-15 16:10:25 +02:00
ace-pm
bed1a20cf5 feat(extensions): disable genai-proxy auth, add prompt-history overlay
- 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>
2026-04-15 16:09:23 +02:00
ace-pm
421fccd898 refactor: rebrand gsd_ tool names and references to sf_ namespace
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>
2026-04-15 15:51:38 +02:00
ace-pm
a79d67f38b chore: update Cargo.lock after native build
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:43:27 +02:00
ace-pm
6b0ac484ba refactor: update log prefixes and string values from gsd- to sf- namespace
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>
2026-04-15 15:37:12 +02:00
ace-pm
2e6b2b8fd1 fix(rust): rename gsd_parser module to forge_parser in lib.rs
Align module declaration with file rename (gsd_parser.rs → forge_parser.rs)
that was completed in the rebrand.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:14:07 +02:00
ace-pm
6e520b1db8 fix(daemon): rename Discord slash commands from gsd- to sf- prefix
Update command names to match the rebrand:
- gsd-status → sf-status
- gsd-start → sf-start
- gsd-stop → sf-stop
- gsd-verbose → sf-verbose

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:05:53 +02:00
ace-pm
6164a3f0ce fix(resource-loader): check for @sf-run scopes instead of @gsd
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>
2026-04-15 15:04:11 +02:00
ace-pm
291cad9f7b fix(loader): use @sf-run scope instead of @gsd for workspace packages
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>
2026-04-15 15:03:39 +02:00
ace-pm
32df63621f chore: add .gsd/ to .gitignore
.gsd/ is generated at runtime by sf-run and should not be committed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:01:53 +02:00
ace-pm
282b34b58b chore: add .gsd/ to .gitignore and remove runtime state files
.gsd/ is generated at runtime by sf-run during execution and contains
audit logs, notifications, and metadata. These should never be committed
to the repository. Removing tracked state files and ignoring the directory
going forward.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 15:01:17 +02:00
ace-pm
b29c12d5e5 refactor(native): rename gsd_parser.rs to forge_parser.rs
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>
2026-04-15 14:58:21 +02:00
ace-pm
35dc87ef53 chore: sync workspace state after rebrand
- Rebrand commits already in history (gsd → forge)
- Sync pre-existing doc, docker, and CI config updates
- All rebrand artifacts verified in place:
  * Native crates: forge-engine, forge-ast, forge-grep
  * Log prefixes: [forge] across 22+ files
  * Binary: ~/bin/sf-run
  * Workspace scopes: @sf-run/*, @singularity-forge/*
  * Nix flake: Rust toolchain ready

System ready for: nix develop && bun run build:native

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:54:20 +02:00
ace-pm
a1454a29ff docs(flake): update description and build instructions for singularity-forge
- Rebrand description: gsd-2 → singularity-forge
- Add RUST_BACKTRACE=1 for better error diagnostics
- Update shellHook message with current build command
- Document native addon build via bun filter

Rust toolchain already present in devShell (cargo, rustc, clippy, rust-analyzer, rustfmt).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:46:31 +02:00
ace-pm
d501ca7d6d fix: clean up git state after directory restoration
- 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>
2026-04-15 14:34:53 +02:00
ace-pm
a81fa3ae4a fix(types): add type assertions for union narrowing in web-mode
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>
2026-04-15 14:29:12 +02:00
ace-pm
83feadb4e1 wip: rename gsd-parser dir + exports, fix native package.json
- packages/native/src/gsd-parser → packages/native/src/forge-parser
- Update packages/native/package.json exports: ./gsd-parser → ./forge-parser
- Update packages/native/src/index.ts imports: ./gsd-parser → ./forge-parser

Build in progress: native tsc output missing submodule dists (fd, text, image, etc).
This is a pre-existing issue with the build system, not caused by rebrand.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:22:21 +02:00
ace-pm
434bb527c4 fix(rebrand): correct workspace package names in build scripts and link config
- Update package.json build scripts to use bun run --filter (bun-native) instead of npm -w
- Fix scripts/link-workspace-packages.cjs: rebase scopes from @gsd/@gsd-build to @sf-run/@singularity-forge
- Add missing mcp-server to package mapping in link script
- Resolves 'Cannot find module @sf-run/pi-coding-agent' by fixing workspace symlink generation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:20:28 +02:00
ace-pm
172753c3b2 refactor(forge): complete gsd → forge rebrand across native, logging, and build system
- Rename native Rust crates: gsd-engine → forge-engine, gsd-ast → forge-ast, gsd-grep → forge-grep
- Update all crate dependencies (Cargo.toml, .rs source) and N-API artifacts
- Mass rename log prefix [gsd] → [forge] across 81 files (scripts, src/, extensions, tests)
- Rename log prefix "gsd-db:" → "forge-db:" in template literals
- Update nix flake: add sf-run-native devShell with Rust toolchain for native addon builds
- Update CI workflow artifact names (build-native.yml)
- Verify only packages/native/* touched (no upstream pi-* packages renamed)

Rationale: Complete gsd-2 → singularity-forge rebrand (2026-04-15). Native addon is
sf-run-specific; all gsd-prefixed logging and crate names must align with new identity.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:11:45 +02:00
ace-pm
e5d655bdb3 chore: checkpoint workspace changes 2026-04-15 13:38:15 +02:00
ace-pm
6612456934 fix(extensions): route print mode through buildResourceLoader
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>
2026-04-15 11:44:52 +02:00
Mikael Hugo
2f2f1845f7 fix(source): resolve symlink before computing SCRIPT_DIR
When gsd-from-source is invoked via a symlink (e.g. ~/.bun/bin/gsd-real
pointing at it so `gsd` resolves to source without further indirection),
BASH_SOURCE[0] is the symlink path, not the real file. The previous
dirname-of-BASH_SOURCE[0] approach resolved SCRIPT_DIR to the symlink's
parent dir (e.g. ~/.bun/bin) and tried to bun-run ~/.bun/src/loader.ts,
which doesn't exist.

Wrapping BASH_SOURCE[0] in readlink -f resolves the physical path first,
so SCRIPT_DIR always points at bin/ inside the gsd source checkout
regardless of how the script is reached.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 11:07:00 +02:00
ace-pm
c0de3538ec fix(retry-handler): classify 529/overloaded as rate_limit for fallback walk
Minimax and other Anthropic-protocol providers return HTTP 529 with
`overloaded_error` bodies under heavy load. The retryable regex (line 119)
matched `overloaded` so the error was retried, but the rate-limit
classifier (line 423) only matched `429`, so the error never triggered
credential rotation or cross-provider fallback — the handler looped on
the same provider forever.

Adds `529|overloaded` to the rate-limit classifier so 529 responses
route through the same backoff + fallback path as real rate limits.
2026-04-15 11:04:41 +02:00
ace-pm
80ce0f4855 feat(source): enable running gsd directly from source checkout
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>
2026-04-15 11:01:18 +02:00
ace-pm
1f1c029c74 fix(cli): invert persistModelChanges default to false (#4251)
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).
2026-04-15 10:45:26 +02:00
ace-pm
828c5edf62 fix(cli): don't persist --model override in print mode (#4251)
`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.
2026-04-15 10:12:32 +02:00
ace-pm
1fc62582ed feat(anthropic): support longcat as Bearer-auth Anthropic-compatible provider
LongCat (Meituan) ships an Anthropic-compatible endpoint at
https://api.longcat.chat/anthropic that authenticates via
`Authorization: Bearer $KEY` instead of Anthropic's native `x-api-key`
header. Without this change, pi sends x-api-key and LongCat replies
with 401 invalid_api_key / missing_api_key.

Same topology as the existing alibaba-coding-plan / minimax /
minimax-cn entries (#3783).

- Add "longcat" to usesAnthropicBearerAuth() so createClient routes
  the key through authToken.
- Add "longcat": "LONGCAT_API_KEY" to env-api-keys.ts envMap so
  getEnvApiKey() can resolve it when options.apiKey is absent.
- Add "longcat" to KnownProvider so the === literal check type-checks.
- Extend anthropic-auth.test.ts to assert usesAnthropicBearerAuth
  returns true for longcat.
2026-04-15 08:54:52 +02:00
Jeremy McSpadden
cb8ac79ce6 Merge pull request #4245 from jeremymcs/fix/claude-mcp-orphaned-subturn-text
fix(chat): preserve Claude MCP chat visibility during tool-only windows
2026-04-14 23:41:36 -05:00
Jeremy
bc98495cdd fix(chat): preserve claude MCP thinking visibility during tool windows 2026-04-14 23:09:20 -05:00
Jeremy
51fdd6e973 fix(chat): cap claude reasoning blocks to keep chat visible 2026-04-14 22:58:56 -05:00
Jeremy McSpadden
7f20908f4e Merge pull request #4234 from jeremymcs/fix/claude-mcp-tool-ordering
fix(gsd-auto): persist stuck-state on dev-path iterations (#4231)
2026-04-14 22:42:00 -05:00