@ikarmic/forge-core 4.5.0 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +44 -21
- package/README.md +1 -1
- package/dist/agent/agent.d.ts +8 -1
- package/dist/agent/agent.js +143 -23
- package/dist/agent/architect.d.ts +0 -1
- package/dist/agent/architect.js +0 -1
- package/dist/agent/background.d.ts +58 -0
- package/dist/agent/background.js +139 -0
- package/dist/agent/cache-hints.d.ts +0 -1
- package/dist/agent/cache-hints.js +0 -1
- package/dist/agent/cost-router.d.ts +0 -1
- package/dist/agent/cost-router.js +0 -1
- package/dist/agent/enhance-prompt.d.ts +9 -0
- package/dist/agent/enhance-prompt.js +34 -0
- package/dist/agent/goal.d.ts +54 -0
- package/dist/agent/goal.js +65 -0
- package/dist/agent/index.d.ts +0 -1
- package/dist/agent/index.js +0 -1
- package/dist/agent/loop-guard.d.ts +21 -0
- package/dist/agent/loop-guard.js +41 -0
- package/dist/agent/prompts.d.ts +0 -1
- package/dist/agent/prompts.js +0 -1
- package/dist/agent/think-tags.d.ts +0 -1
- package/dist/agent/think-tags.js +0 -1
- package/dist/agent/verify.d.ts +0 -1
- package/dist/agent/verify.js +0 -1
- package/dist/agents/agent-files.d.ts +43 -0
- package/dist/agents/agent-files.js +109 -0
- package/dist/ai-comments/index.d.ts +0 -1
- package/dist/ai-comments/index.js +0 -1
- package/dist/attachments.d.ts +0 -1
- package/dist/attachments.js +0 -1
- package/dist/browser/cdp.d.ts +0 -1
- package/dist/browser/cdp.js +0 -1
- package/dist/browser/chrome.d.ts +0 -1
- package/dist/browser/chrome.js +0 -1
- package/dist/browser/session.d.ts +0 -1
- package/dist/browser/session.js +0 -1
- package/dist/checkpoints/index.d.ts +0 -1
- package/dist/checkpoints/index.js +0 -1
- package/dist/checkpoints/store.d.ts +0 -1
- package/dist/checkpoints/store.js +5 -2
- package/dist/checkpoints/types.d.ts +0 -1
- package/dist/checkpoints/types.js +0 -1
- package/dist/code-index/builder.d.ts +0 -1
- package/dist/code-index/builder.js +0 -1
- package/dist/code-index/index-store.d.ts +0 -1
- package/dist/code-index/index-store.js +0 -1
- package/dist/code-index/parser.d.ts +0 -1
- package/dist/code-index/parser.js +0 -1
- package/dist/code-index/types.d.ts +0 -1
- package/dist/code-index/types.js +0 -1
- package/dist/commands/custom-commands.d.ts +9 -5
- package/dist/commands/custom-commands.js +13 -3
- package/dist/config-file.d.ts +47 -1
- package/dist/config-file.js +249 -6
- package/dist/config-merge.d.ts +13 -0
- package/dist/config-merge.js +67 -0
- package/dist/config-schema.d.ts +340 -0
- package/dist/config-schema.js +126 -0
- package/dist/config.d.ts +0 -1
- package/dist/config.js +2 -2
- package/dist/context/compaction.d.ts +0 -1
- package/dist/context/compaction.js +10 -2
- package/dist/context/mask.d.ts +0 -1
- package/dist/context/mask.js +1 -2
- package/dist/credentials/index.d.ts +0 -1
- package/dist/credentials/index.js +0 -1
- package/dist/credentials/types.d.ts +0 -1
- package/dist/credentials/types.js +0 -1
- package/dist/custom-providers.d.ts +95 -0
- package/dist/custom-providers.js +120 -0
- package/dist/diff/index.d.ts +0 -1
- package/dist/diff/index.js +0 -1
- package/dist/diff/unified-diff.d.ts +0 -1
- package/dist/diff/unified-diff.js +0 -1
- package/dist/git/auto-commit.d.ts +3 -4
- package/dist/git/auto-commit.js +8 -7
- package/dist/git/index.d.ts +0 -1
- package/dist/git/index.js +0 -1
- package/dist/github/github-tools.d.ts +2 -3
- package/dist/github/github-tools.js +0 -1
- package/dist/hooks/agent-runner.d.ts +0 -1
- package/dist/hooks/agent-runner.js +0 -1
- package/dist/hooks/bus.d.ts +0 -1
- package/dist/hooks/bus.js +0 -1
- package/dist/hooks/config.d.ts +0 -1
- package/dist/hooks/config.js +0 -1
- package/dist/hooks/events.d.ts +0 -1
- package/dist/hooks/events.js +0 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/index.js +0 -1
- package/dist/hooks/loader.d.ts +0 -1
- package/dist/hooks/loader.js +0 -1
- package/dist/hooks/runner.d.ts +0 -1
- package/dist/hooks/runner.js +3 -3
- package/dist/hooks/watch-coalescer.d.ts +0 -1
- package/dist/hooks/watch-coalescer.js +0 -1
- package/dist/hooks/watch-ignore.d.ts +0 -1
- package/dist/hooks/watch-ignore.js +0 -1
- package/dist/hooks/watcher.d.ts +0 -1
- package/dist/hooks/watcher.js +0 -1
- package/dist/import/claude-code.d.ts +39 -0
- package/dist/import/claude-code.js +254 -0
- package/dist/index.d.ts +37 -7
- package/dist/index.js +28 -5
- package/dist/lazy-model.d.ts +0 -1
- package/dist/lazy-model.js +0 -1
- package/dist/lint/auto-lint.d.ts +0 -1
- package/dist/lint/auto-lint.js +0 -1
- package/dist/lint/index.d.ts +0 -1
- package/dist/lint/index.js +0 -1
- package/dist/lsp/client.d.ts +5 -1
- package/dist/lsp/client.js +39 -4
- package/dist/lsp/diagnostics.d.ts +0 -1
- package/dist/lsp/diagnostics.js +0 -1
- package/dist/lsp/index.d.ts +0 -1
- package/dist/lsp/index.js +0 -1
- package/dist/mcp/catalog.d.ts +0 -1
- package/dist/mcp/catalog.js +0 -1
- package/dist/mcp/index.d.ts +5 -2
- package/dist/mcp/index.js +3 -2
- package/dist/mcp/json-schema-to-zod.d.ts +0 -1
- package/dist/mcp/json-schema-to-zod.js +0 -1
- package/dist/mcp/manager.d.ts +17 -4
- package/dist/mcp/manager.js +27 -3
- package/dist/mcp/marketplace-types.d.ts +0 -1
- package/dist/mcp/marketplace-types.js +0 -1
- package/dist/mcp/marketplace.d.ts +2 -1
- package/dist/mcp/marketplace.js +10 -5
- package/dist/mcp/mcp-client.d.ts +12 -3
- package/dist/mcp/mcp-client.js +74 -18
- package/dist/mcp/mcp-config.d.ts +2 -1
- package/dist/mcp/mcp-config.js +1 -1
- package/dist/mcp/oauth.d.ts +55 -0
- package/dist/mcp/oauth.js +197 -0
- package/dist/mcp/registry.d.ts +0 -1
- package/dist/mcp/registry.js +0 -1
- package/dist/mcp/resource-tools.d.ts +8 -0
- package/dist/mcp/resource-tools.js +56 -0
- package/dist/memory/memory-store.d.ts +0 -1
- package/dist/memory/memory-store.js +0 -1
- package/dist/memory/rank.d.ts +0 -1
- package/dist/memory/rank.js +0 -1
- package/dist/memory/session-digest.d.ts +12 -0
- package/dist/memory/session-digest.js +47 -0
- package/dist/memory/stale.d.ts +0 -1
- package/dist/memory/stale.js +2 -2
- package/dist/model-alias.d.ts +18 -3
- package/dist/model-alias.js +27 -4
- package/dist/model-catalog.d.ts +0 -1
- package/dist/model-catalog.js +0 -2
- package/dist/model-list.d.ts +0 -1
- package/dist/model-list.js +2 -2
- package/dist/model-overrides.d.ts +30 -0
- package/dist/model-overrides.js +48 -0
- package/dist/orchestrator/board-tools.d.ts +0 -1
- package/dist/orchestrator/board-tools.js +0 -1
- package/dist/orchestrator/board.d.ts +0 -1
- package/dist/orchestrator/board.js +0 -1
- package/dist/orchestrator/index.d.ts +0 -1
- package/dist/orchestrator/index.js +0 -1
- package/dist/orchestrator/orchestrator.d.ts +0 -1
- package/dist/orchestrator/orchestrator.js +0 -1
- package/dist/orchestrator/router.d.ts +0 -1
- package/dist/orchestrator/router.js +0 -1
- package/dist/orchestrator/specialists-registry.d.ts +0 -1
- package/dist/orchestrator/specialists-registry.js +2 -4
- package/dist/orchestrator/specialists.d.ts +0 -1
- package/dist/orchestrator/specialists.js +4 -5
- package/dist/orchestrator/types.d.ts +0 -1
- package/dist/orchestrator/types.js +0 -1
- package/dist/plugins/index.d.ts +0 -1
- package/dist/plugins/index.js +0 -1
- package/dist/plugins/install.d.ts +0 -1
- package/dist/plugins/install.js +0 -1
- package/dist/plugins/loader.d.ts +0 -1
- package/dist/plugins/loader.js +0 -1
- package/dist/policy/audit.d.ts +0 -1
- package/dist/policy/audit.js +0 -1
- package/dist/policy/ca-certs.d.ts +8 -0
- package/dist/policy/ca-certs.js +30 -0
- package/dist/policy/policy.d.ts +0 -1
- package/dist/policy/policy.js +0 -1
- package/dist/policy/proxy.d.ts +10 -4
- package/dist/policy/proxy.js +33 -7
- package/dist/pricing.d.ts +0 -1
- package/dist/pricing.js +4 -1
- package/dist/providers.d.ts +7 -1
- package/dist/providers.js +39 -6
- package/dist/repomap/index.d.ts +0 -1
- package/dist/repomap/index.js +0 -1
- package/dist/repomap/repo-map.d.ts +0 -1
- package/dist/repomap/repo-map.js +0 -1
- package/dist/semantic/chunker.d.ts +0 -1
- package/dist/semantic/chunker.js +0 -1
- package/dist/semantic/embedder.d.ts +15 -1
- package/dist/semantic/embedder.js +25 -1
- package/dist/semantic/semantic-index.d.ts +10 -3
- package/dist/semantic/semantic-index.js +16 -8
- package/dist/semantic/vector-store.d.ts +0 -1
- package/dist/semantic/vector-store.js +0 -1
- package/dist/sessions/index.d.ts +1 -1
- package/dist/sessions/index.js +1 -1
- package/dist/sessions/prune.d.ts +23 -0
- package/dist/sessions/prune.js +35 -0
- package/dist/sessions/search.d.ts +0 -1
- package/dist/sessions/search.js +0 -1
- package/dist/sessions/session-export.d.ts +0 -1
- package/dist/sessions/session-export.js +0 -1
- package/dist/sessions/session-store.d.ts +0 -1
- package/dist/sessions/session-store.js +2 -2
- package/dist/sessions/watch.d.ts +0 -1
- package/dist/sessions/watch.js +0 -1
- package/dist/settings-export.d.ts +0 -1
- package/dist/settings-export.js +0 -1
- package/dist/skills/activator.d.ts +0 -1
- package/dist/skills/activator.js +0 -1
- package/dist/skills/builtin.d.ts +2 -0
- package/dist/skills/builtin.js +68 -0
- package/dist/skills/index.d.ts +2 -1
- package/dist/skills/index.js +2 -1
- package/dist/skills/loader.d.ts +10 -4
- package/dist/skills/loader.js +20 -8
- package/dist/skills/marketplace-types.d.ts +0 -1
- package/dist/skills/marketplace-types.js +0 -1
- package/dist/skills/marketplace.d.ts +0 -1
- package/dist/skills/marketplace.js +2 -2
- package/dist/skills/parser.d.ts +0 -1
- package/dist/skills/parser.js +0 -1
- package/dist/skills/remote.d.ts +14 -0
- package/dist/skills/remote.js +131 -0
- package/dist/skills/types.d.ts +10 -1
- package/dist/skills/types.js +0 -1
- package/dist/specs/generate.d.ts +0 -1
- package/dist/specs/generate.js +0 -1
- package/dist/specs/index.d.ts +0 -1
- package/dist/specs/index.js +0 -1
- package/dist/specs/store.d.ts +0 -1
- package/dist/specs/store.js +0 -1
- package/dist/specs/sync.d.ts +0 -1
- package/dist/specs/sync.js +0 -1
- package/dist/specs/tasks-parser.d.ts +0 -1
- package/dist/specs/tasks-parser.js +0 -1
- package/dist/specs/types.d.ts +0 -1
- package/dist/specs/types.js +0 -1
- package/dist/steering/extra-instructions.d.ts +8 -0
- package/dist/steering/extra-instructions.js +104 -0
- package/dist/steering/folder-instructions.d.ts +8 -0
- package/dist/steering/folder-instructions.js +28 -0
- package/dist/steering/glob.d.ts +0 -1
- package/dist/steering/glob.js +0 -1
- package/dist/steering/index.d.ts +0 -1
- package/dist/steering/index.js +0 -1
- package/dist/steering/loader.d.ts +0 -1
- package/dist/steering/loader.js +0 -1
- package/dist/steering/project-instructions.d.ts +0 -1
- package/dist/steering/project-instructions.js +0 -1
- package/dist/steering/select.d.ts +0 -1
- package/dist/steering/select.js +2 -2
- package/dist/steering/types.d.ts +0 -1
- package/dist/steering/types.js +0 -1
- package/dist/structured/index.d.ts +0 -1
- package/dist/structured/index.js +0 -1
- package/dist/structured/retry.d.ts +0 -1
- package/dist/structured/retry.js +0 -1
- package/dist/structured/schema.d.ts +0 -1
- package/dist/structured/schema.js +0 -1
- package/dist/timed-fetch.d.ts +12 -0
- package/dist/timed-fetch.js +83 -0
- package/dist/tools/apply-patch.d.ts +52 -0
- package/dist/tools/apply-patch.js +197 -0
- package/dist/tools/ask-user.d.ts +27 -0
- package/dist/tools/ask-user.js +32 -0
- package/dist/tools/browser-tools.d.ts +6 -7
- package/dist/tools/browser-tools.js +3 -14
- package/dist/tools/codebase-search.d.ts +4 -3
- package/dist/tools/codebase-search.js +2 -3
- package/dist/tools/command-allow.d.ts +0 -1
- package/dist/tools/command-allow.js +0 -1
- package/dist/tools/edit-file.d.ts +0 -1
- package/dist/tools/edit-file.js +5 -4
- package/dist/tools/fetch-url.d.ts +7 -1
- package/dist/tools/fetch-url.js +52 -20
- package/dist/tools/find-references.d.ts +0 -1
- package/dist/tools/find-references.js +0 -1
- package/dist/tools/find-symbol.d.ts +2 -3
- package/dist/tools/find-symbol.js +0 -1
- package/dist/tools/ignore-rules.d.ts +0 -1
- package/dist/tools/ignore-rules.js +2 -2
- package/dist/tools/index.d.ts +5 -2
- package/dist/tools/index.js +10 -2
- package/dist/tools/list-files.d.ts +0 -1
- package/dist/tools/list-files.js +0 -1
- package/dist/tools/list-symbols.d.ts +0 -1
- package/dist/tools/list-symbols.js +0 -1
- package/dist/tools/memory.d.ts +6 -7
- package/dist/tools/memory.js +0 -1
- package/dist/tools/notebook.d.ts +2 -3
- package/dist/tools/notebook.js +0 -1
- package/dist/tools/permission-rules.d.ts +32 -0
- package/dist/tools/permission-rules.js +182 -0
- package/dist/tools/policy.d.ts +0 -1
- package/dist/tools/policy.js +0 -1
- package/dist/tools/read-file.d.ts +5 -1
- package/dist/tools/read-file.js +7 -3
- package/dist/tools/read-image.d.ts +0 -1
- package/dist/tools/read-image.js +0 -1
- package/dist/tools/read-only.d.ts +1 -2
- package/dist/tools/read-only.js +2 -1
- package/dist/tools/redact.d.ts +0 -1
- package/dist/tools/redact.js +0 -1
- package/dist/tools/result-cache.d.ts +0 -1
- package/dist/tools/result-cache.js +0 -1
- package/dist/tools/run-command.d.ts +4 -3
- package/dist/tools/run-command.js +12 -9
- package/dist/tools/sandbox-loader.d.ts +0 -1
- package/dist/tools/sandbox-loader.js +3 -14
- package/dist/tools/search-files.d.ts +8 -3
- package/dist/tools/search-files.js +43 -1
- package/dist/tools/shared.d.ts +5 -1
- package/dist/tools/shared.js +30 -3
- package/dist/tools/shell-env.d.ts +7 -0
- package/dist/tools/shell-env.js +9 -0
- package/dist/tools/sub-agent-wait.d.ts +29 -0
- package/dist/tools/sub-agent-wait.js +60 -0
- package/dist/tools/sub-agent.d.ts +50 -5
- package/dist/tools/sub-agent.js +210 -126
- package/dist/tools/text-encoding.d.ts +10 -0
- package/dist/tools/text-encoding.js +40 -0
- package/dist/tools/todo.d.ts +36 -0
- package/dist/tools/todo.js +42 -0
- package/dist/tools/web-search.d.ts +0 -1
- package/dist/tools/web-search.js +0 -1
- package/dist/tools/write-file.d.ts +0 -1
- package/dist/tools/write-file.js +15 -10
- package/dist/tools/write-tools.d.ts +12 -0
- package/dist/tools/write-tools.js +18 -0
- package/dist/types.d.ts +85 -2
- package/dist/types.js +0 -1
- package/dist/verify/detect.d.ts +0 -1
- package/dist/verify/detect.js +0 -1
- package/dist/verify/index.d.ts +0 -1
- package/dist/verify/index.js +0 -1
- package/dist/worktree/branch-ops.d.ts +0 -1
- package/dist/worktree/branch-ops.js +0 -1
- package/dist/worktree/index.d.ts +0 -1
- package/dist/worktree/index.js +0 -1
- package/dist/worktree/worktree.d.ts +3 -1
- package/dist/worktree/worktree.js +22 -1
- package/package.json +3 -2
- package/dist/agent/agent.d.ts.map +0 -1
- package/dist/agent/agent.js.map +0 -1
- package/dist/agent/architect.d.ts.map +0 -1
- package/dist/agent/architect.js.map +0 -1
- package/dist/agent/cache-hints.d.ts.map +0 -1
- package/dist/agent/cache-hints.js.map +0 -1
- package/dist/agent/cost-router.d.ts.map +0 -1
- package/dist/agent/cost-router.js.map +0 -1
- package/dist/agent/index.d.ts.map +0 -1
- package/dist/agent/index.js.map +0 -1
- package/dist/agent/prompts.d.ts.map +0 -1
- package/dist/agent/prompts.js.map +0 -1
- package/dist/agent/think-tags.d.ts.map +0 -1
- package/dist/agent/think-tags.js.map +0 -1
- package/dist/agent/verify.d.ts.map +0 -1
- package/dist/agent/verify.js.map +0 -1
- package/dist/ai-comments/index.d.ts.map +0 -1
- package/dist/ai-comments/index.js.map +0 -1
- package/dist/attachments.d.ts.map +0 -1
- package/dist/attachments.js.map +0 -1
- package/dist/browser/cdp.d.ts.map +0 -1
- package/dist/browser/cdp.js.map +0 -1
- package/dist/browser/chrome.d.ts.map +0 -1
- package/dist/browser/chrome.js.map +0 -1
- package/dist/browser/session.d.ts.map +0 -1
- package/dist/browser/session.js.map +0 -1
- package/dist/checkpoints/index.d.ts.map +0 -1
- package/dist/checkpoints/index.js.map +0 -1
- package/dist/checkpoints/store.d.ts.map +0 -1
- package/dist/checkpoints/store.js.map +0 -1
- package/dist/checkpoints/types.d.ts.map +0 -1
- package/dist/checkpoints/types.js.map +0 -1
- package/dist/code-index/builder.d.ts.map +0 -1
- package/dist/code-index/builder.js.map +0 -1
- package/dist/code-index/index-store.d.ts.map +0 -1
- package/dist/code-index/index-store.js.map +0 -1
- package/dist/code-index/parser.d.ts.map +0 -1
- package/dist/code-index/parser.js.map +0 -1
- package/dist/code-index/types.d.ts.map +0 -1
- package/dist/code-index/types.js.map +0 -1
- package/dist/commands/custom-commands.d.ts.map +0 -1
- package/dist/commands/custom-commands.js.map +0 -1
- package/dist/config-file.d.ts.map +0 -1
- package/dist/config-file.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/context/compaction.d.ts.map +0 -1
- package/dist/context/compaction.js.map +0 -1
- package/dist/context/mask.d.ts.map +0 -1
- package/dist/context/mask.js.map +0 -1
- package/dist/credentials/index.d.ts.map +0 -1
- package/dist/credentials/index.js.map +0 -1
- package/dist/credentials/types.d.ts.map +0 -1
- package/dist/credentials/types.js.map +0 -1
- package/dist/diff/index.d.ts.map +0 -1
- package/dist/diff/index.js.map +0 -1
- package/dist/diff/unified-diff.d.ts.map +0 -1
- package/dist/diff/unified-diff.js.map +0 -1
- package/dist/git/auto-commit.d.ts.map +0 -1
- package/dist/git/auto-commit.js.map +0 -1
- package/dist/git/index.d.ts.map +0 -1
- package/dist/git/index.js.map +0 -1
- package/dist/github/github-tools.d.ts.map +0 -1
- package/dist/github/github-tools.js.map +0 -1
- package/dist/hooks/agent-runner.d.ts.map +0 -1
- package/dist/hooks/agent-runner.js.map +0 -1
- package/dist/hooks/bus.d.ts.map +0 -1
- package/dist/hooks/bus.js.map +0 -1
- package/dist/hooks/config.d.ts.map +0 -1
- package/dist/hooks/config.js.map +0 -1
- package/dist/hooks/events.d.ts.map +0 -1
- package/dist/hooks/events.js.map +0 -1
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/loader.d.ts.map +0 -1
- package/dist/hooks/loader.js.map +0 -1
- package/dist/hooks/runner.d.ts.map +0 -1
- package/dist/hooks/runner.js.map +0 -1
- package/dist/hooks/watch-coalescer.d.ts.map +0 -1
- package/dist/hooks/watch-coalescer.js.map +0 -1
- package/dist/hooks/watch-ignore.d.ts.map +0 -1
- package/dist/hooks/watch-ignore.js.map +0 -1
- package/dist/hooks/watcher.d.ts.map +0 -1
- package/dist/hooks/watcher.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lazy-model.d.ts.map +0 -1
- package/dist/lazy-model.js.map +0 -1
- package/dist/lint/auto-lint.d.ts.map +0 -1
- package/dist/lint/auto-lint.js.map +0 -1
- package/dist/lint/index.d.ts.map +0 -1
- package/dist/lint/index.js.map +0 -1
- package/dist/lsp/client.d.ts.map +0 -1
- package/dist/lsp/client.js.map +0 -1
- package/dist/lsp/diagnostics.d.ts.map +0 -1
- package/dist/lsp/diagnostics.js.map +0 -1
- package/dist/lsp/index.d.ts.map +0 -1
- package/dist/lsp/index.js.map +0 -1
- package/dist/mcp/catalog.d.ts.map +0 -1
- package/dist/mcp/catalog.js.map +0 -1
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/json-schema-to-zod.d.ts.map +0 -1
- package/dist/mcp/json-schema-to-zod.js.map +0 -1
- package/dist/mcp/manager.d.ts.map +0 -1
- package/dist/mcp/manager.js.map +0 -1
- package/dist/mcp/marketplace-types.d.ts.map +0 -1
- package/dist/mcp/marketplace-types.js.map +0 -1
- package/dist/mcp/marketplace.d.ts.map +0 -1
- package/dist/mcp/marketplace.js.map +0 -1
- package/dist/mcp/mcp-client.d.ts.map +0 -1
- package/dist/mcp/mcp-client.js.map +0 -1
- package/dist/mcp/mcp-config.d.ts.map +0 -1
- package/dist/mcp/mcp-config.js.map +0 -1
- package/dist/mcp/registry.d.ts.map +0 -1
- package/dist/mcp/registry.js.map +0 -1
- package/dist/memory/memory-store.d.ts.map +0 -1
- package/dist/memory/memory-store.js.map +0 -1
- package/dist/memory/rank.d.ts.map +0 -1
- package/dist/memory/rank.js.map +0 -1
- package/dist/memory/stale.d.ts.map +0 -1
- package/dist/memory/stale.js.map +0 -1
- package/dist/model-alias.d.ts.map +0 -1
- package/dist/model-alias.js.map +0 -1
- package/dist/model-catalog.d.ts.map +0 -1
- package/dist/model-catalog.js.map +0 -1
- package/dist/model-list.d.ts.map +0 -1
- package/dist/model-list.js.map +0 -1
- package/dist/orchestrator/board-tools.d.ts.map +0 -1
- package/dist/orchestrator/board-tools.js.map +0 -1
- package/dist/orchestrator/board.d.ts.map +0 -1
- package/dist/orchestrator/board.js.map +0 -1
- package/dist/orchestrator/index.d.ts.map +0 -1
- package/dist/orchestrator/index.js.map +0 -1
- package/dist/orchestrator/orchestrator.d.ts.map +0 -1
- package/dist/orchestrator/orchestrator.js.map +0 -1
- package/dist/orchestrator/router.d.ts.map +0 -1
- package/dist/orchestrator/router.js.map +0 -1
- package/dist/orchestrator/specialists-registry.d.ts.map +0 -1
- package/dist/orchestrator/specialists-registry.js.map +0 -1
- package/dist/orchestrator/specialists.d.ts.map +0 -1
- package/dist/orchestrator/specialists.js.map +0 -1
- package/dist/orchestrator/types.d.ts.map +0 -1
- package/dist/orchestrator/types.js.map +0 -1
- package/dist/plugins/index.d.ts.map +0 -1
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/install.d.ts.map +0 -1
- package/dist/plugins/install.js.map +0 -1
- package/dist/plugins/loader.d.ts.map +0 -1
- package/dist/plugins/loader.js.map +0 -1
- package/dist/policy/audit.d.ts.map +0 -1
- package/dist/policy/audit.js.map +0 -1
- package/dist/policy/policy.d.ts.map +0 -1
- package/dist/policy/policy.js.map +0 -1
- package/dist/policy/proxy.d.ts.map +0 -1
- package/dist/policy/proxy.js.map +0 -1
- package/dist/pricing.d.ts.map +0 -1
- package/dist/pricing.js.map +0 -1
- package/dist/providers.d.ts.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/repomap/index.d.ts.map +0 -1
- package/dist/repomap/index.js.map +0 -1
- package/dist/repomap/repo-map.d.ts.map +0 -1
- package/dist/repomap/repo-map.js.map +0 -1
- package/dist/semantic/chunker.d.ts.map +0 -1
- package/dist/semantic/chunker.js.map +0 -1
- package/dist/semantic/embedder.d.ts.map +0 -1
- package/dist/semantic/embedder.js.map +0 -1
- package/dist/semantic/semantic-index.d.ts.map +0 -1
- package/dist/semantic/semantic-index.js.map +0 -1
- package/dist/semantic/vector-store.d.ts.map +0 -1
- package/dist/semantic/vector-store.js.map +0 -1
- package/dist/sessions/index.d.ts.map +0 -1
- package/dist/sessions/index.js.map +0 -1
- package/dist/sessions/search.d.ts.map +0 -1
- package/dist/sessions/search.js.map +0 -1
- package/dist/sessions/session-export.d.ts.map +0 -1
- package/dist/sessions/session-export.js.map +0 -1
- package/dist/sessions/session-store.d.ts.map +0 -1
- package/dist/sessions/session-store.js.map +0 -1
- package/dist/sessions/watch.d.ts.map +0 -1
- package/dist/sessions/watch.js.map +0 -1
- package/dist/settings-export.d.ts.map +0 -1
- package/dist/settings-export.js.map +0 -1
- package/dist/skills/activator.d.ts.map +0 -1
- package/dist/skills/activator.js.map +0 -1
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/loader.d.ts.map +0 -1
- package/dist/skills/loader.js.map +0 -1
- package/dist/skills/marketplace-types.d.ts.map +0 -1
- package/dist/skills/marketplace-types.js.map +0 -1
- package/dist/skills/marketplace.d.ts.map +0 -1
- package/dist/skills/marketplace.js.map +0 -1
- package/dist/skills/parser.d.ts.map +0 -1
- package/dist/skills/parser.js.map +0 -1
- package/dist/skills/types.d.ts.map +0 -1
- package/dist/skills/types.js.map +0 -1
- package/dist/specs/generate.d.ts.map +0 -1
- package/dist/specs/generate.js.map +0 -1
- package/dist/specs/index.d.ts.map +0 -1
- package/dist/specs/index.js.map +0 -1
- package/dist/specs/store.d.ts.map +0 -1
- package/dist/specs/store.js.map +0 -1
- package/dist/specs/sync.d.ts.map +0 -1
- package/dist/specs/sync.js.map +0 -1
- package/dist/specs/tasks-parser.d.ts.map +0 -1
- package/dist/specs/tasks-parser.js.map +0 -1
- package/dist/specs/types.d.ts.map +0 -1
- package/dist/specs/types.js.map +0 -1
- package/dist/steering/glob.d.ts.map +0 -1
- package/dist/steering/glob.js.map +0 -1
- package/dist/steering/index.d.ts.map +0 -1
- package/dist/steering/index.js.map +0 -1
- package/dist/steering/loader.d.ts.map +0 -1
- package/dist/steering/loader.js.map +0 -1
- package/dist/steering/project-instructions.d.ts.map +0 -1
- package/dist/steering/project-instructions.js.map +0 -1
- package/dist/steering/select.d.ts.map +0 -1
- package/dist/steering/select.js.map +0 -1
- package/dist/steering/types.d.ts.map +0 -1
- package/dist/steering/types.js.map +0 -1
- package/dist/structured/index.d.ts.map +0 -1
- package/dist/structured/index.js.map +0 -1
- package/dist/structured/retry.d.ts.map +0 -1
- package/dist/structured/retry.js.map +0 -1
- package/dist/structured/schema.d.ts.map +0 -1
- package/dist/structured/schema.js.map +0 -1
- package/dist/tools/browser-tools.d.ts.map +0 -1
- package/dist/tools/browser-tools.js.map +0 -1
- package/dist/tools/codebase-search.d.ts.map +0 -1
- package/dist/tools/codebase-search.js.map +0 -1
- package/dist/tools/command-allow.d.ts.map +0 -1
- package/dist/tools/command-allow.js.map +0 -1
- package/dist/tools/edit-file.d.ts.map +0 -1
- package/dist/tools/edit-file.js.map +0 -1
- package/dist/tools/fetch-url.d.ts.map +0 -1
- package/dist/tools/fetch-url.js.map +0 -1
- package/dist/tools/find-references.d.ts.map +0 -1
- package/dist/tools/find-references.js.map +0 -1
- package/dist/tools/find-symbol.d.ts.map +0 -1
- package/dist/tools/find-symbol.js.map +0 -1
- package/dist/tools/ignore-rules.d.ts.map +0 -1
- package/dist/tools/ignore-rules.js.map +0 -1
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/list-files.d.ts.map +0 -1
- package/dist/tools/list-files.js.map +0 -1
- package/dist/tools/list-symbols.d.ts.map +0 -1
- package/dist/tools/list-symbols.js.map +0 -1
- package/dist/tools/memory.d.ts.map +0 -1
- package/dist/tools/memory.js.map +0 -1
- package/dist/tools/notebook.d.ts.map +0 -1
- package/dist/tools/notebook.js.map +0 -1
- package/dist/tools/policy.d.ts.map +0 -1
- package/dist/tools/policy.js.map +0 -1
- package/dist/tools/read-file.d.ts.map +0 -1
- package/dist/tools/read-file.js.map +0 -1
- package/dist/tools/read-image.d.ts.map +0 -1
- package/dist/tools/read-image.js.map +0 -1
- package/dist/tools/read-only.d.ts.map +0 -1
- package/dist/tools/read-only.js.map +0 -1
- package/dist/tools/redact.d.ts.map +0 -1
- package/dist/tools/redact.js.map +0 -1
- package/dist/tools/result-cache.d.ts.map +0 -1
- package/dist/tools/result-cache.js.map +0 -1
- package/dist/tools/run-command.d.ts.map +0 -1
- package/dist/tools/run-command.js.map +0 -1
- package/dist/tools/sandbox-loader.d.ts.map +0 -1
- package/dist/tools/sandbox-loader.js.map +0 -1
- package/dist/tools/search-files.d.ts.map +0 -1
- package/dist/tools/search-files.js.map +0 -1
- package/dist/tools/shared.d.ts.map +0 -1
- package/dist/tools/shared.js.map +0 -1
- package/dist/tools/sub-agent.d.ts.map +0 -1
- package/dist/tools/sub-agent.js.map +0 -1
- package/dist/tools/web-search.d.ts.map +0 -1
- package/dist/tools/web-search.js.map +0 -1
- package/dist/tools/write-file.d.ts.map +0 -1
- package/dist/tools/write-file.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/verify/detect.d.ts.map +0 -1
- package/dist/verify/detect.js.map +0 -1
- package/dist/verify/index.d.ts.map +0 -1
- package/dist/verify/index.js.map +0 -1
- package/dist/worktree/branch-ops.d.ts.map +0 -1
- package/dist/worktree/branch-ops.js.map +0 -1
- package/dist/worktree/index.d.ts.map +0 -1
- package/dist/worktree/index.js.map +0 -1
- package/dist/worktree/worktree.d.ts.map +0 -1
- package/dist/worktree/worktree.js.map +0 -1
package/dist/browser/session.js
CHANGED
|
@@ -9,4 +9,3 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { CheckpointStore, type CheckpointStoreLimits } from './store.js';
|
|
11
11
|
export type { CaptureOptions, Checkpoint, CheckpointFile, CheckpointFileStatus, CheckpointSummary, CheckpointTrigger, PruneResult, RestoreResult, } from './types.js';
|
|
12
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -16,6 +16,7 @@ import { existsSync } from 'node:fs';
|
|
|
16
16
|
import { mkdir, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
17
17
|
import path from 'node:path';
|
|
18
18
|
import { snapshotWorktreeContext } from '../worktree/worktree.js';
|
|
19
|
+
import { isOutsideRel } from '../tools/shared.js';
|
|
19
20
|
const MANIFEST_FILENAME = 'manifest.json';
|
|
20
21
|
const FILES_SUBDIR = 'files';
|
|
21
22
|
/** Default retention for prune. Keeps the last 20 checkpoints. */
|
|
@@ -128,7 +129,7 @@ export class CheckpointStore {
|
|
|
128
129
|
const abs = path.resolve(this.cwd, options.focusPath);
|
|
129
130
|
const rel = path.relative(this.cwd, abs);
|
|
130
131
|
// Skip files outside cwd (security: never capture /etc/passwd).
|
|
131
|
-
if (!
|
|
132
|
+
if (!isOutsideRel(rel)) {
|
|
132
133
|
await this.captureFile(rel, files, dir);
|
|
133
134
|
}
|
|
134
135
|
}
|
|
@@ -316,6 +317,9 @@ export class CheckpointStore {
|
|
|
316
317
|
};
|
|
317
318
|
for (const file of checkpoint.files) {
|
|
318
319
|
const abs = path.join(this.cwd, file.path);
|
|
320
|
+
// A manifest is data on disk: an entry leading out of the workspace (damaged or edited) is never written or removed.
|
|
321
|
+
if (isOutsideRel(path.relative(this.cwd, abs)))
|
|
322
|
+
continue;
|
|
319
323
|
const contentPath = path.join(dir, FILES_SUBDIR, encodePath(file.path));
|
|
320
324
|
if (file.status === 'deleted') {
|
|
321
325
|
if (existsSync(abs)) {
|
|
@@ -408,4 +412,3 @@ function defaultDescription(options) {
|
|
|
408
412
|
}
|
|
409
413
|
return 'manual checkpoint';
|
|
410
414
|
}
|
|
411
|
-
//# sourceMappingURL=store.js.map
|
|
@@ -9,4 +9,3 @@ export declare function saveManifest(cwd: string, manifest: IndexManifest): Prom
|
|
|
9
9
|
export declare function getEntry(manifest: IndexManifest, relPath: string): IndexFileEntry | undefined;
|
|
10
10
|
export declare function setEntry(manifest: IndexManifest, relPath: string, entry: IndexFileEntry): void;
|
|
11
11
|
export declare function deleteEntry(manifest: IndexManifest, relPath: string): void;
|
|
12
|
-
//# sourceMappingURL=index-store.d.ts.map
|
package/dist/code-index/types.js
CHANGED
|
@@ -2,6 +2,14 @@ export interface CustomCommand {
|
|
|
2
2
|
/** Lowercase name used after the slash. */
|
|
3
3
|
name: string;
|
|
4
4
|
description?: string;
|
|
5
|
+
/** Front matter `agent`: the agent (mode) this command runs as. */
|
|
6
|
+
agent?: string;
|
|
7
|
+
/** Front matter `model`: a model for this command. */
|
|
8
|
+
model?: string;
|
|
9
|
+
/** Front matter `variant`: reasoning effort for this command. */
|
|
10
|
+
variant?: 'low' | 'medium' | 'high';
|
|
11
|
+
/** Front matter `subtask: true`: hand the work to `agent` through sub_agent instead of switching to it. */
|
|
12
|
+
subtask?: boolean;
|
|
5
13
|
template: string;
|
|
6
14
|
source: 'user' | 'project';
|
|
7
15
|
/** Absolute path of the template file. */
|
|
@@ -12,14 +20,10 @@ export declare function commandDirs(cwd: string, home?: string): Array<{
|
|
|
12
20
|
source: 'user' | 'project';
|
|
13
21
|
}>;
|
|
14
22
|
/** Split optional `---` front matter from the body and read its `description`. */
|
|
15
|
-
export declare function parseCommandFile(text: string):
|
|
16
|
-
description?: string;
|
|
17
|
-
template: string;
|
|
18
|
-
};
|
|
23
|
+
export declare function parseCommandFile(text: string): Pick<CustomCommand, 'description' | 'agent' | 'model' | 'variant' | 'subtask' | 'template'>;
|
|
19
24
|
/** Every custom command, keyed by name; project commands replace personal ones. */
|
|
20
25
|
export declare function loadCustomCommands(cwd: string, home?: string): Promise<Map<string, CustomCommand>>;
|
|
21
26
|
/** The message a command sends for these arguments. */
|
|
22
27
|
export declare function expandCustomCommand(command: Pick<CustomCommand, 'template'>, args: string): string;
|
|
23
28
|
/** `/name — description` lines for help output. */
|
|
24
29
|
export declare function formatCustomCommands(commands: Map<string, CustomCommand>): string;
|
|
25
|
-
//# sourceMappingURL=custom-commands.d.ts.map
|
|
@@ -34,8 +34,19 @@ export function parseCommandFile(text) {
|
|
|
34
34
|
const m = /^---\n([\s\S]*?)\n---\n?/.exec(normalized);
|
|
35
35
|
if (!m)
|
|
36
36
|
return { template: normalized.trim() };
|
|
37
|
-
const
|
|
38
|
-
|
|
37
|
+
const field = (key) => new RegExp('^' + key + ':\\s*(.+)$', 'm').exec(m[1])?.[1]?.trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
38
|
+
const desc = field('description');
|
|
39
|
+
const agent = field('agent');
|
|
40
|
+
const model = field('model');
|
|
41
|
+
const variant = field('variant');
|
|
42
|
+
return {
|
|
43
|
+
...(desc ? { description: desc } : {}),
|
|
44
|
+
...(agent ? { agent } : {}),
|
|
45
|
+
...(model ? { model } : {}),
|
|
46
|
+
...(variant === 'low' || variant === 'medium' || variant === 'high' ? { variant } : {}),
|
|
47
|
+
...(field('subtask') === 'true' ? { subtask: true } : {}),
|
|
48
|
+
template: normalized.slice(m[0].length).trim(),
|
|
49
|
+
};
|
|
39
50
|
}
|
|
40
51
|
/** Every custom command, keyed by name; project commands replace personal ones. */
|
|
41
52
|
export async function loadCustomCommands(cwd, home) {
|
|
@@ -96,4 +107,3 @@ export function formatCustomCommands(commands) {
|
|
|
96
107
|
.map((c) => `/${c.name}${c.description ? ` — ${c.description}` : ''}${c.source === 'project' ? ' (project)' : ''}`)
|
|
97
108
|
.join('\n');
|
|
98
109
|
}
|
|
99
|
-
//# sourceMappingURL=custom-commands.js.map
|
package/dist/config-file.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { ModelAliases } from './model-alias.js';
|
|
2
|
+
import { type CustomProviderConfig } from './custom-providers.js';
|
|
3
|
+
import type { ModelOverride } from './model-overrides.js';
|
|
4
|
+
import type { PermissionConfig } from './tools/permission-rules.js';
|
|
2
5
|
import type { ProviderName } from './types.js';
|
|
3
6
|
/**
|
|
4
7
|
* Shape of `~/.forge/config.json`: cross-surface provider/model/display
|
|
@@ -20,12 +23,48 @@ export interface ForgeConfigFile {
|
|
|
20
23
|
command: string;
|
|
21
24
|
fingerprint?: string;
|
|
22
25
|
}>>;
|
|
26
|
+
/**
|
|
27
|
+
* Ordered permission rules (`read`, `edit`, `bash`, `webfetch`, `websearch`, `task`, `external_directory`): each maps
|
|
28
|
+
* to an action or to a pattern → action map; the last matching rule wins. See tools/permission-rules.ts.
|
|
29
|
+
*/
|
|
30
|
+
permission?: PermissionConfig;
|
|
31
|
+
/**
|
|
32
|
+
* Providers beyond the built-in eleven, by id: `groq` and other presets need only a key, anything else needs a
|
|
33
|
+
* `baseUrl`. A model on one is written `id:model` (e.g. `acme:fast`). See custom-providers.ts.
|
|
34
|
+
*/
|
|
35
|
+
customProviders?: Record<string, CustomProviderConfig>;
|
|
36
|
+
/** Context and output limits and prices per model, keyed `provider:model`, `id:model` or a bare model id. */
|
|
37
|
+
modelOverrides?: Record<string, ModelOverride>;
|
|
38
|
+
/** Per provider, which model ids the pickers list: `whitelist` (only these) then `blacklist` (not these). */
|
|
39
|
+
modelFilters?: Record<string, {
|
|
40
|
+
whitelist?: string[];
|
|
41
|
+
blacklist?: string[];
|
|
42
|
+
}>;
|
|
43
|
+
/** The model sub-agents use when the model does not name one; blank means the parent's model. */
|
|
44
|
+
subagentModel?: string;
|
|
45
|
+
/** Extra instruction sources added to the system prompt: files, globs (workspace-relative) and http(s) URLs. User config only. */
|
|
46
|
+
instructions?: string[];
|
|
47
|
+
/** Extra places to read skills from: folders (absolute, `~/...`, or relative to the workspace) or http(s) URLs of a skill file or a skill index. User config only. */
|
|
48
|
+
skillPaths?: string[];
|
|
49
|
+
/** PEM files of extra certificate authorities to trust (absolute or `~/...`), for company networks that re-sign TLS. User config only. */
|
|
50
|
+
caCertificates?: string[];
|
|
23
51
|
/** Short names for models: `"fast": "anthropic:claude-haiku-4-5"`. See model-alias.ts. */
|
|
24
52
|
aliases?: ModelAliases;
|
|
53
|
+
/** Model for a chat mode that has none of its own: mode id → `provider:model`, bare model id or alias. */
|
|
54
|
+
modeModels?: Record<string, string>;
|
|
55
|
+
/** Delete saved sessions not updated for this many days, when the VS Code extension starts. Unset keeps everything. */
|
|
56
|
+
sessionRetentionDays?: number;
|
|
25
57
|
display?: {
|
|
26
58
|
blockDefault?: 'collapsed' | 'expanded';
|
|
27
59
|
detail?: 'compact' | 'full';
|
|
28
60
|
showReasoning?: boolean;
|
|
61
|
+
/** Per kind of block; overrides the two settings above for that kind. */
|
|
62
|
+
blocks?: {
|
|
63
|
+
reasoning?: 'hidden' | 'collapsed' | 'expanded';
|
|
64
|
+
terminal?: 'collapsed' | 'expanded';
|
|
65
|
+
edit?: 'collapsed' | 'expanded';
|
|
66
|
+
mcp?: 'collapsed' | 'expanded';
|
|
67
|
+
};
|
|
29
68
|
};
|
|
30
69
|
}
|
|
31
70
|
export interface LoadForgeConfigFileResult {
|
|
@@ -41,4 +80,11 @@ export declare function loadForgeConfigFile(configPath?: string): Promise<LoadFo
|
|
|
41
80
|
* Fields not present in `partial` are left untouched.
|
|
42
81
|
*/
|
|
43
82
|
export declare function saveForgeConfigFile(partial: ForgeConfigFile, configPath?: string): Promise<void>;
|
|
44
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Read-modify-write of a JSON settings file, safely:
|
|
85
|
+
* - merged over the file as written, not the cleaned config, so keys this version drops or does not know survive;
|
|
86
|
+
* - a file that exists but is not valid JSON is never overwritten (that would replace every setting with one);
|
|
87
|
+
* - writes to one path from this process run one after another, so two saves at once both land;
|
|
88
|
+
* - written to a temporary file and renamed, so a crash cannot leave half a file.
|
|
89
|
+
*/
|
|
90
|
+
export declare function updateJsonFile(filePath: string, update: (existing: Record<string, unknown>) => Record<string, unknown>): Promise<void>;
|
package/dist/config-file.js
CHANGED
|
@@ -1,7 +1,178 @@
|
|
|
1
|
-
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
1
|
+
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
2
|
import { existsSync } from 'node:fs';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { customProviderProblems } from './custom-providers.js';
|
|
6
|
+
const PERMISSION_ACTIONS = new Set(['allow', 'ask', 'deny']);
|
|
7
|
+
const isObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
|
|
8
|
+
const positiveNumber = (n) => typeof n === 'number' && Number.isFinite(n) && n > 0;
|
|
9
|
+
const nonNegativeNumber = (n) => typeof n === 'number' && Number.isFinite(n) && n >= 0;
|
|
10
|
+
const stringList = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === 'string') : undefined);
|
|
11
|
+
const BLOCK_KINDS = {
|
|
12
|
+
reasoning: ['hidden', 'collapsed', 'expanded'],
|
|
13
|
+
terminal: ['collapsed', 'expanded'],
|
|
14
|
+
edit: ['collapsed', 'expanded'],
|
|
15
|
+
mcp: ['collapsed', 'expanded'],
|
|
16
|
+
};
|
|
17
|
+
/** `display.blocks`: keep the kinds and values the chat understands, warn once about each thing it would silently ignore. */
|
|
18
|
+
function cleanDisplayBlocks(config, filePath, warnings) {
|
|
19
|
+
const blocks = config.display?.blocks;
|
|
20
|
+
if (blocks === undefined)
|
|
21
|
+
return;
|
|
22
|
+
const display = config.display;
|
|
23
|
+
if (!isObject(blocks)) {
|
|
24
|
+
warnings.push(`${filePath}: display.blocks must be an object (reasoning, terminal, edit, mcp); ignored`);
|
|
25
|
+
delete display.blocks;
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const kept = {};
|
|
29
|
+
for (const [kind, value] of Object.entries(blocks)) {
|
|
30
|
+
const allowed = BLOCK_KINDS[kind];
|
|
31
|
+
if (!allowed)
|
|
32
|
+
warnings.push(`${filePath}: display.blocks.${kind} is not a block kind (${Object.keys(BLOCK_KINDS).join(', ')}); ignored`);
|
|
33
|
+
else if (typeof value !== 'string' || !allowed.includes(value))
|
|
34
|
+
warnings.push(`${filePath}: display.blocks.${kind} must be ${allowed.join(', ')}; ignored`);
|
|
35
|
+
else
|
|
36
|
+
kept[kind] = value;
|
|
37
|
+
}
|
|
38
|
+
if (Object.keys(kept).length)
|
|
39
|
+
display.blocks = kept;
|
|
40
|
+
else
|
|
41
|
+
delete display.blocks;
|
|
42
|
+
}
|
|
43
|
+
/** Validate `customProviders`, `modelOverrides`, `modelFilters` and `subagentModel`, dropping what cannot be used with one warning each. */
|
|
44
|
+
function cleanProviderKeys(config, filePath, warnings) {
|
|
45
|
+
if (config.customProviders !== undefined) {
|
|
46
|
+
const raw = config.customProviders;
|
|
47
|
+
if (!isObject(raw)) {
|
|
48
|
+
warnings.push(`${filePath}: "customProviders" must be an object of provider id → settings; ignored`);
|
|
49
|
+
delete config.customProviders;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const kept = {};
|
|
53
|
+
const bad = new Set(customProviderProblems(raw).map((p) => p.id));
|
|
54
|
+
for (const p of customProviderProblems(raw))
|
|
55
|
+
warnings.push(`${filePath}: ${p.message} Ignored.`);
|
|
56
|
+
for (const [id, value] of Object.entries(raw)) {
|
|
57
|
+
if (bad.has(id) || !isObject(value))
|
|
58
|
+
continue;
|
|
59
|
+
const entry = { ...value };
|
|
60
|
+
if (entry.headers !== undefined && !(isObject(entry.headers) && Object.values(entry.headers).every((h) => typeof h === 'string'))) {
|
|
61
|
+
warnings.push(`${filePath}: customProviders.${id}.headers must be text values; headers ignored`);
|
|
62
|
+
delete entry.headers;
|
|
63
|
+
}
|
|
64
|
+
kept[id] = entry;
|
|
65
|
+
}
|
|
66
|
+
if (Object.keys(kept).length)
|
|
67
|
+
config.customProviders = kept;
|
|
68
|
+
else
|
|
69
|
+
delete config.customProviders;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (config.modelOverrides !== undefined) {
|
|
73
|
+
const raw = config.modelOverrides;
|
|
74
|
+
if (!isObject(raw)) {
|
|
75
|
+
warnings.push(`${filePath}: "modelOverrides" must be an object of model → numbers; ignored`);
|
|
76
|
+
delete config.modelOverrides;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const kept = {};
|
|
80
|
+
for (const [model, value] of Object.entries(raw)) {
|
|
81
|
+
if (!isObject(value)) {
|
|
82
|
+
warnings.push(`${filePath}: modelOverrides.${model} must be an object; ignored`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const out = {};
|
|
86
|
+
const limit = isObject(value.limit) ? value.limit : undefined;
|
|
87
|
+
if (limit) {
|
|
88
|
+
const l = {};
|
|
89
|
+
for (const k of ['context', 'output']) {
|
|
90
|
+
if (limit[k] === undefined)
|
|
91
|
+
continue;
|
|
92
|
+
if (positiveNumber(limit[k]))
|
|
93
|
+
l[k] = limit[k];
|
|
94
|
+
else
|
|
95
|
+
warnings.push(`${filePath}: modelOverrides.${model}.limit.${k} must be a positive number; ignored`);
|
|
96
|
+
}
|
|
97
|
+
if (Object.keys(l).length)
|
|
98
|
+
out.limit = l;
|
|
99
|
+
}
|
|
100
|
+
const cost = isObject(value.cost) ? value.cost : undefined;
|
|
101
|
+
if (cost) {
|
|
102
|
+
const c = {};
|
|
103
|
+
for (const k of ['input', 'output']) {
|
|
104
|
+
if (cost[k] === undefined)
|
|
105
|
+
continue;
|
|
106
|
+
if (nonNegativeNumber(cost[k]))
|
|
107
|
+
c[k] = cost[k];
|
|
108
|
+
else
|
|
109
|
+
warnings.push(`${filePath}: modelOverrides.${model}.cost.${k} must be a number of 0 or more; ignored`);
|
|
110
|
+
}
|
|
111
|
+
if (Object.keys(c).length)
|
|
112
|
+
out.cost = c;
|
|
113
|
+
}
|
|
114
|
+
if (value.limit !== undefined && !limit)
|
|
115
|
+
warnings.push(`${filePath}: modelOverrides.${model}.limit must be an object; ignored`);
|
|
116
|
+
if (Object.keys(out).length)
|
|
117
|
+
kept[model] = out;
|
|
118
|
+
}
|
|
119
|
+
if (Object.keys(kept).length)
|
|
120
|
+
config.modelOverrides = kept;
|
|
121
|
+
else
|
|
122
|
+
delete config.modelOverrides;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (config.modelFilters !== undefined) {
|
|
126
|
+
const raw = config.modelFilters;
|
|
127
|
+
if (!isObject(raw)) {
|
|
128
|
+
warnings.push(`${filePath}: "modelFilters" must be an object of provider → lists; ignored`);
|
|
129
|
+
delete config.modelFilters;
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
const kept = {};
|
|
133
|
+
for (const [provider, value] of Object.entries(raw)) {
|
|
134
|
+
if (!isObject(value))
|
|
135
|
+
continue;
|
|
136
|
+
const whitelist = stringList(value.whitelist);
|
|
137
|
+
const blacklist = stringList(value.blacklist);
|
|
138
|
+
if (whitelist?.length || blacklist?.length)
|
|
139
|
+
kept[provider] = { ...(whitelist?.length ? { whitelist } : {}), ...(blacklist?.length ? { blacklist } : {}) };
|
|
140
|
+
}
|
|
141
|
+
if (Object.keys(kept).length)
|
|
142
|
+
config.modelFilters = kept;
|
|
143
|
+
else
|
|
144
|
+
delete config.modelFilters;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (config.instructions !== undefined) {
|
|
148
|
+
const list = stringList(config.instructions)?.map((s) => s.trim()).filter(Boolean);
|
|
149
|
+
if (list?.length)
|
|
150
|
+
config.instructions = list;
|
|
151
|
+
else
|
|
152
|
+
delete config.instructions;
|
|
153
|
+
}
|
|
154
|
+
if (config.skillPaths !== undefined) {
|
|
155
|
+
const list = stringList(config.skillPaths)?.map((s) => s.trim()).filter(Boolean);
|
|
156
|
+
if (list?.length)
|
|
157
|
+
config.skillPaths = list;
|
|
158
|
+
else
|
|
159
|
+
delete config.skillPaths;
|
|
160
|
+
}
|
|
161
|
+
if (config.caCertificates !== undefined) {
|
|
162
|
+
const list = stringList(config.caCertificates)?.map((s) => s.trim()).filter(Boolean);
|
|
163
|
+
if (list?.length)
|
|
164
|
+
config.caCertificates = list;
|
|
165
|
+
else
|
|
166
|
+
delete config.caCertificates;
|
|
167
|
+
}
|
|
168
|
+
if (config.subagentModel !== undefined) {
|
|
169
|
+
const v = typeof config.subagentModel === 'string' ? config.subagentModel.trim() : '';
|
|
170
|
+
if (v)
|
|
171
|
+
config.subagentModel = v;
|
|
172
|
+
else
|
|
173
|
+
delete config.subagentModel;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
5
176
|
/** Returns `~/.forge/config.json` for the current user. */
|
|
6
177
|
export function defaultForgeConfigPath() {
|
|
7
178
|
return path.join(homedir(), '.forge', 'config.json');
|
|
@@ -40,6 +211,41 @@ export async function loadForgeConfigFile(configPath) {
|
|
|
40
211
|
}
|
|
41
212
|
}
|
|
42
213
|
}
|
|
214
|
+
if (config.permission !== undefined) {
|
|
215
|
+
const raw = config.permission;
|
|
216
|
+
if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
217
|
+
warnings.push(`${filePath}: "permission" must be an object of permission → action or pattern map; ignored`);
|
|
218
|
+
delete config.permission;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
const kept = {};
|
|
222
|
+
for (const [perm, value] of Object.entries(raw)) {
|
|
223
|
+
if (typeof value === 'string') {
|
|
224
|
+
if (PERMISSION_ACTIONS.has(value))
|
|
225
|
+
kept[perm] = value;
|
|
226
|
+
else
|
|
227
|
+
warnings.push(`${filePath}: permission.${perm} is "${value}", not allow, ask or deny; ignored`);
|
|
228
|
+
}
|
|
229
|
+
else if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
|
|
230
|
+
const patterns = {};
|
|
231
|
+
for (const [pattern, action] of Object.entries(value)) {
|
|
232
|
+
if (typeof action === 'string' && PERMISSION_ACTIONS.has(action))
|
|
233
|
+
patterns[pattern] = action;
|
|
234
|
+
else
|
|
235
|
+
warnings.push(`${filePath}: permission.${perm}["${pattern}"] is "${String(action)}", not allow, ask or deny; ignored`);
|
|
236
|
+
}
|
|
237
|
+
if (Object.keys(patterns).length)
|
|
238
|
+
kept[perm] = patterns;
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
warnings.push(`${filePath}: permission.${perm} must be allow, ask, deny or a pattern map; ignored`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
config.permission = kept;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
cleanProviderKeys(config, filePath, warnings);
|
|
248
|
+
cleanDisplayBlocks(config, filePath, warnings);
|
|
43
249
|
return { config, warnings };
|
|
44
250
|
}
|
|
45
251
|
catch (err) {
|
|
@@ -52,9 +258,46 @@ export async function loadForgeConfigFile(configPath) {
|
|
|
52
258
|
*/
|
|
53
259
|
export async function saveForgeConfigFile(partial, configPath) {
|
|
54
260
|
const filePath = configPath ?? defaultForgeConfigPath();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
261
|
+
await updateJsonFile(filePath, (existing) => ({ ...existing, ...partial }));
|
|
262
|
+
}
|
|
263
|
+
const fileQueues = new Map();
|
|
264
|
+
/**
|
|
265
|
+
* Read-modify-write of a JSON settings file, safely:
|
|
266
|
+
* - merged over the file as written, not the cleaned config, so keys this version drops or does not know survive;
|
|
267
|
+
* - a file that exists but is not valid JSON is never overwritten (that would replace every setting with one);
|
|
268
|
+
* - writes to one path from this process run one after another, so two saves at once both land;
|
|
269
|
+
* - written to a temporary file and renamed, so a crash cannot leave half a file.
|
|
270
|
+
*/
|
|
271
|
+
export function updateJsonFile(filePath, update) {
|
|
272
|
+
const key = path.resolve(filePath);
|
|
273
|
+
const run = async () => {
|
|
274
|
+
let existing = {};
|
|
275
|
+
let text;
|
|
276
|
+
try {
|
|
277
|
+
text = await readFile(filePath, 'utf8');
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
if (err.code !== 'ENOENT')
|
|
281
|
+
throw err;
|
|
282
|
+
}
|
|
283
|
+
if (text !== undefined && text.trim()) {
|
|
284
|
+
let parsed;
|
|
285
|
+
try {
|
|
286
|
+
parsed = JSON.parse(text);
|
|
287
|
+
}
|
|
288
|
+
catch (err) {
|
|
289
|
+
throw new Error(`${filePath} is not valid JSON (${err.message}); fix it before saving, so your other settings are not lost`);
|
|
290
|
+
}
|
|
291
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
292
|
+
throw new Error(`${filePath} must hold a JSON object; not saving over it`);
|
|
293
|
+
existing = parsed;
|
|
294
|
+
}
|
|
295
|
+
await mkdir(path.dirname(filePath), { recursive: true });
|
|
296
|
+
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
297
|
+
await writeFile(tmp, JSON.stringify(update(existing), null, 2) + '\n', 'utf8');
|
|
298
|
+
await rename(tmp, filePath);
|
|
299
|
+
};
|
|
300
|
+
const next = (fileQueues.get(key) ?? Promise.resolve()).then(run, run);
|
|
301
|
+
fileQueues.set(key, next.catch(() => undefined));
|
|
302
|
+
return next;
|
|
59
303
|
}
|
|
60
|
-
//# sourceMappingURL=config-file.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ForgeConfigFile, type LoadForgeConfigFileResult } from './config-file.js';
|
|
2
|
+
/**
|
|
3
|
+
* The shared config as one object: `~/.forge/config.json`, then the workspace's `.forge/config.json` on top.
|
|
4
|
+
* A project file can pick the model and add stricter rules, but it can never loosen what the user decided:
|
|
5
|
+
* its `allow` permission rules are dropped, and the keys that hold approvals or delete data are only read
|
|
6
|
+
* from the user file. An untrusted workspace contributes nothing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function projectConfigPath(cwd: string): string;
|
|
9
|
+
export declare const USER_ONLY_CONFIG_KEYS: ReadonlyArray<keyof ForgeConfigFile>;
|
|
10
|
+
export declare function loadMergedForgeConfig(cwd: string, opts: {
|
|
11
|
+
trusted: boolean;
|
|
12
|
+
userPath?: string;
|
|
13
|
+
}): Promise<LoadForgeConfigFileResult>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { loadForgeConfigFile } from './config-file.js';
|
|
4
|
+
/**
|
|
5
|
+
* The shared config as one object: `~/.forge/config.json`, then the workspace's `.forge/config.json` on top.
|
|
6
|
+
* A project file can pick the model and add stricter rules, but it can never loosen what the user decided:
|
|
7
|
+
* its `allow` permission rules are dropped, and the keys that hold approvals or delete data are only read
|
|
8
|
+
* from the user file. An untrusted workspace contributes nothing.
|
|
9
|
+
*/
|
|
10
|
+
export function projectConfigPath(cwd) {
|
|
11
|
+
return path.join(cwd, '.forge', 'config.json');
|
|
12
|
+
}
|
|
13
|
+
// customProviders is user-only because an entry names a URL and the environment variable whose value is sent there:
|
|
14
|
+
// a repository must not be able to point a key at a host of its choosing.
|
|
15
|
+
export const USER_ONLY_CONFIG_KEYS = ['autoApproveTools', 'autoApproveCommands', 'sessionRetentionDays', 'customProviders', 'instructions', 'skillPaths', 'caCertificates'];
|
|
16
|
+
export async function loadMergedForgeConfig(cwd, opts) {
|
|
17
|
+
const user = await loadForgeConfigFile(opts.userPath);
|
|
18
|
+
const file = projectConfigPath(cwd);
|
|
19
|
+
if (!opts.trusted || !existsSync(file))
|
|
20
|
+
return user;
|
|
21
|
+
const project = await loadForgeConfigFile(file);
|
|
22
|
+
const warnings = [...user.warnings, ...project.warnings];
|
|
23
|
+
const p = project.config;
|
|
24
|
+
const merged = { ...user.config };
|
|
25
|
+
for (const key of USER_ONLY_CONFIG_KEYS) {
|
|
26
|
+
if (p[key] !== undefined)
|
|
27
|
+
warnings.push(`${file}: "${key}" is only read from the user config (~/.forge/config.json); ignored`);
|
|
28
|
+
}
|
|
29
|
+
for (const key of ['provider', 'model', 'completionModel', 'compactionModel', 'reasoningEffort', 'subagentModel']) {
|
|
30
|
+
if (p[key] !== undefined)
|
|
31
|
+
merged[key] = p[key];
|
|
32
|
+
}
|
|
33
|
+
if (p.modelOverrides)
|
|
34
|
+
merged.modelOverrides = { ...user.config.modelOverrides, ...p.modelOverrides };
|
|
35
|
+
if (p.aliases)
|
|
36
|
+
merged.aliases = { ...user.config.aliases, ...p.aliases };
|
|
37
|
+
if (p.modeModels)
|
|
38
|
+
merged.modeModels = { ...user.config.modeModels, ...p.modeModels };
|
|
39
|
+
if (p.display)
|
|
40
|
+
merged.display = { ...user.config.display, ...p.display };
|
|
41
|
+
if (p.disabledProviders)
|
|
42
|
+
merged.disabledProviders = [...new Set([...(user.config.disabledProviders ?? []), ...p.disabledProviders])];
|
|
43
|
+
if (p.permission) {
|
|
44
|
+
const permission = tighten(user.config.permission, p.permission);
|
|
45
|
+
if (permission)
|
|
46
|
+
merged.permission = permission;
|
|
47
|
+
}
|
|
48
|
+
return { config: merged, warnings };
|
|
49
|
+
}
|
|
50
|
+
/** User rules first, then the project's `ask` and `deny` rules (an `allow` is dropped), each after everything of the user's. */
|
|
51
|
+
function tighten(user, project) {
|
|
52
|
+
const out = { ...(user ?? {}) };
|
|
53
|
+
for (const [permission, value] of Object.entries(project)) {
|
|
54
|
+
const rules = typeof value === 'string' ? [['*', value]] : Object.entries(value);
|
|
55
|
+
const kept = rules.filter(([, action]) => action !== 'allow');
|
|
56
|
+
if (kept.length === 0)
|
|
57
|
+
continue;
|
|
58
|
+
const existing = out[permission];
|
|
59
|
+
const target = typeof existing === 'string' ? { '*': existing } : { ...(existing ?? {}) };
|
|
60
|
+
for (const [pattern, action] of kept) {
|
|
61
|
+
delete target[pattern];
|
|
62
|
+
target[pattern] = action;
|
|
63
|
+
}
|
|
64
|
+
out[permission] = target;
|
|
65
|
+
}
|
|
66
|
+
return Object.keys(out).length > 0 ? out : undefined;
|
|
67
|
+
}
|