@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/settings-export.js
CHANGED
package/dist/skills/activator.js
CHANGED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { USER_ONLY_CONFIG_KEYS } from '../config-merge.js';
|
|
2
|
+
/** One line per key of `~/.forge/config.json`. Typed against the file's keys: a new key does not compile until it has a line. */
|
|
3
|
+
const KEY_HELP = {
|
|
4
|
+
provider: 'default provider id',
|
|
5
|
+
model: 'default model id, alias or provider:model',
|
|
6
|
+
completionModel: 'model for inline completion',
|
|
7
|
+
compactionModel: 'model that writes the summary when a long chat is condensed',
|
|
8
|
+
disabledProviders: 'providers hidden from the model picker',
|
|
9
|
+
reasoningEffort: 'none, minimal, low, medium, high or xhigh',
|
|
10
|
+
autoApproveTools: 'tools that run without asking',
|
|
11
|
+
autoApproveCommands: 'commands you chose "Always allow"; written by Forge, do not hand-edit',
|
|
12
|
+
permission: 'ordered rules per tool kind (read, edit, bash, webfetch, websearch, task, external_directory), each allow, ask or deny; the last match wins',
|
|
13
|
+
customProviders: 'providers beyond the built-in ones: id to { name, baseUrl, apiKeyEnv or apiKey, headers, api, timeoutMs, models }',
|
|
14
|
+
modelOverrides: 'context and output limits and prices per model',
|
|
15
|
+
modelFilters: 'per provider whitelist and blacklist of model ids',
|
|
16
|
+
subagentModel: 'model sub-agents use when none is named',
|
|
17
|
+
instructions: 'extra instruction files, globs and http(s) URLs added to the system prompt',
|
|
18
|
+
skillPaths: 'extra folders, or http(s) URLs of a skill file or a skill index ({ "skills": [{ "url": "..." }] }), to read skills from',
|
|
19
|
+
caCertificates: 'PEM files of extra certificate authorities to trust; needs a reload',
|
|
20
|
+
aliases: 'short names for models',
|
|
21
|
+
modeModels: 'model per chat mode',
|
|
22
|
+
sessionRetentionDays: 'delete saved chats older than this many days',
|
|
23
|
+
display: 'blockDefault (collapsed or expanded), detail (compact or full), showReasoning (true or false), and blocks: per kind of block, reasoning (hidden, collapsed or expanded) and terminal, edit, mcp (collapsed or expanded). The kinds are exactly reasoning, terminal, edit and mcp; use no other name',
|
|
24
|
+
};
|
|
25
|
+
function configBody() {
|
|
26
|
+
const userOnly = USER_ONLY_CONFIG_KEYS.join(', ');
|
|
27
|
+
const keys = Object.keys(KEY_HELP).map((k) => `- \`${k}\`: ${KEY_HELP[k]}`).join('\n');
|
|
28
|
+
return `# Changing Forge's settings
|
|
29
|
+
|
|
30
|
+
Use this when the user asks to change how Forge behaves: a model, a provider, permissions, MCP servers, agents, commands, skills.
|
|
31
|
+
|
|
32
|
+
## Where things live
|
|
33
|
+
|
|
34
|
+
- \`~/.forge/config.json\`: the user's own settings. Applies in every project.
|
|
35
|
+
- \`<workspace>/.forge/config.json\`: the project's settings, read only when the workspace is trusted. It can set provider, model, completionModel, compactionModel, reasoningEffort, subagentModel, modelOverrides, aliases, modeModels and display, and add stricter permission rules (ask, deny). It can never loosen anything.
|
|
36
|
+
- User-only keys (a project file cannot set them, Forge ignores them there with a warning): ${userOnly}.
|
|
37
|
+
- \`~/.forge/mcp.json\` and \`<workspace>/.forge/mcp.json\`: MCP servers, \`{ "mcpServers": { "name": { "command", "args", "env" } or { "url", "headers" } } }\`.
|
|
38
|
+
- \`<workspace>/.forge/agents/*.md\` and \`~/.forge/agents/*.md\`: agents; front matter (description, mode, model, tools, deny, steps, temperature) then the system prompt.
|
|
39
|
+
- \`<workspace>/.forge/commands/*.md\` and \`~/.forge/commands/*.md\`: slash commands; \`$ARGUMENTS\` is replaced by what the user types after the name.
|
|
40
|
+
- \`<workspace>/.forge/skills/\`, \`<workspace>/skills/\`, \`~/.forge/skills/\`: skills.
|
|
41
|
+
- \`AGENTS.md\` (or \`CLAUDE.md\`) in the workspace or a folder: instructions for the model.
|
|
42
|
+
- In VS Code the same choices also exist as \`forge.*\` settings, edited on the Forge Settings page or in settings.json.
|
|
43
|
+
|
|
44
|
+
## Keys of config.json
|
|
45
|
+
|
|
46
|
+
${keys}
|
|
47
|
+
|
|
48
|
+
## How to change them
|
|
49
|
+
|
|
50
|
+
0. Your file tools only reach the workspace, so you cannot edit \`~/.forge/config.json\`. For a key the project file may set (see above), edit \`<workspace>/.forge/config.json\` and say plainly that the change is workspace-scoped (only for this workspace, and only when it is trusted). For a user-only key, or when the person wants it everywhere, show the exact JSON to add and tell them to paste it into \`~/.forge/config.json\` or use the Forge Settings page; do not write it into the project file.
|
|
51
|
+
1. Read the file first. If it does not exist, create it with only the keys you are setting.
|
|
52
|
+
2. Change only what was asked. Keep every other key and keep the file valid JSON (double quotes, no trailing commas, no comments).
|
|
53
|
+
3. A secret never goes in a project file. Name an environment variable (\`apiKeyEnv\`) instead of pasting a key.
|
|
54
|
+
4. Do not widen permissions (\`autoApproveTools\`, \`permission\` allow rules, \`autoApproveCommands\`) unless the user asked for exactly that, and say what the change allows.
|
|
55
|
+
5. After saving, say what changed and where. Most changes apply on the next message; \`caCertificates\` and the language need a window reload, MCP servers and skills need \`/reload\`.
|
|
56
|
+
6. Do not run Forge commands that write to the real \`~/.forge\` to test a change. Edit the file and let the user check it.
|
|
57
|
+
`;
|
|
58
|
+
}
|
|
59
|
+
export function builtinSkills() {
|
|
60
|
+
return [
|
|
61
|
+
{
|
|
62
|
+
name: 'forge-config',
|
|
63
|
+
description: "Change Forge's own settings: models, providers, permissions, MCP servers, agents, commands, skills and instructions. Use when the user asks to configure or set up Forge itself.",
|
|
64
|
+
body: configBody(),
|
|
65
|
+
source: { kind: 'builtin', path: '(built into Forge)' },
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
}
|
package/dist/skills/index.d.ts
CHANGED
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* internal directory layout.
|
|
7
7
|
*/
|
|
8
8
|
export type { Skill, SkillRegistry, SkillRoots, SkillSource } from './types.js';
|
|
9
|
+
export { builtinSkills } from './builtin.js';
|
|
10
|
+
export { loadRemoteSkills } from './remote.js';
|
|
9
11
|
export { GLOBAL_SKILLS_DIR, LOCAL_SKILLS_DIR, PROJECT_SKILLS_DIR, discoverSkills, loadSkillsRegistry, loadSkillsRegistryAsync, parseSkillsDir, resolveSkillRoots, skillsRegistryFromList, } from './loader.js';
|
|
10
12
|
export { parseSkill } from './parser.js';
|
|
11
13
|
export { buildSkillsBlock, composeSkillsPrompt, scoreSkill, selectSkills, } from './activator.js';
|
|
@@ -13,4 +15,3 @@ export { fetchSkillsCatalog, installSkillFromCatalog, searchSkills, } from './ma
|
|
|
13
15
|
export type { CatalogFetcher } from './marketplace.js';
|
|
14
16
|
export type { SkillCatalog, SkillCatalogEntry, SkillSearchResult, } from './marketplace-types.js';
|
|
15
17
|
export { DEFAULT_SKILL_CATALOG_URL, SKILL_CATALOG_VERSION } from './marketplace-types.js';
|
|
16
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/skills/index.js
CHANGED
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* callers can use skills + the community catalog without knowing the
|
|
6
6
|
* internal directory layout.
|
|
7
7
|
*/
|
|
8
|
+
export { builtinSkills } from './builtin.js';
|
|
9
|
+
export { loadRemoteSkills } from './remote.js';
|
|
8
10
|
export { GLOBAL_SKILLS_DIR, LOCAL_SKILLS_DIR, PROJECT_SKILLS_DIR, discoverSkills, loadSkillsRegistry, loadSkillsRegistryAsync, parseSkillsDir, resolveSkillRoots, skillsRegistryFromList, } from './loader.js';
|
|
9
11
|
export { parseSkill } from './parser.js';
|
|
10
12
|
export { buildSkillsBlock, composeSkillsPrompt, scoreSkill, selectSkills, } from './activator.js';
|
|
11
13
|
// Skills marketplace
|
|
12
14
|
export { fetchSkillsCatalog, installSkillFromCatalog, searchSkills, } from './marketplace.js';
|
|
13
15
|
export { DEFAULT_SKILL_CATALOG_URL, SKILL_CATALOG_VERSION } from './marketplace-types.js';
|
|
14
|
-
//# sourceMappingURL=index.js.map
|
package/dist/skills/loader.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* root wins (local > project > global). The result is an immutable
|
|
7
7
|
* snapshot: call {@link reload} to re-read disk.
|
|
8
8
|
*/
|
|
9
|
+
import { type RemoteSkillOptions } from './remote.js';
|
|
9
10
|
import type { Skill, SkillRegistry, SkillRoots, SkillSource } from './types.js';
|
|
10
11
|
/** Local skill root: `<cwd>/skills/`. Lives next to the project's source so it can be checked into git. */
|
|
11
12
|
export declare const LOCAL_SKILLS_DIR = "skills";
|
|
@@ -31,7 +32,9 @@ export declare function parseSkillsDir(dir: string, kind: SkillSource['kind']):
|
|
|
31
32
|
* Discover all skills visible from `cwd`. Walks local → project → global,
|
|
32
33
|
* merges, and resolves duplicates by precedence (first-wins).
|
|
33
34
|
*/
|
|
34
|
-
export declare function discoverSkills(cwd: string
|
|
35
|
+
export declare function discoverSkills(cwd: string, extraDirs?: readonly string[], remote?: RemoteSkillOptions & {
|
|
36
|
+
onWarning?: (warning: string) => void;
|
|
37
|
+
}): Promise<Skill[]>;
|
|
35
38
|
/**
|
|
36
39
|
* Build an immutable registry from a pre-loaded skill list. Use this when
|
|
37
40
|
* tests want to inject a known set without touching the filesystem. Use
|
|
@@ -42,10 +45,13 @@ export declare function skillsRegistryFromList(skills: Skill[], roots: SkillRoot
|
|
|
42
45
|
* Build a registry by discovering skills from disk relative to `cwd`.
|
|
43
46
|
* The registry caches its initial load; call `reload()` to refresh.
|
|
44
47
|
*/
|
|
45
|
-
export declare function loadSkillsRegistry(cwd: string
|
|
48
|
+
export declare function loadSkillsRegistry(cwd: string, extraDirs?: readonly string[], remote?: RemoteSkillOptions & {
|
|
49
|
+
onWarning?: (warning: string) => void;
|
|
50
|
+
}): SkillRegistry;
|
|
46
51
|
/**
|
|
47
52
|
* Async variant: build a registry and immediately load its initial contents.
|
|
48
53
|
* Useful for callers that want a fully-populated registry in one step.
|
|
49
54
|
*/
|
|
50
|
-
export declare function loadSkillsRegistryAsync(cwd: string
|
|
51
|
-
|
|
55
|
+
export declare function loadSkillsRegistryAsync(cwd: string, extraDirs?: readonly string[], remote?: RemoteSkillOptions & {
|
|
56
|
+
onWarning?: (warning: string) => void;
|
|
57
|
+
}): Promise<SkillRegistry>;
|
package/dist/skills/loader.js
CHANGED
|
@@ -11,6 +11,8 @@ import { readdir, readFile } from 'node:fs/promises';
|
|
|
11
11
|
import { homedir } from 'node:os';
|
|
12
12
|
import path from 'node:path';
|
|
13
13
|
import { discoverPlugins } from '../plugins/loader.js';
|
|
14
|
+
import { builtinSkills } from './builtin.js';
|
|
15
|
+
import { isHttpUrl, loadRemoteSkills } from './remote.js';
|
|
14
16
|
import { parseSkill } from './parser.js';
|
|
15
17
|
/** Local skill root: `<cwd>/skills/`. Lives next to the project's source so it can be checked into git. */
|
|
16
18
|
export const LOCAL_SKILLS_DIR = 'skills';
|
|
@@ -61,19 +63,30 @@ export async function parseSkillsDir(dir, kind) {
|
|
|
61
63
|
* Discover all skills visible from `cwd`. Walks local → project → global,
|
|
62
64
|
* merges, and resolves duplicates by precedence (first-wins).
|
|
63
65
|
*/
|
|
64
|
-
export async function discoverSkills(cwd) {
|
|
66
|
+
export async function discoverSkills(cwd, extraDirs = [], remote = {}) {
|
|
65
67
|
const roots = resolveSkillRoots(cwd);
|
|
66
68
|
const [localSkills, projectSkills, globalSkills] = await Promise.all([
|
|
67
69
|
parseSkillsDir(roots.local, 'local'),
|
|
68
70
|
parseSkillsDir(roots.project, 'project'),
|
|
69
71
|
parseSkillsDir(roots.global, 'global'),
|
|
70
72
|
]);
|
|
73
|
+
// Folders named in the `skillPaths` setting rank after the user's own folders and before plugins.
|
|
74
|
+
// An entry that is an http(s) URL is fetched (one skill file, or an index of them); the rest are folders.
|
|
75
|
+
const extraSkills = (await Promise.all(extraDirs.map(async (d) => {
|
|
76
|
+
if (isHttpUrl(d)) {
|
|
77
|
+
const got = await loadRemoteSkills(d, remote);
|
|
78
|
+
for (const w of got.warnings)
|
|
79
|
+
remote.onWarning?.(w);
|
|
80
|
+
return got.skills;
|
|
81
|
+
}
|
|
82
|
+
return parseSkillsDir(path.resolve(cwd, d.startsWith('~') ? path.join(homedir(), d.slice(1)) : d), 'global');
|
|
83
|
+
}))).flat();
|
|
71
84
|
// Plugin skills rank below the user's own: they never shadow a skill written locally.
|
|
72
85
|
const pluginSkills = (await Promise.all((await discoverPlugins(cwd)).map((p) => (p.skillsDir ? parseSkillsDir(p.skillsDir, p.scope) : Promise.resolve([]))))).flat();
|
|
73
|
-
// Order matters: first to claim a name wins. local > project > global > plugins.
|
|
86
|
+
// Order matters: first to claim a name wins. local > project > global > plugins > built in.
|
|
74
87
|
const seen = new Set();
|
|
75
88
|
const merged = [];
|
|
76
|
-
for (const list of [localSkills, projectSkills, globalSkills, pluginSkills]) {
|
|
89
|
+
for (const list of [localSkills, projectSkills, globalSkills, extraSkills, pluginSkills, builtinSkills()]) {
|
|
77
90
|
for (const skill of list) {
|
|
78
91
|
if (seen.has(skill.name))
|
|
79
92
|
continue;
|
|
@@ -105,11 +118,11 @@ export function skillsRegistryFromList(skills, roots) {
|
|
|
105
118
|
* Build a registry by discovering skills from disk relative to `cwd`.
|
|
106
119
|
* The registry caches its initial load; call `reload()` to refresh.
|
|
107
120
|
*/
|
|
108
|
-
export function loadSkillsRegistry(cwd) {
|
|
121
|
+
export function loadSkillsRegistry(cwd, extraDirs = [], remote = {}) {
|
|
109
122
|
const roots = resolveSkillRoots(cwd);
|
|
110
123
|
let cache = null;
|
|
111
124
|
const refresh = async () => {
|
|
112
|
-
cache = await discoverSkills(cwd);
|
|
125
|
+
cache = await discoverSkills(cwd, extraDirs, remote);
|
|
113
126
|
return cache;
|
|
114
127
|
};
|
|
115
128
|
return {
|
|
@@ -123,9 +136,8 @@ export function loadSkillsRegistry(cwd) {
|
|
|
123
136
|
* Async variant: build a registry and immediately load its initial contents.
|
|
124
137
|
* Useful for callers that want a fully-populated registry in one step.
|
|
125
138
|
*/
|
|
126
|
-
export async function loadSkillsRegistryAsync(cwd) {
|
|
127
|
-
const registry = loadSkillsRegistry(cwd);
|
|
139
|
+
export async function loadSkillsRegistryAsync(cwd, extraDirs = [], remote = {}) {
|
|
140
|
+
const registry = loadSkillsRegistry(cwd, extraDirs, remote);
|
|
128
141
|
await registry.reload();
|
|
129
142
|
return registry;
|
|
130
143
|
}
|
|
131
|
-
//# sourceMappingURL=loader.js.map
|
|
@@ -13,4 +13,3 @@
|
|
|
13
13
|
export const SKILL_CATALOG_VERSION = 1;
|
|
14
14
|
/** Default catalog URL: fetched via {@link fetchSkillsCatalog} when none is supplied. */
|
|
15
15
|
export const DEFAULT_SKILL_CATALOG_URL = 'https://raw.githubusercontent.com/ikarmicai/forge-skills/main/skills-catalog.json';
|
|
16
|
-
//# sourceMappingURL=marketplace-types.js.map
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { normalizeGithubSource } from '../mcp/marketplace.js';
|
|
12
12
|
import { parseSkill } from './parser.js';
|
|
13
13
|
import { DEFAULT_SKILL_CATALOG_URL, SKILL_CATALOG_VERSION, } from './marketplace-types.js';
|
|
14
|
+
import { isOutsideRel } from '../tools/shared.js';
|
|
14
15
|
/**
|
|
15
16
|
* Sanitize a catalog-provided name to a safe filename charset before it is
|
|
16
17
|
* used to build a path on disk. Mirrors `installDirNameFor`'s sanitization
|
|
@@ -168,7 +169,7 @@ export async function installSkillFromCatalog(params) {
|
|
|
168
169
|
const filePath = path.join(dest, `${safeName}.md`);
|
|
169
170
|
const resolvedDest = path.resolve(dest);
|
|
170
171
|
const rel = path.relative(resolvedDest, path.resolve(filePath));
|
|
171
|
-
if (
|
|
172
|
+
if (isOutsideRel(rel)) {
|
|
172
173
|
return null;
|
|
173
174
|
}
|
|
174
175
|
await fs.writeFile(filePath, rawContent, 'utf8');
|
|
@@ -182,4 +183,3 @@ function defaultDestination() {
|
|
|
182
183
|
const path = require('node:path');
|
|
183
184
|
return path.join(homedir(), '.forge', 'skills');
|
|
184
185
|
}
|
|
185
|
-
//# sourceMappingURL=marketplace.js.map
|
package/dist/skills/parser.d.ts
CHANGED
package/dist/skills/parser.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Skill } from './types.js';
|
|
2
|
+
export interface RemoteSkillOptions {
|
|
3
|
+
fetch?: typeof fetch;
|
|
4
|
+
/** Defaults to `~/.forge/skill-cache`. */
|
|
5
|
+
cacheDir?: string;
|
|
6
|
+
ttlMs?: number;
|
|
7
|
+
now?: () => number;
|
|
8
|
+
}
|
|
9
|
+
export interface RemoteSkills {
|
|
10
|
+
skills: Skill[];
|
|
11
|
+
warnings: string[];
|
|
12
|
+
}
|
|
13
|
+
export declare const isHttpUrl: (s: string) => boolean;
|
|
14
|
+
export declare function loadRemoteSkills(url: string, options?: RemoteSkillOptions): Promise<RemoteSkills>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills from a URL: either one skill file (Markdown with front matter) or an index,
|
|
3
|
+
* `{ "skills": [{ "url": "a.md" }, ...] }`, whose links may be relative to the index.
|
|
4
|
+
* Responses are cached on disk so a skill still works offline and a slow host is not asked on every run:
|
|
5
|
+
* a copy younger than the TTL is used as is; an older one is refreshed, and kept if the refresh fails.
|
|
6
|
+
* Anything that times out or is not a skill is skipped with one warning. Only http and https are fetched.
|
|
7
|
+
* The `skillPaths` setting that lists URLs is read from the user's config only.
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { parseSkill } from './parser.js';
|
|
14
|
+
const FETCH_TIMEOUT_MS = 10_000;
|
|
15
|
+
const MAX_CHARS = 200_000;
|
|
16
|
+
const MAX_INDEX_ENTRIES = 20;
|
|
17
|
+
const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
|
|
18
|
+
/** A host that failed is not asked again for this long, so a dead URL does not add its timeout to every message. */
|
|
19
|
+
const RETRY_AFTER_FAILURE_MS = 5 * 60 * 1000;
|
|
20
|
+
const failures = new Map();
|
|
21
|
+
export const isHttpUrl = (s) => /^https?:\/\//i.test(s);
|
|
22
|
+
function cacheFile(dir, url) {
|
|
23
|
+
return path.join(dir, `${createHash('sha256').update(url).digest('hex').slice(0, 32)}.json`);
|
|
24
|
+
}
|
|
25
|
+
async function readCache(dir, url) {
|
|
26
|
+
try {
|
|
27
|
+
const entry = JSON.parse(await readFile(cacheFile(dir, url), 'utf8'));
|
|
28
|
+
return typeof entry.text === 'string' && typeof entry.fetchedAt === 'number' ? entry : undefined;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** The text at `url`: a fresh cached copy, else the network, else a stale cached copy; throws if there is none. */
|
|
35
|
+
async function fetchText(url, opts) {
|
|
36
|
+
const cached = await readCache(opts.cacheDir, url);
|
|
37
|
+
if (cached && opts.now() - cached.fetchedAt < opts.ttlMs)
|
|
38
|
+
return cached.text;
|
|
39
|
+
const failKey = `${opts.cacheDir}|${url}`;
|
|
40
|
+
const failed = failures.get(failKey);
|
|
41
|
+
const since = failed ? opts.now() - failed.at : 0;
|
|
42
|
+
if (failed && since >= 0 && since < RETRY_AFTER_FAILURE_MS) {
|
|
43
|
+
if (cached)
|
|
44
|
+
return cached.text;
|
|
45
|
+
throw new Error(failed.message);
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const res = await opts.fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
49
|
+
if (!res.ok)
|
|
50
|
+
throw new Error(`HTTP ${res.status}`);
|
|
51
|
+
const text = (await res.text()).slice(0, MAX_CHARS);
|
|
52
|
+
try {
|
|
53
|
+
await mkdir(opts.cacheDir, { recursive: true });
|
|
54
|
+
await writeFile(cacheFile(opts.cacheDir, url), JSON.stringify({ url, fetchedAt: opts.now(), text }), 'utf8');
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// a cache that cannot be written only costs a fetch next time
|
|
58
|
+
}
|
|
59
|
+
failures.delete(failKey);
|
|
60
|
+
return text;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
failures.set(failKey, { at: opts.now(), message: err.message });
|
|
64
|
+
if (cached)
|
|
65
|
+
return cached.text;
|
|
66
|
+
throw err;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function fallbackName(url) {
|
|
70
|
+
const last = new URL(url).pathname.split('/').filter(Boolean).pop() ?? 'remote-skill';
|
|
71
|
+
return last.replace(/\.md$/i, '') || 'remote-skill';
|
|
72
|
+
}
|
|
73
|
+
function asSkill(url, text) {
|
|
74
|
+
const head = text.trimStart();
|
|
75
|
+
if (head.startsWith('<') || !head.startsWith('---'))
|
|
76
|
+
return undefined;
|
|
77
|
+
const skill = parseSkill(text, { kind: 'remote', path: url }, fallbackName(url));
|
|
78
|
+
return skill.description.trim() && skill.body ? skill : undefined;
|
|
79
|
+
}
|
|
80
|
+
export async function loadRemoteSkills(url, options = {}) {
|
|
81
|
+
const warnings = [];
|
|
82
|
+
if (!isHttpUrl(url))
|
|
83
|
+
return { skills: [], warnings: [`${url}: only http and https skill URLs are read; skipped`] };
|
|
84
|
+
const opts = {
|
|
85
|
+
fetch: options.fetch ?? fetch,
|
|
86
|
+
cacheDir: options.cacheDir ?? path.join(homedir(), '.forge', 'skill-cache'),
|
|
87
|
+
ttlMs: options.ttlMs ?? DEFAULT_TTL_MS,
|
|
88
|
+
now: options.now ?? Date.now,
|
|
89
|
+
};
|
|
90
|
+
const loadOne = async (target) => {
|
|
91
|
+
try {
|
|
92
|
+
const skill = asSkill(target, await fetchText(target, opts));
|
|
93
|
+
if (!skill)
|
|
94
|
+
warnings.push(`${target}: not a skill (needs front matter with a description); skipped`);
|
|
95
|
+
return skill;
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
warnings.push(`${target}: ${err.message}; skipped`);
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
let text;
|
|
103
|
+
try {
|
|
104
|
+
text = await fetchText(url, opts);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
return { skills: [], warnings: [`${url}: ${err.message}; skipped`] };
|
|
108
|
+
}
|
|
109
|
+
const trimmed = text.trimStart();
|
|
110
|
+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
111
|
+
let index;
|
|
112
|
+
try {
|
|
113
|
+
index = JSON.parse(text);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return { skills: [], warnings: [`${url}: not a skill or a skill index; skipped`] };
|
|
117
|
+
}
|
|
118
|
+
const list = Array.isArray(index) ? index : index?.skills;
|
|
119
|
+
if (!Array.isArray(list))
|
|
120
|
+
return { skills: [], warnings: [`${url}: not a skill or a skill index; skipped`] };
|
|
121
|
+
const targets = list
|
|
122
|
+
.map((e) => (typeof e === 'string' ? e : e?.url))
|
|
123
|
+
.filter((u) => typeof u === 'string' && u.length > 0)
|
|
124
|
+
.slice(0, MAX_INDEX_ENTRIES)
|
|
125
|
+
.map((u) => new URL(u, url).href);
|
|
126
|
+
const skills = (await Promise.all(targets.map(loadOne))).filter((s) => s !== undefined);
|
|
127
|
+
return { skills, warnings };
|
|
128
|
+
}
|
|
129
|
+
const skill = asSkill(url, text);
|
|
130
|
+
return skill ? { skills: [skill], warnings } : { skills: [], warnings: [`${url}: not a skill (needs front matter with a description); skipped`] };
|
|
131
|
+
}
|
package/dist/skills/types.d.ts
CHANGED
|
@@ -38,6 +38,16 @@ export type SkillSource = {
|
|
|
38
38
|
} | {
|
|
39
39
|
kind: 'global';
|
|
40
40
|
path: string;
|
|
41
|
+
}
|
|
42
|
+
/** Ships inside Forge; there is no file, `path` is a label. */
|
|
43
|
+
| {
|
|
44
|
+
kind: 'builtin';
|
|
45
|
+
path: string;
|
|
46
|
+
}
|
|
47
|
+
/** Fetched from a URL listed in `skillPaths`; `path` is the URL. */
|
|
48
|
+
| {
|
|
49
|
+
kind: 'remote';
|
|
50
|
+
path: string;
|
|
41
51
|
};
|
|
42
52
|
/** A parsed skill, ready for activation. */
|
|
43
53
|
export interface Skill {
|
|
@@ -71,4 +81,3 @@ export interface SkillRegistry {
|
|
|
71
81
|
/** Where skills were discovered (for diagnostics). */
|
|
72
82
|
roots(): SkillRoots;
|
|
73
83
|
}
|
|
74
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/skills/types.js
CHANGED
package/dist/specs/generate.d.ts
CHANGED
package/dist/specs/generate.js
CHANGED
package/dist/specs/index.d.ts
CHANGED
|
@@ -12,4 +12,3 @@ export { convertToCheckboxes, parseTasks, setTaskDone } from './tasks-parser.js'
|
|
|
12
12
|
export type { SpecTask } from './tasks-parser.js';
|
|
13
13
|
export { changedSince, changeSize, keepDoneTasks, referencedPaths, specDrift, syncSpecTask } from './sync.js';
|
|
14
14
|
export type { SpecDrift } from './sync.js';
|
|
15
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/specs/index.js
CHANGED
|
@@ -9,4 +9,3 @@ export { SpecStore, isSafeSpecId, runKey, slugifyTaskForSpecId } from './store.j
|
|
|
9
9
|
export { SPEC_READONLY_TOOLS, splitSpecSections } from './generate.js';
|
|
10
10
|
export { convertToCheckboxes, parseTasks, setTaskDone } from './tasks-parser.js';
|
|
11
11
|
export { changedSince, changeSize, keepDoneTasks, referencedPaths, specDrift, syncSpecTask } from './sync.js';
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
package/dist/specs/store.d.ts
CHANGED
package/dist/specs/store.js
CHANGED
package/dist/specs/sync.d.ts
CHANGED
package/dist/specs/sync.js
CHANGED
package/dist/specs/types.d.ts
CHANGED
package/dist/specs/types.js
CHANGED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `instructions` setting: extra files, globs (relative to the workspace) and http(s) URLs whose text is added to
|
|
3
|
+
* the system prompt. Anything unreadable is skipped. Only the user's own config supplies these (a project file
|
|
4
|
+
* could otherwise point the model at text from anywhere), and the caller enforces that.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildExtraInstructionsBlock(cwd: string, entries: readonly string[], deps?: {
|
|
7
|
+
fetch?: typeof fetch;
|
|
8
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { pathMatchesGlob } from './glob.js';
|
|
5
|
+
const PER_SOURCE_BYTES = 12_000;
|
|
6
|
+
const TOTAL_BYTES = 48_000;
|
|
7
|
+
const MAX_WALK_FILES = 5_000;
|
|
8
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'out', 'build', '.next', 'target']);
|
|
9
|
+
const URL_TIMEOUT_MS = 10_000;
|
|
10
|
+
const isGlob = (s) => /[*?[]/.test(s);
|
|
11
|
+
const isUrl = (s) => /^[a-z][a-z0-9+.-]*:\/\//i.test(s);
|
|
12
|
+
async function walk(root) {
|
|
13
|
+
const out = [];
|
|
14
|
+
async function visit(dir, rel, depth) {
|
|
15
|
+
if (depth > 8 || out.length >= MAX_WALK_FILES)
|
|
16
|
+
return;
|
|
17
|
+
let entries;
|
|
18
|
+
try {
|
|
19
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
25
|
+
for (const e of entries) {
|
|
26
|
+
if (out.length >= MAX_WALK_FILES)
|
|
27
|
+
return;
|
|
28
|
+
const r = rel ? `${rel}/${e.name}` : e.name;
|
|
29
|
+
if (e.isDirectory()) {
|
|
30
|
+
if (!SKIP_DIRS.has(e.name))
|
|
31
|
+
await visit(path.join(dir, e.name), r, depth + 1);
|
|
32
|
+
}
|
|
33
|
+
else if (e.isFile())
|
|
34
|
+
out.push(r);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
await visit(root, '', 0);
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
const clip = (text) => (text.length > PER_SOURCE_BYTES ? `${text.slice(0, PER_SOURCE_BYTES)}\n…(truncated)` : text);
|
|
41
|
+
/**
|
|
42
|
+
* The `instructions` setting: extra files, globs (relative to the workspace) and http(s) URLs whose text is added to
|
|
43
|
+
* the system prompt. Anything unreadable is skipped. Only the user's own config supplies these (a project file
|
|
44
|
+
* could otherwise point the model at text from anywhere), and the caller enforces that.
|
|
45
|
+
*/
|
|
46
|
+
export async function buildExtraInstructionsBlock(cwd, entries, deps = {}) {
|
|
47
|
+
const sources = [];
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
const addFile = (label, abs) => {
|
|
50
|
+
const key = path.resolve(abs);
|
|
51
|
+
if (seen.has(key))
|
|
52
|
+
return;
|
|
53
|
+
seen.add(key);
|
|
54
|
+
sources.push({ label, read: () => readFile(abs, 'utf8') });
|
|
55
|
+
};
|
|
56
|
+
let walked;
|
|
57
|
+
for (const raw of entries) {
|
|
58
|
+
const entry = raw.trim();
|
|
59
|
+
if (!entry)
|
|
60
|
+
continue;
|
|
61
|
+
if (isUrl(entry)) {
|
|
62
|
+
if (!/^https?:\/\//i.test(entry) || seen.has(entry))
|
|
63
|
+
continue;
|
|
64
|
+
seen.add(entry);
|
|
65
|
+
sources.push({
|
|
66
|
+
label: entry,
|
|
67
|
+
read: async () => {
|
|
68
|
+
const res = await (deps.fetch ?? fetch)(entry, { signal: AbortSignal.timeout(URL_TIMEOUT_MS) });
|
|
69
|
+
if (!res.ok)
|
|
70
|
+
throw new Error(`HTTP ${res.status}`);
|
|
71
|
+
return (await res.text()).slice(0, PER_SOURCE_BYTES * 2);
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else if (isGlob(entry) && !path.isAbsolute(entry) && !entry.startsWith('~')) {
|
|
76
|
+
walked ??= await walk(cwd);
|
|
77
|
+
for (const rel of walked.filter((f) => pathMatchesGlob(entry, f)))
|
|
78
|
+
addFile(rel, path.join(cwd, rel));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const abs = entry.startsWith('~') ? path.join(homedir(), entry.slice(1)) : path.resolve(cwd, entry);
|
|
82
|
+
addFile(entry, abs);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const blocks = [];
|
|
86
|
+
let total = 0;
|
|
87
|
+
for (const s of sources) {
|
|
88
|
+
if (total >= TOTAL_BYTES)
|
|
89
|
+
break;
|
|
90
|
+
let text;
|
|
91
|
+
try {
|
|
92
|
+
text = (await s.read()).trim();
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (!text)
|
|
98
|
+
continue;
|
|
99
|
+
const body = clip(text);
|
|
100
|
+
total += body.length;
|
|
101
|
+
blocks.push(`<instructions source="${s.label.replace(/"/g, '')}">\n${body}\n</instructions>`);
|
|
102
|
+
}
|
|
103
|
+
return blocks.join('\n\n');
|
|
104
|
+
}
|