@aiwg/cli 0.0.0-bootstrap.0 → 2026.7.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/bin/aiwg.mjs +349 -0
- package/dist/src/a2a/agent-card.js +145 -0
- package/dist/src/a2a/client.js +411 -0
- package/dist/src/a2a/hitl-cli.js +171 -0
- package/dist/src/a2a/hitl-driver.js +370 -0
- package/dist/src/a2a/hitl.js +181 -0
- package/dist/src/a2a/http.js +193 -0
- package/dist/src/a2a/jcs.js +128 -0
- package/dist/src/a2a/jws.js +187 -0
- package/dist/src/a2a/types.js +24 -0
- package/dist/src/a2a/webhook.js +240 -0
- package/dist/src/activity-log/cli.js +348 -0
- package/dist/src/activity-log/parser.js +81 -0
- package/dist/src/activity-log/types.js +50 -0
- package/dist/src/agents/agent-deployer.js +367 -0
- package/dist/src/agents/agent-packager.js +271 -0
- package/dist/src/agents/agent-validator.js +271 -0
- package/dist/src/agents/grounding/knowledge-base.js +161 -0
- package/dist/src/agents/grounding/types.js +12 -0
- package/dist/src/agents/index.js +10 -0
- package/dist/src/agents/packaged-agent-inventory.js +75 -0
- package/dist/src/agents/types.js +7 -0
- package/dist/src/api/index.d.ts +10 -0
- package/dist/src/api/index.js +10 -0
- package/dist/src/artifacts/address-parser.js +73 -0
- package/dist/src/artifacts/audit/cli.js +183 -0
- package/dist/src/artifacts/audit/drift.js +122 -0
- package/dist/src/artifacts/audit/types.js +12 -0
- package/dist/src/artifacts/backends/graphology-backend.js +160 -0
- package/dist/src/artifacts/backends/json-backend.js +129 -0
- package/dist/src/artifacts/backends/sqlite-backend.js +199 -0
- package/dist/src/artifacts/browser-export.js +622 -0
- package/dist/src/artifacts/capability-resolver.js +94 -0
- package/dist/src/artifacts/checksum-manifest.js +91 -0
- package/dist/src/artifacts/citation-parser.js +162 -0
- package/dist/src/artifacts/cli.js +1462 -0
- package/dist/src/artifacts/corpus-tools/citation-densify.js +311 -0
- package/dist/src/artifacts/corpus-tools/cli.js +393 -0
- package/dist/src/artifacts/corpus-tools/corpus-graph.js +225 -0
- package/dist/src/artifacts/corpus-tools/curator.js +186 -0
- package/dist/src/artifacts/corpus-tools/discovery-log.js +70 -0
- package/dist/src/artifacts/corpus-tools/funder-network.js +141 -0
- package/dist/src/artifacts/corpus-tools/induction-audit.js +233 -0
- package/dist/src/artifacts/corpus-tools/integrity-scan.js +202 -0
- package/dist/src/artifacts/corpus-tools/profile-communities.js +166 -0
- package/dist/src/artifacts/corpus-tools/profile-edges.js +72 -0
- package/dist/src/artifacts/corpus-tools/profile-embed.js +113 -0
- package/dist/src/artifacts/corpus-tools/profile-generate-fm.js +167 -0
- package/dist/src/artifacts/corpus-tools/profile-generate.js +181 -0
- package/dist/src/artifacts/corpus-tools/profile-metrics.js +98 -0
- package/dist/src/artifacts/corpus-tools/profile-status.js +86 -0
- package/dist/src/artifacts/corpus-tools/profile-temporal.js +139 -0
- package/dist/src/artifacts/corpus-tools/radar-init.js +93 -0
- package/dist/src/artifacts/corpus-tools/radar-report.js +118 -0
- package/dist/src/artifacts/corpus-tools/radar-shared.js +189 -0
- package/dist/src/artifacts/corpus-tools/radar-status.js +68 -0
- package/dist/src/artifacts/corpus-tools/sidecar-lint.js +233 -0
- package/dist/src/artifacts/corpus-tools/sidecar-repair.js +277 -0
- package/dist/src/artifacts/corpus-tools/snapshot.js +591 -0
- package/dist/src/artifacts/corpus-tools/source-types.js +164 -0
- package/dist/src/artifacts/corpus-tools/vision-extract.js +243 -0
- package/dist/src/artifacts/corpus-views/build.js +126 -0
- package/dist/src/artifacts/corpus-views/corpus-config.js +124 -0
- package/dist/src/artifacts/corpus-views/ref-parser.js +437 -0
- package/dist/src/artifacts/corpus-views/renderers.js +353 -0
- package/dist/src/artifacts/corpus-views/taxonomies.js +131 -0
- package/dist/src/artifacts/dep-graph.js +173 -0
- package/dist/src/artifacts/discover-facets.js +375 -0
- package/dist/src/artifacts/embedding-index.js +354 -0
- package/dist/src/artifacts/enrichment/cli.js +240 -0
- package/dist/src/artifacts/enrichment/prompt.js +47 -0
- package/dist/src/artifacts/enrichment/store.js +90 -0
- package/dist/src/artifacts/enrichment/types.js +12 -0
- package/dist/src/artifacts/fortemi-core-query-adapter.js +475 -0
- package/dist/src/artifacts/fortemi-core-sync.js +251 -0
- package/dist/src/artifacts/fortemi-shard-export.js +44 -0
- package/dist/src/artifacts/fulltext.js +108 -0
- package/dist/src/artifacts/graph-backend.js +51 -0
- package/dist/src/artifacts/graph-query.js +247 -0
- package/dist/src/artifacts/hybrid-query.js +225 -0
- package/dist/src/artifacts/index-builder.js +1089 -0
- package/dist/src/artifacts/index-reader.js +112 -0
- package/dist/src/artifacts/index-status.js +193 -0
- package/dist/src/artifacts/legacy-index-migration.js +169 -0
- package/dist/src/artifacts/move.js +154 -0
- package/dist/src/artifacts/operational-state.js +239 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +49 -0
- package/dist/src/artifacts/query-engine.js +1955 -0
- package/dist/src/artifacts/source-graph.js +529 -0
- package/dist/src/artifacts/stats.js +169 -0
- package/dist/src/artifacts/types.js +606 -0
- package/dist/src/artifacts/views/cli.js +293 -0
- package/dist/src/artifacts/views/definition.js +170 -0
- package/dist/src/artifacts/views/store.js +149 -0
- package/dist/src/artifacts/views/types.js +8 -0
- package/dist/src/artifacts/watcher.js +255 -0
- package/dist/src/catalog/builtin-models.json +636 -0
- package/dist/src/catalog/cli.js +228 -0
- package/dist/src/catalog/cli.mjs +289 -0
- package/dist/src/catalog/index.js +15 -0
- package/dist/src/catalog/loader.js +217 -0
- package/dist/src/catalog/loader.mjs +251 -0
- package/dist/src/catalog/sources.json +41 -0
- package/dist/src/catalog/types.js +8 -0
- package/dist/src/channel/manager.mjs +504 -0
- package/dist/src/cli/agent-spawn.js +178 -0
- package/dist/src/cli/cli-extension-loader.js +245 -0
- package/dist/src/cli/command-log.js +275 -0
- package/dist/src/cli/config-loader.js +232 -0
- package/dist/src/cli/env.js +82 -0
- package/dist/src/cli/errors.js +150 -0
- package/dist/src/cli/find-package-root.js +40 -0
- package/dist/src/cli/git-hooks.js +250 -0
- package/dist/src/cli/handlers/agentcard.js +206 -0
- package/dist/src/cli/handlers/artifacts.js +76 -0
- package/dist/src/cli/handlers/best-practices-audit.js +280 -0
- package/dist/src/cli/handlers/cockpit.js +137 -0
- package/dist/src/cli/handlers/command-log.js +37 -0
- package/dist/src/cli/handlers/daemon.js +59 -0
- package/dist/src/cli/handlers/diagnose.js +300 -0
- package/dist/src/cli/handlers/execution-mode.js +105 -0
- package/dist/src/cli/handlers/feedback.js +341 -0
- package/dist/src/cli/handlers/help.js +147 -0
- package/dist/src/cli/handlers/index.js +302 -0
- package/dist/src/cli/handlers/init.js +179 -0
- package/dist/src/cli/handlers/install.js +129 -0
- package/dist/src/cli/handlers/issues.js +46 -0
- package/dist/src/cli/handlers/lint.js +42 -0
- package/dist/src/cli/handlers/local-executor.js +315 -0
- package/dist/src/cli/handlers/marketplace.js +168 -0
- package/dist/src/cli/handlers/mc.js +1010 -0
- package/dist/src/cli/handlers/models.js +352 -0
- package/dist/src/cli/handlers/packages.js +155 -0
- package/dist/src/cli/handlers/ralph-launcher.js +717 -0
- package/dist/src/cli/handlers/ralph.js +575 -0
- package/dist/src/cli/handlers/refresh.js +432 -0
- package/dist/src/cli/handlers/regenerate.js +336 -0
- package/dist/src/cli/handlers/repo-access.js +109 -0
- package/dist/src/cli/handlers/run.js +165 -0
- package/dist/src/cli/handlers/runtime-info.js +301 -0
- package/dist/src/cli/handlers/sandbox.js +197 -0
- package/dist/src/cli/handlers/scaffolding.js +149 -0
- package/dist/src/cli/handlers/script-runner.js +121 -0
- package/dist/src/cli/handlers/sdlc-accelerate.js +148 -0
- package/dist/src/cli/handlers/serve.js +1835 -0
- package/dist/src/cli/handlers/session.js +348 -0
- package/dist/src/cli/handlers/setup.js +440 -0
- package/dist/src/cli/handlers/skill-lint.js +367 -0
- package/dist/src/cli/handlers/skill-usage.js +74 -0
- package/dist/src/cli/handlers/steward.js +567 -0
- package/dist/src/cli/handlers/subcommands.js +1702 -0
- package/dist/src/cli/handlers/team.js +337 -0
- package/dist/src/cli/handlers/types.js +11 -0
- package/dist/src/cli/handlers/use.js +2772 -0
- package/dist/src/cli/handlers/utilities.js +703 -0
- package/dist/src/cli/handlers/version.js +134 -0
- package/dist/src/cli/handlers/workspace-context.js +93 -0
- package/dist/src/cli/handlers/workspace.js +126 -0
- package/dist/src/cli/help-generator.js +178 -0
- package/dist/src/cli/hooks/builtin/activity-log-hook.js +126 -0
- package/dist/src/cli/hooks/executor.js +96 -0
- package/dist/src/cli/hooks/index.js +15 -0
- package/dist/src/cli/hooks/registry.js +143 -0
- package/dist/src/cli/hooks/types.js +13 -0
- package/dist/src/cli/log.js +492 -0
- package/dist/src/cli/project-isolation/detect.js +70 -0
- package/dist/src/cli/project-isolation/index.js +7 -0
- package/dist/src/cli/project-isolation/signals.js +17 -0
- package/dist/src/cli/project-isolation/warning.js +102 -0
- package/dist/src/cli/prompt-utils.js +155 -0
- package/dist/src/cli/provider-deployment-plan.js +126 -0
- package/dist/src/cli/provider-resolution.js +119 -0
- package/dist/src/cli/router.js +305 -0
- package/dist/src/cli/scope-resolver.js +392 -0
- package/dist/src/cli/skill-usage.js +616 -0
- package/dist/src/cli/ui.js +224 -0
- package/dist/src/cli/watch-service.js +203 -0
- package/dist/src/cli/workflow-orchestrator.js +478 -0
- package/dist/src/cli/workspace-signals.js +321 -0
- package/dist/src/community/footer.js +14 -0
- package/dist/src/community/links.js +123 -0
- package/dist/src/community/milestones.js +46 -0
- package/dist/src/community/nudge-policy.js +93 -0
- package/dist/src/config/aiwg-config.js +883 -0
- package/dist/src/config/cli.js +703 -0
- package/dist/src/config/gitignore.js +156 -0
- package/dist/src/config/project-artifacts.js +76 -0
- package/dist/src/config/user-config.js +428 -0
- package/dist/src/config/user-registry.js +127 -0
- package/dist/src/config/workspace.js +276 -0
- package/dist/src/contributors/detect.js +39 -0
- package/dist/src/contributors/discover.js +172 -0
- package/dist/src/contributors/heuristic.js +186 -0
- package/dist/src/contributors/index.js +11 -0
- package/dist/src/contributors/types.js +13 -0
- package/dist/src/contributors/validation.js +116 -0
- package/dist/src/data/community.schema.json +43 -0
- package/dist/src/data/community.yaml +16 -0
- package/dist/src/extensions/capability-index.js +270 -0
- package/dist/src/extensions/claude-hooks-installer.js +268 -0
- package/dist/src/extensions/commands/definitions.js +3485 -0
- package/dist/src/extensions/deployment-registration.js +463 -0
- package/dist/src/extensions/index.js +22 -0
- package/dist/src/extensions/loader.js +132 -0
- package/dist/src/extensions/managed-marker.js +100 -0
- package/dist/src/extensions/manifest.js +196 -0
- package/dist/src/extensions/project-local-activity.js +114 -0
- package/dist/src/extensions/project-local-discovery.js +261 -0
- package/dist/src/extensions/project-local-doctor.js +281 -0
- package/dist/src/extensions/project-local-gitignore.js +176 -0
- package/dist/src/extensions/project-local-paths.js +121 -0
- package/dist/src/extensions/project-local-promote.js +218 -0
- package/dist/src/extensions/project-local-remove.js +373 -0
- package/dist/src/extensions/project-local-scaffold.js +252 -0
- package/dist/src/extensions/project-quickref.js +291 -0
- package/dist/src/extensions/registry.js +368 -0
- package/dist/src/extensions/shadow-resolver.js +271 -0
- package/dist/src/extensions/types.js +86 -0
- package/dist/src/extensions/upstream-registry.js +195 -0
- package/dist/src/extensions/validation.js +631 -0
- package/dist/src/features/catalog.js +88 -0
- package/dist/src/features/cli.js +197 -0
- package/dist/src/features/installer.js +57 -0
- package/dist/src/features/paths.js +14 -0
- package/dist/src/features/runtime.js +21 -0
- package/dist/src/features/status.js +134 -0
- package/dist/src/hooks/laziness-detection.js +532 -0
- package/dist/src/intake/git-history-analyzer.js +486 -0
- package/dist/src/intake/index.js +9 -0
- package/dist/src/issues/cli.js +327 -0
- package/dist/src/issues/index.js +5 -0
- package/dist/src/issues/live.js +154 -0
- package/dist/src/issues/local.js +666 -0
- package/dist/src/issues/sync.js +143 -0
- package/dist/src/issues/types.js +2 -0
- package/dist/src/issues/workflows.js +164 -0
- package/dist/src/kb/cli.js +173 -0
- package/dist/src/lint/cli.js +171 -0
- package/dist/src/lint/loader.js +225 -0
- package/dist/src/lint/reporters.js +141 -0
- package/dist/src/lint/runner.js +364 -0
- package/dist/src/lint/types.js +10 -0
- package/dist/src/marketplace/cache.js +110 -0
- package/dist/src/marketplace/identifier.js +63 -0
- package/dist/src/marketplace/registry.js +36 -0
- package/dist/src/marketplace/sources/clawhub.js +53 -0
- package/dist/src/marketplace/sources/git.js +45 -0
- package/dist/src/marketplace/types.js +9 -0
- package/dist/src/mcp/adapters/codex-runtime.js +224 -0
- package/dist/src/mcp/cli.mjs +1197 -0
- package/dist/src/mcp/elicitation.mjs +149 -0
- package/dist/src/mcp/helpers.mjs +287 -0
- package/dist/src/mcp/index.mjs +11 -0
- package/dist/src/mcp/profiles.js +263 -0
- package/dist/src/mcp/profiles.mjs +360 -0
- package/dist/src/mcp/registry.js +376 -0
- package/dist/src/mcp/registry.mjs +387 -0
- package/dist/src/mcp/server.mjs +633 -0
- package/dist/src/mcp/test-simple.mjs +271 -0
- package/dist/src/mcp/tools/command-run.mjs +101 -0
- package/dist/src/mcp/tools/discovery.mjs +291 -0
- package/dist/src/mcp/tools/interaction.mjs +87 -0
- package/dist/src/mcp/tools/orchestration.mjs +320 -0
- package/dist/src/mcp/tools/subsystems.mjs +640 -0
- package/dist/src/memory/cli.js +166 -0
- package/dist/src/memory/project-registry.js +282 -0
- package/dist/src/metrics/artifact-metrics.js +184 -0
- package/dist/src/metrics/context-budget.js +174 -0
- package/dist/src/metrics/token-counter.js +133 -0
- package/dist/src/models/config-loader.js +228 -0
- package/dist/src/models/index.js +22 -0
- package/dist/src/models/model-capabilities.v1.json +120 -0
- package/dist/src/models/model-catalog.v1.json +96 -0
- package/dist/src/models/model-discovery.js +521 -0
- package/dist/src/models/provider-models.js +73 -0
- package/dist/src/models/provider-policy.js +273 -0
- package/dist/src/models/resolver.js +245 -0
- package/dist/src/models/router.js +70 -0
- package/dist/src/models/types.js +8 -0
- package/dist/src/models/wrapper-deployment.js +178 -0
- package/dist/src/models/wrapper-route.js +54 -0
- package/dist/src/ops/cli.js +268 -0
- package/dist/src/ops/registry.js +623 -0
- package/dist/src/packages/adapters/clawhub.js +113 -0
- package/dist/src/packages/adapters/git.js +153 -0
- package/dist/src/packages/adapters/gitea.js +93 -0
- package/dist/src/packages/adapters/github.js +69 -0
- package/dist/src/packages/adapters/local-cache.js +89 -0
- package/dist/src/packages/package-registry.js +143 -0
- package/dist/src/packages/registry.js +238 -0
- package/dist/src/packages/types.js +11 -0
- package/dist/src/plugin/cross-framework-ops.js +475 -0
- package/dist/src/plugin/framework-config-loader.js +235 -0
- package/dist/src/plugin/framework-detector.js +186 -0
- package/dist/src/plugin/framework-isolator.js +341 -0
- package/dist/src/plugin/framework-migration.js +371 -0
- package/dist/src/plugin/metadata-validator.js +906 -0
- package/dist/src/plugin/plugin-installer.js +436 -0
- package/dist/src/plugin/plugin-status.js +369 -0
- package/dist/src/plugin/plugin-uninstaller.js +473 -0
- package/dist/src/plugin/registry-validator.js +344 -0
- package/dist/src/plugin/skill-command-translator.js +415 -0
- package/dist/src/plugin/workspace-creator.js +189 -0
- package/dist/src/plugin/workspace-migrator.js +821 -0
- package/dist/src/policy/authorization.js +390 -0
- package/dist/src/policy/repo-access.js +215 -0
- package/dist/src/provenance/cli.js +16 -0
- package/dist/src/providers/capability-matrix.js +300 -0
- package/dist/src/providers/capability-matrix.yaml +514 -0
- package/dist/src/providers/provider-definitions.js +977 -0
- package/dist/src/providers/provider-definitions.mjs +159 -0
- package/dist/src/providers/provider-inventory.js +169 -0
- package/dist/src/quality/feedback-ab.js +174 -0
- package/dist/src/quality/feedback-collector.js +176 -0
- package/dist/src/quality/feedback-tracker.js +123 -0
- package/dist/src/quality/patterns/adr.json +24 -0
- package/dist/src/quality/patterns/sad.json +24 -0
- package/dist/src/quality/patterns/test-plan.json +24 -0
- package/dist/src/quality/patterns/use-case.json +24 -0
- package/dist/src/quality/scoring.js +157 -0
- package/dist/src/reflections/cli.js +15 -0
- package/dist/src/release/plan.js +139 -0
- package/dist/src/research/cache/manager.js +227 -0
- package/dist/src/research/clients/arxiv.js +156 -0
- package/dist/src/research/clients/base.js +197 -0
- package/dist/src/research/clients/crossref.js +112 -0
- package/dist/src/research/clients/semantic-scholar.js +126 -0
- package/dist/src/research/clients/unpaywall.js +87 -0
- package/dist/src/research/index.js +14 -0
- package/dist/src/research/query-cli.js +336 -0
- package/dist/src/research/services/acquisition.js +313 -0
- package/dist/src/research/services/archival.js +225 -0
- package/dist/src/research/services/citation.js +279 -0
- package/dist/src/research/services/discovery.js +243 -0
- package/dist/src/research/services/documentation.js +269 -0
- package/dist/src/research/services/index.js +14 -0
- package/dist/src/research/services/provenance.js +279 -0
- package/dist/src/research/services/quality.js +370 -0
- package/dist/src/research/services/types.js +7 -0
- package/dist/src/research/storage-cli.js +20 -0
- package/dist/src/research/types.js +47 -0
- package/dist/src/resources/index.d.ts +2 -0
- package/dist/src/resources/index.js +2 -0
- package/dist/src/resources/web-release.d.ts +89 -0
- package/dist/src/resources/web-release.js +882 -0
- package/dist/src/rlm/cache/cli.js +162 -0
- package/dist/src/rlm/cache/hash.js +35 -0
- package/dist/src/rlm/cache/store.js +170 -0
- package/dist/src/rlm/cache/types.js +8 -0
- package/dist/src/rlm/cli.js +650 -0
- package/dist/src/serve/a2a-terminal-observer.js +120 -0
- package/dist/src/serve/agent-router.js +205 -0
- package/dist/src/serve/dispatch-router.js +171 -0
- package/dist/src/serve/executor-registry.js +715 -0
- package/dist/src/serve/mission-conductor.js +177 -0
- package/dist/src/serve/orchestrator-adapter.js +113 -0
- package/dist/src/serve/orchestrator-override.js +94 -0
- package/dist/src/serve/orchestrator-pty.js +133 -0
- package/dist/src/serve/pty-bridge.js +799 -0
- package/dist/src/serve/sandbox-registry.js +832 -0
- package/dist/src/serve/screen-reader.js +228 -0
- package/dist/src/serve/stack-adapters.js +68 -0
- package/dist/src/serve/telemetry.js +143 -0
- package/dist/src/skills/adapters/clawhub.js +250 -0
- package/dist/src/skills/adapters/local.js +335 -0
- package/dist/src/skills/adapters/openclaw.js +316 -0
- package/dist/src/skills/cli.js +334 -0
- package/dist/src/skills/registry.js +117 -0
- package/dist/src/skills/run.js +259 -0
- package/dist/src/skills/runtime.js +94 -0
- package/dist/src/skills/types.js +10 -0
- package/dist/src/smiths/agentsmith/demo.js +116 -0
- package/dist/src/smiths/agentsmith/examples.js +300 -0
- package/dist/src/smiths/agentsmith/generator.js +503 -0
- package/dist/src/smiths/agentsmith/index.js +11 -0
- package/dist/src/smiths/agentsmith/types.js +8 -0
- package/dist/src/smiths/commandsmith/example.js +220 -0
- package/dist/src/smiths/commandsmith/generator.js +288 -0
- package/dist/src/smiths/commandsmith/index.js +41 -0
- package/dist/src/smiths/commandsmith/templates.js +296 -0
- package/dist/src/smiths/commandsmith/types.js +7 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +104 -0
- package/dist/src/smiths/context-pipeline/allowlist.js +195 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +127 -0
- package/dist/src/smiths/context-pipeline/discovery.js +187 -0
- package/dist/src/smiths/context-pipeline/external-links-section.js +49 -0
- package/dist/src/smiths/context-pipeline/finalization.js +147 -0
- package/dist/src/smiths/context-pipeline/generator.js +477 -0
- package/dist/src/smiths/context-pipeline/index.js +30 -0
- package/dist/src/smiths/context-pipeline/legacy-inject.js +103 -0
- package/dist/src/smiths/context-pipeline/managed-hook.js +95 -0
- package/dist/src/smiths/context-pipeline/overflow.js +212 -0
- package/dist/src/smiths/context-pipeline/parallelism-section.js +94 -0
- package/dist/src/smiths/context-pipeline/provider-policy.js +64 -0
- package/dist/src/smiths/context-pipeline/sanitizer.js +93 -0
- package/dist/src/smiths/context-pipeline/types.js +23 -0
- package/dist/src/smiths/context-pipeline/workspace-context.js +988 -0
- package/dist/src/smiths/hook-bridge/codex-translator.js +129 -0
- package/dist/src/smiths/hook-bridge/copilot-translator.js +64 -0
- package/dist/src/smiths/hook-bridge/factory-translator.js +43 -0
- package/dist/src/smiths/hook-bridge/hermes-translator.js +88 -0
- package/dist/src/smiths/hook-bridge/index.js +79 -0
- package/dist/src/smiths/hook-bridge/loader.js +116 -0
- package/dist/src/smiths/hook-bridge/shim.js +89 -0
- package/dist/src/smiths/hook-bridge/types.js +31 -0
- package/dist/src/smiths/index.js +39 -0
- package/dist/src/smiths/mcpsmith/analyzers/cli-analyzer.js +390 -0
- package/dist/src/smiths/mcpsmith/example.js +119 -0
- package/dist/src/smiths/mcpsmith/generator.js +236 -0
- package/dist/src/smiths/mcpsmith/index.js +17 -0
- package/dist/src/smiths/mcpsmith/types.js +10 -0
- package/dist/src/smiths/platform-paths.js +101 -0
- package/dist/src/smiths/skillsmith/codex-sidecar.js +85 -0
- package/dist/src/smiths/skillsmith/collision-detector.js +249 -0
- package/dist/src/smiths/skillsmith/demo.js +83 -0
- package/dist/src/smiths/skillsmith/examples.js +161 -0
- package/dist/src/smiths/skillsmith/generator.js +316 -0
- package/dist/src/smiths/skillsmith/index.js +12 -0
- package/dist/src/smiths/skillsmith/namespace-adapter.js +180 -0
- package/dist/src/smiths/skillsmith/platform-resolver.js +157 -0
- package/dist/src/smiths/skillsmith/types.js +9 -0
- package/dist/src/smiths/toolsmith/index.js +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +710 -0
- package/dist/src/smiths/toolsmith/types.js +8 -0
- package/dist/src/storage/backends/fortemi.js +227 -0
- package/dist/src/storage/backends/fs.js +134 -0
- package/dist/src/storage/backends/logseq.js +309 -0
- package/dist/src/storage/backends/obsidian.js +233 -0
- package/dist/src/storage/cli.js +468 -0
- package/dist/src/storage/config.js +272 -0
- package/dist/src/storage/index.js +108 -0
- package/dist/src/storage/subsystem-cli.js +201 -0
- package/dist/src/storage/types.js +33 -0
- package/dist/src/testing/corpus/corpus-builder.js +383 -0
- package/dist/src/testing/corpus/ground-truth-manager.js +460 -0
- package/dist/src/testing/corpus/index.js +10 -0
- package/dist/src/testing/fixtures/index.js +9 -0
- package/dist/src/testing/fixtures/test-data-factory.js +472 -0
- package/dist/src/testing/generators/index.js +11 -0
- package/dist/src/testing/generators/test-case-generator.js +393 -0
- package/dist/src/testing/generators/test-code-generator.js +384 -0
- package/dist/src/testing/generators/use-case-parser.js +325 -0
- package/dist/src/testing/index.js +11 -0
- package/dist/src/tracker/capability-protocol.js +118 -0
- package/dist/src/update/checker.mjs +396 -0
- package/dist/src/update/notifier.mjs +235 -0
- package/dist/src/writing/content-diversifier.js +804 -0
- package/dist/src/writing/example-generator.js +959 -0
- package/dist/src/writing/example-templates.js +99 -0
- package/dist/src/writing/pattern-library.js +486 -0
- package/dist/src/writing/patterns/banned-phrases.json +4413 -0
- package/dist/src/writing/patterns/formulaic-structures.json +1300 -0
- package/dist/src/writing/patterns/generic-adjectives.json +1510 -0
- package/dist/src/writing/patterns/hedging-language.json +2096 -0
- package/dist/src/writing/patterns/transition-words.json +1285 -0
- package/dist/src/writing/patterns/weak-verbs.json +1112 -0
- package/dist/src/writing/prompt-optimizer.js +660 -0
- package/dist/src/writing/prompt-templates.js +583 -0
- package/dist/src/writing/scoring-config-loader.js +168 -0
- package/dist/src/writing/validation-engine.js +595 -0
- package/dist/src/writing/validation-rules.js +380 -0
- package/dist/src/writing/voice-analyzer.js +439 -0
- package/dist/src/writing/voice-calibration.js +661 -0
- package/dist/src/writing/voice-profiles.json +588 -0
- package/package.json +64 -9
|
@@ -0,0 +1,715 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executor Registry
|
|
3
|
+
*
|
|
4
|
+
* Manages registered executor instances per the executor contract v1 spec
|
|
5
|
+
* (docs/contracts/executor.v1.md). Each executor registers with
|
|
6
|
+
* `aiwg serve` via POST /api/v1/executors/register and then pushes
|
|
7
|
+
* real-time events over WebSocket at /ws/executors/:executorId.
|
|
8
|
+
*
|
|
9
|
+
* This is the AIWG-side dispatch surface for the executor contract epic.
|
|
10
|
+
* Executor implementations (sandbox adapter, local executor) are in sibling issues.
|
|
11
|
+
*
|
|
12
|
+
* @issue #1179
|
|
13
|
+
* @see #1177 — executor-contract epic
|
|
14
|
+
* @see #1178 — JSON Schema + conformance fixtures (schemas/executor-v1.json)
|
|
15
|
+
* @see docs/contracts/executor.v1.md — authoritative prose spec
|
|
16
|
+
*/
|
|
17
|
+
import { randomBytes } from 'crypto';
|
|
18
|
+
import { EventEmitter } from 'events';
|
|
19
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, unlinkSync } from 'fs';
|
|
20
|
+
import { homedir } from 'os';
|
|
21
|
+
import { dirname, isAbsolute, join, resolve as resolvePath } from 'path';
|
|
22
|
+
import { createRequire } from 'module';
|
|
23
|
+
import { fileURLToPath } from 'url';
|
|
24
|
+
import { projectAiwgPath } from '../config/project-artifacts.js';
|
|
25
|
+
// ============================================================
|
|
26
|
+
// Ajv bootstrap (transitive dep — zero new top-level deps)
|
|
27
|
+
// ============================================================
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
let _validateRegisterPayload = null;
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
let _validateEventEnvelope = null;
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
let _validateDispatchPayload = null;
|
|
34
|
+
function loadValidators() {
|
|
35
|
+
if (_validateRegisterPayload !== null)
|
|
36
|
+
return; // already loaded
|
|
37
|
+
try {
|
|
38
|
+
const require = createRequire(fileURLToPath(import.meta.url));
|
|
39
|
+
const projectRoot = resolvePath(dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
40
|
+
const ajvPaths = [
|
|
41
|
+
join(projectRoot, 'node_modules', 'ajv', 'dist', '2020.js'),
|
|
42
|
+
join(projectRoot, 'node_modules', 'ajv', 'dist', 'ajv.js'),
|
|
43
|
+
];
|
|
44
|
+
const formatsPath = join(projectRoot, 'node_modules', 'ajv-formats', 'dist', 'index.js');
|
|
45
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
46
|
+
let Ajv = null;
|
|
47
|
+
for (const p of ajvPaths) {
|
|
48
|
+
if (existsSync(p)) {
|
|
49
|
+
try {
|
|
50
|
+
Ajv = require(p);
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
catch { /* try next */ }
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!Ajv)
|
|
57
|
+
return; // graceful: validators stay null, schema checks skipped
|
|
58
|
+
const AjvClass = Ajv?.default ?? Ajv;
|
|
59
|
+
// validateSchema: false — prevents AJV from trying to fetch the draft-2020-12
|
|
60
|
+
// meta-schema URI at runtime. The Ajv2020 constructor already implies the dialect.
|
|
61
|
+
const ajv = new AjvClass({ strict: false, allErrors: true, validateSchema: false });
|
|
62
|
+
if (existsSync(formatsPath)) {
|
|
63
|
+
try {
|
|
64
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
65
|
+
const fmtMod = require(formatsPath);
|
|
66
|
+
const addFormats = fmtMod?.default ?? fmtMod;
|
|
67
|
+
if (typeof addFormats === 'function')
|
|
68
|
+
addFormats(ajv);
|
|
69
|
+
}
|
|
70
|
+
catch { /* formats optional */ }
|
|
71
|
+
}
|
|
72
|
+
const schemaPath = join(projectRoot, 'schemas', 'executor-v1.json');
|
|
73
|
+
if (!existsSync(schemaPath))
|
|
74
|
+
return;
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
76
|
+
const schema = JSON.parse(readFileSync(schemaPath, 'utf-8'));
|
|
77
|
+
ajv.addSchema(schema, 'executor.aiwg.io/v1');
|
|
78
|
+
_validateRegisterPayload = ajv.compile({ $ref: 'executor.aiwg.io/v1#/$defs/register_payload' });
|
|
79
|
+
_validateEventEnvelope = ajv.compile({ $ref: 'executor.aiwg.io/v1#/$defs/event_envelope' });
|
|
80
|
+
_validateDispatchPayload = ajv.compile({ $ref: 'executor.aiwg.io/v1#/$defs/dispatch_payload' });
|
|
81
|
+
}
|
|
82
|
+
catch { /* validation degraded to no-op */ }
|
|
83
|
+
}
|
|
84
|
+
export function validateRegisterPayload(data) {
|
|
85
|
+
loadValidators();
|
|
86
|
+
if (!_validateRegisterPayload)
|
|
87
|
+
return { valid: true, errors: '' }; // graceful degradation
|
|
88
|
+
const valid = _validateRegisterPayload(data);
|
|
89
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
|
+
const errors = valid ? '' : JSON.stringify(_validateRegisterPayload.errors ?? []);
|
|
91
|
+
return { valid, errors };
|
|
92
|
+
}
|
|
93
|
+
export function validateEventEnvelope(data) {
|
|
94
|
+
loadValidators();
|
|
95
|
+
if (!_validateEventEnvelope)
|
|
96
|
+
return { valid: true, errors: '' };
|
|
97
|
+
const valid = _validateEventEnvelope(data);
|
|
98
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
|
+
const errors = valid ? '' : JSON.stringify(_validateEventEnvelope.errors ?? []);
|
|
100
|
+
return { valid, errors };
|
|
101
|
+
}
|
|
102
|
+
export function validateDispatchPayload(data) {
|
|
103
|
+
loadValidators();
|
|
104
|
+
if (!_validateDispatchPayload)
|
|
105
|
+
return { valid: true, errors: '' };
|
|
106
|
+
const valid = _validateDispatchPayload(data);
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
+
const errors = valid ? '' : JSON.stringify(_validateDispatchPayload.errors ?? []);
|
|
109
|
+
return { valid, errors };
|
|
110
|
+
}
|
|
111
|
+
// ============================================================
|
|
112
|
+
// Token issuance
|
|
113
|
+
// ============================================================
|
|
114
|
+
/**
|
|
115
|
+
* Issue an opaque bearer token — base64url, 32 bytes of entropy.
|
|
116
|
+
* Returned once at register time. Re-register with same executor_id reclaims
|
|
117
|
+
* the prior identity (per ADR §9); the token is NOT rotated on re-register.
|
|
118
|
+
*/
|
|
119
|
+
function issueToken() {
|
|
120
|
+
return randomBytes(32).toString('base64url');
|
|
121
|
+
}
|
|
122
|
+
/** The terminal states — mission is done and won't change again. */
|
|
123
|
+
const TERMINAL_STATES = new Set(['done', 'failed', 'aborted']);
|
|
124
|
+
// ============================================================
|
|
125
|
+
// Identity store (#969 pattern — atomic writes)
|
|
126
|
+
// ============================================================
|
|
127
|
+
const DEFAULT_EXECUTOR_IDENTITY_STORE_PATH = join(homedir(), '.config', 'aiwg', 'executor-identities.json');
|
|
128
|
+
export function resolveExecutorIdentityStorePath(projectRootOverride) {
|
|
129
|
+
const envOverride = process.env['AIWG_EXECUTOR_IDENTITY_STORE'];
|
|
130
|
+
if (envOverride)
|
|
131
|
+
return envOverride;
|
|
132
|
+
const projectRoot = projectRootOverride ?? process.cwd();
|
|
133
|
+
const configPath = projectAiwgPath(projectRoot, 'storage.config');
|
|
134
|
+
if (!existsSync(configPath))
|
|
135
|
+
return DEFAULT_EXECUTOR_IDENTITY_STORE_PATH;
|
|
136
|
+
try {
|
|
137
|
+
const parsed = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
138
|
+
if (parsed.version !== '1')
|
|
139
|
+
return DEFAULT_EXECUTOR_IDENTITY_STORE_PATH;
|
|
140
|
+
const override = parsed.roots?.['executor_identity'];
|
|
141
|
+
if (override) {
|
|
142
|
+
let resolved = override;
|
|
143
|
+
if (resolved.startsWith('~/'))
|
|
144
|
+
resolved = join(homedir(), resolved.slice(2));
|
|
145
|
+
else if (resolved === '~')
|
|
146
|
+
resolved = homedir();
|
|
147
|
+
else if (!isAbsolute(resolved))
|
|
148
|
+
resolved = resolvePath(projectRoot, resolved);
|
|
149
|
+
return join(resolved, 'executor-identities.json');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch { /* fall through */ }
|
|
153
|
+
return DEFAULT_EXECUTOR_IDENTITY_STORE_PATH;
|
|
154
|
+
}
|
|
155
|
+
function loadExecutorIdentityStore() {
|
|
156
|
+
const path = resolveExecutorIdentityStorePath();
|
|
157
|
+
try {
|
|
158
|
+
if (existsSync(path)) {
|
|
159
|
+
const data = JSON.parse(readFileSync(path, 'utf-8'));
|
|
160
|
+
return new Map(data.map((r) => [r.executorId, r]));
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch { /* ignore */ }
|
|
164
|
+
return new Map();
|
|
165
|
+
}
|
|
166
|
+
function saveExecutorIdentityStore(store) {
|
|
167
|
+
const path = resolveExecutorIdentityStorePath();
|
|
168
|
+
try {
|
|
169
|
+
const dir = dirname(path);
|
|
170
|
+
mkdirSync(dir, { recursive: true });
|
|
171
|
+
const tmp = `${path}.tmp.${process.pid}`;
|
|
172
|
+
writeFileSync(tmp, JSON.stringify([...store.values()], null, 2), 'utf-8');
|
|
173
|
+
try {
|
|
174
|
+
renameSync(tmp, path);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
try {
|
|
178
|
+
unlinkSync(tmp);
|
|
179
|
+
}
|
|
180
|
+
catch { /* ignore */ }
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
catch { /* non-fatal — best effort */ }
|
|
185
|
+
}
|
|
186
|
+
// ============================================================
|
|
187
|
+
// Max recent events kept per mission
|
|
188
|
+
// ============================================================
|
|
189
|
+
const MAX_MISSION_EVENTS = 50;
|
|
190
|
+
// ============================================================
|
|
191
|
+
// Registry class
|
|
192
|
+
// ============================================================
|
|
193
|
+
/**
|
|
194
|
+
* ExecutorRegistry — state, auth, and identity store integration for
|
|
195
|
+
* registered executor instances. Parallel to SandboxRegistry.
|
|
196
|
+
*
|
|
197
|
+
* Emits EventEmitter events:
|
|
198
|
+
* 'executor:registered' — { executorId, name }
|
|
199
|
+
* 'executor:deregistered' — { executorId, reason }
|
|
200
|
+
* 'mission:assigned' — { missionId, executorId }
|
|
201
|
+
* 'mission:state_change' — { missionId, executorId, state, prevState }
|
|
202
|
+
*/
|
|
203
|
+
export class ExecutorRegistry extends EventEmitter {
|
|
204
|
+
executors = new Map();
|
|
205
|
+
missions = new Map();
|
|
206
|
+
/** Persistent token store — executorId → identity record */
|
|
207
|
+
identityStore;
|
|
208
|
+
constructor() {
|
|
209
|
+
super();
|
|
210
|
+
this.identityStore = loadExecutorIdentityStore();
|
|
211
|
+
}
|
|
212
|
+
// ---- Registration ----
|
|
213
|
+
/**
|
|
214
|
+
* Register an executor. Validates payload against `register_payload` schema.
|
|
215
|
+
* Returns 400-level error string on invalid payload.
|
|
216
|
+
* On re-register with same executor_id: reclaims prior token (per ADR §9).
|
|
217
|
+
*/
|
|
218
|
+
register(req) {
|
|
219
|
+
// Validate against JSON Schema
|
|
220
|
+
const { valid, errors } = validateRegisterPayload(req);
|
|
221
|
+
if (!valid) {
|
|
222
|
+
return { error: `Invalid register payload: ${errors}`, status: 400 };
|
|
223
|
+
}
|
|
224
|
+
const now = new Date().toISOString();
|
|
225
|
+
const { executor_id: executorId } = req;
|
|
226
|
+
// Check for existing token in identity store (re-register reclaims it)
|
|
227
|
+
const existing = this.executors.get(executorId);
|
|
228
|
+
const storedIdentity = this.identityStore.get(executorId);
|
|
229
|
+
const token = existing?.token ?? storedIdentity?.token ?? issueToken();
|
|
230
|
+
// Update or create in-memory registration
|
|
231
|
+
if (existing) {
|
|
232
|
+
// Upsert — preserve token and registeredAt
|
|
233
|
+
existing.name = req.name;
|
|
234
|
+
existing.a2aInstanceId = req.a2a_instance_id;
|
|
235
|
+
existing.version = req.version;
|
|
236
|
+
existing.specVersion = req.spec_version;
|
|
237
|
+
existing.transportEndpoints = req.transport_endpoints;
|
|
238
|
+
existing.capabilities = req.capabilities;
|
|
239
|
+
existing.connected = false; // WS will update this on upgrade
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
const registration = {
|
|
243
|
+
executorId,
|
|
244
|
+
a2aInstanceId: req.a2a_instance_id,
|
|
245
|
+
name: req.name,
|
|
246
|
+
version: req.version,
|
|
247
|
+
specVersion: req.spec_version,
|
|
248
|
+
transportEndpoints: req.transport_endpoints,
|
|
249
|
+
capabilities: req.capabilities,
|
|
250
|
+
token,
|
|
251
|
+
connected: false,
|
|
252
|
+
registeredAt: now,
|
|
253
|
+
currentMissions: new Set(),
|
|
254
|
+
};
|
|
255
|
+
this.executors.set(executorId, registration);
|
|
256
|
+
}
|
|
257
|
+
// Persist token to identity store
|
|
258
|
+
this.identityStore.set(executorId, {
|
|
259
|
+
executorId,
|
|
260
|
+
token,
|
|
261
|
+
lastSeenAt: now,
|
|
262
|
+
});
|
|
263
|
+
saveExecutorIdentityStore(this.identityStore);
|
|
264
|
+
// Emit event (for dashboard SSE, etc.)
|
|
265
|
+
this.emit('executor:registered', { executorId, name: req.name });
|
|
266
|
+
return {
|
|
267
|
+
executor_id: executorId,
|
|
268
|
+
token,
|
|
269
|
+
registered_at: existing?.registeredAt ?? now,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Deregister an executor by ID. Auth must be checked by the caller.
|
|
274
|
+
* Emits 'executor:deregistered'.
|
|
275
|
+
*/
|
|
276
|
+
deregister(executorId, reason = 'operator_deleted') {
|
|
277
|
+
const executor = this.executors.get(executorId);
|
|
278
|
+
if (!executor)
|
|
279
|
+
return false;
|
|
280
|
+
// Close WS if open
|
|
281
|
+
if (executor.wsConn && executor.wsConn.readyState <= 1) {
|
|
282
|
+
try {
|
|
283
|
+
executor.wsConn.close(1000, 'deregistered');
|
|
284
|
+
}
|
|
285
|
+
catch { /* ignore */ }
|
|
286
|
+
}
|
|
287
|
+
this.executors.delete(executorId);
|
|
288
|
+
this.emit('executor:deregistered', { executorId, reason });
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Validate bearer token for an executor.
|
|
293
|
+
*/
|
|
294
|
+
authenticate(executorId, token) {
|
|
295
|
+
const executor = this.executors.get(executorId);
|
|
296
|
+
if (executor)
|
|
297
|
+
return executor.token === token;
|
|
298
|
+
// Fall back to identity store for executors that registered in a prior server run
|
|
299
|
+
const stored = this.identityStore.get(executorId);
|
|
300
|
+
return stored !== undefined && stored.token === token;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Mark the WS event stream as connected or disconnected.
|
|
304
|
+
*/
|
|
305
|
+
setConnected(executorId, connected, wsConn) {
|
|
306
|
+
const executor = this.executors.get(executorId);
|
|
307
|
+
if (!executor)
|
|
308
|
+
return;
|
|
309
|
+
executor.connected = connected;
|
|
310
|
+
if (connected && wsConn) {
|
|
311
|
+
executor.wsConn = wsConn;
|
|
312
|
+
}
|
|
313
|
+
else if (!connected) {
|
|
314
|
+
executor.disconnectedAt = new Date().toISOString();
|
|
315
|
+
executor.wsConn = undefined;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Push a message to the executor's live WS connection.
|
|
320
|
+
* Returns true if sent, false if the executor has no open connection.
|
|
321
|
+
*/
|
|
322
|
+
pushToExecutor(executorId, event) {
|
|
323
|
+
const executor = this.executors.get(executorId);
|
|
324
|
+
if (!executor?.wsConn || executor.wsConn.readyState !== 1)
|
|
325
|
+
return false;
|
|
326
|
+
try {
|
|
327
|
+
executor.wsConn.send(JSON.stringify(event));
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// ---- Event handling ----
|
|
335
|
+
/**
|
|
336
|
+
* Handle an inbound event from an executor WS connection.
|
|
337
|
+
* Validates against event_envelope schema; updates mission state.
|
|
338
|
+
*/
|
|
339
|
+
handleEvent(envelope) {
|
|
340
|
+
const executor = this.executors.get(envelope.executor_id);
|
|
341
|
+
if (!executor)
|
|
342
|
+
return;
|
|
343
|
+
executor.lastEventTs = envelope.ts || new Date().toISOString();
|
|
344
|
+
const missionId = envelope.mission_id;
|
|
345
|
+
switch (envelope.event) {
|
|
346
|
+
case 'executor.resync': {
|
|
347
|
+
// Reconcile mission state on reconnect
|
|
348
|
+
const ownedIds = envelope.data?.['owned_mission_ids'] ?? [];
|
|
349
|
+
for (const mid of ownedIds) {
|
|
350
|
+
const mission = this.missions.get(mid);
|
|
351
|
+
if (mission && !TERMINAL_STATES.has(mission.state)) {
|
|
352
|
+
const prevState = mission.state;
|
|
353
|
+
mission.state = 'running';
|
|
354
|
+
mission.updatedAt = envelope.ts;
|
|
355
|
+
this.appendMissionEvent(mission, envelope);
|
|
356
|
+
this.emit('mission:state_change', { missionId: mid, executorId: envelope.executor_id, state: 'running', prevState });
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case 'mission.assigned': {
|
|
362
|
+
if (!missionId)
|
|
363
|
+
break;
|
|
364
|
+
const mission = this.missions.get(missionId);
|
|
365
|
+
if (mission) {
|
|
366
|
+
const prevState = mission.state;
|
|
367
|
+
mission.state = 'assigned';
|
|
368
|
+
mission.updatedAt = envelope.ts;
|
|
369
|
+
this.appendMissionEvent(mission, envelope);
|
|
370
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'assigned', prevState });
|
|
371
|
+
}
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
374
|
+
case 'mission.started': {
|
|
375
|
+
if (!missionId)
|
|
376
|
+
break;
|
|
377
|
+
const mission = this.missions.get(missionId);
|
|
378
|
+
if (mission) {
|
|
379
|
+
const prevState = mission.state;
|
|
380
|
+
mission.state = 'running';
|
|
381
|
+
mission.updatedAt = envelope.ts;
|
|
382
|
+
if (envelope.data?.['pty_session_id']) {
|
|
383
|
+
mission.ptySessionRef = envelope.data['pty_session_id'];
|
|
384
|
+
}
|
|
385
|
+
this.appendMissionEvent(mission, envelope);
|
|
386
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'running', prevState });
|
|
387
|
+
}
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
case 'mission.progress': {
|
|
391
|
+
if (!missionId)
|
|
392
|
+
break;
|
|
393
|
+
const mission = this.missions.get(missionId);
|
|
394
|
+
if (mission) {
|
|
395
|
+
mission.updatedAt = envelope.ts;
|
|
396
|
+
this.appendMissionEvent(mission, envelope);
|
|
397
|
+
}
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
case 'mission.hitl_required': {
|
|
401
|
+
if (!missionId)
|
|
402
|
+
break;
|
|
403
|
+
const mission = this.missions.get(missionId);
|
|
404
|
+
if (mission) {
|
|
405
|
+
const prevState = mission.state;
|
|
406
|
+
mission.state = 'hitl-required';
|
|
407
|
+
mission.updatedAt = envelope.ts;
|
|
408
|
+
this.appendMissionEvent(mission, envelope);
|
|
409
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'hitl-required', prevState });
|
|
410
|
+
}
|
|
411
|
+
break;
|
|
412
|
+
}
|
|
413
|
+
case 'mission.paused': {
|
|
414
|
+
if (!missionId)
|
|
415
|
+
break;
|
|
416
|
+
const mission = this.missions.get(missionId);
|
|
417
|
+
if (mission) {
|
|
418
|
+
const prevState = mission.state;
|
|
419
|
+
mission.state = 'paused';
|
|
420
|
+
mission.updatedAt = envelope.ts;
|
|
421
|
+
this.appendMissionEvent(mission, envelope);
|
|
422
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'paused', prevState });
|
|
423
|
+
}
|
|
424
|
+
break;
|
|
425
|
+
}
|
|
426
|
+
case 'mission.resumed': {
|
|
427
|
+
if (!missionId)
|
|
428
|
+
break;
|
|
429
|
+
const mission = this.missions.get(missionId);
|
|
430
|
+
if (mission) {
|
|
431
|
+
const prevState = mission.state;
|
|
432
|
+
mission.state = 'running';
|
|
433
|
+
mission.updatedAt = envelope.ts;
|
|
434
|
+
this.appendMissionEvent(mission, envelope);
|
|
435
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'running', prevState });
|
|
436
|
+
}
|
|
437
|
+
break;
|
|
438
|
+
}
|
|
439
|
+
case 'mission.suspended': {
|
|
440
|
+
if (!missionId)
|
|
441
|
+
break;
|
|
442
|
+
const mission = this.missions.get(missionId);
|
|
443
|
+
if (mission) {
|
|
444
|
+
const prevState = mission.state;
|
|
445
|
+
mission.state = 'suspended';
|
|
446
|
+
mission.updatedAt = envelope.ts;
|
|
447
|
+
this.appendMissionEvent(mission, envelope);
|
|
448
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'suspended', prevState });
|
|
449
|
+
}
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
case 'mission.reconnected': {
|
|
453
|
+
if (!missionId)
|
|
454
|
+
break;
|
|
455
|
+
const mission = this.missions.get(missionId);
|
|
456
|
+
if (mission) {
|
|
457
|
+
const prevState = mission.state;
|
|
458
|
+
mission.state = 'running';
|
|
459
|
+
mission.updatedAt = envelope.ts;
|
|
460
|
+
this.appendMissionEvent(mission, envelope);
|
|
461
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'running', prevState });
|
|
462
|
+
}
|
|
463
|
+
break;
|
|
464
|
+
}
|
|
465
|
+
case 'mission.completed': {
|
|
466
|
+
if (!missionId)
|
|
467
|
+
break;
|
|
468
|
+
const mission = this.missions.get(missionId);
|
|
469
|
+
if (mission) {
|
|
470
|
+
const prevState = mission.state;
|
|
471
|
+
mission.state = 'done';
|
|
472
|
+
mission.updatedAt = envelope.ts;
|
|
473
|
+
mission.completedAt = envelope.ts;
|
|
474
|
+
if (typeof envelope.data?.['exit_code'] === 'number') {
|
|
475
|
+
mission.exitCode = envelope.data['exit_code'];
|
|
476
|
+
}
|
|
477
|
+
this.appendMissionEvent(mission, envelope);
|
|
478
|
+
executor.currentMissions.delete(missionId);
|
|
479
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'done', prevState });
|
|
480
|
+
}
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
case 'mission.failed': {
|
|
484
|
+
if (!missionId)
|
|
485
|
+
break;
|
|
486
|
+
const mission = this.missions.get(missionId);
|
|
487
|
+
if (mission) {
|
|
488
|
+
const prevState = mission.state;
|
|
489
|
+
mission.state = 'failed';
|
|
490
|
+
mission.updatedAt = envelope.ts;
|
|
491
|
+
mission.completedAt = envelope.ts;
|
|
492
|
+
if (typeof envelope.data?.['error'] === 'string') {
|
|
493
|
+
mission.error = envelope.data['error'];
|
|
494
|
+
}
|
|
495
|
+
if (typeof envelope.data?.['exit_code'] === 'number') {
|
|
496
|
+
mission.exitCode = envelope.data['exit_code'];
|
|
497
|
+
}
|
|
498
|
+
this.appendMissionEvent(mission, envelope);
|
|
499
|
+
executor.currentMissions.delete(missionId);
|
|
500
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'failed', prevState });
|
|
501
|
+
}
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
case 'mission.aborted': {
|
|
505
|
+
if (!missionId)
|
|
506
|
+
break;
|
|
507
|
+
const mission = this.missions.get(missionId);
|
|
508
|
+
if (mission) {
|
|
509
|
+
const prevState = mission.state;
|
|
510
|
+
mission.state = 'aborted';
|
|
511
|
+
mission.updatedAt = envelope.ts;
|
|
512
|
+
mission.completedAt = envelope.ts;
|
|
513
|
+
this.appendMissionEvent(mission, envelope);
|
|
514
|
+
executor.currentMissions.delete(missionId);
|
|
515
|
+
this.emit('mission:state_change', { missionId, executorId: envelope.executor_id, state: 'aborted', prevState });
|
|
516
|
+
}
|
|
517
|
+
break;
|
|
518
|
+
}
|
|
519
|
+
default:
|
|
520
|
+
// Unknown or pass-through event — update timestamp, do not crash
|
|
521
|
+
break;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
appendMissionEvent(mission, envelope) {
|
|
525
|
+
mission.recentEvents.push(envelope);
|
|
526
|
+
if (mission.recentEvents.length > MAX_MISSION_EVENTS) {
|
|
527
|
+
mission.recentEvents = mission.recentEvents.slice(-MAX_MISSION_EVENTS);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
// ---- Mission management ----
|
|
531
|
+
/**
|
|
532
|
+
* Create a mission record and associate it with an executor.
|
|
533
|
+
* Called by the dispatch route after forwarding succeeds.
|
|
534
|
+
*/
|
|
535
|
+
assignMission(missionId, executorId) {
|
|
536
|
+
const now = new Date().toISOString();
|
|
537
|
+
const mission = {
|
|
538
|
+
missionId,
|
|
539
|
+
executorId,
|
|
540
|
+
state: 'assigned',
|
|
541
|
+
createdAt: now,
|
|
542
|
+
updatedAt: now,
|
|
543
|
+
recentEvents: [],
|
|
544
|
+
};
|
|
545
|
+
this.missions.set(missionId, mission);
|
|
546
|
+
const executor = this.executors.get(executorId);
|
|
547
|
+
if (executor)
|
|
548
|
+
executor.currentMissions.add(missionId);
|
|
549
|
+
this.emit('mission:assigned', { missionId, executorId });
|
|
550
|
+
return mission;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Mark a mission as failed (e.g. executor unreachable on forward).
|
|
554
|
+
*/
|
|
555
|
+
failMission(missionId, error) {
|
|
556
|
+
const mission = this.missions.get(missionId);
|
|
557
|
+
if (!mission)
|
|
558
|
+
return;
|
|
559
|
+
const prevState = mission.state;
|
|
560
|
+
mission.state = 'failed';
|
|
561
|
+
mission.error = error;
|
|
562
|
+
mission.updatedAt = new Date().toISOString();
|
|
563
|
+
mission.completedAt = mission.updatedAt;
|
|
564
|
+
const executor = this.executors.get(mission.executorId);
|
|
565
|
+
if (executor)
|
|
566
|
+
executor.currentMissions.delete(missionId);
|
|
567
|
+
this.emit('mission:state_change', { missionId, executorId: mission.executorId, state: 'failed', prevState });
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Get a mission record by ID.
|
|
571
|
+
*/
|
|
572
|
+
getMission(missionId) {
|
|
573
|
+
return this.missions.get(missionId);
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Transition a mission to a requested operator state.
|
|
577
|
+
* Returns false if the mission is in a terminal state or not found.
|
|
578
|
+
*/
|
|
579
|
+
transitionMission(missionId, targetState) {
|
|
580
|
+
const mission = this.missions.get(missionId);
|
|
581
|
+
if (!mission)
|
|
582
|
+
return false;
|
|
583
|
+
if (TERMINAL_STATES.has(mission.state))
|
|
584
|
+
return false;
|
|
585
|
+
const prevState = mission.state;
|
|
586
|
+
mission.state = targetState;
|
|
587
|
+
mission.updatedAt = new Date().toISOString();
|
|
588
|
+
if (TERMINAL_STATES.has(targetState)) {
|
|
589
|
+
mission.completedAt = mission.updatedAt;
|
|
590
|
+
const executor = this.executors.get(mission.executorId);
|
|
591
|
+
if (executor)
|
|
592
|
+
executor.currentMissions.delete(missionId);
|
|
593
|
+
}
|
|
594
|
+
this.emit('mission:state_change', { missionId, executorId: mission.executorId, state: targetState, prevState });
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
// ---- Query ----
|
|
598
|
+
/**
|
|
599
|
+
* List all executors as serializable summaries.
|
|
600
|
+
*/
|
|
601
|
+
list() {
|
|
602
|
+
return [...this.executors.values()].map(toSummary);
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Get a single executor summary.
|
|
606
|
+
*/
|
|
607
|
+
get(executorId) {
|
|
608
|
+
const executor = this.executors.get(executorId);
|
|
609
|
+
return executor ? toSummary(executor) : undefined;
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Get the raw registration record (internal use by dispatch).
|
|
613
|
+
*/
|
|
614
|
+
getRegistration(executorId) {
|
|
615
|
+
return this.executors.get(executorId);
|
|
616
|
+
}
|
|
617
|
+
/**
|
|
618
|
+
* Pick the best executor matching the given filter.
|
|
619
|
+
*
|
|
620
|
+
* Default-selection policy (per ADR §3):
|
|
621
|
+
* 1. Sandbox-first: prefer any executor with isolation:vm or isolation:container
|
|
622
|
+
* 2. Local fallback: isolation:none or isolation:host
|
|
623
|
+
* 3. 503 if no executor available
|
|
624
|
+
*
|
|
625
|
+
* `long_running: true` requires a 'resumable' capability.
|
|
626
|
+
*/
|
|
627
|
+
pickByFilter(filter, longRunning = false) {
|
|
628
|
+
const candidates = [...this.executors.values()].filter((e) => e.connected);
|
|
629
|
+
const rejected = [];
|
|
630
|
+
// If executor_id is pinned, target it directly
|
|
631
|
+
if (filter.executor_id) {
|
|
632
|
+
const pinned = this.executors.get(filter.executor_id);
|
|
633
|
+
if (!pinned) {
|
|
634
|
+
return null;
|
|
635
|
+
}
|
|
636
|
+
if (!pinned.connected) {
|
|
637
|
+
return null;
|
|
638
|
+
}
|
|
639
|
+
if (longRunning && !pinned.capabilities.includes('resumable')) {
|
|
640
|
+
return null;
|
|
641
|
+
}
|
|
642
|
+
return { executor: pinned, reason: 'pinned by executor_id', rejected: [] };
|
|
643
|
+
}
|
|
644
|
+
// Filter by required capabilities
|
|
645
|
+
const filtered = [];
|
|
646
|
+
for (const executor of candidates) {
|
|
647
|
+
// Long-running requires resumable
|
|
648
|
+
if (longRunning && !executor.capabilities.includes('resumable')) {
|
|
649
|
+
rejected.push({ executorId: executor.executorId, reason: 'long_running requires resumable capability' });
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
// All requested capabilities must be present
|
|
653
|
+
if (filter.capabilities && filter.capabilities.length > 0) {
|
|
654
|
+
const missing = filter.capabilities.filter((c) => !executor.capabilities.includes(c));
|
|
655
|
+
if (missing.length > 0) {
|
|
656
|
+
rejected.push({ executorId: executor.executorId, reason: `missing capabilities: ${missing.join(', ')}` });
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
filtered.push(executor);
|
|
661
|
+
}
|
|
662
|
+
if (filtered.length === 0)
|
|
663
|
+
return null;
|
|
664
|
+
// ADR §3 sandbox-first policy: prefer vm/container isolation
|
|
665
|
+
const sandboxFirst = filtered.filter((e) => e.capabilities.some((c) => c === 'isolation:vm' || c === 'isolation:container'));
|
|
666
|
+
const chosen = sandboxFirst.length > 0 ? sandboxFirst[0] : filtered[0];
|
|
667
|
+
return {
|
|
668
|
+
executor: chosen,
|
|
669
|
+
reason: sandboxFirst.length > 0 ? 'sandbox-first (isolation:vm/container)' : 'local fallback',
|
|
670
|
+
rejected,
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
/** Total registered executor count. */
|
|
674
|
+
get size() {
|
|
675
|
+
return this.executors.size;
|
|
676
|
+
}
|
|
677
|
+
/** Shut down — clear all state. */
|
|
678
|
+
shutdown() {
|
|
679
|
+
for (const executor of this.executors.values()) {
|
|
680
|
+
if (executor.wsConn && executor.wsConn.readyState <= 1) {
|
|
681
|
+
try {
|
|
682
|
+
executor.wsConn.close(1000, 'server shutdown');
|
|
683
|
+
}
|
|
684
|
+
catch { /* ignore */ }
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
this.executors.clear();
|
|
688
|
+
this.missions.clear();
|
|
689
|
+
this.removeAllListeners();
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
// ============================================================
|
|
693
|
+
// Serialization helper
|
|
694
|
+
// ============================================================
|
|
695
|
+
function toSummary(e) {
|
|
696
|
+
const summary = {
|
|
697
|
+
executor_id: e.executorId,
|
|
698
|
+
name: e.name,
|
|
699
|
+
version: e.version,
|
|
700
|
+
spec_version: e.specVersion,
|
|
701
|
+
transport_endpoints: e.transportEndpoints,
|
|
702
|
+
capabilities: e.capabilities,
|
|
703
|
+
connected: e.connected,
|
|
704
|
+
last_event_ts: e.lastEventTs,
|
|
705
|
+
active_mission_count: e.currentMissions.size,
|
|
706
|
+
registered_at: e.registeredAt,
|
|
707
|
+
disconnected_at: e.disconnectedAt,
|
|
708
|
+
};
|
|
709
|
+
if (e.a2aInstanceId)
|
|
710
|
+
summary.a2a_instance_id = e.a2aInstanceId;
|
|
711
|
+
return summary;
|
|
712
|
+
}
|
|
713
|
+
// Singleton instance
|
|
714
|
+
export const executorRegistry = new ExecutorRegistry();
|
|
715
|
+
//# sourceMappingURL=executor-registry.js.map
|