@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.17
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 +21 -1
- package/bin/aiwg.mjs +349 -0
- package/dist/src/a2a/agent-card.js +145 -0
- package/dist/src/a2a/client.js +411 -0
- package/dist/src/a2a/hitl-cli.js +171 -0
- package/dist/src/a2a/hitl-driver.js +370 -0
- package/dist/src/a2a/hitl.js +181 -0
- package/dist/src/a2a/http.js +193 -0
- package/dist/src/a2a/jcs.js +128 -0
- package/dist/src/a2a/jws.js +187 -0
- package/dist/src/a2a/types.js +24 -0
- package/dist/src/a2a/webhook.js +240 -0
- package/dist/src/activity-log/cli.js +348 -0
- package/dist/src/activity-log/parser.js +81 -0
- package/dist/src/activity-log/types.js +50 -0
- package/dist/src/agents/agent-deployer.js +367 -0
- package/dist/src/agents/agent-packager.js +271 -0
- package/dist/src/agents/agent-validator.js +271 -0
- package/dist/src/agents/grounding/knowledge-base.js +161 -0
- package/dist/src/agents/grounding/types.js +12 -0
- package/dist/src/agents/index.js +10 -0
- package/dist/src/agents/packaged-agent-inventory.js +75 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/api/index.d.ts +10 -0
- package/dist/src/api/index.js +10 -0
- package/dist/src/artifacts/address-parser.js +73 -0
- package/dist/src/artifacts/audit/cli.js +183 -0
- package/dist/src/artifacts/audit/drift.js +122 -0
- package/dist/src/artifacts/audit/types.js +12 -0
- package/dist/src/artifacts/backends/graphology-backend.js +160 -0
- package/dist/src/artifacts/backends/json-backend.js +129 -0
- package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
- package/dist/src/artifacts/browser-export.js +622 -0
- package/dist/src/artifacts/capability-resolver.js +94 -0
- package/dist/src/artifacts/checksum-manifest.js +91 -0
- package/dist/src/artifacts/citation-parser.js +162 -0
- package/dist/src/artifacts/cli.js +1462 -0
- package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
- package/dist/src/artifacts/corpus-tools/cli.js +393 -0
- package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
- package/dist/src/artifacts/corpus-tools/curator.js +186 -0
- package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
- package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
- package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
- package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
- package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
- package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
- package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
- package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
- package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
- package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
- package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
- package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
- package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
- package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
- package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
- package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
- package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
- package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
- package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
- package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
- package/dist/src/artifacts/corpus-views/build.js +126 -0
- package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
- package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
- package/dist/src/artifacts/corpus-views/renderers.js +353 -0
- package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
- package/dist/src/artifacts/dep-graph.js +173 -0
- package/dist/src/artifacts/discover-facets.js +375 -0
- package/dist/src/artifacts/embedding-index.js +354 -0
- package/dist/src/artifacts/enrichment/cli.js +240 -0
- package/dist/src/artifacts/enrichment/prompt.js +47 -0
- package/dist/src/artifacts/enrichment/store.js +90 -0
- package/dist/src/artifacts/enrichment/types.js +12 -0
- package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
- package/dist/src/artifacts/fortemi-core-sync.js +251 -0
- package/dist/src/artifacts/fortemi-shard-export.js +44 -0
- package/dist/src/artifacts/fulltext.js +108 -0
- package/dist/src/artifacts/graph-backend.js +51 -0
- package/dist/src/artifacts/graph-query.js +247 -0
- package/dist/src/artifacts/hybrid-query.js +225 -0
- package/dist/src/artifacts/index-builder.js +1089 -0
- package/dist/src/artifacts/index-reader.js +112 -0
- package/dist/src/artifacts/index-status.js +193 -0
- package/dist/src/artifacts/legacy-index-migration.js +169 -0
- package/dist/src/artifacts/move.js +154 -0
- package/dist/src/artifacts/operational-state.js +239 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
- package/dist/src/artifacts/query-engine.js +1955 -0
- package/dist/src/artifacts/source-graph.js +529 -0
- package/dist/src/artifacts/stats.js +169 -0
- package/dist/src/artifacts/types.js +606 -0
- package/dist/src/artifacts/views/cli.js +293 -0
- package/dist/src/artifacts/views/definition.js +170 -0
- package/dist/src/artifacts/views/store.js +149 -0
- package/dist/src/artifacts/views/types.js +8 -0
- package/dist/src/artifacts/watcher.js +255 -0
- package/dist/src/catalog/builtin-models.json +636 -0
- package/dist/src/catalog/cli.js +228 -0
- package/dist/src/catalog/cli.mjs +289 -0
- package/dist/src/catalog/index.js +15 -0
- package/dist/src/catalog/loader.js +217 -0
- package/dist/src/catalog/loader.mjs +251 -0
- package/dist/src/catalog/sources.json +41 -0
- package/dist/src/catalog/types.js +8 -0
- package/dist/src/channel/manager.mjs +504 -0
- package/dist/src/cli/agent-spawn.js +178 -0
- package/dist/src/cli/cli-extension-loader.js +245 -0
- package/dist/src/cli/command-log.js +275 -0
- package/dist/src/cli/config-loader.js +232 -0
- package/dist/src/cli/env.js +82 -0
- package/dist/src/cli/errors.js +150 -0
- package/dist/src/cli/find-package-root.js +40 -0
- package/dist/src/cli/git-hooks.js +250 -0
- package/dist/src/cli/handlers/agentcard.js +206 -0
- package/dist/src/cli/handlers/artifacts.js +76 -0
- package/dist/src/cli/handlers/best-practices-audit.js +280 -0
- package/dist/src/cli/handlers/cockpit.js +137 -0
- package/dist/src/cli/handlers/command-log.js +37 -0
- package/dist/src/cli/handlers/daemon.js +59 -0
- package/dist/src/cli/handlers/diagnose.js +300 -0
- package/dist/src/cli/handlers/execution-mode.js +105 -0
- package/dist/src/cli/handlers/feedback.js +341 -0
- package/dist/src/cli/handlers/help.js +147 -0
- package/dist/src/cli/handlers/index.js +302 -0
- package/dist/src/cli/handlers/init.js +179 -0
- package/dist/src/cli/handlers/install.js +129 -0
- package/dist/src/cli/handlers/issues.js +46 -0
- package/dist/src/cli/handlers/lint.js +42 -0
- package/dist/src/cli/handlers/local-executor.js +315 -0
- package/dist/src/cli/handlers/marketplace.js +168 -0
- package/dist/src/cli/handlers/mc.js +1010 -0
- package/dist/src/cli/handlers/models.js +352 -0
- package/dist/src/cli/handlers/packages.js +155 -0
- package/dist/src/cli/handlers/ralph-launcher.js +717 -0
- package/dist/src/cli/handlers/ralph.js +575 -0
- package/dist/src/cli/handlers/refresh.js +432 -0
- package/dist/src/cli/handlers/regenerate.js +336 -0
- package/dist/src/cli/handlers/repo-access.js +109 -0
- package/dist/src/cli/handlers/run.js +165 -0
- package/dist/src/cli/handlers/runtime-info.js +301 -0
- package/dist/src/cli/handlers/sandbox.js +197 -0
- package/dist/src/cli/handlers/scaffolding.js +149 -0
- package/dist/src/cli/handlers/script-runner.js +121 -0
- package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
- package/dist/src/cli/handlers/serve.js +1835 -0
- package/dist/src/cli/handlers/session.js +348 -0
- package/dist/src/cli/handlers/setup.js +440 -0
- package/dist/src/cli/handlers/skill-lint.js +367 -0
- package/dist/src/cli/handlers/skill-usage.js +74 -0
- package/dist/src/cli/handlers/steward.js +567 -0
- package/dist/src/cli/handlers/subcommands.js +1702 -0
- package/dist/src/cli/handlers/team.js +337 -0
- package/dist/src/cli/handlers/types.js +11 -0
- package/dist/src/cli/handlers/use.js +2772 -0
- package/dist/src/cli/handlers/utilities.js +703 -0
- package/dist/src/cli/handlers/version.js +134 -0
- package/dist/src/cli/handlers/workspace-context.js +93 -0
- package/dist/src/cli/handlers/workspace.js +126 -0
- package/dist/src/cli/help-generator.js +178 -0
- package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
- package/dist/src/cli/hooks/executor.js +96 -0
- package/dist/src/cli/hooks/index.js +15 -0
- package/dist/src/cli/hooks/registry.js +143 -0
- package/dist/src/cli/hooks/types.js +13 -0
- package/dist/src/cli/log.js +492 -0
- package/dist/src/cli/project-isolation/detect.js +70 -0
- package/dist/src/cli/project-isolation/index.js +7 -0
- package/dist/src/cli/project-isolation/signals.js +17 -0
- package/dist/src/cli/project-isolation/warning.js +102 -0
- package/dist/src/cli/prompt-utils.js +155 -0
- package/dist/src/cli/provider-deployment-plan.js +126 -0
- package/dist/src/cli/provider-resolution.js +119 -0
- package/dist/src/cli/router.js +305 -0
- package/dist/src/cli/scope-resolver.js +392 -0
- package/dist/src/cli/skill-usage.js +616 -0
- package/dist/src/cli/ui.js +224 -0
- package/dist/src/cli/watch-service.js +203 -0
- package/dist/src/cli/workflow-orchestrator.js +478 -0
- package/dist/src/cli/workspace-signals.js +321 -0
- package/dist/src/community/footer.js +14 -0
- package/dist/src/community/links.js +123 -0
- package/dist/src/community/milestones.js +46 -0
- package/dist/src/community/nudge-policy.js +93 -0
- package/dist/src/config/aiwg-config.js +883 -0
- package/dist/src/config/cli.js +703 -0
- package/dist/src/config/gitignore.js +156 -0
- package/dist/src/config/project-artifacts.js +76 -0
- package/dist/src/config/user-config.js +428 -0
- package/dist/src/config/user-registry.js +127 -0
- package/dist/src/config/workspace.js +276 -0
- package/dist/src/contributors/detect.js +39 -0
- package/dist/src/contributors/discover.js +172 -0
- package/dist/src/contributors/heuristic.js +186 -0
- package/dist/src/contributors/index.js +11 -0
- package/dist/src/contributors/types.js +13 -0
- package/dist/src/contributors/validation.js +116 -0
- package/dist/src/data/community.schema.json +43 -0
- package/dist/src/data/community.yaml +16 -0
- package/dist/src/extensions/capability-index.js +270 -0
- package/dist/src/extensions/claude-hooks-installer.js +268 -0
- package/dist/src/extensions/commands/definitions.js +3485 -0
- package/dist/src/extensions/deployment-registration.js +463 -0
- package/dist/src/extensions/index.js +22 -0
- package/dist/src/extensions/loader.js +132 -0
- package/dist/src/extensions/managed-marker.js +100 -0
- package/dist/src/extensions/manifest.js +196 -0
- package/dist/src/extensions/project-local-activity.js +114 -0
- package/dist/src/extensions/project-local-discovery.js +261 -0
- package/dist/src/extensions/project-local-doctor.js +281 -0
- package/dist/src/extensions/project-local-gitignore.js +176 -0
- package/dist/src/extensions/project-local-paths.js +121 -0
- package/dist/src/extensions/project-local-promote.js +218 -0
- package/dist/src/extensions/project-local-remove.js +373 -0
- package/dist/src/extensions/project-local-scaffold.js +252 -0
- package/dist/src/extensions/project-quickref.js +291 -0
- package/dist/src/extensions/registry.js +368 -0
- package/dist/src/extensions/shadow-resolver.js +271 -0
- package/dist/src/extensions/types.js +86 -0
- package/dist/src/extensions/upstream-registry.js +195 -0
- package/dist/src/extensions/validation.js +631 -0
- package/dist/src/features/catalog.js +88 -0
- package/dist/src/features/cli.js +197 -0
- package/dist/src/features/installer.js +57 -0
- package/dist/src/features/paths.js +14 -0
- package/dist/src/features/runtime.js +21 -0
- package/dist/src/features/status.js +134 -0
- package/dist/src/hooks/laziness-detection.js +532 -0
- package/dist/src/intake/git-history-analyzer.js +486 -0
- package/dist/src/intake/index.js +9 -0
- package/dist/src/issues/cli.js +327 -0
- package/dist/src/issues/index.js +5 -0
- package/dist/src/issues/live.js +154 -0
- package/dist/src/issues/local.js +666 -0
- package/dist/src/issues/sync.js +143 -0
- package/dist/src/issues/types.js +2 -0
- package/dist/src/issues/workflows.js +164 -0
- package/dist/src/kb/cli.js +173 -0
- package/dist/src/lint/cli.js +171 -0
- package/dist/src/lint/loader.js +225 -0
- package/dist/src/lint/reporters.js +141 -0
- package/dist/src/lint/runner.js +364 -0
- package/dist/src/lint/types.js +10 -0
- package/dist/src/marketplace/cache.js +110 -0
- package/dist/src/marketplace/identifier.js +63 -0
- package/dist/src/marketplace/registry.js +36 -0
- package/dist/src/marketplace/sources/clawhub.js +53 -0
- package/dist/src/marketplace/sources/git.js +45 -0
- package/dist/src/marketplace/types.js +9 -0
- package/dist/src/mcp/adapters/codex-runtime.js +224 -0
- package/dist/src/mcp/cli.mjs +1197 -0
- package/dist/src/mcp/elicitation.mjs +149 -0
- package/dist/src/mcp/helpers.mjs +287 -0
- package/dist/src/mcp/index.mjs +11 -0
- package/dist/src/mcp/profiles.js +263 -0
- package/dist/src/mcp/profiles.mjs +360 -0
- package/dist/src/mcp/registry.js +376 -0
- package/dist/src/mcp/registry.mjs +387 -0
- package/dist/src/mcp/server.mjs +633 -0
- package/dist/src/mcp/test-simple.mjs +271 -0
- package/dist/src/mcp/tools/command-run.mjs +101 -0
- package/dist/src/mcp/tools/discovery.mjs +291 -0
- package/dist/src/mcp/tools/interaction.mjs +87 -0
- package/dist/src/mcp/tools/orchestration.mjs +320 -0
- package/dist/src/mcp/tools/subsystems.mjs +640 -0
- package/dist/src/memory/cli.js +166 -0
- package/dist/src/memory/project-registry.js +282 -0
- package/dist/src/metrics/artifact-metrics.js +184 -0
- package/dist/src/metrics/context-budget.js +174 -0
- package/dist/src/metrics/token-counter.js +133 -0
- package/dist/src/models/config-loader.js +228 -0
- package/dist/src/models/index.js +22 -0
- package/dist/src/models/model-capabilities.v1.json +120 -0
- package/dist/src/models/model-catalog.v1.json +96 -0
- package/dist/src/models/model-discovery.js +521 -0
- package/dist/src/models/provider-models.js +73 -0
- package/dist/src/models/provider-policy.js +273 -0
- package/dist/src/models/resolver.js +245 -0
- package/dist/src/models/router.js +70 -0
- package/dist/src/models/types.js +8 -0
- package/dist/src/models/wrapper-deployment.js +178 -0
- package/dist/src/models/wrapper-route.js +54 -0
- package/dist/src/ops/cli.js +268 -0
- package/dist/src/ops/registry.js +623 -0
- package/dist/src/packages/adapters/clawhub.js +113 -0
- package/dist/src/packages/adapters/git.js +153 -0
- package/dist/src/packages/adapters/gitea.js +93 -0
- package/dist/src/packages/adapters/github.js +69 -0
- package/dist/src/packages/adapters/local-cache.js +89 -0
- package/dist/src/packages/package-registry.js +143 -0
- package/dist/src/packages/registry.js +238 -0
- package/dist/src/packages/types.js +11 -0
- package/dist/src/plugin/cross-framework-ops.js +475 -0
- package/dist/src/plugin/framework-config-loader.js +235 -0
- package/dist/src/plugin/framework-detector.js +186 -0
- package/dist/src/plugin/framework-isolator.js +341 -0
- package/dist/src/plugin/framework-migration.js +371 -0
- package/dist/src/plugin/metadata-validator.js +906 -0
- package/dist/src/plugin/plugin-installer.js +436 -0
- package/dist/src/plugin/plugin-status.js +369 -0
- package/dist/src/plugin/plugin-uninstaller.js +473 -0
- package/dist/src/plugin/registry-validator.js +344 -0
- package/dist/src/plugin/skill-command-translator.js +415 -0
- package/dist/src/plugin/workspace-creator.js +189 -0
- package/dist/src/plugin/workspace-migrator.js +821 -0
- package/dist/src/policy/authorization.js +390 -0
- package/dist/src/policy/repo-access.js +215 -0
- package/dist/src/provenance/cli.js +16 -0
- package/dist/src/providers/capability-matrix.js +300 -0
- package/dist/src/providers/capability-matrix.yaml +514 -0
- package/dist/src/providers/provider-definitions.js +977 -0
- package/dist/src/providers/provider-definitions.mjs +159 -0
- package/dist/src/providers/provider-inventory.js +169 -0
- package/dist/src/quality/feedback-ab.js +174 -0
- package/dist/src/quality/feedback-collector.js +176 -0
- package/dist/src/quality/feedback-tracker.js +123 -0
- package/dist/src/quality/patterns/adr.json +24 -0
- package/dist/src/quality/patterns/sad.json +24 -0
- package/dist/src/quality/patterns/test-plan.json +24 -0
- package/dist/src/quality/patterns/use-case.json +24 -0
- package/dist/src/quality/scoring.js +157 -0
- package/dist/src/reflections/cli.js +15 -0
- package/dist/src/release/plan.js +139 -0
- package/dist/src/research/cache/manager.js +227 -0
- package/dist/src/research/clients/arxiv.js +156 -0
- package/dist/src/research/clients/base.js +197 -0
- package/dist/src/research/clients/crossref.js +112 -0
- package/dist/src/research/clients/semantic-scholar.js +126 -0
- package/dist/src/research/clients/unpaywall.js +87 -0
- package/dist/src/research/index.js +14 -0
- package/dist/src/research/query-cli.js +336 -0
- package/dist/src/research/services/acquisition.js +313 -0
- package/dist/src/research/services/archival.js +225 -0
- package/dist/src/research/services/citation.js +279 -0
- package/dist/src/research/services/discovery.js +243 -0
- package/dist/src/research/services/documentation.js +269 -0
- package/dist/src/research/services/index.js +14 -0
- package/dist/src/research/services/provenance.js +279 -0
- package/dist/src/research/services/quality.js +370 -0
- package/dist/src/research/services/types.js +7 -0
- package/dist/src/research/storage-cli.js +20 -0
- package/dist/src/research/types.js +47 -0
- package/dist/src/resources/index.d.ts +2 -0
- package/dist/src/resources/index.js +2 -0
- package/dist/src/resources/web-release.d.ts +89 -0
- package/dist/src/resources/web-release.js +882 -0
- package/dist/src/rlm/cache/cli.js +162 -0
- package/dist/src/rlm/cache/hash.js +35 -0
- package/dist/src/rlm/cache/store.js +170 -0
- package/dist/src/rlm/cache/types.js +8 -0
- package/dist/src/rlm/cli.js +650 -0
- package/dist/src/serve/a2a-terminal-observer.js +120 -0
- package/dist/src/serve/agent-router.js +205 -0
- package/dist/src/serve/dispatch-router.js +171 -0
- package/dist/src/serve/executor-registry.js +715 -0
- package/dist/src/serve/mission-conductor.js +177 -0
- package/dist/src/serve/orchestrator-adapter.js +113 -0
- package/dist/src/serve/orchestrator-override.js +94 -0
- package/dist/src/serve/orchestrator-pty.js +133 -0
- package/dist/src/serve/pty-bridge.js +799 -0
- package/dist/src/serve/sandbox-registry.js +832 -0
- package/dist/src/serve/screen-reader.js +228 -0
- package/dist/src/serve/stack-adapters.js +68 -0
- package/dist/src/serve/telemetry.js +143 -0
- package/dist/src/skills/adapters/clawhub.js +250 -0
- package/dist/src/skills/adapters/local.js +335 -0
- package/dist/src/skills/adapters/openclaw.js +316 -0
- package/dist/src/skills/cli.js +334 -0
- package/dist/src/skills/registry.js +117 -0
- package/dist/src/skills/run.js +259 -0
- package/dist/src/skills/runtime.js +94 -0
- package/dist/src/skills/types.js +10 -0
- package/dist/src/smiths/agentsmith/demo.js +116 -0
- package/dist/src/smiths/agentsmith/examples.js +300 -0
- package/dist/src/smiths/agentsmith/generator.js +503 -0
- package/dist/src/smiths/agentsmith/index.js +11 -0
- package/dist/src/smiths/agentsmith/types.js +8 -0
- package/dist/src/smiths/commandsmith/example.js +220 -0
- package/dist/src/smiths/commandsmith/generator.js +288 -0
- package/dist/src/smiths/commandsmith/index.js +41 -0
- package/dist/src/smiths/commandsmith/templates.js +296 -0
- package/dist/src/smiths/commandsmith/types.js +7 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
- package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
- package/dist/src/smiths/context-pipeline/discovery.js +187 -0
- package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
- package/dist/src/smiths/context-pipeline/finalization.js +147 -0
- package/dist/src/smiths/context-pipeline/generator.js +477 -0
- package/dist/src/smiths/context-pipeline/index.js +30 -0
- package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
- package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
- package/dist/src/smiths/context-pipeline/overflow.js +212 -0
- package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
- package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
- package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
- package/dist/src/smiths/context-pipeline/types.js +23 -0
- package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
- package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
- package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
- package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
- package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
- package/dist/src/smiths/hook-bridge/index.js +79 -0
- package/dist/src/smiths/hook-bridge/loader.js +116 -0
- package/dist/src/smiths/hook-bridge/shim.js +89 -0
- package/dist/src/smiths/hook-bridge/types.js +31 -0
- package/dist/src/smiths/index.js +39 -0
- package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
- package/dist/src/smiths/mcpsmith/example.js +119 -0
- package/dist/src/smiths/mcpsmith/generator.js +236 -0
- package/dist/src/smiths/mcpsmith/index.js +17 -0
- package/dist/src/smiths/mcpsmith/types.js +10 -0
- package/dist/src/smiths/platform-paths.js +101 -0
- package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
- package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
- package/dist/src/smiths/skillsmith/demo.js +83 -0
- package/dist/src/smiths/skillsmith/examples.js +161 -0
- package/dist/src/smiths/skillsmith/generator.js +316 -0
- package/dist/src/smiths/skillsmith/index.js +12 -0
- package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
- package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
- package/dist/src/smiths/skillsmith/types.js +9 -0
- package/dist/src/smiths/toolsmith/index.js +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
- package/dist/src/smiths/toolsmith/types.js +8 -0
- package/dist/src/storage/backends/fortemi.js +227 -0
- package/dist/src/storage/backends/fs.js +134 -0
- package/dist/src/storage/backends/logseq.js +309 -0
- package/dist/src/storage/backends/obsidian.js +233 -0
- package/dist/src/storage/cli.js +468 -0
- package/dist/src/storage/config.js +272 -0
- package/dist/src/storage/index.js +108 -0
- package/dist/src/storage/subsystem-cli.js +201 -0
- package/dist/src/storage/types.js +33 -0
- package/dist/src/testing/corpus/corpus-builder.js +383 -0
- package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
- package/dist/src/testing/corpus/index.js +10 -0
- package/dist/src/testing/fixtures/index.js +9 -0
- package/dist/src/testing/fixtures/test-data-factory.js +472 -0
- package/dist/src/testing/generators/index.js +11 -0
- package/dist/src/testing/generators/test-case-generator.js +393 -0
- package/dist/src/testing/generators/test-code-generator.js +384 -0
- package/dist/src/testing/generators/use-case-parser.js +325 -0
- package/dist/src/testing/index.js +11 -0
- package/dist/src/tracker/capability-protocol.js +118 -0
- package/dist/src/update/checker.mjs +396 -0
- package/dist/src/update/notifier.mjs +235 -0
- package/dist/src/writing/content-diversifier.js +804 -0
- package/dist/src/writing/example-generator.js +959 -0
- package/dist/src/writing/example-templates.js +99 -0
- package/dist/src/writing/pattern-library.js +486 -0
- package/dist/src/writing/patterns/banned-phrases.json +4413 -0
- package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
- package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
- package/dist/src/writing/patterns/hedging-language.json +2096 -0
- package/dist/src/writing/patterns/transition-words.json +1285 -0
- package/dist/src/writing/patterns/weak-verbs.json +1112 -0
- package/dist/src/writing/prompt-optimizer.js +660 -0
- package/dist/src/writing/prompt-templates.js +583 -0
- package/dist/src/writing/scoring-config-loader.js +168 -0
- package/dist/src/writing/validation-engine.js +595 -0
- package/dist/src/writing/validation-rules.js +380 -0
- package/dist/src/writing/voice-analyzer.js +439 -0
- package/dist/src/writing/voice-calibration.js +661 -0
- package/dist/src/writing/voice-profiles.json +588 -0
- package/package.json +64 -9
|
@@ -0,0 +1,1197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AIWG MCP CLI
|
|
5
|
+
*
|
|
6
|
+
* Command-line interface for AIWG MCP server operations.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { startServer, createServer } from './server.mjs';
|
|
10
|
+
import fs from 'fs/promises';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
import {
|
|
14
|
+
McpServerRegistry,
|
|
15
|
+
injectServers,
|
|
16
|
+
SUPPORTED_PROVIDERS,
|
|
17
|
+
getProviderConfigPath,
|
|
18
|
+
} from './registry.mjs';
|
|
19
|
+
import { McpProfileRegistry } from './profiles.mjs';
|
|
20
|
+
import { getMcpInjectionDefinition } from '../providers/provider-definitions.mjs';
|
|
21
|
+
|
|
22
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Print usage information
|
|
26
|
+
*/
|
|
27
|
+
function printUsage() {
|
|
28
|
+
console.log(`
|
|
29
|
+
AIWG MCP Server
|
|
30
|
+
|
|
31
|
+
Usage:
|
|
32
|
+
aiwg mcp serve [options] Start the MCP server
|
|
33
|
+
aiwg mcp install [target] Install AIWG MCP server into a provider
|
|
34
|
+
aiwg mcp info Show server capabilities
|
|
35
|
+
|
|
36
|
+
aiwg mcp add <name> [opts] Define an MCP server in the registry
|
|
37
|
+
aiwg mcp remove <name> Remove a server from the registry
|
|
38
|
+
aiwg mcp update <name> [opts] Update a server definition
|
|
39
|
+
aiwg mcp list List registered MCP servers
|
|
40
|
+
aiwg mcp inject [opts] Inject servers into provider configs
|
|
41
|
+
aiwg mcp profile <sub> Manage MCP profiles (named server subsets)
|
|
42
|
+
|
|
43
|
+
Server Options (for add/update):
|
|
44
|
+
--url <url> Server URL (for http/sse types)
|
|
45
|
+
--type <type> Server type: http (default), stdio, sse
|
|
46
|
+
--command <cmd> Command to run (for stdio type)
|
|
47
|
+
--args <a1,a2,...> Command arguments (comma-separated, for stdio)
|
|
48
|
+
--env <K=V,...> Environment variables (comma-separated K=V pairs)
|
|
49
|
+
--headers <K=V,...> HTTP headers (comma-separated K=V pairs)
|
|
50
|
+
--description <text> Optional description
|
|
51
|
+
|
|
52
|
+
Inject Options:
|
|
53
|
+
--provider <name> Target provider (claude-code, cursor, factory, codex, opencode, windsurf, warp)
|
|
54
|
+
--all Inject into all previously configured providers
|
|
55
|
+
--servers <a,b,...> Only inject specific servers (comma-separated names)
|
|
56
|
+
--dry-run Show what would change without writing
|
|
57
|
+
|
|
58
|
+
Serve Options:
|
|
59
|
+
--transport <type> Transport type: stdio (default), http
|
|
60
|
+
--port <number> Port for HTTP transport (default: 3100)
|
|
61
|
+
|
|
62
|
+
Examples:
|
|
63
|
+
# Define MCP servers
|
|
64
|
+
aiwg mcp add fortemi --url https://memory.s9.internal/mcp --type http
|
|
65
|
+
aiwg mcp add gitea --url https://mcp-gitea.integrolabs.net/mcp
|
|
66
|
+
aiwg mcp add mytools --type stdio --command npx --args mcp-server-mytools
|
|
67
|
+
|
|
68
|
+
# Inject into provider configs
|
|
69
|
+
aiwg mcp inject --provider claude-code
|
|
70
|
+
aiwg mcp inject --provider cursor --servers fortemi,gitea
|
|
71
|
+
aiwg mcp inject --all
|
|
72
|
+
|
|
73
|
+
# Update a server URL
|
|
74
|
+
aiwg mcp update fortemi --url https://new-url.internal/mcp
|
|
75
|
+
aiwg mcp inject --all # re-inject to all providers
|
|
76
|
+
|
|
77
|
+
# List and manage
|
|
78
|
+
aiwg mcp list
|
|
79
|
+
aiwg mcp remove fortemi
|
|
80
|
+
|
|
81
|
+
# Install AIWG's own MCP server
|
|
82
|
+
aiwg mcp install claude
|
|
83
|
+
aiwg mcp serve
|
|
84
|
+
aiwg mcp info
|
|
85
|
+
`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Generate MCP client configuration
|
|
90
|
+
*/
|
|
91
|
+
async function generateConfig(target, projectDir = '.') {
|
|
92
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
93
|
+
|
|
94
|
+
const configs = {
|
|
95
|
+
claude: {
|
|
96
|
+
path: path.join(projectDir, '.claude/settings.local.json'),
|
|
97
|
+
content: {
|
|
98
|
+
mcpServers: {
|
|
99
|
+
aiwg: {
|
|
100
|
+
command: 'aiwg',
|
|
101
|
+
args: ['mcp', 'serve'],
|
|
102
|
+
env: {
|
|
103
|
+
AIWG_ROOT: process.env.AIWG_ROOT || '~/.local/share/ai-writing-guide'
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
cursor: {
|
|
110
|
+
path: path.join(projectDir, '.cursor/mcp.json'),
|
|
111
|
+
content: {
|
|
112
|
+
mcpServers: {
|
|
113
|
+
aiwg: {
|
|
114
|
+
command: 'aiwg',
|
|
115
|
+
args: ['mcp', 'serve']
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
merge: (existing, content) => ({
|
|
120
|
+
...existing,
|
|
121
|
+
mcpServers: {
|
|
122
|
+
...(existing.mcpServers || {}),
|
|
123
|
+
...content.mcpServers
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
},
|
|
127
|
+
factory: {
|
|
128
|
+
// Factory stores MCP config at user level in ~/.factory/mcp.json
|
|
129
|
+
// or project level in .factory/mcp.json
|
|
130
|
+
path: projectDir === '.' || projectDir === 'global'
|
|
131
|
+
? path.join(homeDir, '.factory/mcp.json')
|
|
132
|
+
: path.join(projectDir, '.factory/mcp.json'),
|
|
133
|
+
content: {
|
|
134
|
+
mcpServers: {
|
|
135
|
+
aiwg: {
|
|
136
|
+
type: 'stdio',
|
|
137
|
+
command: 'aiwg',
|
|
138
|
+
args: ['mcp', 'serve'],
|
|
139
|
+
disabled: false
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
merge: (existing, content) => ({
|
|
144
|
+
...existing,
|
|
145
|
+
mcpServers: {
|
|
146
|
+
...(existing.mcpServers || {}),
|
|
147
|
+
...content.mcpServers
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
},
|
|
151
|
+
codex: {
|
|
152
|
+
// Codex stores config in ~/.codex/config.toml (TOML format)
|
|
153
|
+
path: path.join(homeDir, '.codex/config.toml'),
|
|
154
|
+
// We generate TOML snippet to append, not JSON
|
|
155
|
+
content: null,
|
|
156
|
+
toml: `
|
|
157
|
+
# AIWG MCP Server Configuration
|
|
158
|
+
# Add this section to your ~/.codex/config.toml
|
|
159
|
+
|
|
160
|
+
[mcp_servers.aiwg]
|
|
161
|
+
command = "aiwg"
|
|
162
|
+
args = ["mcp", "serve"]
|
|
163
|
+
startup_timeout_sec = 10.0
|
|
164
|
+
tool_timeout_sec = 60.0
|
|
165
|
+
enabled_tools = [
|
|
166
|
+
"discover",
|
|
167
|
+
"command-run",
|
|
168
|
+
"artifact-read",
|
|
169
|
+
"artifact-write",
|
|
170
|
+
"template-render",
|
|
171
|
+
"agent-list"
|
|
172
|
+
]
|
|
173
|
+
`,
|
|
174
|
+
// Custom handler for TOML
|
|
175
|
+
handler: async (configPath, tomlContent) => {
|
|
176
|
+
// Check if config.toml exists
|
|
177
|
+
let existing = '';
|
|
178
|
+
try {
|
|
179
|
+
existing = await fs.readFile(configPath, 'utf-8');
|
|
180
|
+
} catch {
|
|
181
|
+
// File doesn't exist
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Check if AIWG MCP already configured
|
|
185
|
+
if (existing.includes('[mcp_servers.aiwg]')) {
|
|
186
|
+
console.log('AIWG MCP already configured in ~/.codex/config.toml');
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Append TOML config
|
|
191
|
+
const updated = existing.trimEnd() + '\n' + tomlContent.trim() + '\n';
|
|
192
|
+
|
|
193
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
194
|
+
await fs.writeFile(configPath, updated);
|
|
195
|
+
console.log(`MCP configuration appended to: ${configPath}`);
|
|
196
|
+
console.log(`\nTo use AIWG MCP server with Codex:`);
|
|
197
|
+
console.log(` 1. Restart Codex CLI`);
|
|
198
|
+
console.log(` 2. AIWG tools will be available via MCP`);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
openai: {
|
|
203
|
+
// Alias for codex
|
|
204
|
+
path: path.join(homeDir, '.codex/config.toml'),
|
|
205
|
+
alias: 'codex'
|
|
206
|
+
},
|
|
207
|
+
windsurf: {
|
|
208
|
+
// Windsurf stores MCP config at ~/.codeium/windsurf/mcp_config.json
|
|
209
|
+
path: path.join(homeDir, '.codeium/windsurf/mcp_config.json'),
|
|
210
|
+
content: {
|
|
211
|
+
mcpServers: {
|
|
212
|
+
aiwg: {
|
|
213
|
+
command: 'aiwg',
|
|
214
|
+
args: ['mcp', 'serve']
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
merge: (existing, content) => ({
|
|
219
|
+
...existing,
|
|
220
|
+
mcpServers: {
|
|
221
|
+
...(existing.mcpServers || {}),
|
|
222
|
+
...content.mcpServers
|
|
223
|
+
}
|
|
224
|
+
})
|
|
225
|
+
},
|
|
226
|
+
warp: {
|
|
227
|
+
// Warp configures MCP servers via UI only (Settings > AI > MCP Servers)
|
|
228
|
+
// There is no documented file-based config path
|
|
229
|
+
path: null,
|
|
230
|
+
content: null,
|
|
231
|
+
handler: async () => {
|
|
232
|
+
console.log(`Warp MCP Server Setup (UI-based)\n`);
|
|
233
|
+
console.log(`Warp configures MCP servers through its UI, not config files.`);
|
|
234
|
+
console.log(`\nTo add the AIWG MCP server to Warp:\n`);
|
|
235
|
+
console.log(` 1. Open Warp Terminal`);
|
|
236
|
+
console.log(` 2. Go to Settings > AI > MCP Servers`);
|
|
237
|
+
console.log(` 3. Click "Add MCP Server"`);
|
|
238
|
+
console.log(` 4. Configure:`);
|
|
239
|
+
console.log(` Name: aiwg`);
|
|
240
|
+
console.log(` Type: stdio`);
|
|
241
|
+
console.log(` Command: aiwg`);
|
|
242
|
+
console.log(` Args: mcp serve`);
|
|
243
|
+
console.log(` 5. Save and restart Warp\n`);
|
|
244
|
+
console.log(`Alternatively, use Warp's /add-mcp slash command.`);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
vscode: {
|
|
249
|
+
// VS Code / Copilot stores MCP config in .vscode/mcp.json
|
|
250
|
+
path: path.join(projectDir === '.' ? process.cwd() : projectDir, '.vscode/mcp.json'),
|
|
251
|
+
content: {
|
|
252
|
+
servers: {
|
|
253
|
+
aiwg: {
|
|
254
|
+
type: 'stdio',
|
|
255
|
+
command: 'aiwg',
|
|
256
|
+
args: ['mcp', 'serve']
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
merge: (existing, content) => ({
|
|
261
|
+
...existing,
|
|
262
|
+
servers: {
|
|
263
|
+
...(existing.servers || {}),
|
|
264
|
+
...content.servers
|
|
265
|
+
}
|
|
266
|
+
})
|
|
267
|
+
},
|
|
268
|
+
copilot: {
|
|
269
|
+
// Alias for vscode
|
|
270
|
+
path: path.join(projectDir === '.' ? process.cwd() : projectDir, '.vscode/mcp.json'),
|
|
271
|
+
alias: 'vscode'
|
|
272
|
+
},
|
|
273
|
+
opencode: {
|
|
274
|
+
// OpenCode stores MCP config in opencode.json at project root or .opencode/
|
|
275
|
+
path: projectDir === '.' || projectDir === 'global'
|
|
276
|
+
? path.join(process.cwd(), 'opencode.json')
|
|
277
|
+
: path.join(projectDir, 'opencode.json'),
|
|
278
|
+
content: {
|
|
279
|
+
mcp: {
|
|
280
|
+
aiwg: {
|
|
281
|
+
type: 'local',
|
|
282
|
+
command: ['aiwg', 'mcp', 'serve']
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
merge: (existing, content) => ({
|
|
287
|
+
...existing,
|
|
288
|
+
mcp: {
|
|
289
|
+
...(existing.mcp || {}),
|
|
290
|
+
...content.mcp
|
|
291
|
+
}
|
|
292
|
+
}),
|
|
293
|
+
// Custom handler to handle both JSON and JSONC formats
|
|
294
|
+
handler: async (configPath, _, content, mergeFunc) => {
|
|
295
|
+
// Check multiple locations for opencode config
|
|
296
|
+
const locations = [
|
|
297
|
+
configPath,
|
|
298
|
+
path.join(path.dirname(configPath), '.opencode', 'opencode.jsonc'),
|
|
299
|
+
path.join(path.dirname(configPath), '.opencode', 'opencode.json')
|
|
300
|
+
];
|
|
301
|
+
|
|
302
|
+
let targetPath = configPath;
|
|
303
|
+
let existing = {};
|
|
304
|
+
|
|
305
|
+
// Find existing config
|
|
306
|
+
for (const loc of locations) {
|
|
307
|
+
try {
|
|
308
|
+
const rawContent = await fs.readFile(loc, 'utf-8');
|
|
309
|
+
// Strip JSONC comments for parsing
|
|
310
|
+
const jsonContent = rawContent
|
|
311
|
+
.replace(/\/\/.*$/gm, '')
|
|
312
|
+
.replace(/\/\*[\s\S]*?\*\//g, '');
|
|
313
|
+
existing = JSON.parse(jsonContent);
|
|
314
|
+
targetPath = loc;
|
|
315
|
+
break;
|
|
316
|
+
} catch {
|
|
317
|
+
// Continue to next location
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Check if AIWG MCP already configured
|
|
322
|
+
if (existing.mcp && existing.mcp.aiwg) {
|
|
323
|
+
console.log('AIWG MCP already configured in OpenCode config');
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Merge configuration
|
|
328
|
+
const merged = mergeFunc(existing, content);
|
|
329
|
+
|
|
330
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
331
|
+
await fs.writeFile(targetPath, JSON.stringify(merged, null, 2));
|
|
332
|
+
console.log(`MCP configuration written to: ${targetPath}`);
|
|
333
|
+
console.log(`\nTo use AIWG MCP server with OpenCode:`);
|
|
334
|
+
console.log(` 1. Restart OpenCode`);
|
|
335
|
+
console.log(` 2. AIWG tools will be available via MCP`);
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
let config = configs[target];
|
|
342
|
+
if (!config) {
|
|
343
|
+
console.error(`Unknown target: ${target}`);
|
|
344
|
+
console.error(`Available targets: ${Object.keys(configs).join(', ')}`);
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// Handle alias
|
|
349
|
+
if (config.alias) {
|
|
350
|
+
config = configs[config.alias];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Handle custom handler (for TOML configs like Codex, or OpenCode JSON)
|
|
354
|
+
if (config.handler) {
|
|
355
|
+
return await config.handler(config.path, config.toml, config.content, config.merge);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Ensure directory exists
|
|
359
|
+
await fs.mkdir(path.dirname(config.path), { recursive: true });
|
|
360
|
+
|
|
361
|
+
// Check if file exists and merge
|
|
362
|
+
let existing = {};
|
|
363
|
+
try {
|
|
364
|
+
const content = await fs.readFile(config.path, 'utf-8');
|
|
365
|
+
existing = JSON.parse(content);
|
|
366
|
+
} catch {
|
|
367
|
+
// File doesn't exist, start fresh
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// Merge configuration using custom merge function if available
|
|
371
|
+
const merged = config.merge
|
|
372
|
+
? config.merge(existing, config.content)
|
|
373
|
+
: {
|
|
374
|
+
...existing,
|
|
375
|
+
...config.content,
|
|
376
|
+
mcpServers: {
|
|
377
|
+
...(existing.mcpServers || {}),
|
|
378
|
+
...config.content.mcpServers
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
await fs.writeFile(config.path, JSON.stringify(merged, null, 2));
|
|
383
|
+
console.log(`MCP configuration written to: ${config.path}`);
|
|
384
|
+
console.log(`\nTo use AIWG MCP server with ${target}:`);
|
|
385
|
+
console.log(` 1. Restart ${target}`);
|
|
386
|
+
console.log(` 2. AIWG tools and resources will be available`);
|
|
387
|
+
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Show server capabilities
|
|
393
|
+
*/
|
|
394
|
+
async function showInfo() {
|
|
395
|
+
console.log(`
|
|
396
|
+
AIWG MCP Server v1.0.0
|
|
397
|
+
Protocol Version: 2025-11-25
|
|
398
|
+
|
|
399
|
+
POSITIONING:
|
|
400
|
+
MCP is optional and provider-agnostic. Baseline AIWG reachability is file
|
|
401
|
+
deployment plus CLI discovery: aiwg discover / aiwg show <type> <name>.
|
|
402
|
+
|
|
403
|
+
CORE TOOLS (15, always registered):
|
|
404
|
+
discover Cross-type ranked catalog search
|
|
405
|
+
skill-list / skill-show Skill catalog and SKILL.md body fetch
|
|
406
|
+
command-list / command-show CLI command catalog and command spec fetch
|
|
407
|
+
rule-list / rule-show Rule catalog and rule body fetch
|
|
408
|
+
agent-list / agent-show Agent catalog and agent definition fetch
|
|
409
|
+
template-list / template-show Template catalog and raw template fetch
|
|
410
|
+
template-render Render AIWG template with variables
|
|
411
|
+
command-run Allow-listed CLI dispatch; confirmation-gated when needed
|
|
412
|
+
artifact-read / artifact-write Project .aiwg/ artifact IO
|
|
413
|
+
|
|
414
|
+
OPT-IN TOOLSETS (51 additional tools):
|
|
415
|
+
flows flow-list / flow-show / flow-run
|
|
416
|
+
missions mission-guide / mission-dispatch / mission-status
|
|
417
|
+
memory memory-* and reflections-* storage operations
|
|
418
|
+
kb kb-* storage operations
|
|
419
|
+
research provenance-* and research-store-* storage operations
|
|
420
|
+
activity-log show / append / stats
|
|
421
|
+
index build / query / deps / stats
|
|
422
|
+
ralph start / status / abort / attach
|
|
423
|
+
mc start / dispatch / status / stop / list
|
|
424
|
+
ops status / list / use / push
|
|
425
|
+
|
|
426
|
+
Enable opt-in tools:
|
|
427
|
+
AIWG_MCP_TOOLSETS=flows,missions,memory,kb,ralph aiwg mcp serve
|
|
428
|
+
aiwg mcp serve --toolsets=all
|
|
429
|
+
|
|
430
|
+
RESOURCES:
|
|
431
|
+
aiwg://prompts/catalog List of prompt templates
|
|
432
|
+
aiwg://templates/catalog List of document templates
|
|
433
|
+
aiwg://agents/catalog List of available agents
|
|
434
|
+
aiwg://prompts/{category}/{name} Specific prompt template
|
|
435
|
+
aiwg://templates/{fw}/{cat}/{name} Specific document template
|
|
436
|
+
aiwg://agents/{framework}/{name} Specific agent definition
|
|
437
|
+
|
|
438
|
+
PROMPTS:
|
|
439
|
+
decompose-task Break complex task into subtasks
|
|
440
|
+
parallel-execution Identify parallelizable work
|
|
441
|
+
recovery-protocol PAUSE->DIAGNOSE->ADAPT->RETRY->ESCALATE
|
|
442
|
+
|
|
443
|
+
TRANSPORTS:
|
|
444
|
+
stdio Standard input/output (default, for local use)
|
|
445
|
+
http Streamable HTTP (for remote/containerized use)
|
|
446
|
+
|
|
447
|
+
ENVIRONMENT:
|
|
448
|
+
AIWG_ROOT Path to AIWG installation (default: ~/.local/share/ai-writing-guide)
|
|
449
|
+
AIWG_MCP_TOOLSETS Comma-separated opt-in toolsets; use all for every toolset
|
|
450
|
+
|
|
451
|
+
Docs:
|
|
452
|
+
docs/integrations/mcp-capability-audit.md
|
|
453
|
+
`);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ============================================
|
|
457
|
+
// Registry subcommand handlers
|
|
458
|
+
// ============================================
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Parse --key value pairs from args
|
|
462
|
+
*/
|
|
463
|
+
function parseFlag(args, flag) {
|
|
464
|
+
const idx = args.indexOf(flag);
|
|
465
|
+
if (idx === -1 || idx + 1 >= args.length) return undefined;
|
|
466
|
+
return args[idx + 1];
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Parse comma-separated key=value pairs into an object
|
|
471
|
+
*/
|
|
472
|
+
function parseKVPairs(str) {
|
|
473
|
+
if (!str) return undefined;
|
|
474
|
+
const result = {};
|
|
475
|
+
for (const pair of str.split(',')) {
|
|
476
|
+
const eqIdx = pair.indexOf('=');
|
|
477
|
+
if (eqIdx === -1) continue;
|
|
478
|
+
result[pair.slice(0, eqIdx).trim()] = pair.slice(eqIdx + 1).trim();
|
|
479
|
+
}
|
|
480
|
+
return Object.keys(result).length > 0 ? result : undefined;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Handle `aiwg mcp add <name> [opts]`
|
|
485
|
+
*/
|
|
486
|
+
async function handleAdd(args) {
|
|
487
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
488
|
+
const name = positional[0];
|
|
489
|
+
|
|
490
|
+
if (!name) {
|
|
491
|
+
console.error('Usage: aiwg mcp add <name> --url <url> [--type http|stdio|sse] [--command <cmd>] [--args <a,b>]');
|
|
492
|
+
process.exit(1);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
const type = parseFlag(args, '--type') || 'http';
|
|
496
|
+
const url = parseFlag(args, '--url');
|
|
497
|
+
const command = parseFlag(args, '--command');
|
|
498
|
+
const argsStr = parseFlag(args, '--args');
|
|
499
|
+
const envStr = parseFlag(args, '--env');
|
|
500
|
+
const headersStr = parseFlag(args, '--headers');
|
|
501
|
+
const description = parseFlag(args, '--description');
|
|
502
|
+
|
|
503
|
+
if (type === 'stdio' && !command) {
|
|
504
|
+
console.error('Error: --command is required for stdio type servers');
|
|
505
|
+
process.exit(1);
|
|
506
|
+
}
|
|
507
|
+
if ((type === 'http' || type === 'sse') && !url) {
|
|
508
|
+
console.error(`Error: --url is required for ${type} type servers`);
|
|
509
|
+
process.exit(1);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const registry = new McpServerRegistry();
|
|
513
|
+
await registry.add({
|
|
514
|
+
name,
|
|
515
|
+
type,
|
|
516
|
+
url,
|
|
517
|
+
command,
|
|
518
|
+
args: argsStr ? argsStr.split(',') : undefined,
|
|
519
|
+
env: parseKVPairs(envStr),
|
|
520
|
+
headers: parseKVPairs(headersStr),
|
|
521
|
+
description,
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
console.log(`Added MCP server: ${name}`);
|
|
525
|
+
if (url) console.log(` URL: ${url}`);
|
|
526
|
+
if (command) console.log(` Command: ${command}`);
|
|
527
|
+
console.log(` Type: ${type}`);
|
|
528
|
+
console.log(`\nUse "aiwg mcp inject --provider <name>" to inject into a provider config.`);
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Handle `aiwg mcp remove <name>`
|
|
533
|
+
*/
|
|
534
|
+
async function handleRemove(args) {
|
|
535
|
+
const name = args.filter(a => !a.startsWith('--'))[0];
|
|
536
|
+
if (!name) {
|
|
537
|
+
console.error('Usage: aiwg mcp remove <name>');
|
|
538
|
+
process.exit(1);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
const registry = new McpServerRegistry();
|
|
542
|
+
await registry.remove(name);
|
|
543
|
+
console.log(`Removed MCP server: ${name}`);
|
|
544
|
+
console.log(`\nNote: This does not remove the server from provider configs.`);
|
|
545
|
+
console.log(`Re-run "aiwg mcp inject --all" to update provider configs.`);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Handle `aiwg mcp update <name> [opts]`
|
|
550
|
+
*/
|
|
551
|
+
async function handleUpdate(args) {
|
|
552
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
553
|
+
const name = positional[0];
|
|
554
|
+
|
|
555
|
+
if (!name) {
|
|
556
|
+
console.error('Usage: aiwg mcp update <name> --url <url> [--type <type>] ...');
|
|
557
|
+
process.exit(1);
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
const updates = {};
|
|
561
|
+
const url = parseFlag(args, '--url');
|
|
562
|
+
const type = parseFlag(args, '--type');
|
|
563
|
+
const command = parseFlag(args, '--command');
|
|
564
|
+
const argsStr = parseFlag(args, '--args');
|
|
565
|
+
const envStr = parseFlag(args, '--env');
|
|
566
|
+
const headersStr = parseFlag(args, '--headers');
|
|
567
|
+
const description = parseFlag(args, '--description');
|
|
568
|
+
|
|
569
|
+
if (url !== undefined) updates.url = url;
|
|
570
|
+
if (type !== undefined) updates.type = type;
|
|
571
|
+
if (command !== undefined) updates.command = command;
|
|
572
|
+
if (argsStr !== undefined) updates.args = argsStr.split(',');
|
|
573
|
+
if (envStr !== undefined) updates.env = parseKVPairs(envStr);
|
|
574
|
+
if (headersStr !== undefined) updates.headers = parseKVPairs(headersStr);
|
|
575
|
+
if (description !== undefined) updates.description = description;
|
|
576
|
+
|
|
577
|
+
if (Object.keys(updates).length === 0) {
|
|
578
|
+
console.error('No updates provided. Use --url, --type, --command, etc.');
|
|
579
|
+
process.exit(1);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const registry = new McpServerRegistry();
|
|
583
|
+
await registry.update(name, updates);
|
|
584
|
+
console.log(`Updated MCP server: ${name}`);
|
|
585
|
+
for (const [key, value] of Object.entries(updates)) {
|
|
586
|
+
console.log(` ${key}: ${typeof value === 'object' ? JSON.stringify(value) : value}`);
|
|
587
|
+
}
|
|
588
|
+
console.log(`\nRe-run "aiwg mcp inject --all" to propagate changes to provider configs.`);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Handle `aiwg mcp list` (managed servers from registry)
|
|
593
|
+
*/
|
|
594
|
+
async function handleList() {
|
|
595
|
+
const registry = new McpServerRegistry();
|
|
596
|
+
const servers = await registry.list();
|
|
597
|
+
|
|
598
|
+
if (servers.length === 0) {
|
|
599
|
+
console.log('No MCP servers registered.');
|
|
600
|
+
console.log('\nUse "aiwg mcp add <name> --url <url>" to add one.');
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
console.log(`MCP Servers (${servers.length}):\n`);
|
|
605
|
+
|
|
606
|
+
for (const server of servers) {
|
|
607
|
+
console.log(` ${server.name}`);
|
|
608
|
+
console.log(` Type: ${server.type}`);
|
|
609
|
+
if (server.url) console.log(` URL: ${server.url}`);
|
|
610
|
+
if (server.command) console.log(` Command: ${server.command}${server.args ? ' ' + server.args.join(' ') : ''}`);
|
|
611
|
+
if (server.description) console.log(` Description: ${server.description}`);
|
|
612
|
+
if (server.injectedProviders && server.injectedProviders.length > 0) {
|
|
613
|
+
console.log(` Injected into: ${server.injectedProviders.join(', ')}`);
|
|
614
|
+
}
|
|
615
|
+
console.log('');
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
console.log(`Registry: ${registry.getPath()}`);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Handle `aiwg mcp inject [opts]`
|
|
623
|
+
*
|
|
624
|
+
* Supports:
|
|
625
|
+
* --profile <name> resolve server set from profile registry (#890)
|
|
626
|
+
* --ephemeral write standalone config file, do NOT touch provider default (#890)
|
|
627
|
+
* --out <path> explicit output path for ephemeral mode
|
|
628
|
+
* --all inject into all previously configured providers (existing behavior)
|
|
629
|
+
* --provider <name> target provider
|
|
630
|
+
* --servers a,b explicit server filter
|
|
631
|
+
* --dry-run print what would change
|
|
632
|
+
*/
|
|
633
|
+
async function handleInject(args) {
|
|
634
|
+
const provider = parseFlag(args, '--provider');
|
|
635
|
+
const injectAll = args.includes('--all');
|
|
636
|
+
const serversStr = parseFlag(args, '--servers');
|
|
637
|
+
const dryRun = args.includes('--dry-run');
|
|
638
|
+
const projectDir = parseFlag(args, '--project') || '.';
|
|
639
|
+
const profileName = parseFlag(args, '--profile');
|
|
640
|
+
const ephemeral = args.includes('--ephemeral');
|
|
641
|
+
const outPath = parseFlag(args, '--out');
|
|
642
|
+
|
|
643
|
+
if (!provider && !injectAll) {
|
|
644
|
+
console.error('Usage: aiwg mcp inject --provider <name> [--profile <p>] [--ephemeral] [--servers a,b] [--dry-run]');
|
|
645
|
+
console.error(' aiwg mcp inject --all [--dry-run]');
|
|
646
|
+
console.error(`\nSupported providers: ${SUPPORTED_PROVIDERS.join(', ')}`);
|
|
647
|
+
process.exit(1);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
const registry = new McpServerRegistry();
|
|
651
|
+
|
|
652
|
+
// Resolve server filter: --profile takes precedence over --servers
|
|
653
|
+
let serverFilter;
|
|
654
|
+
if (profileName) {
|
|
655
|
+
const profiles = new McpProfileRegistry();
|
|
656
|
+
const profile = await profiles.get(profileName);
|
|
657
|
+
if (!profile) {
|
|
658
|
+
const all = await profiles.list();
|
|
659
|
+
console.error(`Profile "${profileName}" not found.`);
|
|
660
|
+
if (all.length > 0) console.error(`Available profiles: ${all.map(p => p.name).join(', ')}`);
|
|
661
|
+
process.exit(1);
|
|
662
|
+
}
|
|
663
|
+
// Resolve to server names (expand __all__ later in injectServers)
|
|
664
|
+
serverFilter = profile.servers.includes('__all__')
|
|
665
|
+
? undefined // inject all
|
|
666
|
+
: profile.servers;
|
|
667
|
+
console.log(`Profile: ${profileName} (${profile.servers.length === 1 && profile.servers[0] === '__all__' ? 'all servers' : profile.servers.join(', ')})`);
|
|
668
|
+
} else if (serversStr) {
|
|
669
|
+
serverFilter = serversStr.split(',').map(s => s.trim());
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
let providers;
|
|
673
|
+
if (injectAll) {
|
|
674
|
+
providers = await registry.getInjectedProviders();
|
|
675
|
+
if (providers.length === 0) {
|
|
676
|
+
console.error('No providers have been injected before. Use --provider <name> first.');
|
|
677
|
+
process.exit(1);
|
|
678
|
+
}
|
|
679
|
+
} else {
|
|
680
|
+
const normalized = provider === 'claude' ? 'claude-code' : provider;
|
|
681
|
+
if (!getMcpInjectionDefinition(normalized)) {
|
|
682
|
+
console.error(`Unknown provider: ${provider}`);
|
|
683
|
+
console.error(`Supported providers: ${SUPPORTED_PROVIDERS.join(', ')}`);
|
|
684
|
+
process.exit(1);
|
|
685
|
+
}
|
|
686
|
+
providers = [normalized];
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
if (ephemeral) {
|
|
690
|
+
for (const p of providers) {
|
|
691
|
+
const mcpDefinition = getMcpInjectionDefinition(p);
|
|
692
|
+
if (!mcpDefinition?.supportsEphemeral) {
|
|
693
|
+
console.error(`Error: --ephemeral is not supported for provider "${p}".`);
|
|
694
|
+
if (mcpDefinition?.unsupportedReason) console.error(` ${mcpDefinition.unsupportedReason}`);
|
|
695
|
+
process.exit(1);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
console.log(dryRun ? '[DRY RUN] Ephemeral mode — would write standalone config:' : 'Ephemeral mode — writing standalone config (default provider config NOT modified):');
|
|
699
|
+
} else if (dryRun) {
|
|
700
|
+
console.log('[DRY RUN] Would inject servers into:');
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
let totalInjected = 0;
|
|
704
|
+
|
|
705
|
+
for (const p of providers) {
|
|
706
|
+
if (ephemeral) {
|
|
707
|
+
// Generate a standalone ephemeral config file
|
|
708
|
+
const targetPath = outPath ?? path.join(
|
|
709
|
+
process.env.TMPDIR || '/tmp',
|
|
710
|
+
`aiwg-mcp-${profileName ?? 'custom'}-${p}-${Date.now()}.json`,
|
|
711
|
+
);
|
|
712
|
+
|
|
713
|
+
const allServers = await registry.list();
|
|
714
|
+
const servers = serverFilter
|
|
715
|
+
? allServers.filter(s => serverFilter.includes(s.name))
|
|
716
|
+
: allServers;
|
|
717
|
+
|
|
718
|
+
if (servers.length === 0) {
|
|
719
|
+
console.error(` ${p}: no servers to write`);
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// Build ephemeral config in provider's format
|
|
724
|
+
const mcpDefinition = getMcpInjectionDefinition(p);
|
|
725
|
+
const mcpKey = mcpDefinition?.serversKey || 'mcpServers';
|
|
726
|
+
const mcpBlock = {};
|
|
727
|
+
for (const server of servers) {
|
|
728
|
+
if (mcpDefinition?.configFormat === 'toml') {
|
|
729
|
+
// TOML providers get a note — ephemeral TOML is handled by codex-runtime adapter
|
|
730
|
+
console.log(` ${p}: TOML ephemeral config requires the codex-runtime adapter.`);
|
|
731
|
+
console.log(` Use "aiwg session --provider codex --profile ${profileName}" instead.`);
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
const cfg = {};
|
|
735
|
+
if (server.type === 'stdio') {
|
|
736
|
+
cfg.command = server.command;
|
|
737
|
+
cfg.args = server.args || [];
|
|
738
|
+
if (server.env) cfg.env = server.env;
|
|
739
|
+
} else {
|
|
740
|
+
cfg.url = server.url;
|
|
741
|
+
if (server.headers) cfg.headers = server.headers;
|
|
742
|
+
}
|
|
743
|
+
mcpBlock[server.name] = cfg;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
if (Object.keys(mcpBlock).length === 0) continue;
|
|
747
|
+
|
|
748
|
+
const config = { [mcpKey]: mcpBlock };
|
|
749
|
+
|
|
750
|
+
if (!dryRun) {
|
|
751
|
+
await fs.mkdir(path.dirname(targetPath), { recursive: true });
|
|
752
|
+
await fs.writeFile(targetPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
const prefix = dryRun ? '[DRY RUN] ' : '';
|
|
756
|
+
console.log(`${prefix}${p}: ${targetPath}`);
|
|
757
|
+
console.log(` ${prefix}Servers: ${Object.keys(mcpBlock).join(', ')}`);
|
|
758
|
+
if (!dryRun && (p === 'claude-code' || p === 'claude')) {
|
|
759
|
+
console.log(` Launch with: claude --mcp-config ${targetPath}`);
|
|
760
|
+
}
|
|
761
|
+
totalInjected += Object.keys(mcpBlock).length;
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
// Persistent injection (existing behavior)
|
|
766
|
+
const result = await injectServers(registry, p, {
|
|
767
|
+
servers: serverFilter,
|
|
768
|
+
projectDir,
|
|
769
|
+
dryRun,
|
|
770
|
+
});
|
|
771
|
+
|
|
772
|
+
if (result.error) {
|
|
773
|
+
console.error(` ${p}: ${result.error}`);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
const prefix = dryRun ? '[DRY RUN] ' : '';
|
|
778
|
+
console.log(`${prefix}${p}: ${result.configPath}`);
|
|
779
|
+
if (result.serversInjected.length > 0) {
|
|
780
|
+
console.log(` ${prefix}Injected: ${result.serversInjected.join(', ')}`);
|
|
781
|
+
totalInjected += result.serversInjected.length;
|
|
782
|
+
}
|
|
783
|
+
if (result.alreadyPresent.length > 0) {
|
|
784
|
+
console.log(` ${prefix}Updated in place: ${result.alreadyPresent.join(', ')}`);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
if (!dryRun && totalInjected > 0 && !ephemeral) {
|
|
789
|
+
console.log(`\nDone. Restart your provider(s) to pick up the changes.`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// ============================================
|
|
794
|
+
// Profile subcommand handlers (#889)
|
|
795
|
+
// ============================================
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Print profile subcommand usage
|
|
799
|
+
*/
|
|
800
|
+
function printProfileUsage() {
|
|
801
|
+
console.log(`
|
|
802
|
+
aiwg mcp profile — MCP server profiles (named server subsets)
|
|
803
|
+
|
|
804
|
+
Usage:
|
|
805
|
+
aiwg mcp profile add <name> --servers a,b,c [--description "..."]
|
|
806
|
+
aiwg mcp profile list
|
|
807
|
+
aiwg mcp profile show <name>
|
|
808
|
+
aiwg mcp profile edit <name> [--add-server x] [--remove-server y] [--description "..."]
|
|
809
|
+
aiwg mcp profile remove <name>
|
|
810
|
+
aiwg mcp profile import <file>
|
|
811
|
+
aiwg mcp profile export <name> [--out <file>]
|
|
812
|
+
aiwg mcp profile init-presets
|
|
813
|
+
|
|
814
|
+
Profiles let you define named subsets of your registered MCP servers:
|
|
815
|
+
aiwg mcp profile add dev --servers git-gitea,memory-fortemi --description "Dev work"
|
|
816
|
+
aiwg mcp profile show dev
|
|
817
|
+
aiwg mcp inject --provider claude --profile dev --ephemeral
|
|
818
|
+
aiwg session --provider claude --profile dev
|
|
819
|
+
|
|
820
|
+
Preset profiles (minimal, dev, ops, research, incident, full):
|
|
821
|
+
aiwg mcp profile init-presets
|
|
822
|
+
`);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
/**
|
|
826
|
+
* Handle `aiwg mcp profile add <name> [opts]`
|
|
827
|
+
*/
|
|
828
|
+
async function handleProfileAdd(args) {
|
|
829
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
830
|
+
const name = positional[0];
|
|
831
|
+
if (!name) {
|
|
832
|
+
console.error('Usage: aiwg mcp profile add <name> --servers a,b,c [--description "..."]');
|
|
833
|
+
process.exit(1);
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
const serversStr = parseFlag(args, '--servers');
|
|
837
|
+
const description = parseFlag(args, '--description');
|
|
838
|
+
|
|
839
|
+
if (!serversStr && name !== 'minimal') {
|
|
840
|
+
console.error('Warning: no --servers specified. Profile will start empty.');
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
const servers = serversStr ? serversStr.split(',').map(s => s.trim()).filter(Boolean) : [];
|
|
844
|
+
|
|
845
|
+
const profiles = new McpProfileRegistry();
|
|
846
|
+
const registry = new McpServerRegistry();
|
|
847
|
+
|
|
848
|
+
await profiles.add({ name, description, servers }, registry);
|
|
849
|
+
|
|
850
|
+
console.log(`Profile added: ${name}`);
|
|
851
|
+
if (description) console.log(` Description: ${description}`);
|
|
852
|
+
console.log(` Servers (${servers.length}): ${servers.length > 0 ? servers.join(', ') : '(none)'}`);
|
|
853
|
+
console.log(`\nUse "aiwg mcp inject --provider <p> --profile ${name}" to inject this profile.`);
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Handle `aiwg mcp profile list`
|
|
858
|
+
*/
|
|
859
|
+
async function handleProfileList() {
|
|
860
|
+
const profiles = new McpProfileRegistry();
|
|
861
|
+
const all = await profiles.list();
|
|
862
|
+
|
|
863
|
+
if (all.length === 0) {
|
|
864
|
+
console.log('No profiles defined.');
|
|
865
|
+
console.log('\nCreate one: aiwg mcp profile add dev --servers git-gitea,memory-fortemi');
|
|
866
|
+
console.log('Or install presets: aiwg mcp profile init-presets');
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
console.log(`MCP Profiles (${all.length}):\n`);
|
|
871
|
+
for (const p of all) {
|
|
872
|
+
const serverCount = p.servers.length === 1 && p.servers[0] === '__all__'
|
|
873
|
+
? 'all'
|
|
874
|
+
: String(p.servers.length);
|
|
875
|
+
console.log(` ${p.name.padEnd(16)} [${serverCount} server${serverCount === '1' ? '' : 's'}] ${p.description ?? ''}`);
|
|
876
|
+
}
|
|
877
|
+
console.log(`\nProfiles file: ${profiles.getPath()}`);
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Handle `aiwg mcp profile show <name>`
|
|
882
|
+
*/
|
|
883
|
+
async function handleProfileShow(args) {
|
|
884
|
+
const name = args.filter(a => !a.startsWith('--'))[0];
|
|
885
|
+
if (!name) {
|
|
886
|
+
console.error('Usage: aiwg mcp profile show <name>');
|
|
887
|
+
process.exit(1);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
const profiles = new McpProfileRegistry();
|
|
891
|
+
const profile = await profiles.get(name);
|
|
892
|
+
|
|
893
|
+
if (!profile) {
|
|
894
|
+
const all = await profiles.list();
|
|
895
|
+
console.error(`Profile "${name}" not found.`);
|
|
896
|
+
if (all.length > 0) {
|
|
897
|
+
console.error(`Available profiles: ${all.map(p => p.name).join(', ')}`);
|
|
898
|
+
}
|
|
899
|
+
process.exit(1);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
console.log(`Profile: ${profile.name}`);
|
|
903
|
+
if (profile.description) console.log(`Description: ${profile.description}`);
|
|
904
|
+
console.log(`\nServers (${profile.servers.length}):`);
|
|
905
|
+
|
|
906
|
+
if (profile.servers.length === 0) {
|
|
907
|
+
console.log(' (none)');
|
|
908
|
+
} else if (profile.servers[0] === '__all__') {
|
|
909
|
+
console.log(' (all registered servers)');
|
|
910
|
+
} else {
|
|
911
|
+
// Resolve server configs
|
|
912
|
+
const registry = new McpServerRegistry();
|
|
913
|
+
for (const serverName of profile.servers) {
|
|
914
|
+
const server = await registry.get(serverName);
|
|
915
|
+
if (server) {
|
|
916
|
+
const detail = server.type === 'stdio'
|
|
917
|
+
? `stdio ${server.command}${server.args ? ' ' + server.args.join(' ') : ''}`
|
|
918
|
+
: `${server.type} ${server.url}`;
|
|
919
|
+
console.log(` ${serverName.padEnd(24)} ${detail}`);
|
|
920
|
+
if (server.description) console.log(` ${''.padEnd(24)} ${server.description}`);
|
|
921
|
+
} else {
|
|
922
|
+
console.log(` ${serverName.padEnd(24)} (not in registry — missing)`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
if (profile.providerOverrides && Object.keys(profile.providerOverrides).length > 0) {
|
|
928
|
+
console.log('\nProvider overrides:');
|
|
929
|
+
for (const [provider, overrides] of Object.entries(profile.providerOverrides)) {
|
|
930
|
+
console.log(` ${provider}:`);
|
|
931
|
+
if (overrides.toolDeny) console.log(` toolDeny: ${overrides.toolDeny.join(', ')}`);
|
|
932
|
+
if (overrides.toolAllow) console.log(` toolAllow: ${overrides.toolAllow.join(', ')}`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
if (profile.createdAt) console.log(`\nCreated: ${profile.createdAt}`);
|
|
937
|
+
if (profile.updatedAt) console.log(`Updated: ${profile.updatedAt}`);
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/**
|
|
941
|
+
* Handle `aiwg mcp profile edit <name> [opts]`
|
|
942
|
+
*/
|
|
943
|
+
async function handleProfileEdit(args) {
|
|
944
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
945
|
+
const name = positional[0];
|
|
946
|
+
if (!name) {
|
|
947
|
+
console.error('Usage: aiwg mcp profile edit <name> [--add-server x] [--remove-server y] [--description "..."]');
|
|
948
|
+
process.exit(1);
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
const addServer = parseFlag(args, '--add-server');
|
|
952
|
+
const removeServer = parseFlag(args, '--remove-server');
|
|
953
|
+
const description = parseFlag(args, '--description');
|
|
954
|
+
|
|
955
|
+
const changes = {
|
|
956
|
+
description,
|
|
957
|
+
addServers: addServer ? addServer.split(',').map(s => s.trim()) : undefined,
|
|
958
|
+
removeServers: removeServer ? removeServer.split(',').map(s => s.trim()) : undefined,
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
if (!description && !addServer && !removeServer) {
|
|
962
|
+
console.error('No changes specified. Use --add-server, --remove-server, or --description.');
|
|
963
|
+
process.exit(1);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
const profiles = new McpProfileRegistry();
|
|
967
|
+
const registry = new McpServerRegistry();
|
|
968
|
+
const updated = await profiles.edit(name, changes, registry);
|
|
969
|
+
|
|
970
|
+
console.log(`Profile updated: ${name}`);
|
|
971
|
+
console.log(` Servers (${updated.servers.length}): ${updated.servers.join(', ') || '(none)'}`);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
/**
|
|
975
|
+
* Handle `aiwg mcp profile remove <name>`
|
|
976
|
+
*/
|
|
977
|
+
async function handleProfileRemove(args) {
|
|
978
|
+
const name = args.filter(a => !a.startsWith('--'))[0];
|
|
979
|
+
if (!name) {
|
|
980
|
+
console.error('Usage: aiwg mcp profile remove <name>');
|
|
981
|
+
process.exit(1);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
const profiles = new McpProfileRegistry();
|
|
985
|
+
await profiles.remove(name);
|
|
986
|
+
console.log(`Profile removed: ${name}`);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* Handle `aiwg mcp profile import <file>`
|
|
991
|
+
*/
|
|
992
|
+
async function handleProfileImport(args) {
|
|
993
|
+
const filePath = args.filter(a => !a.startsWith('--'))[0];
|
|
994
|
+
if (!filePath) {
|
|
995
|
+
console.error('Usage: aiwg mcp profile import <file>');
|
|
996
|
+
process.exit(1);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
const profiles = new McpProfileRegistry();
|
|
1000
|
+
const result = await profiles.importFrom(filePath);
|
|
1001
|
+
console.log(`Imported ${result.added} new profile(s), updated ${result.updated} existing.`);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
/**
|
|
1005
|
+
* Handle `aiwg mcp profile export <name> [--out <file>]`
|
|
1006
|
+
*/
|
|
1007
|
+
async function handleProfileExport(args) {
|
|
1008
|
+
const positional = args.filter(a => !a.startsWith('--'));
|
|
1009
|
+
const name = positional[0]; // optional — omit to export all
|
|
1010
|
+
const outFile = parseFlag(args, '--out') || (name ? `${name}-profile.json` : 'mcp-profiles.json');
|
|
1011
|
+
|
|
1012
|
+
const profiles = new McpProfileRegistry();
|
|
1013
|
+
await profiles.exportTo(outFile, name);
|
|
1014
|
+
console.log(`Exported ${name ? `profile "${name}"` : 'all profiles'} to: ${outFile}`);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
/**
|
|
1018
|
+
* Handle `aiwg mcp profile init-presets`
|
|
1019
|
+
*/
|
|
1020
|
+
async function handleProfileInitPresets() {
|
|
1021
|
+
const profiles = new McpProfileRegistry();
|
|
1022
|
+
const result = await profiles.initPresets();
|
|
1023
|
+
|
|
1024
|
+
if (result.added === 0) {
|
|
1025
|
+
console.log(`All ${result.total} preset profiles are already installed.`);
|
|
1026
|
+
console.log('Use "aiwg mcp profile list" to view them.');
|
|
1027
|
+
} else {
|
|
1028
|
+
console.log(`Installed ${result.added} preset profile(s) (${result.total} total presets):`);
|
|
1029
|
+
console.log(' minimal, dev, ops, research, incident, full');
|
|
1030
|
+
console.log('\nNote: preset server names reference expected registry entries.');
|
|
1031
|
+
console.log('Run "aiwg mcp list" to see which servers are registered.');
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
/**
|
|
1036
|
+
* Route `aiwg mcp profile <subcommand>`
|
|
1037
|
+
*/
|
|
1038
|
+
async function handleProfile(args) {
|
|
1039
|
+
const sub = args[0];
|
|
1040
|
+
const subArgs = args.slice(1);
|
|
1041
|
+
|
|
1042
|
+
switch (sub) {
|
|
1043
|
+
case 'add':
|
|
1044
|
+
await handleProfileAdd(subArgs);
|
|
1045
|
+
break;
|
|
1046
|
+
case 'list':
|
|
1047
|
+
case 'ls':
|
|
1048
|
+
await handleProfileList();
|
|
1049
|
+
break;
|
|
1050
|
+
case 'show':
|
|
1051
|
+
await handleProfileShow(subArgs);
|
|
1052
|
+
break;
|
|
1053
|
+
case 'edit':
|
|
1054
|
+
await handleProfileEdit(subArgs);
|
|
1055
|
+
break;
|
|
1056
|
+
case 'remove':
|
|
1057
|
+
case 'rm':
|
|
1058
|
+
await handleProfileRemove(subArgs);
|
|
1059
|
+
break;
|
|
1060
|
+
case 'import':
|
|
1061
|
+
await handleProfileImport(subArgs);
|
|
1062
|
+
break;
|
|
1063
|
+
case 'export':
|
|
1064
|
+
await handleProfileExport(subArgs);
|
|
1065
|
+
break;
|
|
1066
|
+
case 'init-presets':
|
|
1067
|
+
await handleProfileInitPresets();
|
|
1068
|
+
break;
|
|
1069
|
+
default:
|
|
1070
|
+
if (sub) console.error(`Unknown profile subcommand: ${sub}\n`);
|
|
1071
|
+
printProfileUsage();
|
|
1072
|
+
process.exit(sub ? 1 : 0);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
// ============================================
|
|
1077
|
+
// Main CLI entry point
|
|
1078
|
+
// ============================================
|
|
1079
|
+
|
|
1080
|
+
/**
|
|
1081
|
+
* Main CLI entry point
|
|
1082
|
+
*/
|
|
1083
|
+
export async function main(args = process.argv.slice(2)) {
|
|
1084
|
+
const command = args[0];
|
|
1085
|
+
const subArgs = args.slice(1);
|
|
1086
|
+
|
|
1087
|
+
switch (command) {
|
|
1088
|
+
case 'serve': {
|
|
1089
|
+
// Parse options
|
|
1090
|
+
const transportIdx = args.indexOf('--transport');
|
|
1091
|
+
const transport = transportIdx !== -1 ? args[transportIdx + 1] : 'stdio';
|
|
1092
|
+
|
|
1093
|
+
if (transport === 'http') {
|
|
1094
|
+
const portIdx = args.indexOf('--port');
|
|
1095
|
+
const port = portIdx !== -1 ? parseInt(args[portIdx + 1], 10) : 3100;
|
|
1096
|
+
console.error(`HTTP transport not yet implemented. Use stdio for now.`);
|
|
1097
|
+
console.error(`Would start on port ${port}`);
|
|
1098
|
+
process.exit(1);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
// --toolsets flag overrides AIWG_MCP_TOOLSETS env (#1332 / S18)
|
|
1102
|
+
const toolsetsIdx = args.indexOf('--toolsets');
|
|
1103
|
+
if (toolsetsIdx !== -1 && args[toolsetsIdx + 1]) {
|
|
1104
|
+
process.env.AIWG_MCP_TOOLSETS = args[toolsetsIdx + 1];
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
await startServer();
|
|
1108
|
+
break;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
case 'install': {
|
|
1112
|
+
// Parse install arguments (skip flags)
|
|
1113
|
+
const installArgs = args.slice(1).filter(a => !a.startsWith('--'));
|
|
1114
|
+
const target = installArgs[0] || 'claude';
|
|
1115
|
+
const projectDir = installArgs[1] || '.';
|
|
1116
|
+
|
|
1117
|
+
// Check for --dry-run flag
|
|
1118
|
+
if (args.includes('--dry-run')) {
|
|
1119
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE;
|
|
1120
|
+
console.log(`[DRY RUN] Would generate MCP config for: ${target}`);
|
|
1121
|
+
console.log(`[DRY RUN] Target directory: ${projectDir}`);
|
|
1122
|
+
const configPaths = {
|
|
1123
|
+
claude: '.claude/settings.local.json',
|
|
1124
|
+
cursor: '.cursor/mcp.json',
|
|
1125
|
+
factory: (projectDir === '.' || projectDir === 'global')
|
|
1126
|
+
? path.join(homeDir, '.factory/mcp.json')
|
|
1127
|
+
: path.join(projectDir, '.factory/mcp.json'),
|
|
1128
|
+
codex: path.join(homeDir, '.codex/config.toml'),
|
|
1129
|
+
openai: path.join(homeDir, '.codex/config.toml'),
|
|
1130
|
+
vscode: '.vscode/mcp.json',
|
|
1131
|
+
copilot: '.vscode/mcp.json',
|
|
1132
|
+
opencode: (projectDir === '.' || projectDir === 'global')
|
|
1133
|
+
? 'opencode.json'
|
|
1134
|
+
: path.join(projectDir, 'opencode.json'),
|
|
1135
|
+
windsurf: path.join(homeDir, '.codeium/windsurf/mcp_config.json'),
|
|
1136
|
+
warp: '(UI-based — Settings > AI > MCP Servers)'
|
|
1137
|
+
};
|
|
1138
|
+
console.log(`[DRY RUN] Config file: ${configPaths[target] || 'unknown'}`);
|
|
1139
|
+
break;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
await generateConfig(target, projectDir);
|
|
1143
|
+
break;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
case 'info':
|
|
1147
|
+
await showInfo();
|
|
1148
|
+
break;
|
|
1149
|
+
|
|
1150
|
+
case 'add':
|
|
1151
|
+
await handleAdd(subArgs);
|
|
1152
|
+
break;
|
|
1153
|
+
|
|
1154
|
+
case 'remove':
|
|
1155
|
+
case 'rm':
|
|
1156
|
+
await handleRemove(subArgs);
|
|
1157
|
+
break;
|
|
1158
|
+
|
|
1159
|
+
case 'update':
|
|
1160
|
+
await handleUpdate(subArgs);
|
|
1161
|
+
break;
|
|
1162
|
+
|
|
1163
|
+
case 'list':
|
|
1164
|
+
case 'ls':
|
|
1165
|
+
await handleList();
|
|
1166
|
+
break;
|
|
1167
|
+
|
|
1168
|
+
case 'inject':
|
|
1169
|
+
await handleInject(subArgs);
|
|
1170
|
+
break;
|
|
1171
|
+
|
|
1172
|
+
case 'profile':
|
|
1173
|
+
await handleProfile(subArgs);
|
|
1174
|
+
break;
|
|
1175
|
+
|
|
1176
|
+
case '--help':
|
|
1177
|
+
case '-h':
|
|
1178
|
+
case 'help':
|
|
1179
|
+
printUsage();
|
|
1180
|
+
break;
|
|
1181
|
+
|
|
1182
|
+
default:
|
|
1183
|
+
if (command) {
|
|
1184
|
+
console.error(`Unknown command: ${command}`);
|
|
1185
|
+
}
|
|
1186
|
+
printUsage();
|
|
1187
|
+
process.exit(command ? 1 : 0);
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
// Run if executed directly
|
|
1192
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
|
1193
|
+
main().catch(error => {
|
|
1194
|
+
console.error('Error:', error.message);
|
|
1195
|
+
process.exit(1);
|
|
1196
|
+
});
|
|
1197
|
+
}
|