@entelligentsia/forgecli 0.7.10 → 0.9.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/CHANGELOG.md +127 -0
- package/dist/CHANGELOG-forge-plugin.md +70 -0
- package/dist/CHANGELOG-pi.md +63 -0
- package/dist/bin/argv.d.ts +2 -2
- package/dist/bin/argv.js +27 -0
- package/dist/bin/argv.js.map +1 -1
- package/dist/bin/config.d.ts +69 -0
- package/dist/bin/config.js +315 -0
- package/dist/bin/config.js.map +1 -0
- package/dist/bin/doctor.d.ts +1 -0
- package/dist/bin/doctor.js +12 -0
- package/dist/bin/doctor.js.map +1 -1
- package/dist/bin/env-defaults.d.ts +1 -0
- package/dist/bin/env-defaults.js +13 -0
- package/dist/bin/env-defaults.js.map +1 -0
- package/dist/bin/forge.js +16 -0
- package/dist/bin/forge.js.map +1 -1
- package/dist/bin/update-cli.d.ts +9 -0
- package/dist/bin/update-cli.js +120 -0
- package/dist/bin/update-cli.js.map +1 -0
- package/dist/extensions/forgecli/config-command.d.ts +8 -0
- package/dist/extensions/forgecli/config-command.js +66 -0
- package/dist/extensions/forgecli/config-command.js.map +1 -0
- package/dist/extensions/forgecli/config-layer.d.ts +38 -0
- package/dist/extensions/forgecli/config-layer.js +68 -0
- package/dist/extensions/forgecli/config-layer.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/component.d.ts +35 -0
- package/dist/extensions/forgecli/config-tui/component.js +236 -0
- package/dist/extensions/forgecli/config-tui/component.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/handler.d.ts +40 -0
- package/dist/extensions/forgecli/config-tui/handler.js +240 -0
- package/dist/extensions/forgecli/config-tui/handler.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/index.d.ts +5 -0
- package/dist/extensions/forgecli/config-tui/index.js +5 -0
- package/dist/extensions/forgecli/config-tui/index.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/keys.d.ts +26 -0
- package/dist/extensions/forgecli/config-tui/keys.js +33 -0
- package/dist/extensions/forgecli/config-tui/keys.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/plugin-config-reader.d.ts +23 -0
- package/dist/extensions/forgecli/config-tui/plugin-config-reader.js +58 -0
- package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +83 -0
- package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +11 -0
- package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +54 -0
- package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +11 -0
- package/dist/extensions/forgecli/config-tui/screens/override-editor.js +233 -0
- package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +91 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +71 -0
- package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +10 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +182 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +76 -0
- package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/personas-list.js +98 -0
- package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +29 -0
- package/dist/extensions/forgecli/config-tui/screens/shared.js +100 -0
- package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +23 -0
- package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +128 -0
- package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +7 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +135 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +9 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +122 -0
- package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens/types.d.ts +24 -0
- package/dist/extensions/forgecli/config-tui/screens/types.js +5 -0
- package/dist/extensions/forgecli/config-tui/screens/types.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/screens.d.ts +24 -0
- package/dist/extensions/forgecli/config-tui/screens.js +78 -0
- package/dist/extensions/forgecli/config-tui/screens.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +11 -0
- package/dist/extensions/forgecli/config-tui/state/buffer.js +91 -0
- package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/constants.d.ts +4 -0
- package/dist/extensions/forgecli/config-tui/state/constants.js +14 -0
- package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/index.d.ts +6 -0
- package/dist/extensions/forgecli/config-tui/state/index.js +9 -0
- package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/init.d.ts +2 -0
- package/dist/extensions/forgecli/config-tui/state/init.js +30 -0
- package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/model.d.ts +192 -0
- package/dist/extensions/forgecli/config-tui/state/model.js +4 -0
- package/dist/extensions/forgecli/config-tui/state/model.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/reducer.d.ts +2 -0
- package/dist/extensions/forgecli/config-tui/state/reducer.js +212 -0
- package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +91 -0
- package/dist/extensions/forgecli/config-tui/state/selectors.js +231 -0
- package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/state.d.ts +6 -0
- package/dist/extensions/forgecli/config-tui/state.js +11 -0
- package/dist/extensions/forgecli/config-tui/state.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/theme.d.ts +37 -0
- package/dist/extensions/forgecli/config-tui/theme.js +88 -0
- package/dist/extensions/forgecli/config-tui/theme.js.map +1 -0
- package/dist/extensions/forgecli/config-tui/tier-meta.d.ts +28 -0
- package/dist/extensions/forgecli/config-tui/tier-meta.js +69 -0
- package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -0
- package/dist/extensions/forgecli/config-writer.d.ts +16 -0
- package/dist/extensions/forgecli/config-writer.js +63 -0
- package/dist/extensions/forgecli/config-writer.js.map +1 -0
- package/dist/extensions/forgecli/fix-bug.js +85 -1
- package/dist/extensions/forgecli/fix-bug.js.map +1 -1
- package/dist/extensions/forgecli/forge-cli-schema.json +54 -0
- package/dist/extensions/forgecli/forge-commands.js +3 -8
- package/dist/extensions/forgecli/forge-commands.js.map +1 -1
- package/dist/extensions/forgecli/forge-subagent.d.ts +13 -0
- package/dist/extensions/forgecli/forge-subagent.js +19 -0
- package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
- package/dist/extensions/forgecli/index.js +19 -3
- package/dist/extensions/forgecli/index.js.map +1 -1
- package/dist/extensions/forgecli/input-router.d.ts +33 -0
- package/dist/extensions/forgecli/input-router.js +133 -0
- package/dist/extensions/forgecli/input-router.js.map +1 -0
- package/dist/extensions/forgecli/model-resolver.d.ts +32 -0
- package/dist/extensions/forgecli/model-resolver.js +65 -0
- package/dist/extensions/forgecli/model-resolver.js.map +1 -0
- package/dist/extensions/forgecli/model-validator.d.ts +29 -0
- package/dist/extensions/forgecli/model-validator.js +107 -0
- package/dist/extensions/forgecli/model-validator.js.map +1 -0
- package/dist/extensions/forgecli/run-sprint.js +59 -0
- package/dist/extensions/forgecli/run-sprint.js.map +1 -1
- package/dist/extensions/forgecli/run-task.js +93 -1
- package/dist/extensions/forgecli/run-task.js.map +1 -1
- package/dist/extensions/forgecli/thread-switcher.js +5 -2
- package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
- package/dist/extensions/forgecli/update-check.js +1 -1
- package/dist/extensions/forgecli/update-check.js.map +1 -1
- package/dist/extensions/forgecli/whats-new-widget.d.ts +5 -5
- package/dist/extensions/forgecli/whats-new-widget.js +16 -13
- package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
- package/dist/extensions/forgecli/whats-new.js +6 -5
- package/dist/extensions/forgecli/whats-new.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +27 -98
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js +62 -132
- package/node_modules/@earendil-works/pi-ai/dist/models.generated.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js +25 -15
- package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js +17 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js +8 -2
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js +17 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js +8 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/CHANGELOG.md +63 -0
- package/node_modules/@earendil-works/pi-coding-agent/README.md +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli/config-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js +6 -10
- package/node_modules/@earendil-works/pi-coding-agent/dist/cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js +12 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/config.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts +1 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js +30 -15
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts +3 -3
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js +23 -13
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts +4 -0
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js +58 -38
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/package-manager.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js +0 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js +3 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js +7 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js +6 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js +3 -4
- package/node_modules/@earendil-works/pi-coding-agent/dist/package-manager-cli.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts +7 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js +60 -7
- package/node_modules/@earendil-works/pi-coding-agent/dist/utils/child-process.js.map +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/docs/packages.md +2 -2
- package/node_modules/@earendil-works/pi-coding-agent/docs/settings.md +1 -3
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package.json +1 -1
- package/node_modules/@earendil-works/pi-coding-agent/package.json +6 -6
- package/node_modules/@earendil-works/pi-tui/package.json +2 -2
- package/node_modules/@protobufjs/fetch/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/fetch/index.d.ts +7 -7
- package/node_modules/@protobufjs/fetch/index.js +4 -7
- package/node_modules/@protobufjs/fetch/package.json +7 -5
- package/node_modules/@protobufjs/fetch/tests/data/file.txt +1 -0
- package/node_modules/@protobufjs/fetch/tests/index.js +150 -8
- package/node_modules/@protobufjs/fetch/util/fs.js +11 -0
- package/node_modules/@protobufjs/inquire/CHANGELOG.md +8 -0
- package/node_modules/@protobufjs/inquire/index.d.ts +1 -0
- package/node_modules/@protobufjs/inquire/index.js +1 -0
- package/node_modules/@protobufjs/inquire/package.json +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.js +187 -153
- package/node_modules/protobufjs/dist/light/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/light/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/light/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.js +14 -5
- package/node_modules/protobufjs/dist/minimal/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/minimal/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.js +207 -173
- package/node_modules/protobufjs/dist/protobuf.js.map +1 -1
- package/node_modules/protobufjs/dist/protobuf.min.js +3 -3
- package/node_modules/protobufjs/dist/protobuf.min.js.map +1 -1
- package/node_modules/protobufjs/package.json +6 -3
- package/node_modules/protobufjs/src/util/fs.js +11 -0
- package/node_modules/protobufjs/src/util/minimal.js +10 -2
- package/node_modules/protobufjs/src/util.js +1 -1
- package/node_modules/undici/README.md +14 -5
- package/node_modules/undici/docs/docs/api/Client.md +4 -2
- package/node_modules/undici/docs/docs/api/Dispatcher.md +62 -27
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +7 -5
- package/node_modules/undici/docs/docs/api/H2CClient.md +1 -1
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +14 -9
- package/node_modules/undici/docs/docs/api/RetryAgent.md +0 -1
- package/node_modules/undici/docs/docs/api/RetryHandler.md +12 -14
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +23 -0
- package/node_modules/undici/docs/docs/best-practices/migrating-from-v7-to-v8.md +231 -0
- package/node_modules/undici/index.js +4 -2
- package/node_modules/undici/lib/api/api-connect.js +13 -11
- package/node_modules/undici/lib/api/api-pipeline.js +26 -13
- package/node_modules/undici/lib/api/api-request.js +45 -21
- package/node_modules/undici/lib/api/api-stream.js +81 -20
- package/node_modules/undici/lib/api/api-upgrade.js +21 -11
- package/node_modules/undici/lib/api/readable.js +3 -2
- package/node_modules/undici/lib/cache/memory-cache-store.js +1 -1
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +6 -4
- package/node_modules/undici/lib/core/connect.js +17 -1
- package/node_modules/undici/lib/core/constants.js +1 -24
- package/node_modules/undici/lib/core/errors.js +2 -2
- package/node_modules/undici/lib/core/request.js +115 -18
- package/node_modules/undici/lib/core/socks5-client.js +24 -9
- package/node_modules/undici/lib/core/socks5-utils.js +32 -23
- package/node_modules/undici/lib/core/symbols.js +1 -0
- package/node_modules/undici/lib/core/util.js +70 -43
- package/node_modules/undici/lib/dispatcher/agent.js +47 -33
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +21 -26
- package/node_modules/undici/lib/dispatcher/client-h1.js +98 -39
- package/node_modules/undici/lib/dispatcher/client-h2.js +603 -272
- package/node_modules/undici/lib/dispatcher/client.js +12 -5
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +24 -5
- package/node_modules/undici/lib/dispatcher/dispatcher.js +0 -4
- package/node_modules/undici/lib/dispatcher/dispatcher1-wrapper.js +107 -0
- package/node_modules/undici/lib/dispatcher/h2c-client.js +5 -5
- package/node_modules/undici/lib/dispatcher/pool-base.js +28 -10
- package/node_modules/undici/lib/dispatcher/pool.js +31 -6
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +38 -13
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +31 -9
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +95 -80
- package/node_modules/undici/lib/global.js +13 -1
- package/node_modules/undici/lib/handler/cache-handler.js +16 -8
- package/node_modules/undici/lib/handler/decorator-handler.js +1 -2
- package/node_modules/undici/lib/handler/redirect-handler.js +5 -51
- package/node_modules/undici/lib/handler/retry-handler.js +15 -2
- package/node_modules/undici/lib/interceptor/cache.js +30 -17
- package/node_modules/undici/lib/interceptor/decompress.js +28 -2
- package/node_modules/undici/lib/interceptor/dns.js +1 -1
- package/node_modules/undici/lib/interceptor/redirect.js +3 -3
- package/node_modules/undici/lib/llhttp/llhttp-wasm.js +1 -1
- package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +1 -1
- package/node_modules/undici/lib/mock/mock-agent.js +8 -8
- package/node_modules/undici/lib/mock/mock-call-history.js +15 -15
- package/node_modules/undici/lib/mock/mock-utils.js +37 -22
- package/node_modules/undici/lib/mock/snapshot-agent.js +16 -6
- package/node_modules/undici/lib/mock/snapshot-recorder.js +38 -3
- package/node_modules/undici/lib/util/cache.js +8 -7
- package/node_modules/undici/lib/util/runtime-features.js +3 -34
- package/node_modules/undici/lib/web/cache/cache.js +6 -8
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +245 -150
- package/node_modules/undici/lib/web/fetch/body.js +3 -9
- package/node_modules/undici/lib/web/fetch/formdata-parser.js +17 -6
- package/node_modules/undici/lib/web/fetch/formdata.js +21 -2
- package/node_modules/undici/lib/web/fetch/index.js +214 -221
- package/node_modules/undici/lib/web/webidl/index.js +7 -9
- package/node_modules/undici/lib/web/websocket/frame.js +1 -7
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +13 -31
- package/node_modules/undici/lib/web/websocket/receiver.js +62 -22
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +11 -17
- package/node_modules/undici/lib/web/websocket/websocket.js +6 -1
- package/node_modules/undici/package.json +9 -9
- package/node_modules/undici/types/agent.d.ts +0 -2
- package/node_modules/undici/types/client.d.ts +25 -19
- package/node_modules/undici/types/dispatcher.d.ts +7 -27
- package/node_modules/undici/types/dispatcher1-wrapper.d.ts +7 -0
- package/node_modules/undici/types/formdata.d.ts +0 -6
- package/node_modules/undici/types/h2c-client.d.ts +6 -6
- package/node_modules/undici/types/header.d.ts +5 -0
- package/node_modules/undici/types/index.d.ts +3 -1
- package/node_modules/undici/types/interceptors.d.ts +1 -1
- package/node_modules/undici/types/pool.d.ts +0 -2
- package/node_modules/undici/types/proxy-agent.d.ts +2 -2
- package/node_modules/undici/types/round-robin-pool.d.ts +0 -2
- package/node_modules/undici/types/snapshot-agent.d.ts +4 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +2 -2
- package/node_modules/undici/types/webidl.d.ts +0 -1
- package/package.json +16 -9
- package/dist/extensions/forgecli/review-command.d.ts +0 -2
- package/dist/extensions/forgecli/review-command.js +0 -184
- package/dist/extensions/forgecli/review-command.js.map +0 -1
- package/dist/forge-payload/.tools/banners.cjs +0 -435
- package/dist/forge-payload/.tools/build-context-pack.cjs +0 -290
- package/dist/forge-payload/.tools/build-init-context.cjs +0 -322
- package/dist/forge-payload/.tools/build-overlay.cjs +0 -326
- package/dist/forge-payload/.tools/build-persona-pack.cjs +0 -226
- package/dist/forge-payload/.tools/collate.cjs +0 -1041
- package/dist/forge-payload/.tools/generation-manifest.cjs +0 -311
- package/dist/forge-payload/.tools/lib/forge-root.cjs +0 -59
- package/dist/forge-payload/.tools/lib/paths.cjs +0 -29
- package/dist/forge-payload/.tools/lib/pricing.cjs +0 -165
- package/dist/forge-payload/.tools/lib/project-root.cjs +0 -32
- package/dist/forge-payload/.tools/lib/result.js +0 -40
- package/dist/forge-payload/.tools/lib/store-facade.cjs +0 -162
- package/dist/forge-payload/.tools/lib/store-nlp.cjs +0 -250
- package/dist/forge-payload/.tools/lib/store-query-exec.cjs +0 -272
- package/dist/forge-payload/.tools/lib/validate.js +0 -141
- package/dist/forge-payload/.tools/manage-config.cjs +0 -340
- package/dist/forge-payload/.tools/manage-versions.cjs +0 -365
- package/dist/forge-payload/.tools/package.json +0 -3
- package/dist/forge-payload/.tools/parse-gates.cjs +0 -151
- package/dist/forge-payload/.tools/parse-verdict.cjs +0 -67
- package/dist/forge-payload/.tools/preflight-gate.cjs +0 -350
- package/dist/forge-payload/.tools/prompts/sprint-plan-prompt.md +0 -70
- package/dist/forge-payload/.tools/schemas/task-list.schema.json +0 -53
- package/dist/forge-payload/.tools/seed-store.cjs +0 -237
- package/dist/forge-payload/.tools/store-cli.cjs +0 -1226
- package/dist/forge-payload/.tools/store-query.cjs +0 -319
- package/dist/forge-payload/.tools/store.cjs +0 -315
- package/dist/forge-payload/.tools/substitute-placeholders.cjs +0 -625
- package/dist/forge-payload/.tools/validate-store.cjs +0 -593
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/custom-provider-anthropic/package-lock.json +0 -24
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/sandbox/package-lock.json +0 -92
- package/node_modules/@earendil-works/pi-coding-agent/examples/extensions/with-deps/package-lock.json +0 -31
- package/node_modules/undici/lib/handler/unwrap-handler.js +0 -100
- package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
- package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/node_modules/undici/lib/util/promise.js +0 -28
- package/skills/refresh-kb-links/SKILL.md +0 -217
- package/skills/store-custodian/SKILL.md +0 -163
- package/skills/store-query-grammar/SKILL.md +0 -145
- package/skills/store-query-nlp/SKILL.md +0 -110
|
@@ -1,311 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
// Forge tool: generation-manifest
|
|
5
|
-
// Track and verify generated file integrity via content hashes.
|
|
6
|
-
// Usage: generation-manifest record <path>
|
|
7
|
-
// generation-manifest record-all
|
|
8
|
-
// generation-manifest check <path>
|
|
9
|
-
// generation-manifest list [--modified]
|
|
10
|
-
// generation-manifest status
|
|
11
|
-
// generation-manifest remove <path>
|
|
12
|
-
// generation-manifest clear-namespace <prefix> Remove all entries whose path starts with <prefix>.
|
|
13
|
-
// prefix must start with .forge/ or .claude/ and end with /
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
const crypto = require('crypto');
|
|
18
|
-
|
|
19
|
-
const MANIFEST_PATH = path.join(process.cwd(), '.forge', 'generation-manifest.json');
|
|
20
|
-
|
|
21
|
-
function normalize(content) {
|
|
22
|
-
return content
|
|
23
|
-
.replace(/\r\n/g, '\n')
|
|
24
|
-
.split('\n')
|
|
25
|
-
.map(line => line.trimEnd())
|
|
26
|
-
.join('\n');
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function hashContent(content) {
|
|
30
|
-
return 'sha256:' + crypto.createHash('sha256').update(normalize(content), 'utf8').digest('hex');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// ── exports (for testing) ────────────────────────────────────────────────────
|
|
34
|
-
|
|
35
|
-
module.exports = { normalize, hashContent, MANIFEST_PATH };
|
|
36
|
-
|
|
37
|
-
// ── CLI guard ────────────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
if (require.main === module) {
|
|
40
|
-
process.on('uncaughtException', (e) => {
|
|
41
|
-
process.stderr.write(`× ${e.message}\n`);
|
|
42
|
-
process.exit(1);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
function readManifest() {
|
|
46
|
-
if (!fs.existsSync(MANIFEST_PATH)) return { files: {} };
|
|
47
|
-
try {
|
|
48
|
-
return JSON.parse(fs.readFileSync(MANIFEST_PATH, 'utf8'));
|
|
49
|
-
} catch (e) {
|
|
50
|
-
process.stderr.write(`× reading manifest: ${e.message}\n`);
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function writeManifest(manifest) {
|
|
56
|
-
const dir = path.dirname(MANIFEST_PATH);
|
|
57
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
58
|
-
const tmp = MANIFEST_PATH + '.tmp.' + process.pid;
|
|
59
|
-
try {
|
|
60
|
-
fs.writeFileSync(tmp, JSON.stringify(manifest, null, 2) + '\n', 'utf8');
|
|
61
|
-
fs.renameSync(tmp, MANIFEST_PATH);
|
|
62
|
-
} catch (e) {
|
|
63
|
-
try { fs.unlinkSync(tmp); } catch {}
|
|
64
|
-
process.stderr.write(`× writing manifest: ${e.message}\n`);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function getForgeVersion() {
|
|
70
|
-
try {
|
|
71
|
-
const configPath = path.join(process.cwd(), '.forge', 'config.json');
|
|
72
|
-
if (fs.existsSync(configPath)) {
|
|
73
|
-
const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
74
|
-
if (cfg.version) return cfg.version;
|
|
75
|
-
}
|
|
76
|
-
} catch {}
|
|
77
|
-
return 'unknown';
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function toRelPath(filePath) {
|
|
81
|
-
return path.relative(process.cwd(), path.resolve(filePath));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function fileStatus(relPath, entry) {
|
|
85
|
-
const absPath = path.resolve(relPath);
|
|
86
|
-
if (!fs.existsSync(absPath)) return 'missing';
|
|
87
|
-
const current = hashContent(fs.readFileSync(absPath, 'utf8'));
|
|
88
|
-
return current === entry.hash ? 'pristine' : 'modified';
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const STATUS_SYMBOL = { pristine: '〇', modified: '△', missing: '×' };
|
|
92
|
-
|
|
93
|
-
// ── subcommands ──────────────────────────────────────────────────────────────
|
|
94
|
-
|
|
95
|
-
const [,, subcmd, ...args] = process.argv;
|
|
96
|
-
|
|
97
|
-
if (!subcmd) {
|
|
98
|
-
process.stderr.write([
|
|
99
|
-
'Usage: generation-manifest <subcommand> [options]',
|
|
100
|
-
'',
|
|
101
|
-
'Subcommands:',
|
|
102
|
-
' record <path> Hash and store/update a file in the manifest',
|
|
103
|
-
' record-all Re-hash all files currently tracked in the manifest',
|
|
104
|
-
' check <path> Exit 0=pristine 1=modified 2=untracked 3=file missing',
|
|
105
|
-
' list [--modified] Table of tracked files with status',
|
|
106
|
-
' status Summary counts',
|
|
107
|
-
' remove <path> Remove a file from tracking',
|
|
108
|
-
' clear-namespace <prefix> Remove all entries whose path starts with <prefix>.',
|
|
109
|
-
' prefix must start with .forge/ or .claude/ and end with /',
|
|
110
|
-
].join('\n') + '\n');
|
|
111
|
-
process.exit(2);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// ── record ───────────────────────────────────────────────────────────────────
|
|
115
|
-
|
|
116
|
-
if (subcmd === 'record') {
|
|
117
|
-
const filePath = args[0];
|
|
118
|
-
if (!filePath) {
|
|
119
|
-
process.stderr.write('Usage: generation-manifest record <path>\n');
|
|
120
|
-
process.exit(2);
|
|
121
|
-
}
|
|
122
|
-
const relPath = toRelPath(filePath);
|
|
123
|
-
const absPath = path.resolve(filePath);
|
|
124
|
-
if (!fs.existsSync(absPath)) {
|
|
125
|
-
process.stderr.write(`× File not found: ${filePath}\n`);
|
|
126
|
-
process.exit(1);
|
|
127
|
-
}
|
|
128
|
-
const manifest = readManifest();
|
|
129
|
-
if (!manifest.files) manifest.files = {};
|
|
130
|
-
manifest.files[relPath] = {
|
|
131
|
-
hash: hashContent(fs.readFileSync(absPath, 'utf8')),
|
|
132
|
-
generatedAt: new Date().toISOString(),
|
|
133
|
-
generatedByVersion: getForgeVersion(),
|
|
134
|
-
};
|
|
135
|
-
writeManifest(manifest);
|
|
136
|
-
process.stdout.write(`〇 Recorded: ${relPath}\n`);
|
|
137
|
-
process.exit(0);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// ── record-all ───────────────────────────────────────────────────────────────
|
|
141
|
-
|
|
142
|
-
if (subcmd === 'record-all') {
|
|
143
|
-
const manifest = readManifest();
|
|
144
|
-
const files = manifest.files || {};
|
|
145
|
-
if (Object.keys(files).length === 0) {
|
|
146
|
-
process.stdout.write('── No files tracked — nothing to re-hash.\n');
|
|
147
|
-
process.exit(0);
|
|
148
|
-
}
|
|
149
|
-
let updated = 0, missing = 0;
|
|
150
|
-
const version = getForgeVersion();
|
|
151
|
-
for (const relPath of Object.keys(files)) {
|
|
152
|
-
const absPath = path.resolve(relPath);
|
|
153
|
-
if (!fs.existsSync(absPath)) {
|
|
154
|
-
process.stdout.write(`△ Missing (skipped): ${relPath}\n`);
|
|
155
|
-
missing++;
|
|
156
|
-
continue;
|
|
157
|
-
}
|
|
158
|
-
files[relPath] = {
|
|
159
|
-
hash: hashContent(fs.readFileSync(absPath, 'utf8')),
|
|
160
|
-
generatedAt: new Date().toISOString(),
|
|
161
|
-
generatedByVersion: version,
|
|
162
|
-
};
|
|
163
|
-
updated++;
|
|
164
|
-
}
|
|
165
|
-
writeManifest(manifest);
|
|
166
|
-
process.stdout.write(`〇 Re-hashed ${updated} file(s).${missing ? ` △ ${missing} missing.` : ''}\n`);
|
|
167
|
-
process.exit(0);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// ── check ────────────────────────────────────────────────────────────────────
|
|
171
|
-
|
|
172
|
-
if (subcmd === 'check') {
|
|
173
|
-
const filePath = args[0];
|
|
174
|
-
if (!filePath) {
|
|
175
|
-
process.stderr.write('Usage: generation-manifest check <path>\n');
|
|
176
|
-
process.exit(2);
|
|
177
|
-
}
|
|
178
|
-
const relPath = toRelPath(filePath);
|
|
179
|
-
const manifest = readManifest();
|
|
180
|
-
const entry = manifest.files && manifest.files[relPath];
|
|
181
|
-
|
|
182
|
-
if (!entry) {
|
|
183
|
-
process.stdout.write(`── ${relPath}: untracked\n`);
|
|
184
|
-
process.exit(2);
|
|
185
|
-
}
|
|
186
|
-
const absPath = path.resolve(relPath);
|
|
187
|
-
if (!fs.existsSync(absPath)) {
|
|
188
|
-
process.stdout.write(`× ${relPath}: file not found\n`);
|
|
189
|
-
process.exit(3);
|
|
190
|
-
}
|
|
191
|
-
const current = hashContent(fs.readFileSync(absPath, 'utf8'));
|
|
192
|
-
if (current === entry.hash) {
|
|
193
|
-
process.stdout.write(`〇 ${relPath}: pristine\n`);
|
|
194
|
-
process.exit(0);
|
|
195
|
-
} else {
|
|
196
|
-
process.stdout.write(`△ ${relPath}: modified (generated by v${entry.generatedByVersion || '?'})\n`);
|
|
197
|
-
process.exit(1);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// ── list ─────────────────────────────────────────────────────────────────────
|
|
202
|
-
|
|
203
|
-
if (subcmd === 'list') {
|
|
204
|
-
const modifiedOnly = args.includes('--modified');
|
|
205
|
-
const manifest = readManifest();
|
|
206
|
-
const files = manifest.files || {};
|
|
207
|
-
|
|
208
|
-
if (Object.keys(files).length === 0) {
|
|
209
|
-
process.stdout.write('── No files tracked.\n');
|
|
210
|
-
process.exit(0);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const rows = [];
|
|
214
|
-
for (const [relPath, entry] of Object.entries(files)) {
|
|
215
|
-
const status = fileStatus(relPath, entry);
|
|
216
|
-
if (modifiedOnly && status === 'pristine') continue;
|
|
217
|
-
rows.push({
|
|
218
|
-
symbol: STATUS_SYMBOL[status],
|
|
219
|
-
status,
|
|
220
|
-
relPath,
|
|
221
|
-
version: entry.generatedByVersion || '—',
|
|
222
|
-
date: entry.generatedAt ? entry.generatedAt.slice(0, 10) : '—',
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
if (rows.length === 0) {
|
|
227
|
-
process.stdout.write('〇 All tracked files are pristine.\n');
|
|
228
|
-
process.exit(0);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
process.stdout.write('| Status | File | Version | Date |\n');
|
|
232
|
-
process.stdout.write('|--------|------|---------|------|\n');
|
|
233
|
-
for (const r of rows) {
|
|
234
|
-
process.stdout.write(`| ${r.symbol} ${r.status} | \`${r.relPath}\` | ${r.version} | ${r.date} |\n`);
|
|
235
|
-
}
|
|
236
|
-
process.exit(0);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// ── status ───────────────────────────────────────────────────────────────────
|
|
240
|
-
|
|
241
|
-
if (subcmd === 'status') {
|
|
242
|
-
const manifest = readManifest();
|
|
243
|
-
const files = manifest.files || {};
|
|
244
|
-
let pristine = 0, modified = 0, missing = 0;
|
|
245
|
-
for (const [relPath, entry] of Object.entries(files)) {
|
|
246
|
-
const s = fileStatus(relPath, entry);
|
|
247
|
-
if (s === 'pristine') pristine++;
|
|
248
|
-
else if (s === 'modified') modified++;
|
|
249
|
-
else missing++;
|
|
250
|
-
}
|
|
251
|
-
const total = pristine + modified + missing;
|
|
252
|
-
if (total === 0) {
|
|
253
|
-
process.stdout.write('── No files tracked.\n');
|
|
254
|
-
process.exit(0);
|
|
255
|
-
}
|
|
256
|
-
process.stdout.write(`── ${total} file(s) tracked\n`);
|
|
257
|
-
if (pristine > 0) process.stdout.write(`〇 ${pristine} pristine\n`);
|
|
258
|
-
if (modified > 0) process.stdout.write(`△ ${modified} modified\n`);
|
|
259
|
-
if (missing > 0) process.stdout.write(`× ${missing} missing\n`);
|
|
260
|
-
process.exit(0);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// ── remove ───────────────────────────────────────────────────────────────────
|
|
264
|
-
|
|
265
|
-
if (subcmd === 'remove') {
|
|
266
|
-
const filePath = args[0];
|
|
267
|
-
if (!filePath) {
|
|
268
|
-
process.stderr.write('Usage: generation-manifest remove <path>\n');
|
|
269
|
-
process.exit(2);
|
|
270
|
-
}
|
|
271
|
-
const relPath = toRelPath(filePath);
|
|
272
|
-
const manifest = readManifest();
|
|
273
|
-
if (!manifest.files || !manifest.files[relPath]) {
|
|
274
|
-
process.stderr.write(`× Not tracked: ${relPath}\n`);
|
|
275
|
-
process.exit(1);
|
|
276
|
-
}
|
|
277
|
-
delete manifest.files[relPath];
|
|
278
|
-
writeManifest(manifest);
|
|
279
|
-
process.stdout.write(`〇 Removed from tracking: ${relPath}\n`);
|
|
280
|
-
process.exit(0);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
// ── clear-namespace ──────────────────────────────────────────────────────────
|
|
284
|
-
|
|
285
|
-
if (subcmd === 'clear-namespace') {
|
|
286
|
-
const prefix = args[0];
|
|
287
|
-
if (!prefix) {
|
|
288
|
-
process.stderr.write('Usage: generation-manifest clear-namespace <prefix>\n');
|
|
289
|
-
process.exit(2);
|
|
290
|
-
}
|
|
291
|
-
const validPrefix = (prefix.startsWith('.forge/') || prefix.startsWith('.claude/')) && prefix.endsWith('/');
|
|
292
|
-
if (!validPrefix) {
|
|
293
|
-
process.stderr.write('Usage error: prefix must start with .forge/ or .claude/ and end with /\n');
|
|
294
|
-
process.exit(2);
|
|
295
|
-
}
|
|
296
|
-
const manifest = readManifest();
|
|
297
|
-
const files = manifest.files || {};
|
|
298
|
-
const keys = Object.keys(files).filter(k => k.startsWith(prefix));
|
|
299
|
-
if (keys.length === 0) {
|
|
300
|
-
process.stdout.write(`── No entries matching ${prefix}\n`);
|
|
301
|
-
} else {
|
|
302
|
-
for (const k of keys) delete files[k];
|
|
303
|
-
writeManifest(manifest);
|
|
304
|
-
process.stdout.write(`〇 Cleared ${keys.length} entries matching ${prefix}\n`);
|
|
305
|
-
}
|
|
306
|
-
process.exit(0);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
process.stderr.write(`× Unknown subcommand: ${subcmd}\n`);
|
|
310
|
-
process.exit(2);
|
|
311
|
-
} // end if (require.main === module)
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Forge shared helper: resolveForgeRoot
|
|
4
|
-
// FR-001: 3-tier priority resolution for FORGE_ROOT with actionable error.
|
|
5
|
-
//
|
|
6
|
-
// Resolution order:
|
|
7
|
-
// 1. FORGE_ROOT env var — accepted only if ${FORGE_ROOT}/.claude-plugin/plugin.json exists
|
|
8
|
-
// 2. __dirname/.. — the parent of this module's directory (tools/lib -> forge root)
|
|
9
|
-
// 3. Actionable error listing all checked paths
|
|
10
|
-
//
|
|
11
|
-
// This follows the same pattern as project-root.cjs (library module pattern):
|
|
12
|
-
// - Export functions, no require.main === module CLI block
|
|
13
|
-
// - Throw errors, don't call process.exit
|
|
14
|
-
|
|
15
|
-
const fs = require('fs');
|
|
16
|
-
const path = require('path');
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Resolve the Forge plugin root directory.
|
|
20
|
-
*
|
|
21
|
-
* @param {string} [envForgeRoot] - Value of FORGE_ROOT environment variable.
|
|
22
|
-
* If provided and points to a directory containing .claude-plugin/plugin.json,
|
|
23
|
-
* it is accepted. If provided but plugin.json is missing, resolution falls
|
|
24
|
-
* through to the __dirname fallback. If omitted/undefined, falls through.
|
|
25
|
-
* @returns {string} Absolute path to the Forge plugin root.
|
|
26
|
-
* @throws {Error} When no valid resolution path is found, with a message listing
|
|
27
|
-
* all paths that were checked.
|
|
28
|
-
*/
|
|
29
|
-
function resolveForgeRoot(envForgeRoot) {
|
|
30
|
-
const checkedPaths = [];
|
|
31
|
-
|
|
32
|
-
// Tier 1: Environment variable — only accepted if plugin.json exists
|
|
33
|
-
if (envForgeRoot) {
|
|
34
|
-
const pluginJsonPath = path.join(envForgeRoot, '.claude-plugin', 'plugin.json');
|
|
35
|
-
checkedPaths.push(pluginJsonPath);
|
|
36
|
-
if (fs.existsSync(pluginJsonPath)) {
|
|
37
|
-
return envForgeRoot;
|
|
38
|
-
}
|
|
39
|
-
// Env var provided but doesn't point to a valid plugin root — fall through
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Tier 2: __dirname/../.. — the standard layout (forge/forge/tools/lib/ -> forge/forge/)
|
|
43
|
-
// This module lives in tools/lib/, so going up two directories reaches the plugin root.
|
|
44
|
-
const fallbackRoot = path.resolve(path.join(__dirname, '..', '..'));
|
|
45
|
-
const fallbackPluginJson = path.join(fallbackRoot, '.claude-plugin', 'plugin.json');
|
|
46
|
-
checkedPaths.push(fallbackPluginJson);
|
|
47
|
-
if (fs.existsSync(fallbackPluginJson)) {
|
|
48
|
-
return fallbackRoot;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Tier 3: Actionable error
|
|
52
|
-
throw new Error(
|
|
53
|
-
`Cannot resolve Forge plugin root. Checked paths:\n` +
|
|
54
|
-
checkedPaths.map(p => ` - ${p}`).join('\n') +
|
|
55
|
-
'\nSet FORGE_ROOT to a directory containing .claude-plugin/plugin.json'
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
module.exports = { resolveForgeRoot };
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* paths.cjs — Shared path-computation helpers for Forge tools.
|
|
5
|
-
*
|
|
6
|
-
* Single source of truth for directory-name conventions that must be
|
|
7
|
-
* consistent across substitute-placeholders.cjs, check-structure.cjs, etc.
|
|
8
|
-
*
|
|
9
|
-
* Exported API:
|
|
10
|
-
* getCommandsSubdir(prefix) — returns prefix.toLowerCase()
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Compute the commands subdirectory name from a project prefix.
|
|
15
|
-
*
|
|
16
|
-
* The canonical commands subfolder under .claude/commands/ is derived
|
|
17
|
-
* from the project prefix (lowercased), NOT hardcoded as 'forge'.
|
|
18
|
-
*
|
|
19
|
-
* @param {string} prefix — project prefix (e.g. 'ACME', 'FORGE')
|
|
20
|
-
* @returns {string} lowercased prefix (e.g. 'acme', 'forge')
|
|
21
|
-
*/
|
|
22
|
-
function getCommandsSubdir(prefix) {
|
|
23
|
-
if (typeof prefix !== 'string' || prefix.length === 0) {
|
|
24
|
-
throw new Error('paths.getCommandsSubdir: prefix must be a non-empty string');
|
|
25
|
-
}
|
|
26
|
-
return prefix.toLowerCase();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
module.exports = { getCommandsSubdir };
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* pricing.cjs — Shared pricing primitive for Forge cost tooling.
|
|
5
|
-
*
|
|
6
|
-
* Exports:
|
|
7
|
-
* MODEL_PRICING - frozen object mapping canonical model name → { input, output, cacheRead, cacheWrite }
|
|
8
|
-
* All rates are in USD per token (not per 1M tokens).
|
|
9
|
-
* canonicalizeModel(model) - normalises model name variants/aliases to canonical form.
|
|
10
|
-
* Returns { canonical, contextWindow } or null if unknown.
|
|
11
|
-
* computeCost(opts) - computes USD cost from { inputTokens, outputTokens,
|
|
12
|
-
* cacheReadTokens, cacheWriteTokens, model }.
|
|
13
|
-
* Returns number (may be 0), or null for unknown model.
|
|
14
|
-
*
|
|
15
|
-
* This module is a pure library — no CLI, no process.exit.
|
|
16
|
-
* Published Anthropic pricing (USD/MTok → divide by 1,000,000 for per-token rate):
|
|
17
|
-
* claude-opus-4-5: input $15.00, output $75.00, cacheRead $1.50, cacheWrite $18.75
|
|
18
|
-
* claude-opus-4-7: input $15.00, output $75.00, cacheRead $1.50, cacheWrite $18.75
|
|
19
|
-
* claude-sonnet-4-5: input $3.00, output $15.00, cacheRead $0.30, cacheWrite $3.75
|
|
20
|
-
* claude-sonnet-4-6: input $3.00, output $15.00, cacheRead $0.30, cacheWrite $3.75
|
|
21
|
-
* claude-haiku-3-5: input $0.80, output $4.00, cacheRead $0.08, cacheWrite $1.00
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// All rates in USD per token (divide MTok rate by 1,000,000)
|
|
25
|
-
const MODEL_PRICING = Object.freeze({
|
|
26
|
-
'claude-opus-4-5': {
|
|
27
|
-
input: 15.00 / 1_000_000,
|
|
28
|
-
output: 75.00 / 1_000_000,
|
|
29
|
-
cacheRead: 1.50 / 1_000_000,
|
|
30
|
-
cacheWrite: 18.75 / 1_000_000,
|
|
31
|
-
},
|
|
32
|
-
'claude-opus-4-7': {
|
|
33
|
-
input: 15.00 / 1_000_000,
|
|
34
|
-
output: 75.00 / 1_000_000,
|
|
35
|
-
cacheRead: 1.50 / 1_000_000,
|
|
36
|
-
cacheWrite: 18.75 / 1_000_000,
|
|
37
|
-
},
|
|
38
|
-
'claude-sonnet-4-5': {
|
|
39
|
-
input: 3.00 / 1_000_000,
|
|
40
|
-
output: 15.00 / 1_000_000,
|
|
41
|
-
cacheRead: 0.30 / 1_000_000,
|
|
42
|
-
cacheWrite: 3.75 / 1_000_000,
|
|
43
|
-
},
|
|
44
|
-
'claude-sonnet-4-6': {
|
|
45
|
-
input: 3.00 / 1_000_000,
|
|
46
|
-
output: 15.00 / 1_000_000,
|
|
47
|
-
cacheRead: 0.30 / 1_000_000,
|
|
48
|
-
cacheWrite: 3.75 / 1_000_000,
|
|
49
|
-
},
|
|
50
|
-
'claude-haiku-3-5': {
|
|
51
|
-
input: 0.80 / 1_000_000,
|
|
52
|
-
output: 4.00 / 1_000_000,
|
|
53
|
-
cacheRead: 0.08 / 1_000_000,
|
|
54
|
-
cacheWrite: 1.00 / 1_000_000,
|
|
55
|
-
},
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Known model families for canonical resolution.
|
|
60
|
-
* Each entry is [baseCanonical, [...synonymPatterns]]
|
|
61
|
-
* Patterns are tested after lower-casing the input model string.
|
|
62
|
-
* The order matters: more specific patterns must come before more general ones.
|
|
63
|
-
*/
|
|
64
|
-
const MODEL_FAMILIES = [
|
|
65
|
-
// Opus family
|
|
66
|
-
'claude-opus-4-7',
|
|
67
|
-
'claude-opus-4-5',
|
|
68
|
-
// Sonnet family
|
|
69
|
-
'claude-sonnet-4-6',
|
|
70
|
-
'claude-sonnet-4-5',
|
|
71
|
-
// Haiku family
|
|
72
|
-
'claude-haiku-3-5',
|
|
73
|
-
];
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* canonicalizeModel(model)
|
|
77
|
-
*
|
|
78
|
-
* Given a raw model string (possibly fragmented / aliased), returns:
|
|
79
|
-
* { canonical: string, contextWindow: string|null }
|
|
80
|
-
* where:
|
|
81
|
-
* - canonical is one of the keys in MODEL_PRICING
|
|
82
|
-
* - contextWindow is '1m' when a 1M-context-window variant was detected, otherwise null
|
|
83
|
-
*
|
|
84
|
-
* Returns null if the model cannot be mapped to a known canonical name.
|
|
85
|
-
*
|
|
86
|
-
* Examples:
|
|
87
|
-
* 'claude-sonnet-4-6' → { canonical: 'claude-sonnet-4-6', contextWindow: null }
|
|
88
|
-
* 'claude-sonnet-4-6-1m' → { canonical: 'claude-sonnet-4-6', contextWindow: '1m' }
|
|
89
|
-
* 'claude-sonnet-4-6[1m]'→ { canonical: 'claude-sonnet-4-6', contextWindow: '1m' }
|
|
90
|
-
* 'sonnet-4-6' → { canonical: 'claude-sonnet-4-6', contextWindow: null }
|
|
91
|
-
* 'opus-4-7-1m' → { canonical: 'claude-opus-4-7', contextWindow: '1m' }
|
|
92
|
-
* 'totally-unknown-9-9' → null
|
|
93
|
-
*/
|
|
94
|
-
function canonicalizeModel(model) {
|
|
95
|
-
if (model == null || typeof model !== 'string' || model.trim() === '') return null;
|
|
96
|
-
|
|
97
|
-
const raw = model.trim();
|
|
98
|
-
|
|
99
|
-
// Detect and strip 1m context-window suffix variants:
|
|
100
|
-
// -1m suffix (e.g. claude-sonnet-4-6-1m)
|
|
101
|
-
// [1m] suffix (e.g. claude-sonnet-4-6[1m])
|
|
102
|
-
let contextWindow = null;
|
|
103
|
-
let stripped = raw;
|
|
104
|
-
if (/\[1m\]$/i.test(stripped)) {
|
|
105
|
-
contextWindow = '1m';
|
|
106
|
-
stripped = stripped.replace(/\[1m\]$/i, '').replace(/-+$/, '');
|
|
107
|
-
} else if (/-1m$/i.test(stripped)) {
|
|
108
|
-
contextWindow = '1m';
|
|
109
|
-
stripped = stripped.replace(/-1m$/i, '');
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Normalise to lowercase for matching
|
|
113
|
-
const lower = stripped.toLowerCase();
|
|
114
|
-
|
|
115
|
-
for (const canonical of MODEL_FAMILIES) {
|
|
116
|
-
// Exact match (after stripping)
|
|
117
|
-
if (lower === canonical) {
|
|
118
|
-
return { canonical, contextWindow };
|
|
119
|
-
}
|
|
120
|
-
// Short alias: canonical without leading 'claude-'
|
|
121
|
-
const short = canonical.replace(/^claude-/, '');
|
|
122
|
-
if (lower === short) {
|
|
123
|
-
return { canonical, contextWindow };
|
|
124
|
-
}
|
|
125
|
-
// Contains the canonical family segment (e.g. 'claude-sonnet-4-6' in a longer variant)
|
|
126
|
-
if (lower.includes(canonical)) {
|
|
127
|
-
return { canonical, contextWindow };
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* computeCost({ inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, model })
|
|
136
|
-
*
|
|
137
|
-
* Returns the estimated USD cost as a number, or null if the model is unknown.
|
|
138
|
-
* Returns 0 (not null) when all token counts are zero and the model is known.
|
|
139
|
-
* Never returns a negative number.
|
|
140
|
-
*
|
|
141
|
-
* @param {object} opts
|
|
142
|
-
* @param {number} opts.inputTokens
|
|
143
|
-
* @param {number} opts.outputTokens
|
|
144
|
-
* @param {number} opts.cacheReadTokens
|
|
145
|
-
* @param {number} opts.cacheWriteTokens
|
|
146
|
-
* @param {string} opts.model - raw model string (will be canonicalized)
|
|
147
|
-
* @returns {number|null}
|
|
148
|
-
*/
|
|
149
|
-
function computeCost({ inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, model }) {
|
|
150
|
-
const canonResult = canonicalizeModel(model);
|
|
151
|
-
if (canonResult === null) return null;
|
|
152
|
-
|
|
153
|
-
const rates = MODEL_PRICING[canonResult.canonical];
|
|
154
|
-
if (!rates) return null;
|
|
155
|
-
|
|
156
|
-
const cost =
|
|
157
|
-
(inputTokens || 0) * rates.input +
|
|
158
|
-
(outputTokens || 0) * rates.output +
|
|
159
|
-
(cacheReadTokens || 0) * rates.cacheRead +
|
|
160
|
-
(cacheWriteTokens || 0) * rates.cacheWrite;
|
|
161
|
-
|
|
162
|
-
return Math.max(0, cost);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
module.exports = { MODEL_PRICING, canonicalizeModel, computeCost };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Walk up from startDir to find the project root (directory containing .forge/config.json).
|
|
8
|
-
* @param {string} [startDir] - Directory to start searching from. Defaults to process.cwd().
|
|
9
|
-
* @returns {string|null} Absolute path to the project root, or null if not found.
|
|
10
|
-
*/
|
|
11
|
-
function findProjectRoot(startDir) {
|
|
12
|
-
let dir = path.resolve(startDir || process.cwd());
|
|
13
|
-
const root = path.parse(dir).root;
|
|
14
|
-
|
|
15
|
-
while (dir !== root) {
|
|
16
|
-
const configPath = path.join(dir, '.forge', 'config.json');
|
|
17
|
-
if (fs.existsSync(configPath)) {
|
|
18
|
-
return dir;
|
|
19
|
-
}
|
|
20
|
-
dir = path.dirname(dir);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Check root directory as well
|
|
24
|
-
const rootConfigPath = path.join(root, '.forge', 'config.json');
|
|
25
|
-
if (fs.existsSync(rootConfigPath)) {
|
|
26
|
-
return root;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
module.exports = { findProjectRoot };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// Structured Result helpers for Forge CJS module APIs.
|
|
4
|
-
//
|
|
5
|
-
// Pattern: every exported function that can fail returns either
|
|
6
|
-
// { ok: true, value } — success
|
|
7
|
-
// { ok: false, code, message } — failure
|
|
8
|
-
//
|
|
9
|
-
// Code is always a string from RESULT_CODES, never a magic literal.
|
|
10
|
-
|
|
11
|
-
const RESULT_CODES = {
|
|
12
|
-
// collate.cjs — resolveTaskDir
|
|
13
|
-
MISSING_DIR: 'MISSING_DIR', // no matching task directory found on disk
|
|
14
|
-
|
|
15
|
-
// estimate-usage.cjs — estimateTokens
|
|
16
|
-
E_ZERO_DURATION: 'E_ZERO_DURATION', // durationMinutes is exactly 0
|
|
17
|
-
E_MISSING_DURATION: 'E_MISSING_DURATION', // durationMinutes is null or undefined
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Wrap a success value in a Result.
|
|
22
|
-
* @template T
|
|
23
|
-
* @param {T} [value]
|
|
24
|
-
* @returns {{ ok: true, value: T }}
|
|
25
|
-
*/
|
|
26
|
-
function ok(value) {
|
|
27
|
-
return { ok: true, value };
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Wrap an error in a Result.
|
|
32
|
-
* @param {string} code — one of RESULT_CODES
|
|
33
|
-
* @param {string} message — human-readable explanation
|
|
34
|
-
* @returns {{ ok: false, code: string, message: string }}
|
|
35
|
-
*/
|
|
36
|
-
function fail(code, message) {
|
|
37
|
-
return { ok: false, code, message };
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
module.exports = { ok, fail, RESULT_CODES };
|