@specforge/cli 0.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/README.md +781 -0
- package/bin/specforge +21 -0
- package/dist/channel.d.ts +27 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +22 -0
- package/dist/channel.js.map +1 -0
- package/dist/cli/commands/configure.d.ts +16 -0
- package/dist/cli/commands/configure.d.ts.map +1 -0
- package/dist/cli/commands/configure.js +186 -0
- package/dist/cli/commands/configure.js.map +1 -0
- package/dist/cli/commands/configure.types.d.ts +110 -0
- package/dist/cli/commands/configure.types.d.ts.map +1 -0
- package/dist/cli/commands/configure.types.js +82 -0
- package/dist/cli/commands/configure.types.js.map +1 -0
- package/dist/cli/commands/debug/call.d.ts +14 -0
- package/dist/cli/commands/debug/call.d.ts.map +1 -0
- package/dist/cli/commands/debug/call.js +96 -0
- package/dist/cli/commands/debug/call.js.map +1 -0
- package/dist/cli/commands/debug/index.d.ts +12 -0
- package/dist/cli/commands/debug/index.d.ts.map +1 -0
- package/dist/cli/commands/debug/index.js +14 -0
- package/dist/cli/commands/debug/index.js.map +1 -0
- package/dist/cli/commands/debug/register.d.ts +11 -0
- package/dist/cli/commands/debug/register.d.ts.map +1 -0
- package/dist/cli/commands/debug/register.js +78 -0
- package/dist/cli/commands/debug/register.js.map +1 -0
- package/dist/cli/commands/debug/test.d.ts +13 -0
- package/dist/cli/commands/debug/test.d.ts.map +1 -0
- package/dist/cli/commands/debug/test.js +91 -0
- package/dist/cli/commands/debug/test.js.map +1 -0
- package/dist/cli/commands/debug/tools.d.ts +13 -0
- package/dist/cli/commands/debug/tools.d.ts.map +1 -0
- package/dist/cli/commands/debug/tools.js +86 -0
- package/dist/cli/commands/debug/tools.js.map +1 -0
- package/dist/cli/commands/debug/types.d.ts +119 -0
- package/dist/cli/commands/debug/types.d.ts.map +1 -0
- package/dist/cli/commands/debug/types.js +36 -0
- package/dist/cli/commands/debug/types.js.map +1 -0
- package/dist/cli/commands/debug/whoami.d.ts +13 -0
- package/dist/cli/commands/debug/whoami.d.ts.map +1 -0
- package/dist/cli/commands/debug/whoami.js +131 -0
- package/dist/cli/commands/debug/whoami.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +16 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +413 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/doctor.types.d.ts +180 -0
- package/dist/cli/commands/doctor.types.d.ts.map +1 -0
- package/dist/cli/commands/doctor.types.js +140 -0
- package/dist/cli/commands/doctor.types.js.map +1 -0
- package/dist/cli/commands/feedback.d.ts +27 -0
- package/dist/cli/commands/feedback.d.ts.map +1 -0
- package/dist/cli/commands/feedback.js +262 -0
- package/dist/cli/commands/feedback.js.map +1 -0
- package/dist/cli/commands/feedback.types.d.ts +116 -0
- package/dist/cli/commands/feedback.types.d.ts.map +1 -0
- package/dist/cli/commands/feedback.types.js +65 -0
- package/dist/cli/commands/feedback.types.js.map +1 -0
- package/dist/cli/commands/index.d.ts +15 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +21 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +17 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +773 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/init.types.d.ts +193 -0
- package/dist/cli/commands/init.types.d.ts.map +1 -0
- package/dist/cli/commands/init.types.js +29 -0
- package/dist/cli/commands/init.types.js.map +1 -0
- package/dist/cli/commands/invitations.d.ts +31 -0
- package/dist/cli/commands/invitations.d.ts.map +1 -0
- package/dist/cli/commands/invitations.js +250 -0
- package/dist/cli/commands/invitations.js.map +1 -0
- package/dist/cli/commands/login.d.ts +40 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +139 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/commands/members.d.ts +55 -0
- package/dist/cli/commands/members.d.ts.map +1 -0
- package/dist/cli/commands/members.js +296 -0
- package/dist/cli/commands/members.js.map +1 -0
- package/dist/cli/commands/scaffold/agent-types.d.ts +54 -0
- package/dist/cli/commands/scaffold/agent-types.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/agent-types.js +22 -0
- package/dist/cli/commands/scaffold/agent-types.js.map +1 -0
- package/dist/cli/commands/scaffold/display.d.ts +56 -0
- package/dist/cli/commands/scaffold/display.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/display.js +217 -0
- package/dist/cli/commands/scaffold/display.js.map +1 -0
- package/dist/cli/commands/scaffold/files.d.ts +99 -0
- package/dist/cli/commands/scaffold/files.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/files.js +122 -0
- package/dist/cli/commands/scaffold/files.js.map +1 -0
- package/dist/cli/commands/scaffold/index.d.ts +13 -0
- package/dist/cli/commands/scaffold/index.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/index.js +12 -0
- package/dist/cli/commands/scaffold/index.js.map +1 -0
- package/dist/cli/commands/scaffold/register.d.ts +11 -0
- package/dist/cli/commands/scaffold/register.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/register.js +11 -0
- package/dist/cli/commands/scaffold/register.js.map +1 -0
- package/dist/cli/commands/scaffold/scaffold.d.ts +11 -0
- package/dist/cli/commands/scaffold/scaffold.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/scaffold.js +728 -0
- package/dist/cli/commands/scaffold/scaffold.js.map +1 -0
- package/dist/cli/commands/scaffold/targets.d.ts +60 -0
- package/dist/cli/commands/scaffold/targets.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/targets.js +251 -0
- package/dist/cli/commands/scaffold/targets.js.map +1 -0
- package/dist/cli/commands/scaffold/types.d.ts +170 -0
- package/dist/cli/commands/scaffold/types.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/types.js +12 -0
- package/dist/cli/commands/scaffold/types.js.map +1 -0
- package/dist/cli/commands/scaffold/utils.d.ts +89 -0
- package/dist/cli/commands/scaffold/utils.d.ts.map +1 -0
- package/dist/cli/commands/scaffold/utils.js +401 -0
- package/dist/cli/commands/scaffold/utils.js.map +1 -0
- package/dist/cli/commands/status.d.ts +19 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +124 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/status.types.d.ts +37 -0
- package/dist/cli/commands/status.types.d.ts.map +1 -0
- package/dist/cli/commands/status.types.js +7 -0
- package/dist/cli/commands/status.types.js.map +1 -0
- package/dist/cli/commands/switch.d.ts +18 -0
- package/dist/cli/commands/switch.d.ts.map +1 -0
- package/dist/cli/commands/switch.js +134 -0
- package/dist/cli/commands/switch.js.map +1 -0
- package/dist/cli/commands/switch.types.d.ts +123 -0
- package/dist/cli/commands/switch.types.d.ts.map +1 -0
- package/dist/cli/commands/switch.types.js +46 -0
- package/dist/cli/commands/switch.types.js.map +1 -0
- package/dist/cli/config/agent-teams.types.d.ts +120 -0
- package/dist/cli/config/agent-teams.types.d.ts.map +1 -0
- package/dist/cli/config/agent-teams.types.js +23 -0
- package/dist/cli/config/agent-teams.types.js.map +1 -0
- package/dist/cli/config/index.d.ts +13 -0
- package/dist/cli/config/index.d.ts.map +1 -0
- package/dist/cli/config/index.js +7 -0
- package/dist/cli/config/index.js.map +1 -0
- package/dist/cli/config/loader.d.ts +114 -0
- package/dist/cli/config/loader.d.ts.map +1 -0
- package/dist/cli/config/loader.js +198 -0
- package/dist/cli/config/loader.js.map +1 -0
- package/dist/cli/config/paths.d.ts +107 -0
- package/dist/cli/config/paths.d.ts.map +1 -0
- package/dist/cli/config/paths.js +79 -0
- package/dist/cli/config/paths.js.map +1 -0
- package/dist/cli/config/planning-sessions-registry.d.ts +52 -0
- package/dist/cli/config/planning-sessions-registry.d.ts.map +1 -0
- package/dist/cli/config/planning-sessions-registry.js +46 -0
- package/dist/cli/config/planning-sessions-registry.js.map +1 -0
- package/dist/cli/config/types.d.ts +186 -0
- package/dist/cli/config/types.d.ts.map +1 -0
- package/dist/cli/config/types.js +27 -0
- package/dist/cli/config/types.js.map +1 -0
- package/dist/cli/config/validation.d.ts +62 -0
- package/dist/cli/config/validation.d.ts.map +1 -0
- package/dist/cli/config/validation.js +133 -0
- package/dist/cli/config/validation.js.map +1 -0
- package/dist/cli/config/writer.d.ts +153 -0
- package/dist/cli/config/writer.d.ts.map +1 -0
- package/dist/cli/config/writer.js +168 -0
- package/dist/cli/config/writer.js.map +1 -0
- package/dist/cli/index.d.ts +30 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +142 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/middleware/auth-guard.d.ts +107 -0
- package/dist/cli/middleware/auth-guard.d.ts.map +1 -0
- package/dist/cli/middleware/auth-guard.js +97 -0
- package/dist/cli/middleware/auth-guard.js.map +1 -0
- package/dist/cli/middleware/error-handler.d.ts +133 -0
- package/dist/cli/middleware/error-handler.d.ts.map +1 -0
- package/dist/cli/middleware/error-handler.js +139 -0
- package/dist/cli/middleware/error-handler.js.map +1 -0
- package/dist/cli/middleware/index.d.ts +6 -0
- package/dist/cli/middleware/index.d.ts.map +1 -0
- package/dist/cli/middleware/index.js +3 -0
- package/dist/cli/middleware/index.js.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts +9 -0
- package/dist/cli/templates/agents/content/core/sfag-orchestrator.d.ts.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-orchestrator.js +160 -0
- package/dist/cli/templates/agents/content/core/sfag-orchestrator.js.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts +9 -0
- package/dist/cli/templates/agents/content/core/sfag-spec-creator.d.ts.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-spec-creator.js +343 -0
- package/dist/cli/templates/agents/content/core/sfag-spec-creator.js.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts +9 -0
- package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.d.ts.map +1 -0
- package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js +254 -0
- package/dist/cli/templates/agents/content/core/sfag-ticket-implementer.js.map +1 -0
- package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts +8 -0
- package/dist/cli/templates/agents/content/research/sfag-package-researcher.d.ts.map +1 -0
- package/dist/cli/templates/agents/content/research/sfag-package-researcher.js +128 -0
- package/dist/cli/templates/agents/content/research/sfag-package-researcher.js.map +1 -0
- package/dist/cli/templates/agents/index.d.ts +23 -0
- package/dist/cli/templates/agents/index.d.ts.map +1 -0
- package/dist/cli/templates/agents/index.js +29 -0
- package/dist/cli/templates/agents/index.js.map +1 -0
- package/dist/cli/templates/commands.d.ts +17 -0
- package/dist/cli/templates/commands.d.ts.map +1 -0
- package/dist/cli/templates/commands.js +78 -0
- package/dist/cli/templates/commands.js.map +1 -0
- package/dist/cli/templates/content/sf-blockers.d.ts +7 -0
- package/dist/cli/templates/content/sf-blockers.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-blockers.js +69 -0
- package/dist/cli/templates/content/sf-blockers.js.map +1 -0
- package/dist/cli/templates/content/sf-commit.d.ts +7 -0
- package/dist/cli/templates/content/sf-commit.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-commit.js +79 -0
- package/dist/cli/templates/content/sf-commit.js.map +1 -0
- package/dist/cli/templates/content/sf-context.d.ts +7 -0
- package/dist/cli/templates/content/sf-context.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-context.js +63 -0
- package/dist/cli/templates/content/sf-context.js.map +1 -0
- package/dist/cli/templates/content/sf-help.d.ts +7 -0
- package/dist/cli/templates/content/sf-help.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-help.js +42 -0
- package/dist/cli/templates/content/sf-help.js.map +1 -0
- package/dist/cli/templates/content/sf-init.d.ts +7 -0
- package/dist/cli/templates/content/sf-init.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-init.js +62 -0
- package/dist/cli/templates/content/sf-init.js.map +1 -0
- package/dist/cli/templates/content/sf-reset.d.ts +7 -0
- package/dist/cli/templates/content/sf-reset.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-reset.js +67 -0
- package/dist/cli/templates/content/sf-reset.js.map +1 -0
- package/dist/cli/templates/content/sf-search.d.ts +7 -0
- package/dist/cli/templates/content/sf-search.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-search.js +63 -0
- package/dist/cli/templates/content/sf-search.js.map +1 -0
- package/dist/cli/templates/content/sf-status.d.ts +7 -0
- package/dist/cli/templates/content/sf-status.d.ts.map +1 -0
- package/dist/cli/templates/content/sf-status.js +62 -0
- package/dist/cli/templates/content/sf-status.js.map +1 -0
- package/dist/cli/templates/index.d.ts +8 -0
- package/dist/cli/templates/index.d.ts.map +1 -0
- package/dist/cli/templates/index.js +17 -0
- package/dist/cli/templates/index.js.map +1 -0
- package/dist/cli/ui/banner.d.ts +38 -0
- package/dist/cli/ui/banner.d.ts.map +1 -0
- package/dist/cli/ui/banner.js +89 -0
- package/dist/cli/ui/banner.js.map +1 -0
- package/dist/cli/ui/colors.d.ts +76 -0
- package/dist/cli/ui/colors.d.ts.map +1 -0
- package/dist/cli/ui/colors.js +67 -0
- package/dist/cli/ui/colors.js.map +1 -0
- package/dist/cli/ui/index.d.ts +7 -0
- package/dist/cli/ui/index.d.ts.map +1 -0
- package/dist/cli/ui/index.js +4 -0
- package/dist/cli/ui/index.js.map +1 -0
- package/dist/cli/ui/output.d.ts +117 -0
- package/dist/cli/ui/output.d.ts.map +1 -0
- package/dist/cli/ui/output.js +83 -0
- package/dist/cli/ui/output.js.map +1 -0
- package/dist/cli/ui/spinner.d.ts +120 -0
- package/dist/cli/ui/spinner.d.ts.map +1 -0
- package/dist/cli/ui/spinner.js +158 -0
- package/dist/cli/ui/spinner.js.map +1 -0
- package/dist/cli/ui/time.d.ts +54 -0
- package/dist/cli/ui/time.d.ts.map +1 -0
- package/dist/cli/ui/time.js +119 -0
- package/dist/cli/ui/time.js.map +1 -0
- package/dist/client/api-client.d.ts +123 -0
- package/dist/client/api-client.d.ts.map +1 -0
- package/dist/client/api-client.js +105 -0
- package/dist/client/api-client.js.map +1 -0
- package/dist/client/cli-client.d.ts +26 -0
- package/dist/client/cli-client.d.ts.map +1 -0
- package/dist/client/cli-client.js +20 -0
- package/dist/client/cli-client.js.map +1 -0
- package/dist/config/index.d.ts +78 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +79 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/format.d.ts +126 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +71 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/index.d.ts +11 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +45 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/monorepo-detector.d.ts +31 -0
- package/dist/lib/monorepo-detector.d.ts.map +1 -0
- package/dist/lib/monorepo-detector.js +188 -0
- package/dist/lib/monorepo-detector.js.map +1 -0
- package/dist/lib/prompt-generator.d.ts +65 -0
- package/dist/lib/prompt-generator.d.ts.map +1 -0
- package/dist/lib/prompt-generator.js +162 -0
- package/dist/lib/prompt-generator.js.map +1 -0
- package/dist/lib/strategy-analyzer.d.ts +59 -0
- package/dist/lib/strategy-analyzer.d.ts.map +1 -0
- package/dist/lib/strategy-analyzer.js +91 -0
- package/dist/lib/strategy-analyzer.js.map +1 -0
- package/dist/lib/workflow-definitions.d.ts +41 -0
- package/dist/lib/workflow-definitions.d.ts.map +1 -0
- package/dist/lib/workflow-definitions.js +497 -0
- package/dist/lib/workflow-definitions.js.map +1 -0
- package/dist/patterns/index.d.ts +9 -0
- package/dist/patterns/index.d.ts.map +1 -0
- package/dist/patterns/index.js +21 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/inheritance.d.ts +193 -0
- package/dist/patterns/inheritance.d.ts.map +1 -0
- package/dist/patterns/inheritance.js +125 -0
- package/dist/patterns/inheritance.js.map +1 -0
- package/dist/server.d.ts +44 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +91 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/core/context-helper.d.ts +50 -0
- package/dist/tools/core/context-helper.d.ts.map +1 -0
- package/dist/tools/core/context-helper.js +49 -0
- package/dist/tools/core/context-helper.js.map +1 -0
- package/dist/tools/core/index.d.ts +2 -0
- package/dist/tools/core/index.d.ts.map +1 -0
- package/dist/tools/core/index.js +2 -0
- package/dist/tools/core/index.js.map +1 -0
- package/dist/tools/index.d.ts +58 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +1499 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/transport/__tests__/resolve-endpoint.test.d.ts +6 -0
- package/dist/transport/__tests__/resolve-endpoint.test.d.ts.map +1 -0
- package/dist/transport/index.d.ts +6 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +5 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/interface.d.ts +25 -0
- package/dist/transport/interface.d.ts.map +1 -0
- package/dist/transport/interface.js +1 -0
- package/dist/transport/interface.js.map +1 -0
- package/dist/transport/remote.d.ts +38 -0
- package/dist/transport/remote.d.ts.map +1 -0
- package/dist/transport/remote.js +107 -0
- package/dist/transport/remote.js.map +1 -0
- package/dist/transport/resolve-endpoint.d.ts +58 -0
- package/dist/transport/resolve-endpoint.d.ts.map +1 -0
- package/dist/transport/resolve-endpoint.js +146 -0
- package/dist/transport/resolve-endpoint.js.map +1 -0
- package/dist/types/index.d.ts +212 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +16 -0
- package/dist/types/index.js.map +1 -0
- package/dist/validation/index.d.ts +86 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +392 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/ticket-validation.d.ts +162 -0
- package/dist/validation/ticket-validation.d.ts.map +1 -0
- package/dist/validation/ticket-validation.js +188 -0
- package/dist/validation/ticket-validation.js.map +1 -0
- package/package.json +69 -0
- package/src/cli/templates/agents/content/core/sfag-orchestrator.ts +165 -0
- package/src/cli/templates/agents/content/core/sfag-spec-creator.ts +348 -0
- package/src/cli/templates/agents/content/core/sfag-ticket-implementer.ts +259 -0
- package/src/cli/templates/agents/content/research/sfag-package-researcher.ts +132 -0
- package/src/cli/templates/agents/index.ts +47 -0
- package/src/cli/templates/commands.ts +90 -0
- package/src/cli/templates/content/sf-blockers.ts +71 -0
- package/src/cli/templates/content/sf-commit.ts +81 -0
- package/src/cli/templates/content/sf-context.ts +65 -0
- package/src/cli/templates/content/sf-help.ts +44 -0
- package/src/cli/templates/content/sf-init.ts +64 -0
- package/src/cli/templates/content/sf-reset.ts +69 -0
- package/src/cli/templates/content/sf-search.ts +65 -0
- package/src/cli/templates/content/sf-status.ts +64 -0
- package/src/cli/templates/index.ts +16 -0
- package/src/cli/templates/skills/specforge-conventions.md +114 -0
- package/src/cli/templates/skills/specforge-orchestrator.md +409 -0
- package/src/cli/templates/skills/specforge-validator.md +128 -0
- package/src/cli/templates/skills/specforge-worker.md +412 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Teams Configuration Types — Claude Code specific
|
|
3
|
+
*
|
|
4
|
+
* Defines interfaces for the Agent Teams integration sections
|
|
5
|
+
* of the .specforge/config.json configuration file. These extend the
|
|
6
|
+
* existing ProjectConfig without breaking backward compatibility.
|
|
7
|
+
*
|
|
8
|
+
* Agent Teams is the Claude Code-specific orchestration layer that uses
|
|
9
|
+
* Claude Code primitives (TeamCreate, TaskCreate, SendMessage, etc.)
|
|
10
|
+
* to coordinate parallel ticket implementation.
|
|
11
|
+
*
|
|
12
|
+
* @see specforge-agent-teams-spec.md (v2.0.0)
|
|
13
|
+
*/
|
|
14
|
+
import type { ProjectConfig } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* Execution strategy for Agent Teams (Claude Code specific).
|
|
17
|
+
*
|
|
18
|
+
* - `auto` – Analyzer picks based on spec structure (default)
|
|
19
|
+
* - `single` – Sequential, one worker at a time (<=3 tickets, no epic deps)
|
|
20
|
+
* - `parallel` – All epic teams run concurrently (independent epics)
|
|
21
|
+
* - `phased` – Epics run in dependency-ordered phases (cross-epic deps)
|
|
22
|
+
*
|
|
23
|
+
* @see specforge-agent-teams-spec.md Section 4.3
|
|
24
|
+
*/
|
|
25
|
+
export type AgentTeamsStrategy = 'auto' | 'single' | 'parallel' | 'phased';
|
|
26
|
+
/**
|
|
27
|
+
* Currently active specification for Agent Teams implementation (Claude Code specific).
|
|
28
|
+
*
|
|
29
|
+
* Set automatically by `specforge spec activate`. Tells the Agent Teams Lead
|
|
30
|
+
* which specification to work on at startup.
|
|
31
|
+
*
|
|
32
|
+
* @see specforge-agent-teams-spec.md Section 4.2 (LOAD step)
|
|
33
|
+
*/
|
|
34
|
+
export interface ActiveSpecification {
|
|
35
|
+
/** SpecForge specification UUID */
|
|
36
|
+
id: string;
|
|
37
|
+
/** Human-readable spec title (for display) */
|
|
38
|
+
title: string;
|
|
39
|
+
/**
|
|
40
|
+
* ISO 8601 timestamp of activation.
|
|
41
|
+
* Set automatically by `specforge spec activate`.
|
|
42
|
+
*/
|
|
43
|
+
activatedAt: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Agent Teams execution settings (Claude Code specific).
|
|
47
|
+
*
|
|
48
|
+
* Controls how Agent Teams orchestrate spec implementation.
|
|
49
|
+
* All fields are optional — sensible defaults are applied.
|
|
50
|
+
*
|
|
51
|
+
* v2.0.0 simplified to 6 fields. Previous fields (maxTokensPerWorker,
|
|
52
|
+
* branchPattern, autoValidate, validationCommands, escalationPolicy,
|
|
53
|
+
* monorepo) are ignored on read and stripped on write.
|
|
54
|
+
*
|
|
55
|
+
* @see specforge-agent-teams-spec.md Section 9.1
|
|
56
|
+
*/
|
|
57
|
+
export interface AgentTeamsConfig {
|
|
58
|
+
/**
|
|
59
|
+
* Master toggle for Agent Teams.
|
|
60
|
+
* @default false
|
|
61
|
+
*/
|
|
62
|
+
enabled?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Execution strategy selection.
|
|
65
|
+
* @default "auto"
|
|
66
|
+
*/
|
|
67
|
+
strategy?: AgentTeamsStrategy;
|
|
68
|
+
/**
|
|
69
|
+
* Maximum tickets assigned to a single team (1-20).
|
|
70
|
+
* @default 10
|
|
71
|
+
*/
|
|
72
|
+
maxTicketsPerTeam?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Maximum number of epics running in parallel (1-10).
|
|
75
|
+
* @default 3
|
|
76
|
+
*/
|
|
77
|
+
maxParallelEpics?: number;
|
|
78
|
+
/**
|
|
79
|
+
* Git branch naming prefix.
|
|
80
|
+
* @default "ticket/"
|
|
81
|
+
*/
|
|
82
|
+
branchPrefix?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Per-worker timeout in minutes (5-60).
|
|
85
|
+
* @default 15
|
|
86
|
+
*/
|
|
87
|
+
timeoutMinutes?: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Extended .specforge/config.json configuration with Agent Teams support.
|
|
91
|
+
*
|
|
92
|
+
* Extends the existing {@link ProjectConfig} with optional sections
|
|
93
|
+
* for Agent Teams integration (Claude Code specific). All new fields
|
|
94
|
+
* are optional to maintain full backward compatibility.
|
|
95
|
+
*/
|
|
96
|
+
export interface SpecforgeJsonConfig extends ProjectConfig {
|
|
97
|
+
/** Currently active specification for implementation (Agent Teams) */
|
|
98
|
+
activeSpecification?: ActiveSpecification;
|
|
99
|
+
/** Agent Teams execution settings (Claude Code specific) */
|
|
100
|
+
agentTeams?: AgentTeamsConfig;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Default values for AgentTeamsConfig fields (v2.0.0).
|
|
104
|
+
*
|
|
105
|
+
* @see specforge-agent-teams-spec.md Section 9.1
|
|
106
|
+
*/
|
|
107
|
+
export declare const AGENT_TEAMS_DEFAULTS: {
|
|
108
|
+
readonly enabled: false;
|
|
109
|
+
readonly strategy: AgentTeamsStrategy;
|
|
110
|
+
readonly maxTicketsPerTeam: 10;
|
|
111
|
+
readonly maxParallelEpics: 3;
|
|
112
|
+
readonly branchPrefix: "ticket/";
|
|
113
|
+
readonly timeoutMinutes: 15;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Fields that existed pre-v2.0.0 and should be stripped on config write.
|
|
117
|
+
* These are silently ignored on read for backward compatibility.
|
|
118
|
+
*/
|
|
119
|
+
export declare const DEPRECATED_AGENT_TEAMS_FIELDS: readonly ["maxParallelTeams", "maxTokensPerWorker", "branchPattern", "autoValidate", "validationCommands", "escalationPolicy", "maxWorkersPerTeam", "monorepo"];
|
|
120
|
+
//# sourceMappingURL=agent-teams.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-teams.types.d.ts","sourceRoot":"","sources":["../../../src/cli/config/agent-teams.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAMhD;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;AAM3E;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC;IAEX,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAE9B;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,mBAAoB,SAAQ,aAAa;IACxD,sEAAsE;IACtE,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAE1C,4DAA4D;IAC5D,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B;AAMD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;uBAEX,kBAAkB;;;;;CAK9B,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,6BAA6B,iKAShC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const AGENT_TEAMS_DEFAULTS = {
|
|
2
|
+
enabled: false,
|
|
3
|
+
strategy: "auto",
|
|
4
|
+
maxTicketsPerTeam: 10,
|
|
5
|
+
maxParallelEpics: 3,
|
|
6
|
+
branchPrefix: "ticket/",
|
|
7
|
+
timeoutMinutes: 15
|
|
8
|
+
};
|
|
9
|
+
const DEPRECATED_AGENT_TEAMS_FIELDS = [
|
|
10
|
+
"maxParallelTeams",
|
|
11
|
+
"maxTokensPerWorker",
|
|
12
|
+
"branchPattern",
|
|
13
|
+
"autoValidate",
|
|
14
|
+
"validationCommands",
|
|
15
|
+
"escalationPolicy",
|
|
16
|
+
"maxWorkersPerTeam",
|
|
17
|
+
"monorepo"
|
|
18
|
+
];
|
|
19
|
+
export {
|
|
20
|
+
AGENT_TEAMS_DEFAULTS,
|
|
21
|
+
DEPRECATED_AGENT_TEAMS_FIELDS
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=agent-teams.types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/config/agent-teams.types.ts"],"sourcesContent":["/**\n * Agent Teams Configuration Types — Claude Code specific\n *\n * Defines interfaces for the Agent Teams integration sections\n * of the .specforge/config.json configuration file. These extend the\n * existing ProjectConfig without breaking backward compatibility.\n *\n * Agent Teams is the Claude Code-specific orchestration layer that uses\n * Claude Code primitives (TeamCreate, TaskCreate, SendMessage, etc.)\n * to coordinate parallel ticket implementation.\n *\n * @see specforge-agent-teams-spec.md (v2.0.0)\n */\n\nimport type { ProjectConfig } from './types.js';\n\n// ---------------------------------------------------------------------------\n// Literal union types\n// ---------------------------------------------------------------------------\n\n/**\n * Execution strategy for Agent Teams (Claude Code specific).\n *\n * - `auto` – Analyzer picks based on spec structure (default)\n * - `single` – Sequential, one worker at a time (<=3 tickets, no epic deps)\n * - `parallel` – All epic teams run concurrently (independent epics)\n * - `phased` – Epics run in dependency-ordered phases (cross-epic deps)\n *\n * @see specforge-agent-teams-spec.md Section 4.3\n */\nexport type AgentTeamsStrategy = 'auto' | 'single' | 'parallel' | 'phased';\n\n// ---------------------------------------------------------------------------\n// ActiveSpecification\n// ---------------------------------------------------------------------------\n\n/**\n * Currently active specification for Agent Teams implementation (Claude Code specific).\n *\n * Set automatically by `specforge spec activate`. Tells the Agent Teams Lead\n * which specification to work on at startup.\n *\n * @see specforge-agent-teams-spec.md Section 4.2 (LOAD step)\n */\nexport interface ActiveSpecification {\n /** SpecForge specification UUID */\n id: string;\n\n /** Human-readable spec title (for display) */\n title: string;\n\n /**\n * ISO 8601 timestamp of activation.\n * Set automatically by `specforge spec activate`.\n */\n activatedAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// AgentTeamsConfig (v2.0.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Agent Teams execution settings (Claude Code specific).\n *\n * Controls how Agent Teams orchestrate spec implementation.\n * All fields are optional — sensible defaults are applied.\n *\n * v2.0.0 simplified to 6 fields. Previous fields (maxTokensPerWorker,\n * branchPattern, autoValidate, validationCommands, escalationPolicy,\n * monorepo) are ignored on read and stripped on write.\n *\n * @see specforge-agent-teams-spec.md Section 9.1\n */\nexport interface AgentTeamsConfig {\n /**\n * Master toggle for Agent Teams.\n * @default false\n */\n enabled?: boolean;\n\n /**\n * Execution strategy selection.\n * @default \"auto\"\n */\n strategy?: AgentTeamsStrategy;\n\n /**\n * Maximum tickets assigned to a single team (1-20).\n * @default 10\n */\n maxTicketsPerTeam?: number;\n\n /**\n * Maximum number of epics running in parallel (1-10).\n * @default 3\n */\n maxParallelEpics?: number;\n\n /**\n * Git branch naming prefix.\n * @default \"ticket/\"\n */\n branchPrefix?: string;\n\n /**\n * Per-worker timeout in minutes (5-60).\n * @default 15\n */\n timeoutMinutes?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Extended .specforge/config.json\n// ---------------------------------------------------------------------------\n\n/**\n * Extended .specforge/config.json configuration with Agent Teams support.\n *\n * Extends the existing {@link ProjectConfig} with optional sections\n * for Agent Teams integration (Claude Code specific). All new fields\n * are optional to maintain full backward compatibility.\n */\nexport interface SpecforgeJsonConfig extends ProjectConfig {\n /** Currently active specification for implementation (Agent Teams) */\n activeSpecification?: ActiveSpecification;\n\n /** Agent Teams execution settings (Claude Code specific) */\n agentTeams?: AgentTeamsConfig;\n}\n\n// ---------------------------------------------------------------------------\n// Defaults (v2.0.0)\n// ---------------------------------------------------------------------------\n\n/**\n * Default values for AgentTeamsConfig fields (v2.0.0).\n *\n * @see specforge-agent-teams-spec.md Section 9.1\n */\nexport const AGENT_TEAMS_DEFAULTS = {\n enabled: false,\n strategy: 'auto' as AgentTeamsStrategy,\n maxTicketsPerTeam: 10,\n maxParallelEpics: 3,\n branchPrefix: 'ticket/',\n timeoutMinutes: 15,\n} as const;\n\n/**\n * Fields that existed pre-v2.0.0 and should be stripped on config write.\n * These are silently ignored on read for backward compatibility.\n */\nexport const DEPRECATED_AGENT_TEAMS_FIELDS = [\n 'maxParallelTeams',\n 'maxTokensPerWorker',\n 'branchPattern',\n 'autoValidate',\n 'validationCommands',\n 'escalationPolicy',\n 'maxWorkersPerTeam',\n 'monorepo',\n] as const;\n"],"mappings":"AA4IO,MAAM,uBAAuB;AAAA,EAClC,SAAS;AAAA,EACT,UAAU;AAAA,EACV,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,cAAc;AAAA,EACd,gBAAgB;AAClB;AAMO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Configuration Module
|
|
3
|
+
*
|
|
4
|
+
* Provides configuration loading, writing, and path resolution
|
|
5
|
+
* for the SpecForge CLI.
|
|
6
|
+
*/
|
|
7
|
+
export * from './types.js';
|
|
8
|
+
export * from './agent-teams.types.js';
|
|
9
|
+
export * from './validation.js';
|
|
10
|
+
export * from './paths.js';
|
|
11
|
+
export * from './loader.js';
|
|
12
|
+
export * from './writer.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/config/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/config/index.ts"],"sourcesContent":["/**\n * CLI Configuration Module\n *\n * Provides configuration loading, writing, and path resolution\n * for the SpecForge CLI.\n */\n\nexport * from './types.js';\nexport * from './agent-teams.types.js';\nexport * from './validation.js';\nexport * from './paths.js';\nexport * from './loader.js';\nexport * from './writer.js';\n"],"mappings":"AAOA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and merges configuration from multiple sources with the following priority:
|
|
5
|
+
* 1. Environment variables (highest)
|
|
6
|
+
* 2. Project config (.specforge/config.json)
|
|
7
|
+
* 3. Global config (~/.specforge/config.json)
|
|
8
|
+
* 4. Default values (lowest)
|
|
9
|
+
*
|
|
10
|
+
* Project config is a pure read: no migration, no best-effort writes, no
|
|
11
|
+
* deprecation shims. The loader throws a {@link ConfigError} when the config
|
|
12
|
+
* is missing or when a legacy `.specforge.json` is detected.
|
|
13
|
+
*/
|
|
14
|
+
import { GlobalConfig, ResolvedConfig } from './types.js';
|
|
15
|
+
import type { SpecforgeJsonConfig, ActiveSpecification, AgentTeamsConfig } from './agent-teams.types.js';
|
|
16
|
+
/**
|
|
17
|
+
* AgentTeamsConfig with all defaults applied (all fields required).
|
|
18
|
+
*
|
|
19
|
+
* Claude Code Agent Teams only. Not used by MCP tool handlers.
|
|
20
|
+
*/
|
|
21
|
+
export type ResolvedAgentTeamsConfig = Required<AgentTeamsConfig>;
|
|
22
|
+
/**
|
|
23
|
+
* Structured error thrown by {@link loadProjectConfig}.
|
|
24
|
+
*
|
|
25
|
+
* `CONFIG_MISSING` — neither new nor legacy config exists
|
|
26
|
+
* `LEGACY_CONFIG_DETECTED` — only the legacy `.specforge.json` exists
|
|
27
|
+
*/
|
|
28
|
+
export type ConfigErrorCode = 'CONFIG_MISSING' | 'LEGACY_CONFIG_DETECTED';
|
|
29
|
+
export declare class ConfigError extends Error {
|
|
30
|
+
readonly code: ConfigErrorCode;
|
|
31
|
+
constructor(code: ConfigErrorCode, message: string);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load global configuration from ~/.specforge/config.json
|
|
35
|
+
*
|
|
36
|
+
* @returns GlobalConfig object (empty object if file doesn't exist or is invalid)
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadGlobalConfig(): GlobalConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Load project configuration from .specforge/config.json.
|
|
41
|
+
*
|
|
42
|
+
* Pure read: performs no filesystem writes under any code path.
|
|
43
|
+
*
|
|
44
|
+
* @throws {ConfigError} `LEGACY_CONFIG_DETECTED` when only `.specforge.json` exists
|
|
45
|
+
* @throws {ConfigError} `CONFIG_MISSING` when neither new nor legacy config exists
|
|
46
|
+
* @throws {Error} when the config file exists but cannot be parsed as a JSON object
|
|
47
|
+
*/
|
|
48
|
+
export declare function loadProjectConfig(): SpecforgeJsonConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Tolerant wrapper around {@link loadProjectConfig}.
|
|
51
|
+
*
|
|
52
|
+
* Returns `null` when the project config is missing (no file at all), which
|
|
53
|
+
* is a valid state for commands like `login` or `init` that can run outside
|
|
54
|
+
* a configured project. Rethrows `LEGACY_CONFIG_DETECTED` so legacy files
|
|
55
|
+
* keep surfacing the breaking-change notice on every operation.
|
|
56
|
+
*/
|
|
57
|
+
export declare function tryLoadProjectConfig(): SpecforgeJsonConfig | null;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve final configuration from all sources
|
|
60
|
+
*
|
|
61
|
+
* Merges configuration with the following priority (highest to lowest):
|
|
62
|
+
* 1. Environment variables
|
|
63
|
+
* 2. Project config (.specforge/config.json)
|
|
64
|
+
* 3. Global config (~/.specforge/config.json)
|
|
65
|
+
* 4. Default values
|
|
66
|
+
*
|
|
67
|
+
* @returns ResolvedConfig with all values and source tracking
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveConfig(): ResolvedConfig;
|
|
70
|
+
/**
|
|
71
|
+
* Check if user is authenticated (has API key configured)
|
|
72
|
+
*
|
|
73
|
+
* @returns true if API key is available from any source
|
|
74
|
+
*/
|
|
75
|
+
export declare function isAuthenticated(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Get API key if available
|
|
78
|
+
*
|
|
79
|
+
* @returns API key string or null if not configured
|
|
80
|
+
*/
|
|
81
|
+
export declare function getApiKey(): string | null;
|
|
82
|
+
/**
|
|
83
|
+
* Check if running in a project context
|
|
84
|
+
*
|
|
85
|
+
* @returns true if a valid project config was found (legacy files rethrow)
|
|
86
|
+
*/
|
|
87
|
+
export declare function hasProjectContext(): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Get current project ID if available
|
|
90
|
+
*/
|
|
91
|
+
export declare function getProjectId(): string | null;
|
|
92
|
+
/**
|
|
93
|
+
* Get current specification ID if available
|
|
94
|
+
*/
|
|
95
|
+
export declare function getSpecificationId(): string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Get Agent Teams config with defaults merged (v2.0.0).
|
|
98
|
+
*
|
|
99
|
+
* Claude Code Agent Teams only. Not used by MCP tool handlers.
|
|
100
|
+
*
|
|
101
|
+
* Always returns a fully-resolved config object — never null.
|
|
102
|
+
* Partial configs are merged with defaults via spread operator.
|
|
103
|
+
*
|
|
104
|
+
* @param config - Parsed project config (or null for all defaults)
|
|
105
|
+
* @returns Resolved Agent Teams config with all defaults applied
|
|
106
|
+
*/
|
|
107
|
+
export declare function getAgentTeamsConfig(config: SpecforgeJsonConfig | null): ResolvedAgentTeamsConfig;
|
|
108
|
+
/**
|
|
109
|
+
* Get the active specification from config.
|
|
110
|
+
*
|
|
111
|
+
* Claude Code Agent Teams only. Not used by MCP tool handlers.
|
|
112
|
+
*/
|
|
113
|
+
export declare function getActiveSpecification(config: SpecforgeJsonConfig | null): ActiveSpecification | null;
|
|
114
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/cli/config/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EACL,YAAY,EACZ,cAAc,EAMf,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAahC;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,wBAAwB,CAAC;AAE1E,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;gBAEnB,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM;CAKnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,YAAY,CAyB/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,mBAAmB,CAqCvD;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,mBAAmB,GAAG,IAAI,CASjE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAyE9C;AASD;;;;GAIG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAGzC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAGzC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAG5C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAGlD;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,GAAG,wBAAwB,CAUhG;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI,GAAG,mBAAmB,GAAG,IAAI,CAErG"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import {
|
|
3
|
+
CONFIG_DEFAULTS,
|
|
4
|
+
CONFIG_ENV_VARS,
|
|
5
|
+
CONFIG_FILES
|
|
6
|
+
} from "./types.js";
|
|
7
|
+
import {
|
|
8
|
+
AGENT_TEAMS_DEFAULTS
|
|
9
|
+
} from "./agent-teams.types.js";
|
|
10
|
+
import {
|
|
11
|
+
getGlobalConfigPath,
|
|
12
|
+
findProjectConfigPath
|
|
13
|
+
} from "./paths.js";
|
|
14
|
+
import {
|
|
15
|
+
validateSpecforgeJson,
|
|
16
|
+
formatValidationErrors
|
|
17
|
+
} from "./validation.js";
|
|
18
|
+
class ConfigError extends Error {
|
|
19
|
+
code;
|
|
20
|
+
constructor(code, message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "ConfigError";
|
|
23
|
+
this.code = code;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function loadGlobalConfig() {
|
|
27
|
+
const configPath = getGlobalConfigPath();
|
|
28
|
+
if (!fs.existsSync(configPath)) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
33
|
+
const parsed = JSON.parse(content);
|
|
34
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
35
|
+
console.warn(`Warning: ${configPath} is not a valid config object`);
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
return parsed;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if (error instanceof SyntaxError) {
|
|
41
|
+
console.warn(`Warning: Failed to parse ${configPath} - invalid JSON`);
|
|
42
|
+
} else {
|
|
43
|
+
console.warn(`Warning: Failed to read ${configPath}`);
|
|
44
|
+
}
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function loadProjectConfig() {
|
|
49
|
+
const configPath = findProjectConfigPath();
|
|
50
|
+
if (!configPath) {
|
|
51
|
+
throw new ConfigError(
|
|
52
|
+
"CONFIG_MISSING",
|
|
53
|
+
"No SpecForge config found. Run `specforge init` to initialize this project."
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (configPath.endsWith(CONFIG_FILES.LEGACY_PROJECT_CONFIG)) {
|
|
57
|
+
throw new ConfigError(
|
|
58
|
+
"LEGACY_CONFIG_DETECTED",
|
|
59
|
+
"Legacy .specforge.json detected. Run `specforge init` to upgrade to the new .specforge/config.json layout. This is a one-time breaking change for the first production release."
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const content = fs.readFileSync(configPath, "utf-8");
|
|
63
|
+
let parsed;
|
|
64
|
+
try {
|
|
65
|
+
parsed = JSON.parse(content);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
68
|
+
throw new Error(`Invalid JSON in ${configPath}: ${detail}`);
|
|
69
|
+
}
|
|
70
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
71
|
+
throw new Error(`${configPath} is not a valid config object`);
|
|
72
|
+
}
|
|
73
|
+
const validation = validateSpecforgeJson(parsed);
|
|
74
|
+
if (!validation.valid) {
|
|
75
|
+
const lines = formatValidationErrors(validation.errors);
|
|
76
|
+
console.warn(`Warning: Invalid config in ${configPath}:
|
|
77
|
+
${lines.join("\n")}`);
|
|
78
|
+
}
|
|
79
|
+
return parsed;
|
|
80
|
+
}
|
|
81
|
+
function tryLoadProjectConfig() {
|
|
82
|
+
try {
|
|
83
|
+
return loadProjectConfig();
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (error instanceof ConfigError && error.code === "CONFIG_MISSING") {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function resolveConfig() {
|
|
92
|
+
const globalConfig = loadGlobalConfig();
|
|
93
|
+
const projectConfig = tryLoadProjectConfig();
|
|
94
|
+
const sources = {
|
|
95
|
+
apiKey: null,
|
|
96
|
+
projectId: null,
|
|
97
|
+
specificationId: null,
|
|
98
|
+
mcpOutputFormat: "default"
|
|
99
|
+
};
|
|
100
|
+
const resolved = {
|
|
101
|
+
apiKey: null,
|
|
102
|
+
apiUrl: CONFIG_DEFAULTS.apiUrl,
|
|
103
|
+
mcpOutputFormat: CONFIG_DEFAULTS.mcpOutputFormat,
|
|
104
|
+
projectId: null,
|
|
105
|
+
specificationId: null,
|
|
106
|
+
autoSetContext: CONFIG_DEFAULTS.autoSetContext,
|
|
107
|
+
debug: CONFIG_DEFAULTS.debug,
|
|
108
|
+
sources
|
|
109
|
+
};
|
|
110
|
+
if (process.env[CONFIG_ENV_VARS.API_KEY]) {
|
|
111
|
+
resolved.apiKey = process.env[CONFIG_ENV_VARS.API_KEY];
|
|
112
|
+
sources.apiKey = "env";
|
|
113
|
+
} else if (globalConfig.apiKey) {
|
|
114
|
+
resolved.apiKey = globalConfig.apiKey;
|
|
115
|
+
sources.apiKey = "global";
|
|
116
|
+
}
|
|
117
|
+
if (process.env[CONFIG_ENV_VARS.API_URL]) {
|
|
118
|
+
resolved.apiUrl = process.env[CONFIG_ENV_VARS.API_URL];
|
|
119
|
+
}
|
|
120
|
+
resolved.debug = process.env[CONFIG_ENV_VARS.DEBUG] === "true";
|
|
121
|
+
const envFormat = process.env[CONFIG_ENV_VARS.MCP_OUTPUT_FORMAT];
|
|
122
|
+
if (envFormat && isValidFormat(envFormat)) {
|
|
123
|
+
resolved.mcpOutputFormat = envFormat;
|
|
124
|
+
sources.mcpOutputFormat = "env";
|
|
125
|
+
} else if (projectConfig?.mcpOutputFormat && isValidFormat(projectConfig.mcpOutputFormat)) {
|
|
126
|
+
resolved.mcpOutputFormat = projectConfig.mcpOutputFormat;
|
|
127
|
+
sources.mcpOutputFormat = "project";
|
|
128
|
+
} else if (globalConfig.mcpOutputFormat && isValidFormat(globalConfig.mcpOutputFormat)) {
|
|
129
|
+
resolved.mcpOutputFormat = globalConfig.mcpOutputFormat;
|
|
130
|
+
sources.mcpOutputFormat = "global";
|
|
131
|
+
}
|
|
132
|
+
if (projectConfig?.projectId) {
|
|
133
|
+
resolved.projectId = projectConfig.projectId;
|
|
134
|
+
sources.projectId = "project";
|
|
135
|
+
} else if (globalConfig.defaultProjectId) {
|
|
136
|
+
resolved.projectId = globalConfig.defaultProjectId;
|
|
137
|
+
sources.projectId = "global";
|
|
138
|
+
}
|
|
139
|
+
if (projectConfig?.specificationId) {
|
|
140
|
+
resolved.specificationId = projectConfig.specificationId;
|
|
141
|
+
sources.specificationId = "project";
|
|
142
|
+
}
|
|
143
|
+
if (projectConfig?.autoSetContext !== void 0) {
|
|
144
|
+
resolved.autoSetContext = projectConfig.autoSetContext;
|
|
145
|
+
}
|
|
146
|
+
return resolved;
|
|
147
|
+
}
|
|
148
|
+
function isValidFormat(format) {
|
|
149
|
+
return format === "json" || format === "toon";
|
|
150
|
+
}
|
|
151
|
+
function isAuthenticated() {
|
|
152
|
+
const config = resolveConfig();
|
|
153
|
+
return config.apiKey !== null;
|
|
154
|
+
}
|
|
155
|
+
function getApiKey() {
|
|
156
|
+
const config = resolveConfig();
|
|
157
|
+
return config.apiKey;
|
|
158
|
+
}
|
|
159
|
+
function hasProjectContext() {
|
|
160
|
+
return tryLoadProjectConfig() !== null;
|
|
161
|
+
}
|
|
162
|
+
function getProjectId() {
|
|
163
|
+
const config = resolveConfig();
|
|
164
|
+
return config.projectId;
|
|
165
|
+
}
|
|
166
|
+
function getSpecificationId() {
|
|
167
|
+
const config = resolveConfig();
|
|
168
|
+
return config.specificationId;
|
|
169
|
+
}
|
|
170
|
+
function getAgentTeamsConfig(config) {
|
|
171
|
+
const partial = config?.agentTeams;
|
|
172
|
+
return {
|
|
173
|
+
enabled: partial?.enabled ?? AGENT_TEAMS_DEFAULTS.enabled,
|
|
174
|
+
strategy: partial?.strategy ?? AGENT_TEAMS_DEFAULTS.strategy,
|
|
175
|
+
maxTicketsPerTeam: partial?.maxTicketsPerTeam ?? AGENT_TEAMS_DEFAULTS.maxTicketsPerTeam,
|
|
176
|
+
maxParallelEpics: partial?.maxParallelEpics ?? AGENT_TEAMS_DEFAULTS.maxParallelEpics,
|
|
177
|
+
branchPrefix: partial?.branchPrefix ?? AGENT_TEAMS_DEFAULTS.branchPrefix,
|
|
178
|
+
timeoutMinutes: partial?.timeoutMinutes ?? AGENT_TEAMS_DEFAULTS.timeoutMinutes
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function getActiveSpecification(config) {
|
|
182
|
+
return config?.activeSpecification ?? null;
|
|
183
|
+
}
|
|
184
|
+
export {
|
|
185
|
+
ConfigError,
|
|
186
|
+
getActiveSpecification,
|
|
187
|
+
getAgentTeamsConfig,
|
|
188
|
+
getApiKey,
|
|
189
|
+
getProjectId,
|
|
190
|
+
getSpecificationId,
|
|
191
|
+
hasProjectContext,
|
|
192
|
+
isAuthenticated,
|
|
193
|
+
loadGlobalConfig,
|
|
194
|
+
loadProjectConfig,
|
|
195
|
+
resolveConfig,
|
|
196
|
+
tryLoadProjectConfig
|
|
197
|
+
};
|
|
198
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/cli/config/loader.ts"],"sourcesContent":["/**\n * Config Loader\n *\n * Loads and merges configuration from multiple sources with the following priority:\n * 1. Environment variables (highest)\n * 2. Project config (.specforge/config.json)\n * 3. Global config (~/.specforge/config.json)\n * 4. Default values (lowest)\n *\n * Project config is a pure read: no migration, no best-effort writes, no\n * deprecation shims. The loader throws a {@link ConfigError} when the config\n * is missing or when a legacy `.specforge.json` is detected.\n */\n\nimport fs from 'node:fs';\nimport {\n GlobalConfig,\n ResolvedConfig,\n ConfigSources,\n OutputFormat,\n CONFIG_DEFAULTS,\n CONFIG_ENV_VARS,\n CONFIG_FILES,\n} from './types.js';\nimport type {\n SpecforgeJsonConfig,\n ActiveSpecification,\n AgentTeamsConfig,\n} from './agent-teams.types.js';\nimport {\n AGENT_TEAMS_DEFAULTS,\n} from './agent-teams.types.js';\nimport {\n getGlobalConfigPath,\n findProjectConfigPath,\n} from './paths.js';\nimport {\n validateSpecforgeJson,\n formatValidationErrors,\n} from './validation.js';\n\n/**\n * AgentTeamsConfig with all defaults applied (all fields required).\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n */\nexport type ResolvedAgentTeamsConfig = Required<AgentTeamsConfig>;\n\n/**\n * Structured error thrown by {@link loadProjectConfig}.\n *\n * `CONFIG_MISSING` — neither new nor legacy config exists\n * `LEGACY_CONFIG_DETECTED` — only the legacy `.specforge.json` exists\n */\nexport type ConfigErrorCode = 'CONFIG_MISSING' | 'LEGACY_CONFIG_DETECTED';\n\nexport class ConfigError extends Error {\n readonly code: ConfigErrorCode;\n\n constructor(code: ConfigErrorCode, message: string) {\n super(message);\n this.name = 'ConfigError';\n this.code = code;\n }\n}\n\n/**\n * Load global configuration from ~/.specforge/config.json\n *\n * @returns GlobalConfig object (empty object if file doesn't exist or is invalid)\n */\nexport function loadGlobalConfig(): GlobalConfig {\n const configPath = getGlobalConfigPath();\n\n if (!fs.existsSync(configPath)) {\n return {};\n }\n\n try {\n const content = fs.readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(content);\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n console.warn(`Warning: ${configPath} is not a valid config object`);\n return {};\n }\n\n return parsed as GlobalConfig;\n } catch (error) {\n if (error instanceof SyntaxError) {\n console.warn(`Warning: Failed to parse ${configPath} - invalid JSON`);\n } else {\n console.warn(`Warning: Failed to read ${configPath}`);\n }\n return {};\n }\n}\n\n/**\n * Load project configuration from .specforge/config.json.\n *\n * Pure read: performs no filesystem writes under any code path.\n *\n * @throws {ConfigError} `LEGACY_CONFIG_DETECTED` when only `.specforge.json` exists\n * @throws {ConfigError} `CONFIG_MISSING` when neither new nor legacy config exists\n * @throws {Error} when the config file exists but cannot be parsed as a JSON object\n */\nexport function loadProjectConfig(): SpecforgeJsonConfig {\n const configPath = findProjectConfigPath();\n\n if (!configPath) {\n throw new ConfigError(\n 'CONFIG_MISSING',\n 'No SpecForge config found. Run `specforge init` to initialize this project.'\n );\n }\n\n if (configPath.endsWith(CONFIG_FILES.LEGACY_PROJECT_CONFIG)) {\n throw new ConfigError(\n 'LEGACY_CONFIG_DETECTED',\n 'Legacy .specforge.json detected. Run `specforge init` to upgrade to the new .specforge/config.json layout. This is a one-time breaking change for the first production release.'\n );\n }\n\n const content = fs.readFileSync(configPath, 'utf-8');\n let parsed: unknown;\n try {\n parsed = JSON.parse(content);\n } catch (error) {\n const detail = error instanceof Error ? error.message : String(error);\n throw new Error(`Invalid JSON in ${configPath}: ${detail}`);\n }\n\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(`${configPath} is not a valid config object`);\n }\n\n const validation = validateSpecforgeJson(parsed);\n if (!validation.valid) {\n const lines = formatValidationErrors(validation.errors);\n console.warn(`Warning: Invalid config in ${configPath}:\\n${lines.join('\\n')}`);\n }\n\n return parsed as SpecforgeJsonConfig;\n}\n\n/**\n * Tolerant wrapper around {@link loadProjectConfig}.\n *\n * Returns `null` when the project config is missing (no file at all), which\n * is a valid state for commands like `login` or `init` that can run outside\n * a configured project. Rethrows `LEGACY_CONFIG_DETECTED` so legacy files\n * keep surfacing the breaking-change notice on every operation.\n */\nexport function tryLoadProjectConfig(): SpecforgeJsonConfig | null {\n try {\n return loadProjectConfig();\n } catch (error) {\n if (error instanceof ConfigError && error.code === 'CONFIG_MISSING') {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Resolve final configuration from all sources\n *\n * Merges configuration with the following priority (highest to lowest):\n * 1. Environment variables\n * 2. Project config (.specforge/config.json)\n * 3. Global config (~/.specforge/config.json)\n * 4. Default values\n *\n * @returns ResolvedConfig with all values and source tracking\n */\nexport function resolveConfig(): ResolvedConfig {\n const globalConfig = loadGlobalConfig();\n const projectConfig = tryLoadProjectConfig();\n\n const sources: ConfigSources = {\n apiKey: null,\n projectId: null,\n specificationId: null,\n mcpOutputFormat: 'default',\n };\n\n const resolved: ResolvedConfig = {\n apiKey: null,\n apiUrl: CONFIG_DEFAULTS.apiUrl,\n mcpOutputFormat: CONFIG_DEFAULTS.mcpOutputFormat,\n projectId: null,\n specificationId: null,\n autoSetContext: CONFIG_DEFAULTS.autoSetContext,\n debug: CONFIG_DEFAULTS.debug,\n sources,\n };\n\n // --- API Key: ENV > Global ---\n if (process.env[CONFIG_ENV_VARS.API_KEY]) {\n resolved.apiKey = process.env[CONFIG_ENV_VARS.API_KEY]!;\n sources.apiKey = 'env';\n } else if (globalConfig.apiKey) {\n resolved.apiKey = globalConfig.apiKey;\n sources.apiKey = 'global';\n }\n\n // --- API URL: ENV > Default ---\n if (process.env[CONFIG_ENV_VARS.API_URL]) {\n resolved.apiUrl = process.env[CONFIG_ENV_VARS.API_URL]!;\n }\n\n // --- Debug: ENV only ---\n resolved.debug = process.env[CONFIG_ENV_VARS.DEBUG] === 'true';\n\n // --- MCP output format: ENV > Project > Global > Default ---\n const envFormat = process.env[CONFIG_ENV_VARS.MCP_OUTPUT_FORMAT];\n if (envFormat && isValidFormat(envFormat)) {\n resolved.mcpOutputFormat = envFormat;\n sources.mcpOutputFormat = 'env';\n } else if (projectConfig?.mcpOutputFormat && isValidFormat(projectConfig.mcpOutputFormat)) {\n resolved.mcpOutputFormat = projectConfig.mcpOutputFormat;\n sources.mcpOutputFormat = 'project';\n } else if (globalConfig.mcpOutputFormat && isValidFormat(globalConfig.mcpOutputFormat)) {\n resolved.mcpOutputFormat = globalConfig.mcpOutputFormat;\n sources.mcpOutputFormat = 'global';\n }\n\n // --- Project ID: Project > Global ---\n if (projectConfig?.projectId) {\n resolved.projectId = projectConfig.projectId;\n sources.projectId = 'project';\n } else if (globalConfig.defaultProjectId) {\n resolved.projectId = globalConfig.defaultProjectId;\n sources.projectId = 'global';\n }\n\n // --- Specification ID: Project only ---\n if (projectConfig?.specificationId) {\n resolved.specificationId = projectConfig.specificationId;\n sources.specificationId = 'project';\n }\n\n // --- Auto Set Context: Project > Default ---\n if (projectConfig?.autoSetContext !== undefined) {\n resolved.autoSetContext = projectConfig.autoSetContext;\n }\n\n return resolved;\n}\n\n/**\n * Validate that a string is a valid output format\n */\nfunction isValidFormat(format: string): format is OutputFormat {\n return format === 'json' || format === 'toon';\n}\n\n/**\n * Check if user is authenticated (has API key configured)\n *\n * @returns true if API key is available from any source\n */\nexport function isAuthenticated(): boolean {\n const config = resolveConfig();\n return config.apiKey !== null;\n}\n\n/**\n * Get API key if available\n *\n * @returns API key string or null if not configured\n */\nexport function getApiKey(): string | null {\n const config = resolveConfig();\n return config.apiKey;\n}\n\n/**\n * Check if running in a project context\n *\n * @returns true if a valid project config was found (legacy files rethrow)\n */\nexport function hasProjectContext(): boolean {\n return tryLoadProjectConfig() !== null;\n}\n\n/**\n * Get current project ID if available\n */\nexport function getProjectId(): string | null {\n const config = resolveConfig();\n return config.projectId;\n}\n\n/**\n * Get current specification ID if available\n */\nexport function getSpecificationId(): string | null {\n const config = resolveConfig();\n return config.specificationId;\n}\n\n// ---------------------------------------------------------------------------\n// Agent Teams config helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Get Agent Teams config with defaults merged (v2.0.0).\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n *\n * Always returns a fully-resolved config object — never null.\n * Partial configs are merged with defaults via spread operator.\n *\n * @param config - Parsed project config (or null for all defaults)\n * @returns Resolved Agent Teams config with all defaults applied\n */\nexport function getAgentTeamsConfig(config: SpecforgeJsonConfig | null): ResolvedAgentTeamsConfig {\n const partial = config?.agentTeams;\n return {\n enabled: partial?.enabled ?? AGENT_TEAMS_DEFAULTS.enabled,\n strategy: partial?.strategy ?? AGENT_TEAMS_DEFAULTS.strategy,\n maxTicketsPerTeam: partial?.maxTicketsPerTeam ?? AGENT_TEAMS_DEFAULTS.maxTicketsPerTeam,\n maxParallelEpics: partial?.maxParallelEpics ?? AGENT_TEAMS_DEFAULTS.maxParallelEpics,\n branchPrefix: partial?.branchPrefix ?? AGENT_TEAMS_DEFAULTS.branchPrefix,\n timeoutMinutes: partial?.timeoutMinutes ?? AGENT_TEAMS_DEFAULTS.timeoutMinutes,\n };\n}\n\n/**\n * Get the active specification from config.\n *\n * Claude Code Agent Teams only. Not used by MCP tool handlers.\n */\nexport function getActiveSpecification(config: SpecforgeJsonConfig | null): ActiveSpecification | null {\n return config?.activeSpecification ?? null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Paths Resolution
|
|
3
|
+
*
|
|
4
|
+
* Provides functions for resolving configuration file paths.
|
|
5
|
+
* Handles both global (~/.specforge/) and project-level (.specforge.json) paths.
|
|
6
|
+
*/
|
|
7
|
+
import { ConfigPaths } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Get all configuration file paths
|
|
10
|
+
*
|
|
11
|
+
* @returns ConfigPaths object with all resolved paths
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* const paths = getConfigPaths();
|
|
16
|
+
* console.log(paths.globalDir); // /home/user/.specforge
|
|
17
|
+
* console.log(paths.globalConfig); // /home/user/.specforge/config.json
|
|
18
|
+
* console.log(paths.projectConfig); // /current/dir/.specforge.json
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function getConfigPaths(): ConfigPaths;
|
|
22
|
+
/**
|
|
23
|
+
* Get the global configuration directory path
|
|
24
|
+
*
|
|
25
|
+
* Uses $HOME/.specforge on all platforms.
|
|
26
|
+
* Does not create the directory - that's handled by the writer.
|
|
27
|
+
*
|
|
28
|
+
* @returns Absolute path to global config directory
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* const dir = getGlobalConfigDir();
|
|
33
|
+
* // Linux/macOS: /home/user/.specforge
|
|
34
|
+
* // Windows: C:\Users\user\.specforge
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function getGlobalConfigDir(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Get the global configuration file path
|
|
40
|
+
*
|
|
41
|
+
* @returns Absolute path to ~/.specforge/config.json
|
|
42
|
+
*/
|
|
43
|
+
export declare function getGlobalConfigPath(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get the project configuration file path
|
|
46
|
+
*
|
|
47
|
+
* Resolves to .specforge.json in the current working directory.
|
|
48
|
+
* Note: This returns the path in CWD only - for searching up the
|
|
49
|
+
* directory tree, use findProjectConfigPath().
|
|
50
|
+
*
|
|
51
|
+
* @returns Absolute path to .specforge.json in current directory
|
|
52
|
+
*/
|
|
53
|
+
export declare function getProjectConfigPath(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Get the MCP configuration file path
|
|
56
|
+
*
|
|
57
|
+
* @returns Absolute path to .mcp.json in current directory
|
|
58
|
+
*/
|
|
59
|
+
export declare function getMcpConfigPath(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Get the planning-sessions registry path (M9.6 §2.6).
|
|
62
|
+
*
|
|
63
|
+
* Lives alongside config.json under the channel-aware project config dir
|
|
64
|
+
* (`.specforge/planning-sessions.json` on stable, `.specforge-canary/...` on
|
|
65
|
+
* canary — `CONFIG_FILES.PROJECT_DIR` flows from `CHANNEL.configDir`).
|
|
66
|
+
*
|
|
67
|
+
* @param targetDir - Project root (defaults to cwd)
|
|
68
|
+
* @returns Absolute path to the planning-sessions registry file
|
|
69
|
+
*/
|
|
70
|
+
export declare function getPlanningSessionsRegistryPath(targetDir?: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Find project config by searching up the directory tree
|
|
73
|
+
*
|
|
74
|
+
* Starts from the current directory and walks up to the filesystem root,
|
|
75
|
+
* looking for .specforge.json at each level.
|
|
76
|
+
*
|
|
77
|
+
* @param startDir - Directory to start searching from (defaults to cwd)
|
|
78
|
+
* @returns Absolute path to .specforge.json if found, null otherwise
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* // Given: /home/user/projects/myapp/src/components
|
|
83
|
+
* // With .specforge.json at /home/user/projects/myapp/.specforge.json
|
|
84
|
+
*
|
|
85
|
+
* const configPath = findProjectConfigPath();
|
|
86
|
+
* // Returns: /home/user/projects/myapp/.specforge.json
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export declare function findProjectConfigPath(startDir?: string): string | null;
|
|
90
|
+
/**
|
|
91
|
+
* Get the directory containing the project config
|
|
92
|
+
*
|
|
93
|
+
* Useful for resolving relative paths from the project root.
|
|
94
|
+
*
|
|
95
|
+
* @returns Directory path if project config found, null otherwise
|
|
96
|
+
*/
|
|
97
|
+
export declare function findProjectRoot(): string | null;
|
|
98
|
+
/**
|
|
99
|
+
* Check if a path is within the global config directory
|
|
100
|
+
*
|
|
101
|
+
* Security check to prevent path traversal attacks.
|
|
102
|
+
*
|
|
103
|
+
* @param targetPath - Path to check
|
|
104
|
+
* @returns true if path is within ~/.specforge/
|
|
105
|
+
*/
|
|
106
|
+
export declare function isWithinGlobalDir(targetPath: string): boolean;
|
|
107
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/cli/config/paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAC;AAEvD;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAS5C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+BtE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAU/C;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAO7D"}
|