@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +22 -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 +1486 -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 +886 -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 +65 -9
|
@@ -0,0 +1,1702 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subcommand Handlers
|
|
3
|
+
*
|
|
4
|
+
* Handlers for MCP, catalog, plugin, and other subcommands.
|
|
5
|
+
* Handles CLI subcommand routing.
|
|
6
|
+
*
|
|
7
|
+
* @implements @.aiwg/architecture/decisions/ADR-001-unified-extension-system.md
|
|
8
|
+
* @implements #56, #57
|
|
9
|
+
* @source @src/cli/router.ts
|
|
10
|
+
* @tests @test/unit/cli/handlers/subcommands.test.ts
|
|
11
|
+
* @issue #33
|
|
12
|
+
*/
|
|
13
|
+
import { createScriptRunner } from "./script-runner.js";
|
|
14
|
+
import { getFrameworkRoot } from "../../channel/manager.mjs";
|
|
15
|
+
import { getRegistry } from "../../extensions/registry.js";
|
|
16
|
+
import { registerDeployedExtensions } from "../../extensions/deployment-registration.js";
|
|
17
|
+
import { discoverProjectLocalBundles } from "../../extensions/project-local-discovery.js";
|
|
18
|
+
import { buildUpstreamRegistry } from "../../extensions/upstream-registry.js";
|
|
19
|
+
import { resolveShadows } from "../../extensions/shadow-resolver.js";
|
|
20
|
+
import { sessionHandler } from "./session.js";
|
|
21
|
+
import { feedbackHandler } from "./feedback.js";
|
|
22
|
+
import { handlerResultFromError } from "../errors.js";
|
|
23
|
+
import { getProjectDir } from "../../config/aiwg-config.js";
|
|
24
|
+
import { formatDeployedWorkspaceSignalPlan, readWorkspaceSignalPlan } from "../workspace-signals.js";
|
|
25
|
+
import * as path from "node:path";
|
|
26
|
+
import * as fsSync from "node:fs";
|
|
27
|
+
/** Generate or deploy the canonical project quickref. */
|
|
28
|
+
export const quickrefHandler = {
|
|
29
|
+
id: 'quickref',
|
|
30
|
+
name: 'Project Quickref',
|
|
31
|
+
description: 'Generate and deploy an always-visible project quickref',
|
|
32
|
+
category: 'project',
|
|
33
|
+
aliases: [],
|
|
34
|
+
async execute(ctx) {
|
|
35
|
+
const action = ctx.args.find(arg => !arg.startsWith('-')) ?? 'generate';
|
|
36
|
+
if (!ctx.args.includes('--project')) {
|
|
37
|
+
return { exitCode: 1, message: 'Error: project quickrefs require --project\n\nUsage: aiwg quickref generate|deploy --project [--provider <id>] [--dry-run]' };
|
|
38
|
+
}
|
|
39
|
+
if (!['generate', 'deploy'].includes(action)) {
|
|
40
|
+
return { exitCode: 1, message: `Error: unknown quickref action '${action}' (expected generate or deploy)` };
|
|
41
|
+
}
|
|
42
|
+
const { generateProjectQuickref, deployProjectQuickref, } = await import('../../extensions/project-quickref.js');
|
|
43
|
+
try {
|
|
44
|
+
if (action === 'generate') {
|
|
45
|
+
const result = await generateProjectQuickref(ctx.cwd, { dryRun: ctx.dryRun });
|
|
46
|
+
const verb = ctx.dryRun ? 'Would generate' : result.changed ? 'Generated' : 'Unchanged';
|
|
47
|
+
console.log(`${verb} ${result.skillName}`);
|
|
48
|
+
console.log(` Source: ${result.sourcePath}`);
|
|
49
|
+
console.log(` Output: ${result.outputPath}`);
|
|
50
|
+
if (ctx.dryRun) {
|
|
51
|
+
console.log('\n--- preview ---\n');
|
|
52
|
+
console.log(result.content);
|
|
53
|
+
}
|
|
54
|
+
return { exitCode: 0 };
|
|
55
|
+
}
|
|
56
|
+
const providerIndex = ctx.args.indexOf('--provider');
|
|
57
|
+
const explicitProvider = providerIndex >= 0 ? ctx.args[providerIndex + 1] : undefined;
|
|
58
|
+
const { readAiwgConfig } = await import('../../config/aiwg-config.js');
|
|
59
|
+
const config = await readAiwgConfig(ctx.cwd);
|
|
60
|
+
const providers = explicitProvider ? [explicitProvider] : (config?.providers ?? []);
|
|
61
|
+
if (providers.length === 0) {
|
|
62
|
+
return { exitCode: 1, message: 'No providers configured. Pass --provider <id> or add providers to .aiwg/aiwg.config.' };
|
|
63
|
+
}
|
|
64
|
+
for (const provider of providers) {
|
|
65
|
+
const result = await deployProjectQuickref(ctx.cwd, provider, { dryRun: ctx.dryRun });
|
|
66
|
+
const verb = ctx.dryRun ? 'Would deploy' : result.changed ? 'Deployed' : 'Unchanged';
|
|
67
|
+
console.log(`${verb} ${result.skillName} -> ${result.provider}: ${result.targetPath}${result.emulated ? ' (emulated skill surface)' : ''}`);
|
|
68
|
+
for (const stale of result.pruned) {
|
|
69
|
+
console.log(` ${ctx.dryRun ? 'Would prune' : 'Pruned'} stale managed quickref: ${stale}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return { exitCode: 0 };
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return { exitCode: 1, message: `Project quickref failed: ${error.message}` };
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
const LIST_PROVIDER_TARGETS = [
|
|
80
|
+
{ name: 'claude', root: '.claude', agentsPath: '.claude/agents', skillsPath: '.claude/skills', commandsPath: '.claude/commands' },
|
|
81
|
+
{ name: 'codex', root: '.codex', agentsPath: '.codex/agents', skillsPath: '.codex/skills', commandsPath: '.codex/commands' },
|
|
82
|
+
{ name: 'copilot', root: '.github', agentsPath: '.github/agents', skillsPath: '.github/skills', commandsPath: '.github/prompts' },
|
|
83
|
+
{ name: 'cursor', root: '.cursor', agentsPath: '.cursor/agents', skillsPath: '.cursor/skills', commandsPath: '.cursor/commands' },
|
|
84
|
+
{ name: 'opencode', root: '.opencode', agentsPath: '.opencode/agent', skillsPath: '.opencode/skill', commandsPath: '.opencode/command' },
|
|
85
|
+
{ name: 'warp', root: '.warp', agentsPath: '.warp/agents', skillsPath: '.warp/skills', commandsPath: '.warp/commands' },
|
|
86
|
+
{ name: 'factory', root: '.factory', agentsPath: '.factory/droids', skillsPath: '.factory/skills', commandsPath: '.factory/commands' },
|
|
87
|
+
{ name: 'windsurf', root: '.windsurf', agentsPath: '.windsurf/agents', skillsPath: '.windsurf/skills', commandsPath: '.windsurf/workflows' },
|
|
88
|
+
{ name: 'universal', root: '.agents', agentsPath: '.agents/agents', skillsPath: '.agents/skills', commandsPath: '.agents/commands' },
|
|
89
|
+
];
|
|
90
|
+
function hasAnyPopulated(cwd, p) {
|
|
91
|
+
const candidates = [p.agentsPath, p.skillsPath, p.commandsPath];
|
|
92
|
+
for (const rel of candidates) {
|
|
93
|
+
const abs = path.join(cwd, rel);
|
|
94
|
+
try {
|
|
95
|
+
if (fsSync.statSync(abs).isDirectory() && fsSync.readdirSync(abs).length > 0)
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// dir doesn't exist or unreadable — skip
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
function detectDeployedProviders(cwd) {
|
|
105
|
+
return LIST_PROVIDER_TARGETS.filter(p => hasAnyPopulated(cwd, p));
|
|
106
|
+
}
|
|
107
|
+
const REMOVE_FLAGS_WITH_VALUES = new Set([
|
|
108
|
+
'--provider',
|
|
109
|
+
'--platform',
|
|
110
|
+
'--scope',
|
|
111
|
+
'--target',
|
|
112
|
+
]);
|
|
113
|
+
function firstRemovePositional(args) {
|
|
114
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
115
|
+
const arg = args[i];
|
|
116
|
+
if (REMOVE_FLAGS_WITH_VALUES.has(arg)) {
|
|
117
|
+
i += 1;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!arg.startsWith('-'))
|
|
121
|
+
return arg;
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
function parseRemoveProvider(args) {
|
|
126
|
+
const idx = args.findIndex(a => a === '--provider' || a === '--platform');
|
|
127
|
+
if (idx < 0)
|
|
128
|
+
return {};
|
|
129
|
+
const provider = args[idx + 1];
|
|
130
|
+
if (!provider || provider.startsWith('-')) {
|
|
131
|
+
return { error: 'Error: --provider requires a provider name' };
|
|
132
|
+
}
|
|
133
|
+
return { provider };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* MCP server command handler
|
|
137
|
+
*
|
|
138
|
+
* Dynamically imports and delegates to src/mcp/cli.mjs.
|
|
139
|
+
* Handles subcommands: serve, install, info
|
|
140
|
+
*/
|
|
141
|
+
export const mcpHandler = {
|
|
142
|
+
id: "aiwg-mcp-server",
|
|
143
|
+
name: "AIWG MCP Server",
|
|
144
|
+
description: "AIWG MCP server commands (serve, install, add, remove, update, list, inject, info)",
|
|
145
|
+
category: "mcp",
|
|
146
|
+
aliases: ["mcp", "aiwg-mcp"],
|
|
147
|
+
async execute(ctx) {
|
|
148
|
+
try {
|
|
149
|
+
// Dynamic import to avoid loading MCP dependencies unless needed
|
|
150
|
+
const { main } = await import("../../mcp/cli.mjs");
|
|
151
|
+
await main(ctx.args);
|
|
152
|
+
return {
|
|
153
|
+
exitCode: 0,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const result = handlerResultFromError(error);
|
|
158
|
+
return { ...result, message: `MCP command failed: ${result.message}` };
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Model catalog command handler
|
|
164
|
+
*
|
|
165
|
+
* Dynamically imports and delegates to src/catalog/cli.mjs.
|
|
166
|
+
* Handles subcommands: list, info, search
|
|
167
|
+
*/
|
|
168
|
+
export const catalogHandler = {
|
|
169
|
+
id: "catalog",
|
|
170
|
+
name: "Model Catalog",
|
|
171
|
+
description: "Model catalog commands (list, info, search)",
|
|
172
|
+
category: "catalog",
|
|
173
|
+
aliases: [],
|
|
174
|
+
async execute(ctx) {
|
|
175
|
+
try {
|
|
176
|
+
// Dynamic import to avoid loading catalog dependencies unless needed
|
|
177
|
+
const { main } = await import("../../catalog/cli.mjs");
|
|
178
|
+
await main(ctx.args);
|
|
179
|
+
return {
|
|
180
|
+
exitCode: 0,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const result = handlerResultFromError(error);
|
|
185
|
+
return { ...result, message: `Catalog command failed: ${result.message}` };
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* List frameworks handler
|
|
191
|
+
*
|
|
192
|
+
* Lists deployed extensions from the registry.
|
|
193
|
+
* Falls back to legacy plugin-status script if needed.
|
|
194
|
+
*/
|
|
195
|
+
export const listHandler = {
|
|
196
|
+
id: "list",
|
|
197
|
+
name: "List Frameworks",
|
|
198
|
+
description: "List installed frameworks and plugins",
|
|
199
|
+
category: "framework",
|
|
200
|
+
aliases: ["ls"],
|
|
201
|
+
async execute(ctx) {
|
|
202
|
+
// Filter args: positional type filter, plus --project-local flag (#1034)
|
|
203
|
+
const projectLocalOnly = ctx.args.includes('--project-local');
|
|
204
|
+
const shadowsOnly = ctx.args.includes('--shadows');
|
|
205
|
+
const deployedOnly = ctx.args.includes('--deployed');
|
|
206
|
+
const filterType = ctx.args.find((a) => !a.startsWith('--')); // 'agents'|'skills'|'commands'|'all'|undefined
|
|
207
|
+
// #1156 Phase 1 — --scope user / --user surfaces the per-user registry
|
|
208
|
+
// (~/.aiwg/installed.json) instead of the project-scope deployed-extensions
|
|
209
|
+
// registry. Works from any cwd; does not require a project to be present.
|
|
210
|
+
const userScopeRequested = ctx.args.includes('--user') || isScopeUser(ctx.args);
|
|
211
|
+
if (userScopeRequested) {
|
|
212
|
+
return await formatUserScopeRegistry();
|
|
213
|
+
}
|
|
214
|
+
// Project-local bundle discovery (#1034) — read-only scan, no deploy
|
|
215
|
+
const projectLocal = await discoverProjectLocalBundles(ctx.cwd);
|
|
216
|
+
if (shadowsOnly) {
|
|
217
|
+
// #1036 — surface only artifacts that shadow upstream
|
|
218
|
+
return await formatShadowsOnly(projectLocal);
|
|
219
|
+
}
|
|
220
|
+
if (projectLocalOnly) {
|
|
221
|
+
// --project-local: only show project-local bundles; skip the deployed-
|
|
222
|
+
// extension registry read entirely
|
|
223
|
+
return formatProjectLocalOnly(projectLocal);
|
|
224
|
+
}
|
|
225
|
+
// Ensure registry is populated with deployed extensions
|
|
226
|
+
const registry = getRegistry();
|
|
227
|
+
// If registry is empty, try to populate it from EVERY deployed provider
|
|
228
|
+
// in the workspace (not just claude). Fixes #1530: in a Codex-only
|
|
229
|
+
// workspace the legacy hard-coded `.claude/...` lookup reported zero
|
|
230
|
+
// extensions even though `.codex/` was populated. Detection mirrors
|
|
231
|
+
// `tools/cli/workspace-status.mjs` so `aiwg list` and `aiwg status`
|
|
232
|
+
// agree on what counts as deployed.
|
|
233
|
+
//
|
|
234
|
+
// `--provider <name>` narrows registration to one provider; otherwise
|
|
235
|
+
// we register the union of everything detected so a multi-provider
|
|
236
|
+
// workspace shows everything in a single inventory.
|
|
237
|
+
if (registry.size === 0) {
|
|
238
|
+
try {
|
|
239
|
+
const provIdx = ctx.args.findIndex((a) => a === '--provider' || a === '--platform');
|
|
240
|
+
const requestedProvider = provIdx >= 0 ? ctx.args[provIdx + 1] : undefined;
|
|
241
|
+
let targets = detectDeployedProviders(ctx.cwd);
|
|
242
|
+
if (requestedProvider) {
|
|
243
|
+
targets = targets.filter((p) => p.name === requestedProvider);
|
|
244
|
+
if (targets.length === 0) {
|
|
245
|
+
return {
|
|
246
|
+
exitCode: 1,
|
|
247
|
+
message: `Error: provider '${requestedProvider}' is not deployed in this workspace.\n\nRun 'aiwg status' to see deployed providers.`,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (targets.length === 0) {
|
|
252
|
+
// No deployed providers detected → return a clean empty-inventory
|
|
253
|
+
// message rather than dispatching to the legacy script (which
|
|
254
|
+
// requires a path argument it doesn't get here). Matches the
|
|
255
|
+
// legacy script's helpful guidance from #1530.
|
|
256
|
+
return {
|
|
257
|
+
exitCode: 0,
|
|
258
|
+
message: 'No agents, skills, or commands deployed in this workspace.\n\n' +
|
|
259
|
+
'Tip: Deploy a framework with "aiwg use sdlc" (or another framework) to get started.\n' +
|
|
260
|
+
'Run "aiwg status" for workspace health detail.\n',
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
for (const target of targets) {
|
|
264
|
+
await registerDeployedExtensions(registry, {
|
|
265
|
+
agentsPath: target.agentsPath,
|
|
266
|
+
skillsPath: target.skillsPath,
|
|
267
|
+
commandsPath: target.commandsPath,
|
|
268
|
+
provider: target.name,
|
|
269
|
+
cwd: ctx.cwd,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
// If registry population fails, fall back to legacy script
|
|
275
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
276
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
277
|
+
return runner.run("tools/plugin/plugin-status-cli.mjs", ctx.args, {
|
|
278
|
+
cwd: ctx.cwd,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Determine what to show
|
|
283
|
+
const showAgents = !filterType || filterType === 'agents' || filterType === 'all';
|
|
284
|
+
const showSkills = !filterType || filterType === 'skills' || filterType === 'all';
|
|
285
|
+
const showCommands = !filterType || filterType === 'commands' || filterType === 'all';
|
|
286
|
+
let output = '';
|
|
287
|
+
if (showAgents) {
|
|
288
|
+
const agents = registry.getByType('agent');
|
|
289
|
+
output += `\nAgents (${agents.length}):\n`;
|
|
290
|
+
output += '─'.repeat(60) + '\n';
|
|
291
|
+
if (agents.length === 0) {
|
|
292
|
+
output += ' No agents deployed\n';
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
for (const agent of agents.slice(0, 20)) { // Limit to 20 for readability
|
|
296
|
+
output += ` ${agent.name}\n`;
|
|
297
|
+
output += ` ID: ${agent.id}\n`;
|
|
298
|
+
output += ` Description: ${agent.description.slice(0, 80)}${agent.description.length > 80 ? '...' : ''}\n`;
|
|
299
|
+
if (agent.installation) {
|
|
300
|
+
output += ` Path: ${agent.installation.installedPath}\n`;
|
|
301
|
+
}
|
|
302
|
+
output += '\n';
|
|
303
|
+
}
|
|
304
|
+
if (agents.length > 20) {
|
|
305
|
+
output += ` ... and ${agents.length - 20} more\n`;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (showSkills) {
|
|
310
|
+
const skills = registry.getByType('skill');
|
|
311
|
+
output += `\nSkills (${skills.length}):\n`;
|
|
312
|
+
output += '─'.repeat(60) + '\n';
|
|
313
|
+
if (skills.length === 0) {
|
|
314
|
+
output += ' No skills deployed\n';
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
for (const skill of skills.slice(0, 20)) {
|
|
318
|
+
output += ` ${skill.name}\n`;
|
|
319
|
+
output += ` ID: ${skill.id}\n`;
|
|
320
|
+
output += ` Description: ${skill.description.slice(0, 80)}${skill.description.length > 80 ? '...' : ''}\n`;
|
|
321
|
+
if (skill.installation) {
|
|
322
|
+
output += ` Path: ${skill.installation.installedPath}\n`;
|
|
323
|
+
}
|
|
324
|
+
output += '\n';
|
|
325
|
+
}
|
|
326
|
+
if (skills.length > 20) {
|
|
327
|
+
output += ` ... and ${skills.length - 20} more\n`;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (showCommands) {
|
|
332
|
+
const commands = registry.getByType('command');
|
|
333
|
+
output += `\nCommands (${commands.length}):\n`;
|
|
334
|
+
output += '─'.repeat(60) + '\n';
|
|
335
|
+
if (commands.length === 0) {
|
|
336
|
+
output += ' No commands registered\n';
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
for (const command of commands.slice(0, 20)) {
|
|
340
|
+
output += ` ${command.name}\n`;
|
|
341
|
+
output += ` ID: ${command.id}\n`;
|
|
342
|
+
output += ` Description: ${command.description.slice(0, 80)}${command.description.length > 80 ? '...' : ''}\n`;
|
|
343
|
+
output += '\n';
|
|
344
|
+
}
|
|
345
|
+
if (commands.length > 20) {
|
|
346
|
+
output += ` ... and ${commands.length - 20} more\n`;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// Project-local bundles (#1034) — surfaced as a separate section with
|
|
351
|
+
// [project] source label
|
|
352
|
+
const totalProjectLocal = projectLocal.counts.extension +
|
|
353
|
+
projectLocal.counts.addon +
|
|
354
|
+
projectLocal.counts.framework +
|
|
355
|
+
projectLocal.counts.plugin;
|
|
356
|
+
if (totalProjectLocal > 0 || projectLocal.errors.length > 0) {
|
|
357
|
+
output += `\nProject-local bundles (${totalProjectLocal}):\n`;
|
|
358
|
+
output += '─'.repeat(60) + '\n';
|
|
359
|
+
for (const b of projectLocal.bundles) {
|
|
360
|
+
output += ` ${b.id} [project] [${b.type}]\n`;
|
|
361
|
+
output += ` Path: ${b.localPath}\n`;
|
|
362
|
+
output += ` Description: ${b.manifest.description.slice(0, 80)}${b.manifest.description.length > 80 ? '...' : ''}\n\n`;
|
|
363
|
+
}
|
|
364
|
+
if (projectLocal.errors.length > 0) {
|
|
365
|
+
output += ` ⚠ ${projectLocal.errors.length} validation error(s) — see "aiwg doctor" for details\n`;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Summary
|
|
369
|
+
const totalAgents = registry.getByType('agent').length;
|
|
370
|
+
const totalSkills = registry.getByType('skill').length;
|
|
371
|
+
const totalCommands = registry.getByType('command').length;
|
|
372
|
+
const total = totalAgents + totalSkills + totalCommands;
|
|
373
|
+
output += '\n' + '═'.repeat(60) + '\n';
|
|
374
|
+
output += `Total: ${total} extensions (${totalAgents} agents, ${totalSkills} skills, ${totalCommands} commands)`;
|
|
375
|
+
if (totalProjectLocal > 0) {
|
|
376
|
+
output += ` + ${totalProjectLocal} project-local`;
|
|
377
|
+
}
|
|
378
|
+
output += '\n';
|
|
379
|
+
if (total === 0 && totalProjectLocal === 0) {
|
|
380
|
+
output += '\nTip: Deploy a framework with "aiwg use sdlc" to get started\n';
|
|
381
|
+
}
|
|
382
|
+
else if (totalCommands === 0 && totalAgents > 0) {
|
|
383
|
+
// Skill-only model (Claude Code default): commands aren't deployed as
|
|
384
|
+
// slash commands; capabilities reach the agent via natural language or
|
|
385
|
+
// `aiwg discover` (#1228). Surface this so 0 commands doesn't look like
|
|
386
|
+
// a deploy failure.
|
|
387
|
+
output += '\nNote: 0 commands is expected on Claude Code — capabilities are reached via natural language or `aiwg discover "<phrase>"`.\n';
|
|
388
|
+
}
|
|
389
|
+
if (deployedOnly) {
|
|
390
|
+
const projectDir = getProjectDir(ctx, ctx.args);
|
|
391
|
+
const plan = await readWorkspaceSignalPlan(projectDir);
|
|
392
|
+
if (plan) {
|
|
393
|
+
output += formatDeployedWorkspaceSignalPlan(plan);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
output += '\nWorkspace skill filter: no recorded plan found.\n';
|
|
397
|
+
output += 'Run `aiwg use --profile <name>` to record workspace-aware include/exclude reasons.\n';
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
exitCode: 0,
|
|
402
|
+
message: output,
|
|
403
|
+
};
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
/**
|
|
407
|
+
* Format `aiwg list --project-local` output: only project-local bundles, with
|
|
408
|
+
* per-type breakdown and any validation errors surfaced. (#1034)
|
|
409
|
+
*/
|
|
410
|
+
function formatProjectLocalOnly(result) {
|
|
411
|
+
let output = '';
|
|
412
|
+
const total = result.counts.extension +
|
|
413
|
+
result.counts.addon +
|
|
414
|
+
result.counts.framework +
|
|
415
|
+
result.counts.plugin;
|
|
416
|
+
if (total === 0 && result.errors.length === 0) {
|
|
417
|
+
output += '\nNo project-local bundles found.\n';
|
|
418
|
+
output += '\nTip: place a manifest.json under the configured AIWG artifact root at {extensions,addons,frameworks,plugins,providers}/<name>/ to author a project-local artifact.\n';
|
|
419
|
+
return { exitCode: 0, message: output };
|
|
420
|
+
}
|
|
421
|
+
output += `\nProject-local bundles (${total}):\n`;
|
|
422
|
+
output += '─'.repeat(60) + '\n';
|
|
423
|
+
for (const b of result.bundles) {
|
|
424
|
+
output += ` ${b.id} [project] [${b.type}] v${b.manifest.version}\n`;
|
|
425
|
+
output += ` Path: ${b.localPath}\n`;
|
|
426
|
+
output += ` Description: ${b.manifest.description.slice(0, 80)}${b.manifest.description.length > 80 ? '...' : ''}\n\n`;
|
|
427
|
+
}
|
|
428
|
+
if (result.errors.length > 0) {
|
|
429
|
+
output += '\nValidation errors:\n';
|
|
430
|
+
output += '─'.repeat(60) + '\n';
|
|
431
|
+
for (const e of result.errors.slice(0, 10)) {
|
|
432
|
+
output += ` [${e.severity}] ${e.path}\n`;
|
|
433
|
+
output += ` ${e.field}: expected ${e.expected}, got ${e.actual}\n`;
|
|
434
|
+
if (e.hint)
|
|
435
|
+
output += ` hint: ${e.hint}\n`;
|
|
436
|
+
}
|
|
437
|
+
if (result.errors.length > 10) {
|
|
438
|
+
output += ` ... and ${result.errors.length - 10} more\n`;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
output += '\n' + '═'.repeat(60) + '\n';
|
|
442
|
+
output += `Counts by type: extension=${result.counts.extension} addon=${result.counts.addon} framework=${result.counts.framework} plugin=${result.counts.plugin}\n`;
|
|
443
|
+
return { exitCode: 0, message: output };
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Format `aiwg list --shadows` output: only artifacts that currently shadow
|
|
447
|
+
* an upstream artifact, with safety-critical and override status. (#1036)
|
|
448
|
+
*/
|
|
449
|
+
async function formatShadowsOnly(projectLocal) {
|
|
450
|
+
let output = '';
|
|
451
|
+
if (projectLocal.bundles.length === 0) {
|
|
452
|
+
output += '\nNo project-local bundles — no shadows possible.\n';
|
|
453
|
+
return { exitCode: 0, message: output };
|
|
454
|
+
}
|
|
455
|
+
const { getFrameworkRoot: gfr } = await import('../../channel/manager.mjs');
|
|
456
|
+
const frameworkRoot = await gfr();
|
|
457
|
+
const upstream = await buildUpstreamRegistry({ frameworkRoot });
|
|
458
|
+
const result = await resolveShadows(projectLocal.bundles, upstream);
|
|
459
|
+
if (result.shadows.length === 0) {
|
|
460
|
+
output += '\nNo active shadows.\n';
|
|
461
|
+
output += '\nProject-local bundles deploy alongside upstream without collision.\n';
|
|
462
|
+
return { exitCode: 0, message: output };
|
|
463
|
+
}
|
|
464
|
+
output += `\nActive shadows (${result.shadows.length}):\n`;
|
|
465
|
+
output += '─'.repeat(60) + '\n';
|
|
466
|
+
for (const r of result.shadows) {
|
|
467
|
+
const sc = r.upstream?.safetyCritical ? ' [SAFETY-CRITICAL]' : '';
|
|
468
|
+
output += ` ${r.artifactType}/${r.artifactId}${sc}\n`;
|
|
469
|
+
output += ` Bundle: ${r.bundleId} (${r.bundleLocalPath})\n`;
|
|
470
|
+
output += ` Project-local: ${r.artifactSourcePath}\n`;
|
|
471
|
+
if (r.upstream) {
|
|
472
|
+
output += ` Shadows ${r.upstream.source}: ${r.upstream.sourcePath}\n`;
|
|
473
|
+
}
|
|
474
|
+
output += ` Verdict: ${r.verdict}\n\n`;
|
|
475
|
+
}
|
|
476
|
+
if (result.blockedBundleIds.size > 0) {
|
|
477
|
+
output += `\n⚠ ${result.blockedBundleIds.size} bundle(s) blocked from deployment due to unsafe shadows.\n`;
|
|
478
|
+
}
|
|
479
|
+
return { exitCode: 0, message: output };
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* #1156 Phase 1 — `--scope user` detection. Mirrors `detectScope()` from
|
|
483
|
+
* scope-resolver but tolerates the absence of the flag (no throw on absent).
|
|
484
|
+
* Returns true when args contain `--scope user`.
|
|
485
|
+
*/
|
|
486
|
+
function isScopeUser(args) {
|
|
487
|
+
const idx = args.findIndex((a) => a === '--scope');
|
|
488
|
+
if (idx === -1)
|
|
489
|
+
return false;
|
|
490
|
+
return args[idx + 1] === 'user';
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* #1156 Phase 1 — Format the per-user registry (~/.aiwg/installed.json) as a
|
|
494
|
+
* human-readable inventory. Used by `aiwg list --scope user` / `aiwg list
|
|
495
|
+
* --user`. Independent of any project — works from any cwd.
|
|
496
|
+
*/
|
|
497
|
+
async function formatUserScopeRegistry() {
|
|
498
|
+
const { readUserRegistry, userRegistryPath } = await import('../../config/user-registry.js');
|
|
499
|
+
const registry = await readUserRegistry();
|
|
500
|
+
const frameworks = Object.entries(registry.installed);
|
|
501
|
+
let output = '';
|
|
502
|
+
if (frameworks.length === 0) {
|
|
503
|
+
output += '\nNo frameworks deployed at user scope.\n';
|
|
504
|
+
output += `\nRegistry path: ${userRegistryPath()}\n`;
|
|
505
|
+
output += '\nTip: run `aiwg use <framework> --provider <p> --scope user` to install at user scope.\n';
|
|
506
|
+
return { exitCode: 0, message: output };
|
|
507
|
+
}
|
|
508
|
+
output += `\nUser-scope deployments (${frameworks.length}):\n`;
|
|
509
|
+
output += '─'.repeat(60) + '\n';
|
|
510
|
+
for (const [name, entry] of frameworks) {
|
|
511
|
+
output += ` ${name} v${entry.version} [${entry.source}]\n`;
|
|
512
|
+
output += ` Installed: ${entry.installedAt}\n`;
|
|
513
|
+
const providers = Object.entries(entry.deployedTo);
|
|
514
|
+
for (const [provider, counts] of providers) {
|
|
515
|
+
const parts = [];
|
|
516
|
+
if (counts.agents > 0)
|
|
517
|
+
parts.push(`${counts.agents} agents`);
|
|
518
|
+
if (counts.commands > 0)
|
|
519
|
+
parts.push(`${counts.commands} commands`);
|
|
520
|
+
if (counts.skills > 0)
|
|
521
|
+
parts.push(`${counts.skills} skills`);
|
|
522
|
+
if (counts.rules > 0)
|
|
523
|
+
parts.push(`${counts.rules} rules`);
|
|
524
|
+
output += ` ${provider}: ${parts.length > 0 ? parts.join(', ') : '(empty)'}\n`;
|
|
525
|
+
}
|
|
526
|
+
output += '\n';
|
|
527
|
+
}
|
|
528
|
+
output += '═'.repeat(60) + '\n';
|
|
529
|
+
output += `Registry path: ${userRegistryPath()}\n`;
|
|
530
|
+
return { exitCode: 0, message: output };
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* #1156 Phase 1 — Revert a user-scope mirror.
|
|
534
|
+
*
|
|
535
|
+
* Reads `~/.aiwg/installed.json`, looks up the framework + provider entry,
|
|
536
|
+
* and deletes the specific artifact entries this deploy created (recorded
|
|
537
|
+
* by the mirror in Cycle 3). With `--dry-run`, lists what would be removed
|
|
538
|
+
* without touching the filesystem.
|
|
539
|
+
*
|
|
540
|
+
* Back-compat: registry entries written before Cycle 3 lack the `entries`
|
|
541
|
+
* snapshot. For those, the handler falls back to the conservative
|
|
542
|
+
* registry-only revert and tells the operator to clean up manually.
|
|
543
|
+
*
|
|
544
|
+
* Multi-provider: if `--provider` is omitted, all of the framework's
|
|
545
|
+
* provider deployments are reverted in one pass.
|
|
546
|
+
*/
|
|
547
|
+
async function removeUserScopeDeploy(args) {
|
|
548
|
+
const positional = firstRemovePositional(args);
|
|
549
|
+
if (!positional) {
|
|
550
|
+
return {
|
|
551
|
+
exitCode: 1,
|
|
552
|
+
message: 'Error: framework name required\n\nUsage: aiwg remove <framework> --scope user [--provider <p>] [--dry-run]',
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
const dryRun = args.includes('--dry-run');
|
|
556
|
+
const providerParse = parseRemoveProvider(args);
|
|
557
|
+
if (providerParse.error) {
|
|
558
|
+
return {
|
|
559
|
+
exitCode: 1,
|
|
560
|
+
message: `${providerParse.error}\n\nUsage: aiwg remove <framework> --scope user [--provider <p>] [--dry-run]`,
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
const provider = providerParse.provider;
|
|
564
|
+
const { readUserRegistry, removeUserDeploy } = await import('../../config/user-registry.js');
|
|
565
|
+
const { USER_SCOPE_PATHS } = await import('../scope-resolver.js');
|
|
566
|
+
const registry = await readUserRegistry();
|
|
567
|
+
const entry = registry.installed[positional];
|
|
568
|
+
if (!entry) {
|
|
569
|
+
return {
|
|
570
|
+
exitCode: 1,
|
|
571
|
+
message: `Error: framework '${positional}' is not deployed at user scope.\n\nRun 'aiwg list --scope user' to see installed frameworks.`,
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
const providersToRevert = provider ? [provider] : Object.keys(entry.deployedTo);
|
|
575
|
+
if (provider && !entry.deployedTo[provider]) {
|
|
576
|
+
return {
|
|
577
|
+
exitCode: 1,
|
|
578
|
+
message: `Error: framework '${positional}' is not deployed at user scope for provider '${provider}'.\n\nDeployed providers: ${Object.keys(entry.deployedTo).join(', ') || '(none)'}`,
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
const fs = await import('node:fs/promises');
|
|
582
|
+
const path = await import('node:path');
|
|
583
|
+
const linesOut = [];
|
|
584
|
+
if (dryRun)
|
|
585
|
+
linesOut.push(`[dry-run] Plan for user-scope remove of '${positional}':`);
|
|
586
|
+
else
|
|
587
|
+
linesOut.push(`Removing user-scope mirror of '${positional}':`);
|
|
588
|
+
let totalDeleted = 0;
|
|
589
|
+
let conservativeFallbackUsed = false;
|
|
590
|
+
for (const p of providersToRevert) {
|
|
591
|
+
const userPaths = USER_SCOPE_PATHS[p];
|
|
592
|
+
if (!userPaths) {
|
|
593
|
+
linesOut.push(` ⚠ ${p}: no user-scope paths registered — skipping (manual cleanup may be needed)`);
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
// Cast through unknown to access the optional `entries` snapshot recorded
|
|
597
|
+
// by the Cycle 3 mirror. Older registry entries won't have it.
|
|
598
|
+
const providerEntry = entry.deployedTo[p];
|
|
599
|
+
const recorded = providerEntry?.entries;
|
|
600
|
+
if (!recorded) {
|
|
601
|
+
// Pre-Cycle-3 entry: surface the deploy paths and let the operator
|
|
602
|
+
// clean them up manually. We can't safely auto-delete because the dirs
|
|
603
|
+
// are shared with other frameworks.
|
|
604
|
+
conservativeFallbackUsed = true;
|
|
605
|
+
const existingDirs = [
|
|
606
|
+
{ type: 'agents', path: userPaths.agents },
|
|
607
|
+
{ type: 'commands', path: userPaths.commands },
|
|
608
|
+
{ type: 'skills', path: userPaths.skills },
|
|
609
|
+
{ type: 'rules', path: userPaths.rules },
|
|
610
|
+
{ type: 'behaviors', path: userPaths.behaviors },
|
|
611
|
+
].filter(t => t.path);
|
|
612
|
+
linesOut.push(` ⚠ ${p}: registry entry has no per-artifact manifest (deployed before Cycle 3). Manual cleanup of these dirs may be needed:`);
|
|
613
|
+
for (const t of existingDirs) {
|
|
614
|
+
const stat = await fs.stat(t.path).catch(() => null);
|
|
615
|
+
if (stat && stat.isDirectory()) {
|
|
616
|
+
linesOut.push(` - ${t.path}`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
// Precise revert — walk the recorded entry names and delete each one
|
|
622
|
+
// from its corresponding user-scope dir.
|
|
623
|
+
const sets = [
|
|
624
|
+
['agents', userPaths.agents, recorded.agents],
|
|
625
|
+
['commands', userPaths.commands, recorded.commands],
|
|
626
|
+
['skills', userPaths.skills, recorded.skills],
|
|
627
|
+
['rules', userPaths.rules, recorded.rules],
|
|
628
|
+
['behaviors', userPaths.behaviors, recorded.behaviors],
|
|
629
|
+
];
|
|
630
|
+
for (const [type, dir, names] of sets) {
|
|
631
|
+
if (!dir || !names || names.length === 0)
|
|
632
|
+
continue;
|
|
633
|
+
let deletedHere = 0;
|
|
634
|
+
for (const name of names) {
|
|
635
|
+
const target = path.join(dir, name);
|
|
636
|
+
if (dryRun) {
|
|
637
|
+
linesOut.push(` · ${p} ${type}: ${target}`);
|
|
638
|
+
deletedHere++;
|
|
639
|
+
continue;
|
|
640
|
+
}
|
|
641
|
+
try {
|
|
642
|
+
await fs.rm(target, { recursive: true, force: true });
|
|
643
|
+
deletedHere++;
|
|
644
|
+
totalDeleted++;
|
|
645
|
+
}
|
|
646
|
+
catch (err) {
|
|
647
|
+
linesOut.push(` ⚠ ${p} ${type}: failed to remove ${target}: ${err instanceof Error ? err.message : String(err)}`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if (!dryRun && deletedHere > 0) {
|
|
651
|
+
linesOut.push(` ✓ ${p} ${type}: removed ${deletedHere} entry/entries from ${dir}`);
|
|
652
|
+
}
|
|
653
|
+
else if (dryRun) {
|
|
654
|
+
linesOut.push(` (${deletedHere} ${type} would be removed from ${dir})`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (!dryRun) {
|
|
659
|
+
if (provider) {
|
|
660
|
+
await removeUserDeploy({ framework: positional, provider });
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
await removeUserDeploy({ framework: positional });
|
|
664
|
+
}
|
|
665
|
+
linesOut.push('');
|
|
666
|
+
if (conservativeFallbackUsed) {
|
|
667
|
+
linesOut.push('Registry updated. Some providers had no per-artifact manifest (pre-Cycle-3 deploys); inspect the dirs listed above and clean up manually if needed.');
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
linesOut.push(`Registry updated. ${totalDeleted} artifact entry/entries removed.`);
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
return {
|
|
674
|
+
exitCode: 0,
|
|
675
|
+
message: linesOut.join('\n') + '\n',
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Remove framework handler
|
|
680
|
+
*
|
|
681
|
+
* Delegates to tools/plugin/plugin-uninstaller-cli.mjs
|
|
682
|
+
*/
|
|
683
|
+
export const removeHandler = {
|
|
684
|
+
id: "remove",
|
|
685
|
+
name: "Remove Framework",
|
|
686
|
+
description: "Remove installed framework, plugin, or project-local bundle",
|
|
687
|
+
category: "framework",
|
|
688
|
+
aliases: [],
|
|
689
|
+
async execute(ctx) {
|
|
690
|
+
// #1156 Phase 1 — `--scope user` / `--user`: revert the user-scope mirror
|
|
691
|
+
// for the given framework. Independent of any project; reads the per-user
|
|
692
|
+
// registry at ~/.aiwg/installed.json to find what was deployed, deletes
|
|
693
|
+
// the mirrored artifacts under the provider's USER_SCOPE_PATHS, and
|
|
694
|
+
// updates the registry.
|
|
695
|
+
if (ctx.args.includes('--user') || isScopeUser(ctx.args)) {
|
|
696
|
+
return await removeUserScopeDeploy(ctx.args);
|
|
697
|
+
}
|
|
698
|
+
// #1037 — Project-local-aware remove. If the first positional arg matches
|
|
699
|
+
// a project-local entry in `installed`, route to the new handler.
|
|
700
|
+
// Otherwise fall through to the existing plugin-uninstaller flow.
|
|
701
|
+
const positionalArg = firstRemovePositional(ctx.args);
|
|
702
|
+
const providerParse = parseRemoveProvider(ctx.args);
|
|
703
|
+
if (providerParse.error) {
|
|
704
|
+
return {
|
|
705
|
+
exitCode: 1,
|
|
706
|
+
message: `${providerParse.error}\n\nUsage: aiwg remove <id> [--force] [--dry-run] [--provider <p>] [--keep-registry]`,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
if (!positionalArg) {
|
|
710
|
+
return {
|
|
711
|
+
exitCode: 1,
|
|
712
|
+
message: 'Error: framework or bundle id required\n\nUsage: aiwg remove <id> [--force] [--dry-run] [--provider <p>] [--keep-registry]',
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
if (positionalArg) {
|
|
716
|
+
try {
|
|
717
|
+
const { readAiwgConfig, writeAiwgConfig, getProjectDir } = await import('../../config/aiwg-config.js');
|
|
718
|
+
const { removeProjectLocalBundle } = await import('../../extensions/project-local-remove.js');
|
|
719
|
+
const projectDir = getProjectDir({ cwd: ctx.cwd }, ctx.args);
|
|
720
|
+
const config = await readAiwgConfig(projectDir);
|
|
721
|
+
const entry = config?.installed?.[positionalArg];
|
|
722
|
+
if (config && entry?.source === 'project-local') {
|
|
723
|
+
const force = ctx.args.includes('--force');
|
|
724
|
+
const dryRun = ctx.args.includes('--dry-run');
|
|
725
|
+
const keepRegistry = ctx.args.includes('--keep-registry');
|
|
726
|
+
const provider = providerParse.provider;
|
|
727
|
+
const result = await removeProjectLocalBundle(config, projectDir, positionalArg, { force, dryRun, keepRegistry, provider });
|
|
728
|
+
// Print outcome summary
|
|
729
|
+
const lines = [];
|
|
730
|
+
if (dryRun)
|
|
731
|
+
lines.push(`[dry-run] Plan for project-local '${positionalArg}':`);
|
|
732
|
+
for (const o of result.outcomes) {
|
|
733
|
+
const marker = o.reverted ? '✓' : '⚠';
|
|
734
|
+
lines.push(` ${marker} ${o.provider} :: ${o.artifactPath} [${o.case}] ${o.message}`);
|
|
735
|
+
}
|
|
736
|
+
if (result.revertedProviders.length > 0) {
|
|
737
|
+
lines.push(`Fully reverted: ${result.revertedProviders.join(', ')}`);
|
|
738
|
+
}
|
|
739
|
+
if (result.partialProviders.length > 0) {
|
|
740
|
+
lines.push(`Partial (registry preserved): ${result.partialProviders.join(', ')}`);
|
|
741
|
+
}
|
|
742
|
+
if (lines.length > 0)
|
|
743
|
+
console.log(lines.join('\n'));
|
|
744
|
+
if (!dryRun) {
|
|
745
|
+
await writeAiwgConfig(projectDir, config);
|
|
746
|
+
}
|
|
747
|
+
// Note: source under .aiwg/<type>/<name>/ is intentionally NOT
|
|
748
|
+
// deleted (load-bearing invariant from #1048 design).
|
|
749
|
+
return {
|
|
750
|
+
exitCode: result.partialProviders.length > 0 ? 1 : 0,
|
|
751
|
+
message: result.partialProviders.length > 0
|
|
752
|
+
? `Some artifacts skipped (see above). Use --force to override mutation refusal.`
|
|
753
|
+
: '',
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
catch (err) {
|
|
758
|
+
// Fall through to upstream remove on any error in the project-local path
|
|
759
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
760
|
+
process.stderr.write(`project-local remove pre-check failed (falling through): ${msg}\n`);
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
if (providerParse.provider) {
|
|
764
|
+
return {
|
|
765
|
+
exitCode: 1,
|
|
766
|
+
message: `Error: --provider is only supported for project-local or user-scope remove. '${positionalArg}' is not a project-local bundle.\n\nUse 'aiwg remove ${positionalArg}' without --provider, or 'aiwg remove ${positionalArg} --scope user --provider ${providerParse.provider}' for a user-scope mirror. Refs #1610.`,
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
770
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
771
|
+
return runner.run("tools/plugin/plugin-uninstaller-cli.mjs", ctx.args, {
|
|
772
|
+
cwd: ctx.cwd,
|
|
773
|
+
});
|
|
774
|
+
},
|
|
775
|
+
};
|
|
776
|
+
/**
|
|
777
|
+
* Promote handler — graduate a project-local bundle to upstream or to a
|
|
778
|
+
* private corpus path. Implements the design at
|
|
779
|
+
* @.aiwg/architecture/design-doctor-log-promote.md (#1049).
|
|
780
|
+
*
|
|
781
|
+
* Usage:
|
|
782
|
+
* aiwg promote <name> # default: --to upstream
|
|
783
|
+
* aiwg promote <name> --to upstream
|
|
784
|
+
* aiwg promote <name> --to corpus <path>
|
|
785
|
+
* aiwg promote <name> --dry-run
|
|
786
|
+
* aiwg promote <name> --cleanup
|
|
787
|
+
* aiwg promote <name> --force
|
|
788
|
+
*
|
|
789
|
+
* @implements #1037
|
|
790
|
+
*/
|
|
791
|
+
export const promoteHandler = {
|
|
792
|
+
id: 'promote',
|
|
793
|
+
name: 'Promote',
|
|
794
|
+
description: 'Graduate a project-local bundle to upstream or a corpus path',
|
|
795
|
+
category: 'framework',
|
|
796
|
+
aliases: ['-promote', '--promote', 'graduate'],
|
|
797
|
+
async execute(ctx) {
|
|
798
|
+
const args = ctx.args;
|
|
799
|
+
const positional = args.find(a => !a.startsWith('-'));
|
|
800
|
+
if (!positional) {
|
|
801
|
+
return { exitCode: 1, message: 'Error: bundle name required\n\nUsage: aiwg promote <name> [--to upstream|corpus <path>] [--dry-run] [--cleanup] [--force]' };
|
|
802
|
+
}
|
|
803
|
+
const toIdx = args.findIndex(a => a === '--to');
|
|
804
|
+
const toValue = toIdx >= 0 ? args[toIdx + 1] : 'upstream';
|
|
805
|
+
let corpusPath;
|
|
806
|
+
if (toValue === 'corpus') {
|
|
807
|
+
// The argument *after* "corpus" is the path
|
|
808
|
+
corpusPath = args[toIdx + 2];
|
|
809
|
+
if (!corpusPath || corpusPath.startsWith('-')) {
|
|
810
|
+
return { exitCode: 1, message: 'Error: --to corpus requires a path argument' };
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
else if (toValue !== 'upstream') {
|
|
814
|
+
return { exitCode: 1, message: `Error: --to must be 'upstream' or 'corpus' (got '${toValue}')` };
|
|
815
|
+
}
|
|
816
|
+
const dryRun = args.includes('--dry-run');
|
|
817
|
+
const cleanup = args.includes('--cleanup');
|
|
818
|
+
const force = args.includes('--force');
|
|
819
|
+
try {
|
|
820
|
+
const { readAiwgConfig, writeAiwgConfig, getProjectDir } = await import('../../config/aiwg-config.js');
|
|
821
|
+
const { promoteProjectLocalBundle } = await import('../../extensions/project-local-promote.js');
|
|
822
|
+
const projectDir = getProjectDir({ cwd: ctx.cwd }, args);
|
|
823
|
+
const config = await readAiwgConfig(projectDir);
|
|
824
|
+
if (!config) {
|
|
825
|
+
return { exitCode: 1, message: 'Error: no .aiwg/aiwg.config found — run `aiwg init` first' };
|
|
826
|
+
}
|
|
827
|
+
const fr = await getFrameworkRoot();
|
|
828
|
+
const result = await promoteProjectLocalBundle(config, projectDir, positional, {
|
|
829
|
+
to: toValue,
|
|
830
|
+
corpusPath,
|
|
831
|
+
dryRun,
|
|
832
|
+
cleanup,
|
|
833
|
+
force,
|
|
834
|
+
frameworkRoot: fr,
|
|
835
|
+
});
|
|
836
|
+
if (!result.ok) {
|
|
837
|
+
return { exitCode: 1, message: `Error: ${result.message ?? result.failureReason}` };
|
|
838
|
+
}
|
|
839
|
+
if (dryRun && result.plan) {
|
|
840
|
+
console.log('[dry-run] Would copy:');
|
|
841
|
+
console.log(` ${result.plan.source} → ${result.plan.destination}`);
|
|
842
|
+
console.log(` Files: ${result.plan.files.length}, ${result.plan.totalBytes} bytes`);
|
|
843
|
+
console.log(' Pre-flight: ✓ manifest valid ✓ destination clean');
|
|
844
|
+
console.log(' Hash verification: skipped (dry-run)');
|
|
845
|
+
console.log(` Registry update: source: project-local → ${toValue === 'upstream' ? 'bundled' : 'corpus'}`);
|
|
846
|
+
console.log(` Cleanup: ${cleanup ? 'will remove .aiwg source after copy' : 'skipped (--cleanup not set)'}`);
|
|
847
|
+
return { exitCode: 0 };
|
|
848
|
+
}
|
|
849
|
+
await writeAiwgConfig(projectDir, config);
|
|
850
|
+
console.log(`✓ Promoted '${positional}' → ${result.plan?.destination}`);
|
|
851
|
+
if (cleanup) {
|
|
852
|
+
console.log(' Source removed from .aiwg/');
|
|
853
|
+
}
|
|
854
|
+
return { exitCode: 0 };
|
|
855
|
+
}
|
|
856
|
+
catch (err) {
|
|
857
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
858
|
+
return { exitCode: 1, message: `promote failed: ${msg}` };
|
|
859
|
+
}
|
|
860
|
+
},
|
|
861
|
+
};
|
|
862
|
+
/**
|
|
863
|
+
* New bundle handler — scaffolds a project-local bundle under the configured
|
|
864
|
+
* AIWG artifact root with a valid manifest, starter artifact, and a
|
|
865
|
+
* README that includes the identical-form portability reminder.
|
|
866
|
+
*
|
|
867
|
+
* Usage:
|
|
868
|
+
* aiwg new-bundle <name> # default: --type extension --starter skill
|
|
869
|
+
* aiwg new-bundle <name> --type addon
|
|
870
|
+
* aiwg new-bundle <name> --type framework --starter minimal
|
|
871
|
+
* aiwg new-bundle <name> --starter rule --description "Custom rule"
|
|
872
|
+
*
|
|
873
|
+
* @implements #1050
|
|
874
|
+
*/
|
|
875
|
+
export const newBundleHandler = {
|
|
876
|
+
id: 'new-bundle',
|
|
877
|
+
name: 'New Bundle',
|
|
878
|
+
description: 'Scaffold a project-local bundle under the configured AIWG artifact root',
|
|
879
|
+
category: 'scaffolding',
|
|
880
|
+
aliases: ['new-extension', 'new-addon', 'new-framework', 'new-plugin', 'new-provider'],
|
|
881
|
+
async execute(ctx) {
|
|
882
|
+
const args = ctx.args;
|
|
883
|
+
const positional = args.find(a => !a.startsWith('-'));
|
|
884
|
+
if (!positional) {
|
|
885
|
+
return {
|
|
886
|
+
exitCode: 1,
|
|
887
|
+
message: 'Error: bundle name required\n\nUsage: aiwg new-bundle <name> [--type extension|addon|framework|plugin|provider] [--starter skill|rule|agent|minimal] [--description "..."]',
|
|
888
|
+
};
|
|
889
|
+
}
|
|
890
|
+
// Type can be inferred from the alias used to invoke (new-extension etc.)
|
|
891
|
+
const aliasMap = {
|
|
892
|
+
'new-extension': 'extension',
|
|
893
|
+
'new-addon': 'addon',
|
|
894
|
+
'new-framework': 'framework',
|
|
895
|
+
'new-plugin': 'plugin',
|
|
896
|
+
'new-provider': 'provider',
|
|
897
|
+
};
|
|
898
|
+
const invoked = ctx.rawArgs[0] ?? '';
|
|
899
|
+
const aliasType = aliasMap[invoked];
|
|
900
|
+
const typeIdx = args.findIndex(a => a === '--type');
|
|
901
|
+
const typeFlag = typeIdx >= 0 ? args[typeIdx + 1] : undefined;
|
|
902
|
+
const type = (typeFlag ?? aliasType ?? 'extension');
|
|
903
|
+
if (!['extension', 'addon', 'framework', 'plugin', 'provider'].includes(type)) {
|
|
904
|
+
return { exitCode: 1, message: `Error: --type must be one of extension|addon|framework|plugin|provider (got '${type}')` };
|
|
905
|
+
}
|
|
906
|
+
const starterIdx = args.findIndex(a => a === '--starter');
|
|
907
|
+
const starter = starterIdx >= 0 ? args[starterIdx + 1] : undefined;
|
|
908
|
+
if (starter && !['skill', 'rule', 'agent', 'minimal'].includes(starter)) {
|
|
909
|
+
return { exitCode: 1, message: `Error: --starter must be one of skill|rule|agent|minimal (got '${starter}')` };
|
|
910
|
+
}
|
|
911
|
+
const descIdx = args.findIndex(a => a === '--description');
|
|
912
|
+
const description = descIdx >= 0 ? args[descIdx + 1] : undefined;
|
|
913
|
+
const dryRun = args.includes('--dry-run');
|
|
914
|
+
const { scaffoldProjectLocalBundle } = await import('../../extensions/project-local-scaffold.js');
|
|
915
|
+
try {
|
|
916
|
+
const result = await scaffoldProjectLocalBundle({
|
|
917
|
+
type,
|
|
918
|
+
name: positional,
|
|
919
|
+
description,
|
|
920
|
+
starter,
|
|
921
|
+
projectDir: ctx.cwd,
|
|
922
|
+
dryRun,
|
|
923
|
+
});
|
|
924
|
+
if (result.alreadyExists) {
|
|
925
|
+
return {
|
|
926
|
+
exitCode: 1,
|
|
927
|
+
message: `Refused: bundle already exists at ${result.bundlePath}. Remove it first or pick a different name.`,
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
if (dryRun) {
|
|
931
|
+
console.log(`[DRY RUN] Would scaffold project-local ${type} '${positional}' at ${result.bundlePath}`);
|
|
932
|
+
console.log(' Files that would be created:');
|
|
933
|
+
for (const f of result.filesCreated)
|
|
934
|
+
console.log(` + ${f}`);
|
|
935
|
+
console.log('');
|
|
936
|
+
console.log('No files written. Re-run without --dry-run to create.');
|
|
937
|
+
return { exitCode: 0 };
|
|
938
|
+
}
|
|
939
|
+
console.log(`✓ Scaffolded project-local ${type} '${positional}' at ${result.bundlePath}`);
|
|
940
|
+
console.log(' Files created:');
|
|
941
|
+
for (const f of result.filesCreated)
|
|
942
|
+
console.log(` + ${f}`);
|
|
943
|
+
// #1085 — when the project blanket-ignores .aiwg/, the new bundle's
|
|
944
|
+
// source would be silently dropped from version control. Detect and
|
|
945
|
+
// self-heal idempotently.
|
|
946
|
+
try {
|
|
947
|
+
const { appendAiwgSourceTrackBlock } = await import('../../extensions/project-local-gitignore.js');
|
|
948
|
+
const ig = await appendAiwgSourceTrackBlock(ctx.cwd);
|
|
949
|
+
if (ig.added) {
|
|
950
|
+
console.log('');
|
|
951
|
+
console.log(` → ${ig.reason}`);
|
|
952
|
+
console.log(' .aiwg/{addons,extensions,frameworks,plugins,providers}/ now tracked by git.');
|
|
953
|
+
console.log(' Generated state under .aiwg/ (working/, ralph/, research/, ...) stays ignored.');
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
catch {
|
|
957
|
+
// .gitignore management is best-effort; don't fail the scaffold
|
|
958
|
+
}
|
|
959
|
+
// #1235 / #1758 — auto-rebuild the project graph and refresh the
|
|
960
|
+
// Fortemi Core static cache so the new bundle is immediately
|
|
961
|
+
// discoverable via top-level `aiwg discover` / `aiwg show`.
|
|
962
|
+
// Best-effort: don't fail the scaffold if indexing hiccups.
|
|
963
|
+
let indexedOk = false;
|
|
964
|
+
let fortemiSyncedOk = false;
|
|
965
|
+
try {
|
|
966
|
+
const { buildIndex } = await import('../../artifacts/index-builder.js');
|
|
967
|
+
await buildIndex(ctx.cwd, { graph: 'project', force: false, explicit: true });
|
|
968
|
+
indexedOk = true;
|
|
969
|
+
const { syncFortemiCoreIndex } = await import('../../artifacts/fortemi-core-sync.js');
|
|
970
|
+
syncFortemiCoreIndex(ctx.cwd, { graph: 'project' });
|
|
971
|
+
fortemiSyncedOk = true;
|
|
972
|
+
}
|
|
973
|
+
catch {
|
|
974
|
+
// ignore — surface via next-steps hint instead
|
|
975
|
+
}
|
|
976
|
+
console.log('');
|
|
977
|
+
console.log('Next steps:');
|
|
978
|
+
console.log(` 1. Edit manifest.json (description, version, keywords)`);
|
|
979
|
+
console.log(` 2. Customize the starter artifact under ${result.bundlePath}/`);
|
|
980
|
+
if (indexedOk && fortemiSyncedOk) {
|
|
981
|
+
console.log(` 3. Discoverable now via: aiwg discover "${positional}"`);
|
|
982
|
+
}
|
|
983
|
+
else if (indexedOk) {
|
|
984
|
+
console.log(` 3. Sync project search cache: aiwg index sync --graph project`);
|
|
985
|
+
console.log(` then: aiwg discover "${positional}"`);
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
console.log(` 3. Rebuild project index: aiwg index build --graph project`);
|
|
989
|
+
console.log(` then sync search cache: aiwg index sync --graph project`);
|
|
990
|
+
console.log(` then: aiwg discover "${positional}"`);
|
|
991
|
+
}
|
|
992
|
+
console.log(` 4. Deploy: aiwg use ${positional}`);
|
|
993
|
+
console.log(` 5. Inspect: aiwg doctor --project-local`);
|
|
994
|
+
console.log(` 6. When mature, promote: aiwg promote ${positional}`);
|
|
995
|
+
return { exitCode: 0 };
|
|
996
|
+
}
|
|
997
|
+
catch (err) {
|
|
998
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
999
|
+
return { exitCode: 1, message: `Error: ${msg}` };
|
|
1000
|
+
}
|
|
1001
|
+
},
|
|
1002
|
+
};
|
|
1003
|
+
/**
|
|
1004
|
+
* New project handler
|
|
1005
|
+
*
|
|
1006
|
+
* Delegates to tools/install/new-project.mjs
|
|
1007
|
+
*/
|
|
1008
|
+
export const newProjectHandler = {
|
|
1009
|
+
id: "new",
|
|
1010
|
+
name: "New Project",
|
|
1011
|
+
description: "Scaffold a new project with AIWG",
|
|
1012
|
+
category: "project",
|
|
1013
|
+
aliases: ["-new", "--new"],
|
|
1014
|
+
async execute(ctx) {
|
|
1015
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1016
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1017
|
+
const result = await runner.run("tools/install/new-project.mjs", ctx.args, {
|
|
1018
|
+
cwd: ctx.cwd,
|
|
1019
|
+
});
|
|
1020
|
+
if (result.exitCode === 0) {
|
|
1021
|
+
// The real scaffolder always runs in an existing target directory. Keep
|
|
1022
|
+
// mocked/script-runner-only calls side-effect free when their synthetic
|
|
1023
|
+
// cwd does not exist.
|
|
1024
|
+
const { access } = await import('node:fs/promises');
|
|
1025
|
+
const { constants } = await import('node:fs');
|
|
1026
|
+
try {
|
|
1027
|
+
await access(ctx.cwd, constants.W_OK);
|
|
1028
|
+
const { ensureWorkspaceContext } = await import('../../smiths/context-pipeline/workspace-context.js');
|
|
1029
|
+
await ensureWorkspaceContext(ctx.cwd);
|
|
1030
|
+
}
|
|
1031
|
+
catch (error) {
|
|
1032
|
+
if (!['ENOENT', 'EACCES'].includes(error.code ?? ''))
|
|
1033
|
+
throw error;
|
|
1034
|
+
}
|
|
1035
|
+
const { formatStarNudge } = await import("../../community/links.js");
|
|
1036
|
+
const { markNudgeShown, shouldShowNudge } = await import("../../community/nudge-policy.js");
|
|
1037
|
+
if (shouldShowNudge('intake')) {
|
|
1038
|
+
const nudge = formatStarNudge();
|
|
1039
|
+
if (nudge) {
|
|
1040
|
+
console.log('');
|
|
1041
|
+
console.log(nudge);
|
|
1042
|
+
markNudgeShown('intake');
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
return result;
|
|
1047
|
+
},
|
|
1048
|
+
};
|
|
1049
|
+
/**
|
|
1050
|
+
* Install plugin handler
|
|
1051
|
+
*
|
|
1052
|
+
* Delegates to tools/plugin/plugin-installer-cli.mjs
|
|
1053
|
+
*/
|
|
1054
|
+
export const installPluginHandler = {
|
|
1055
|
+
id: "install-plugin",
|
|
1056
|
+
name: "Install Plugin",
|
|
1057
|
+
description: "Install a plugin from the registry",
|
|
1058
|
+
category: "plugin",
|
|
1059
|
+
aliases: ["-install-plugin", "--install-plugin"],
|
|
1060
|
+
async execute(ctx) {
|
|
1061
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1062
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1063
|
+
return runner.run("tools/plugin/plugin-installer-cli.mjs", ctx.args, {
|
|
1064
|
+
cwd: ctx.cwd,
|
|
1065
|
+
});
|
|
1066
|
+
},
|
|
1067
|
+
};
|
|
1068
|
+
/**
|
|
1069
|
+
* Uninstall plugin handler
|
|
1070
|
+
*
|
|
1071
|
+
* Delegates to tools/plugin/plugin-uninstaller-cli.mjs
|
|
1072
|
+
*/
|
|
1073
|
+
export const uninstallPluginHandler = {
|
|
1074
|
+
id: "uninstall-plugin",
|
|
1075
|
+
name: "Uninstall Plugin",
|
|
1076
|
+
description: "Uninstall a plugin",
|
|
1077
|
+
category: "plugin",
|
|
1078
|
+
aliases: ["-uninstall-plugin", "--uninstall-plugin"],
|
|
1079
|
+
async execute(ctx) {
|
|
1080
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1081
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1082
|
+
return runner.run("tools/plugin/plugin-uninstaller-cli.mjs", ctx.args, {
|
|
1083
|
+
cwd: ctx.cwd,
|
|
1084
|
+
});
|
|
1085
|
+
},
|
|
1086
|
+
};
|
|
1087
|
+
/**
|
|
1088
|
+
* Plugin status handler
|
|
1089
|
+
*
|
|
1090
|
+
* Delegates to tools/plugin/plugin-status-cli.mjs
|
|
1091
|
+
*/
|
|
1092
|
+
export const pluginStatusHandler = {
|
|
1093
|
+
id: "plugin-status",
|
|
1094
|
+
name: "Plugin Status",
|
|
1095
|
+
description: "Show plugin status and installation details",
|
|
1096
|
+
category: "plugin",
|
|
1097
|
+
aliases: ["-plugin-status", "--plugin-status"],
|
|
1098
|
+
async execute(ctx) {
|
|
1099
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1100
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1101
|
+
return runner.run("tools/plugin/plugin-status-cli.mjs", ctx.args, {
|
|
1102
|
+
cwd: ctx.cwd,
|
|
1103
|
+
});
|
|
1104
|
+
},
|
|
1105
|
+
};
|
|
1106
|
+
/**
|
|
1107
|
+
* Package plugin handler
|
|
1108
|
+
*
|
|
1109
|
+
* Delegates to tools/plugin/package-plugins.mjs
|
|
1110
|
+
*/
|
|
1111
|
+
export const packagePluginHandler = {
|
|
1112
|
+
id: "package-plugin",
|
|
1113
|
+
name: "Package Plugin",
|
|
1114
|
+
description: "Package a plugin for distribution",
|
|
1115
|
+
category: "plugin",
|
|
1116
|
+
aliases: ["-package-plugin", "--package-plugin"],
|
|
1117
|
+
async execute(ctx) {
|
|
1118
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1119
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1120
|
+
return runner.run("tools/plugin/package-plugins.mjs", ctx.args, {
|
|
1121
|
+
cwd: ctx.cwd,
|
|
1122
|
+
});
|
|
1123
|
+
},
|
|
1124
|
+
};
|
|
1125
|
+
/**
|
|
1126
|
+
* Package all plugins handler
|
|
1127
|
+
*
|
|
1128
|
+
* Delegates to tools/plugin/package-plugins.mjs with --all flag
|
|
1129
|
+
*/
|
|
1130
|
+
export const packageAllPluginsHandler = {
|
|
1131
|
+
id: "package-all-plugins",
|
|
1132
|
+
name: "Package All Plugins",
|
|
1133
|
+
description: "Package all plugins for distribution",
|
|
1134
|
+
category: "plugin",
|
|
1135
|
+
aliases: ["-package-all-plugins", "--package-all-plugins"],
|
|
1136
|
+
async execute(ctx) {
|
|
1137
|
+
const frameworkRoot = await getFrameworkRoot();
|
|
1138
|
+
const runner = createScriptRunner(frameworkRoot);
|
|
1139
|
+
return runner.run("tools/plugin/package-plugins.mjs", ["--all", ...ctx.args], {
|
|
1140
|
+
cwd: ctx.cwd,
|
|
1141
|
+
});
|
|
1142
|
+
},
|
|
1143
|
+
};
|
|
1144
|
+
/**
|
|
1145
|
+
* Artifact index command handler
|
|
1146
|
+
*
|
|
1147
|
+
* Dynamically imports and delegates to src/artifacts/cli.mjs.
|
|
1148
|
+
* Handles subcommands: build, query, deps, stats
|
|
1149
|
+
*
|
|
1150
|
+
* @implements #420
|
|
1151
|
+
*/
|
|
1152
|
+
export const indexHandler = {
|
|
1153
|
+
id: "index",
|
|
1154
|
+
name: "Artifact Index",
|
|
1155
|
+
description: "Artifact index commands (build, query, deps, stats)",
|
|
1156
|
+
category: "index",
|
|
1157
|
+
aliases: [],
|
|
1158
|
+
async execute(ctx) {
|
|
1159
|
+
try {
|
|
1160
|
+
const { main } = await import("../../artifacts/cli.js");
|
|
1161
|
+
await main(ctx.args);
|
|
1162
|
+
return {
|
|
1163
|
+
exitCode: 0,
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
catch (error) {
|
|
1167
|
+
const result = handlerResultFromError(error);
|
|
1168
|
+
return { ...result, message: `Index command failed: ${result.message}` };
|
|
1169
|
+
}
|
|
1170
|
+
},
|
|
1171
|
+
};
|
|
1172
|
+
/**
|
|
1173
|
+
* `aiwg corpus` — research-corpus tools (radar/freshness subsystem, #1498).
|
|
1174
|
+
* Delegates to the corpus-tools router, mirroring indexHandler.
|
|
1175
|
+
*/
|
|
1176
|
+
export const corpusHandler = {
|
|
1177
|
+
id: "corpus",
|
|
1178
|
+
name: "Research Corpus Tools",
|
|
1179
|
+
description: "Research-corpus tools (radar-init, radar-status, radar-report)",
|
|
1180
|
+
category: "index",
|
|
1181
|
+
aliases: [],
|
|
1182
|
+
async execute(ctx) {
|
|
1183
|
+
try {
|
|
1184
|
+
const { corpusMain } = await import("../../artifacts/corpus-tools/cli.js");
|
|
1185
|
+
await corpusMain(ctx.args, ctx.cwd);
|
|
1186
|
+
return { exitCode: 0 };
|
|
1187
|
+
}
|
|
1188
|
+
catch (error) {
|
|
1189
|
+
const result = handlerResultFromError(error);
|
|
1190
|
+
return { ...result, message: `Corpus command failed: ${result.message}` };
|
|
1191
|
+
}
|
|
1192
|
+
},
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Discovery command handler — first-class top-level verb (#1212).
|
|
1196
|
+
*
|
|
1197
|
+
* Forwards to the same implementation as `aiwg index discover` but
|
|
1198
|
+
* exposes discovery as its own command so agents don't conflate it
|
|
1199
|
+
* with the project's general-purpose artifact graph indices.
|
|
1200
|
+
*
|
|
1201
|
+
* aiwg discover "<phrase>" [--limit N] [--type skill,agent,...] [--json]
|
|
1202
|
+
* [--resource-source local|web|auto] [--aiwg-version <exact-or-channel>] [--offline]
|
|
1203
|
+
*/
|
|
1204
|
+
export const discoverHandler = {
|
|
1205
|
+
id: "discover",
|
|
1206
|
+
name: "Discover",
|
|
1207
|
+
description: "Find AIWG operational assets by capability — index-driven on-demand discovery",
|
|
1208
|
+
category: "index",
|
|
1209
|
+
aliases: [],
|
|
1210
|
+
async execute(ctx) {
|
|
1211
|
+
try {
|
|
1212
|
+
// Delegate to the same handler `aiwg index discover` uses, by
|
|
1213
|
+
// prepending the `discover` subcommand and reusing the artifacts
|
|
1214
|
+
// CLI router. This keeps a single implementation path.
|
|
1215
|
+
const { main } = await import("../../artifacts/cli.js");
|
|
1216
|
+
await main(["discover", ...ctx.args]);
|
|
1217
|
+
return { exitCode: 0 };
|
|
1218
|
+
}
|
|
1219
|
+
catch (error) {
|
|
1220
|
+
const result = handlerResultFromError(error);
|
|
1221
|
+
return { ...result, message: `Discover command failed: ${result.message}` };
|
|
1222
|
+
}
|
|
1223
|
+
},
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* Features command handler — manage AIWG's optional runtime features (#1219).
|
|
1227
|
+
*
|
|
1228
|
+
* Subcommands: status / info / install / remove. Native feature installs use
|
|
1229
|
+
* a user-owned package root with explicit package-level script approval.
|
|
1230
|
+
*/
|
|
1231
|
+
export const featuresHandler = {
|
|
1232
|
+
id: "features",
|
|
1233
|
+
name: "Features",
|
|
1234
|
+
description: "List, inspect, and install AIWG's optional runtime features",
|
|
1235
|
+
category: "maintenance",
|
|
1236
|
+
aliases: [],
|
|
1237
|
+
async execute(ctx) {
|
|
1238
|
+
try {
|
|
1239
|
+
const { main } = await import("../../features/cli.js");
|
|
1240
|
+
await main(ctx.args);
|
|
1241
|
+
return { exitCode: 0 };
|
|
1242
|
+
}
|
|
1243
|
+
catch (error) {
|
|
1244
|
+
const result = handlerResultFromError(error);
|
|
1245
|
+
return { ...result, message: `Features command failed: ${result.message}` };
|
|
1246
|
+
}
|
|
1247
|
+
},
|
|
1248
|
+
};
|
|
1249
|
+
/**
|
|
1250
|
+
* Show command handler — fetch the full text of a specific artifact (#1218).
|
|
1251
|
+
*
|
|
1252
|
+
* Forwards to the same implementation as `aiwg index show`. Companion to
|
|
1253
|
+
* `aiwg discover`: where discover ranks candidates, show fetches the body
|
|
1254
|
+
* so consumers don't need to navigate AIWG's storage paths themselves.
|
|
1255
|
+
*
|
|
1256
|
+
* aiwg show <name> [--type skill,agent,...] [--json] [--first]
|
|
1257
|
+
* [--resource-source local|web|auto] [--aiwg-version <exact-or-channel>] [--offline]
|
|
1258
|
+
*/
|
|
1259
|
+
export const showHandler = {
|
|
1260
|
+
id: "show",
|
|
1261
|
+
name: "Show",
|
|
1262
|
+
description: "Print the full text of a specific AIWG skill, agent, command, or rule by name",
|
|
1263
|
+
category: "index",
|
|
1264
|
+
aliases: [],
|
|
1265
|
+
async execute(ctx) {
|
|
1266
|
+
try {
|
|
1267
|
+
const { main } = await import("../../artifacts/cli.js");
|
|
1268
|
+
await main(["show", ...ctx.args]);
|
|
1269
|
+
return { exitCode: 0 };
|
|
1270
|
+
}
|
|
1271
|
+
catch (error) {
|
|
1272
|
+
const result = handlerResultFromError(error);
|
|
1273
|
+
return { ...result, message: `Show command failed: ${result.message}` };
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
};
|
|
1277
|
+
/**
|
|
1278
|
+
* Skills command handler
|
|
1279
|
+
*
|
|
1280
|
+
* Dynamically imports and delegates to src/skills/cli.ts.
|
|
1281
|
+
* Handles subcommands: search, info, list, install, publish
|
|
1282
|
+
*
|
|
1283
|
+
* @implements #539
|
|
1284
|
+
*/
|
|
1285
|
+
export const skillsHandler = {
|
|
1286
|
+
id: "skills",
|
|
1287
|
+
name: "Skills Registry",
|
|
1288
|
+
description: "Skill commands (search, info, list, install, publish)",
|
|
1289
|
+
category: "catalog",
|
|
1290
|
+
aliases: [],
|
|
1291
|
+
async execute(ctx) {
|
|
1292
|
+
try {
|
|
1293
|
+
const { main } = await import("../../skills/cli.js");
|
|
1294
|
+
await main(ctx.args);
|
|
1295
|
+
return {
|
|
1296
|
+
exitCode: 0,
|
|
1297
|
+
};
|
|
1298
|
+
}
|
|
1299
|
+
catch (error) {
|
|
1300
|
+
const result = handlerResultFromError(error);
|
|
1301
|
+
return { ...result, message: `Skills command failed: ${result.message}` };
|
|
1302
|
+
}
|
|
1303
|
+
},
|
|
1304
|
+
};
|
|
1305
|
+
/**
|
|
1306
|
+
* Config command handler
|
|
1307
|
+
*
|
|
1308
|
+
* Dynamically imports and delegates to src/config/cli.ts.
|
|
1309
|
+
* Handles subcommands: get, set, list, validate, reset, path, edit
|
|
1310
|
+
*
|
|
1311
|
+
* @implements #545
|
|
1312
|
+
*/
|
|
1313
|
+
export const configHandler = {
|
|
1314
|
+
id: "config",
|
|
1315
|
+
name: "Config",
|
|
1316
|
+
description: "User config commands (get, set, list, validate, reset, path, edit)",
|
|
1317
|
+
category: "config",
|
|
1318
|
+
aliases: [],
|
|
1319
|
+
async execute(ctx) {
|
|
1320
|
+
try {
|
|
1321
|
+
const { main } = await import("../../config/cli.js");
|
|
1322
|
+
await main(ctx.args);
|
|
1323
|
+
return {
|
|
1324
|
+
exitCode: 0,
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
catch (error) {
|
|
1328
|
+
const result = handlerResultFromError(error);
|
|
1329
|
+
return { ...result, message: `Config command failed: ${result.message}` };
|
|
1330
|
+
}
|
|
1331
|
+
},
|
|
1332
|
+
};
|
|
1333
|
+
/**
|
|
1334
|
+
* Ops command handler
|
|
1335
|
+
*
|
|
1336
|
+
* Dynamically imports and delegates to src/ops/cli.ts.
|
|
1337
|
+
* Handles subcommands: init, status, use, list, push
|
|
1338
|
+
*
|
|
1339
|
+
* @implements #544
|
|
1340
|
+
*/
|
|
1341
|
+
export const opsHandler = {
|
|
1342
|
+
id: "ops",
|
|
1343
|
+
name: "Ops",
|
|
1344
|
+
description: "Ops ecosystem commands (init, status, use, list, push)",
|
|
1345
|
+
category: "ops",
|
|
1346
|
+
aliases: [],
|
|
1347
|
+
async execute(ctx) {
|
|
1348
|
+
try {
|
|
1349
|
+
const { main } = await import("../../ops/cli.js");
|
|
1350
|
+
await main(ctx.args);
|
|
1351
|
+
return {
|
|
1352
|
+
exitCode: 0,
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
catch (error) {
|
|
1356
|
+
const result = handlerResultFromError(error);
|
|
1357
|
+
return { ...result, message: `Ops command failed: ${result.message}` };
|
|
1358
|
+
}
|
|
1359
|
+
},
|
|
1360
|
+
};
|
|
1361
|
+
/**
|
|
1362
|
+
* Activity-log command handler
|
|
1363
|
+
*
|
|
1364
|
+
* Dynamically imports and delegates to src/activity-log/cli.ts.
|
|
1365
|
+
* Handles subcommands: show, append, stats. Persistence routes through
|
|
1366
|
+
* resolveStorage('activity_log') so the log honors any storage.config
|
|
1367
|
+
* override (#934).
|
|
1368
|
+
*
|
|
1369
|
+
* @implements #934
|
|
1370
|
+
* @implements #964
|
|
1371
|
+
*/
|
|
1372
|
+
export const activityLogHandler = {
|
|
1373
|
+
id: 'activity-log',
|
|
1374
|
+
name: 'Activity Log',
|
|
1375
|
+
description: 'Query and manage .aiwg/activity.log (show, append, stats)',
|
|
1376
|
+
category: 'utility',
|
|
1377
|
+
aliases: [],
|
|
1378
|
+
async execute(ctx) {
|
|
1379
|
+
try {
|
|
1380
|
+
const { main } = await import('../../activity-log/cli.js');
|
|
1381
|
+
await main(ctx.args);
|
|
1382
|
+
return { exitCode: 0 };
|
|
1383
|
+
}
|
|
1384
|
+
catch (error) {
|
|
1385
|
+
const result = handlerResultFromError(error);
|
|
1386
|
+
return { ...result, message: `activity-log command failed: ${result.message}` };
|
|
1387
|
+
}
|
|
1388
|
+
},
|
|
1389
|
+
};
|
|
1390
|
+
/**
|
|
1391
|
+
* Provenance command handler — routes \`aiwg provenance\` through
|
|
1392
|
+
* resolveStorage('provenance') for provenance-* skills (#968).
|
|
1393
|
+
*
|
|
1394
|
+
* @implements #934
|
|
1395
|
+
* @implements #968
|
|
1396
|
+
*/
|
|
1397
|
+
export const provenanceHandler = {
|
|
1398
|
+
id: 'provenance',
|
|
1399
|
+
name: 'Provenance',
|
|
1400
|
+
description: 'Provenance subsystem storage operations (path, list, get, put, delete, append-log)',
|
|
1401
|
+
category: 'utility',
|
|
1402
|
+
aliases: [],
|
|
1403
|
+
async execute(ctx) {
|
|
1404
|
+
try {
|
|
1405
|
+
const { main } = await import('../../provenance/cli.js');
|
|
1406
|
+
await main(ctx.args);
|
|
1407
|
+
return { exitCode: 0 };
|
|
1408
|
+
}
|
|
1409
|
+
catch (error) {
|
|
1410
|
+
const result = handlerResultFromError(error);
|
|
1411
|
+
return { ...result, message: `provenance command failed: ${result.message}` };
|
|
1412
|
+
}
|
|
1413
|
+
},
|
|
1414
|
+
};
|
|
1415
|
+
/**
|
|
1416
|
+
* Research storage command handler — routes \`aiwg research-store\`
|
|
1417
|
+
* through resolveStorage('research') for research-acquire / corpus-*
|
|
1418
|
+
* skills (#968). Disambiguated from existing research-* workflow
|
|
1419
|
+
* commands by the \`-store\` suffix.
|
|
1420
|
+
*
|
|
1421
|
+
* @implements #934
|
|
1422
|
+
* @implements #968
|
|
1423
|
+
*/
|
|
1424
|
+
export const researchStoreHandler = {
|
|
1425
|
+
id: 'research-store',
|
|
1426
|
+
name: 'Research Store',
|
|
1427
|
+
description: 'Research subsystem storage operations (path, list, get, put, delete, append-log)',
|
|
1428
|
+
category: 'utility',
|
|
1429
|
+
aliases: [],
|
|
1430
|
+
async execute(ctx) {
|
|
1431
|
+
try {
|
|
1432
|
+
const { main } = await import('../../research/storage-cli.js');
|
|
1433
|
+
await main(ctx.args);
|
|
1434
|
+
return { exitCode: 0 };
|
|
1435
|
+
}
|
|
1436
|
+
catch (error) {
|
|
1437
|
+
const result = handlerResultFromError(error);
|
|
1438
|
+
return { ...result, message: `research-store command failed: ${result.message}` };
|
|
1439
|
+
}
|
|
1440
|
+
},
|
|
1441
|
+
};
|
|
1442
|
+
/** Executable source-selection companion to the research-query skill. */
|
|
1443
|
+
export const researchQueryHandler = {
|
|
1444
|
+
id: 'research-query',
|
|
1445
|
+
name: 'Research Query',
|
|
1446
|
+
description: 'Select research sources for a question with local or Fortemi Core retrieval',
|
|
1447
|
+
category: 'index',
|
|
1448
|
+
aliases: [],
|
|
1449
|
+
async execute(ctx) {
|
|
1450
|
+
try {
|
|
1451
|
+
const { main } = await import('../../research/query-cli.js');
|
|
1452
|
+
await main(ctx.args, ctx.cwd);
|
|
1453
|
+
return { exitCode: 0 };
|
|
1454
|
+
}
|
|
1455
|
+
catch (error) {
|
|
1456
|
+
const result = handlerResultFromError(error);
|
|
1457
|
+
return { ...result, message: `research-query command failed: ${result.message}` };
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1460
|
+
};
|
|
1461
|
+
/**
|
|
1462
|
+
* Reflections command handler
|
|
1463
|
+
*
|
|
1464
|
+
* Routes \`aiwg reflections <subcommand>\` through resolveStorage('reflections')
|
|
1465
|
+
* for ralph-reflect / reflection-injection skills (#967).
|
|
1466
|
+
*
|
|
1467
|
+
* @implements #934
|
|
1468
|
+
* @implements #967
|
|
1469
|
+
*/
|
|
1470
|
+
export const reflectionsHandler = {
|
|
1471
|
+
id: 'reflections',
|
|
1472
|
+
name: 'Reflections',
|
|
1473
|
+
description: 'Reflections subsystem storage operations (path, list, get, put, delete, append-log)',
|
|
1474
|
+
category: 'utility',
|
|
1475
|
+
aliases: [],
|
|
1476
|
+
async execute(ctx) {
|
|
1477
|
+
try {
|
|
1478
|
+
const { main } = await import('../../reflections/cli.js');
|
|
1479
|
+
await main(ctx.args);
|
|
1480
|
+
return { exitCode: 0 };
|
|
1481
|
+
}
|
|
1482
|
+
catch (error) {
|
|
1483
|
+
const result = handlerResultFromError(error);
|
|
1484
|
+
return { ...result, message: `reflections command failed: ${result.message}` };
|
|
1485
|
+
}
|
|
1486
|
+
},
|
|
1487
|
+
};
|
|
1488
|
+
/**
|
|
1489
|
+
* Memory command handler
|
|
1490
|
+
*
|
|
1491
|
+
* Routes \`aiwg memory <subcommand>\` through resolveStorage('memory') so
|
|
1492
|
+
* the four memory skills (memory-ingest, memory-lint, memory-log-append,
|
|
1493
|
+
* memory-query-capture) honor any storage.config redirection.
|
|
1494
|
+
*
|
|
1495
|
+
* @implements #934
|
|
1496
|
+
* @implements #966
|
|
1497
|
+
*/
|
|
1498
|
+
export const memoryHandler = {
|
|
1499
|
+
id: 'memory',
|
|
1500
|
+
name: 'Memory',
|
|
1501
|
+
description: 'Memory subsystem storage operations (path, list, get, put, delete, append-log)',
|
|
1502
|
+
category: 'utility',
|
|
1503
|
+
aliases: [],
|
|
1504
|
+
async execute(ctx) {
|
|
1505
|
+
try {
|
|
1506
|
+
const { main } = await import('../../memory/cli.js');
|
|
1507
|
+
await main(ctx.args);
|
|
1508
|
+
return { exitCode: 0 };
|
|
1509
|
+
}
|
|
1510
|
+
catch (error) {
|
|
1511
|
+
const result = handlerResultFromError(error);
|
|
1512
|
+
return { ...result, message: `memory command failed: ${result.message}` };
|
|
1513
|
+
}
|
|
1514
|
+
},
|
|
1515
|
+
};
|
|
1516
|
+
/**
|
|
1517
|
+
* Knowledge-base command handler
|
|
1518
|
+
*
|
|
1519
|
+
* Routes \`aiwg kb <subcommand>\` through resolveStorage('kb') so the KB
|
|
1520
|
+
* honors any storage.config redirection without each kb skill
|
|
1521
|
+
* hardcoding `.aiwg/kb/`.
|
|
1522
|
+
*
|
|
1523
|
+
* @implements #934
|
|
1524
|
+
* @implements #965
|
|
1525
|
+
*/
|
|
1526
|
+
export const kbHandler = {
|
|
1527
|
+
id: 'kb',
|
|
1528
|
+
name: 'Knowledge Base',
|
|
1529
|
+
description: 'Knowledge base storage operations (path, list, get, put, delete)',
|
|
1530
|
+
category: 'utility',
|
|
1531
|
+
aliases: [],
|
|
1532
|
+
async execute(ctx) {
|
|
1533
|
+
try {
|
|
1534
|
+
const { main } = await import('../../kb/cli.js');
|
|
1535
|
+
await main(ctx.args);
|
|
1536
|
+
return { exitCode: 0 };
|
|
1537
|
+
}
|
|
1538
|
+
catch (error) {
|
|
1539
|
+
const result = handlerResultFromError(error);
|
|
1540
|
+
return { ...result, message: `kb command failed: ${result.message}` };
|
|
1541
|
+
}
|
|
1542
|
+
},
|
|
1543
|
+
};
|
|
1544
|
+
/**
|
|
1545
|
+
* Storage command handler
|
|
1546
|
+
*
|
|
1547
|
+
* Dynamically imports and delegates to src/storage/cli.ts.
|
|
1548
|
+
* Handles subcommands: show, list-backends, test
|
|
1549
|
+
*
|
|
1550
|
+
* @implements #934
|
|
1551
|
+
* @implements #954
|
|
1552
|
+
*/
|
|
1553
|
+
export const storageHandler = {
|
|
1554
|
+
id: 'storage',
|
|
1555
|
+
name: 'Storage',
|
|
1556
|
+
description: 'Storage adapter commands (show, list-backends, test)',
|
|
1557
|
+
category: 'utility',
|
|
1558
|
+
aliases: [],
|
|
1559
|
+
async execute(ctx) {
|
|
1560
|
+
try {
|
|
1561
|
+
const { main } = await import('../../storage/cli.js');
|
|
1562
|
+
await main(ctx.args);
|
|
1563
|
+
return { exitCode: 0 };
|
|
1564
|
+
}
|
|
1565
|
+
catch (error) {
|
|
1566
|
+
const result = handlerResultFromError(error);
|
|
1567
|
+
return { ...result, message: `Storage command failed: ${result.message}` };
|
|
1568
|
+
}
|
|
1569
|
+
},
|
|
1570
|
+
};
|
|
1571
|
+
/**
|
|
1572
|
+
* RLM agentic tools handler
|
|
1573
|
+
*
|
|
1574
|
+
* Routes `aiwg chunk`, `aiwg fanout`, `aiwg rlm-prep`, `aiwg rlm-search`,
|
|
1575
|
+
* and `aiwg rlm-status` to src/rlm/cli.ts.
|
|
1576
|
+
*
|
|
1577
|
+
* These are support tools for agentic sessions — callable by users but
|
|
1578
|
+
* primarily used by RLM agents during recursive and fanout operations.
|
|
1579
|
+
*
|
|
1580
|
+
* @implements #559
|
|
1581
|
+
*/
|
|
1582
|
+
export const rlmToolsHandler = {
|
|
1583
|
+
id: 'rlm-tools',
|
|
1584
|
+
name: 'RLM Tools',
|
|
1585
|
+
description: 'Agentic support tools for RLM operations (chunk, fanout, rlm-prep, rlm-search, rlm-status)',
|
|
1586
|
+
category: 'agentic-tools',
|
|
1587
|
+
aliases: [],
|
|
1588
|
+
async execute(ctx) {
|
|
1589
|
+
try {
|
|
1590
|
+
const { main } = await import('../../rlm/cli.js');
|
|
1591
|
+
await main(ctx.args);
|
|
1592
|
+
return {
|
|
1593
|
+
exitCode: 0,
|
|
1594
|
+
};
|
|
1595
|
+
}
|
|
1596
|
+
catch (error) {
|
|
1597
|
+
const result = handlerResultFromError(error);
|
|
1598
|
+
return { ...result, message: `RLM tools command failed: ${result.message}` };
|
|
1599
|
+
}
|
|
1600
|
+
},
|
|
1601
|
+
};
|
|
1602
|
+
// Individual handlers that delegate to rlmToolsHandler with their command prepended
|
|
1603
|
+
export const chunkHandler = {
|
|
1604
|
+
id: 'chunk',
|
|
1605
|
+
name: 'Chunk',
|
|
1606
|
+
description: 'Split a file into overlapping chunks for parallel fanout processing',
|
|
1607
|
+
category: 'agentic-tools',
|
|
1608
|
+
aliases: [],
|
|
1609
|
+
async execute(ctx) {
|
|
1610
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['chunk', ...ctx.args] });
|
|
1611
|
+
},
|
|
1612
|
+
};
|
|
1613
|
+
export const fanoutHandler = {
|
|
1614
|
+
id: 'fanout',
|
|
1615
|
+
name: 'Fanout',
|
|
1616
|
+
description: 'Dispatch parallel subagent queries across a chunk manifest',
|
|
1617
|
+
category: 'agentic-tools',
|
|
1618
|
+
aliases: [],
|
|
1619
|
+
async execute(ctx) {
|
|
1620
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['fanout', ...ctx.args] });
|
|
1621
|
+
},
|
|
1622
|
+
};
|
|
1623
|
+
export const rlmPrepHandler = {
|
|
1624
|
+
id: 'rlm-prep',
|
|
1625
|
+
name: 'RLM Prep',
|
|
1626
|
+
description: 'Prepare source content for RLM processing (chunk + index + manifest)',
|
|
1627
|
+
category: 'agentic-tools',
|
|
1628
|
+
aliases: [],
|
|
1629
|
+
async execute(ctx) {
|
|
1630
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['rlm-prep', ...ctx.args] });
|
|
1631
|
+
},
|
|
1632
|
+
};
|
|
1633
|
+
export const rlmSearchHandler = {
|
|
1634
|
+
id: 'rlm-search',
|
|
1635
|
+
name: 'RLM Search',
|
|
1636
|
+
description: 'Full recursive search pipeline: decompose source, fanout query, synthesize results',
|
|
1637
|
+
category: 'agentic-tools',
|
|
1638
|
+
aliases: [],
|
|
1639
|
+
async execute(ctx) {
|
|
1640
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['rlm-search', ...ctx.args] });
|
|
1641
|
+
},
|
|
1642
|
+
};
|
|
1643
|
+
export const rlmStatusCliHandler = {
|
|
1644
|
+
id: 'rlm-status',
|
|
1645
|
+
name: 'RLM Status',
|
|
1646
|
+
description: 'Show active RLM task tree, progress, and cost breakdown',
|
|
1647
|
+
category: 'agentic-tools',
|
|
1648
|
+
aliases: [],
|
|
1649
|
+
async execute(ctx) {
|
|
1650
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['rlm-status', ...ctx.args] });
|
|
1651
|
+
},
|
|
1652
|
+
};
|
|
1653
|
+
/** RLM result cache (#1203). */
|
|
1654
|
+
export const rlmCacheHandler = {
|
|
1655
|
+
id: 'rlm-cache',
|
|
1656
|
+
name: 'RLM Cache',
|
|
1657
|
+
description: 'Manage cached RLM results (list, stats, evict, clear) — keyed by index content-hash',
|
|
1658
|
+
category: 'agentic-tools',
|
|
1659
|
+
aliases: [],
|
|
1660
|
+
async execute(ctx) {
|
|
1661
|
+
return rlmToolsHandler.execute({ ...ctx, args: ['rlm-cache', ...ctx.args] });
|
|
1662
|
+
},
|
|
1663
|
+
};
|
|
1664
|
+
/**
|
|
1665
|
+
* All subcommand handlers
|
|
1666
|
+
*/
|
|
1667
|
+
export const subcommandHandlers = [
|
|
1668
|
+
mcpHandler,
|
|
1669
|
+
catalogHandler,
|
|
1670
|
+
listHandler,
|
|
1671
|
+
removeHandler,
|
|
1672
|
+
newProjectHandler,
|
|
1673
|
+
installPluginHandler,
|
|
1674
|
+
uninstallPluginHandler,
|
|
1675
|
+
pluginStatusHandler,
|
|
1676
|
+
packagePluginHandler,
|
|
1677
|
+
packageAllPluginsHandler,
|
|
1678
|
+
indexHandler,
|
|
1679
|
+
discoverHandler,
|
|
1680
|
+
showHandler,
|
|
1681
|
+
featuresHandler,
|
|
1682
|
+
skillsHandler,
|
|
1683
|
+
configHandler,
|
|
1684
|
+
opsHandler,
|
|
1685
|
+
storageHandler,
|
|
1686
|
+
activityLogHandler,
|
|
1687
|
+
kbHandler,
|
|
1688
|
+
memoryHandler,
|
|
1689
|
+
reflectionsHandler,
|
|
1690
|
+
provenanceHandler,
|
|
1691
|
+
researchStoreHandler,
|
|
1692
|
+
researchQueryHandler,
|
|
1693
|
+
chunkHandler,
|
|
1694
|
+
fanoutHandler,
|
|
1695
|
+
rlmPrepHandler,
|
|
1696
|
+
rlmSearchHandler,
|
|
1697
|
+
rlmStatusCliHandler,
|
|
1698
|
+
rlmCacheHandler,
|
|
1699
|
+
sessionHandler,
|
|
1700
|
+
feedbackHandler,
|
|
1701
|
+
];
|
|
1702
|
+
//# sourceMappingURL=subcommands.js.map
|