@aiwg/cli 2026.10.1 → 2026.10.4
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 +2 -2
- package/agentic/code/providers/capability-matrix.yaml +270 -0
- package/agentic/code/providers/model-capabilities.v1.json +3183 -24
- package/bin/aiwg.mjs +135 -47
- package/dist/src/a2a/codecs.js +9 -0
- package/dist/src/agents/grounding/knowledge-base.js +54 -6
- package/dist/src/artifacts/browser-export.js +6 -0
- package/dist/src/artifacts/checksum-manifest.js +1 -0
- package/dist/src/artifacts/citation-parser.js +173 -92
- package/dist/src/artifacts/citation-table-schema.js +59 -0
- package/dist/src/artifacts/cli.js +57 -18
- package/dist/src/artifacts/corpus-tools/snapshot.js +1 -1
- package/dist/src/artifacts/corpus-tools/vision-extract.js +107 -15
- package/dist/src/artifacts/corpus-views/ref-parser.js +3 -1
- package/dist/src/artifacts/corpus-views/renderers.js +3 -3
- package/dist/src/artifacts/discovery-eval.js +6 -4
- package/dist/src/artifacts/fortemi-core-query-adapter.js +36 -3
- package/dist/src/artifacts/fortemi-core-sync.js +166 -40
- package/dist/src/artifacts/framework-capabilities.js +171 -0
- package/dist/src/artifacts/framework-index-paths.js +73 -0
- package/dist/src/artifacts/framework-source-digest.js +75 -0
- package/dist/src/artifacts/index-builder.js +285 -131
- package/dist/src/artifacts/index-files.js +132 -18
- package/dist/src/artifacts/index-preparation.js +65 -0
- package/dist/src/artifacts/index-refresh.js +576 -0
- package/dist/src/artifacts/index-worker.mjs +9 -0
- package/dist/src/artifacts/prebuilt-build-lock.js +47 -4
- package/dist/src/artifacts/prebuilt-deployment.js +46 -0
- package/dist/src/artifacts/prebuilt-relations.js +80 -0
- package/dist/src/artifacts/query-engine.js +410 -88
- package/dist/src/artifacts/relations-builder.js +168 -0
- package/dist/src/artifacts/relations.js +148 -0
- package/dist/src/artifacts/repair.js +9 -4
- package/dist/src/artifacts/stats.js +5 -2
- package/dist/src/artifacts/types.js +30 -10
- package/dist/src/artifacts/watcher.js +1 -1
- package/dist/src/auth/credential-store.js +2 -1
- package/dist/src/catalog/cli.d.mts +5 -0
- package/dist/src/channel/manager.d.mts +20 -0
- package/dist/src/channel/manager.mjs +78 -12
- package/dist/src/cli/child-process-result.js +40 -0
- package/dist/src/cli/command-log.js +2 -3
- package/dist/src/cli/env.js +38 -16
- package/dist/src/cli/flag-parsing.js +236 -0
- package/dist/src/cli/handlers/artifacts.js +3 -0
- package/dist/src/cli/handlers/auth.js +3 -0
- package/dist/src/cli/handlers/decision.js +218 -5
- package/dist/src/cli/handlers/diagnose.js +13 -5
- package/dist/src/cli/handlers/effect.js +4 -2
- package/dist/src/cli/handlers/evidence.js +3 -0
- package/dist/src/cli/handlers/feedback.js +14 -5
- package/dist/src/cli/handlers/help.js +1 -0
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/init.js +248 -30
- package/dist/src/cli/handlers/lint.js +5 -0
- package/dist/src/cli/handlers/mc.js +23 -0
- package/dist/src/cli/handlers/models.js +169 -10
- package/dist/src/cli/handlers/ralph-launcher.js +2 -0
- package/dist/src/cli/handlers/ralph.js +3 -0
- package/dist/src/cli/handlers/refresh.js +28 -0
- package/dist/src/cli/handlers/regenerate.js +14 -0
- package/dist/src/cli/handlers/resource-versions.js +3 -0
- package/dist/src/cli/handlers/rules.js +195 -0
- package/dist/src/cli/handlers/run.js +4 -0
- package/dist/src/cli/handlers/runtime-info.js +25 -11
- package/dist/src/cli/handlers/script-runner.js +19 -8
- package/dist/src/cli/handlers/session.js +406 -62
- package/dist/src/cli/handlers/sessions.js +243 -76
- package/dist/src/cli/handlers/setup-manifest.js +474 -79
- package/dist/src/cli/handlers/setup.js +180 -39
- package/dist/src/cli/handlers/steward.js +11 -0
- package/dist/src/cli/handlers/subcommands.js +60 -3
- package/dist/src/cli/handlers/team.js +18 -8
- package/dist/src/cli/handlers/uhp.js +3 -0
- package/dist/src/cli/handlers/use.js +307 -55
- package/dist/src/cli/handlers/utilities.js +125 -26
- package/dist/src/cli/handlers/version.js +8 -0
- package/dist/src/cli/prompt-utils.js +72 -0
- package/dist/src/cli/provider-resolution.js +11 -0
- package/dist/src/cli/router.js +15 -1
- package/dist/src/cli/services/deployment-verification.js +19 -9
- package/dist/src/cli/services/provider-prepare-coordinator.js +24 -0
- package/dist/src/cli/skill-usage.js +2 -3
- package/dist/src/config/aiwg-config.js +349 -35
- package/dist/src/config/cli.js +256 -23
- package/dist/src/config/decision-config.js +106 -0
- package/dist/src/config/dispatch-thresholds-runtime.d.mts +8 -0
- package/dist/src/config/dispatch-thresholds-runtime.mjs +38 -0
- package/dist/src/config/gitignore.js +50 -0
- package/dist/src/config/index-graph-overrides.js +36 -0
- package/dist/src/config/project-artifacts-health.d.mts +37 -0
- package/dist/src/config/project-artifacts-health.mjs +14 -3
- package/dist/src/config/project-artifacts-runtime.d.mts +16 -0
- package/dist/src/config/user-config-dir.d.mts +9 -0
- package/dist/src/config/user-config.js +38 -11
- package/dist/src/config/user-registry.js +23 -15
- package/dist/src/config/user-state.js +7 -0
- package/dist/src/decision/adapters/jev.js +75 -27
- package/dist/src/decision/ask.js +203 -43
- package/dist/src/decision/context-live-qualification.js +2 -2
- package/dist/src/decision/driver.js +14 -7
- package/dist/src/decision/ensemble/aggregate.js +23 -10
- package/dist/src/decision/ensemble-study/multifact-study.js +6 -2
- package/dist/src/decision/entry.js +25 -6
- package/dist/src/decision/graph-live-qualification.js +1 -1
- package/dist/src/decision/graph-run.js +9 -0
- package/dist/src/decision/heldout/collector.js +15 -14
- package/dist/src/decision/heldout/contract.js +30 -7
- package/dist/src/decision/index.js +1 -0
- package/dist/src/decision/interop.js +60 -8
- package/dist/src/decision/jev-credentials.js +15 -1
- package/dist/src/decision/ledger.js +942 -0
- package/dist/src/decision/offload-activation.js +137 -0
- package/dist/src/decision/offload.js +550 -0
- package/dist/src/decision/qualification/load.js +4 -6
- package/dist/src/decision/savings.js +28 -0
- package/dist/src/decision/validate.js +6 -3
- package/dist/src/effects/dispatch-verifier.js +252 -0
- package/dist/src/effects/index.js +1 -0
- package/dist/src/effects/types.js +5 -1
- package/dist/src/effects/verifiers/git.js +2 -1
- package/dist/src/effects/verifiers/tracker.js +26 -14
- package/dist/src/extensions/commands/definitions.js +19 -0
- package/dist/src/extensions/project-local-remove.js +36 -1
- package/dist/src/features/installer.js +2 -2
- package/dist/src/flow/graph-metadata.js +5 -0
- package/dist/src/gates/providers/loader.js +64 -18
- package/dist/src/installation/manager-command.d.mts +18 -0
- package/dist/src/installation/manager-command.mjs +15 -3
- package/dist/src/installation/manager.d.mts +49 -0
- package/dist/src/installation/manager.mjs +95 -5
- package/dist/src/issues/cli.js +4 -4
- package/dist/src/issues/local.js +24 -5
- package/dist/src/jobs/runner.js +1 -1
- package/dist/src/lint/cli.js +27 -1
- package/dist/src/lint/loader.js +2 -1
- package/dist/src/lint/reporters.js +25 -1
- package/dist/src/lint/rule-activation.js +43 -0
- package/dist/src/lint/runner.js +137 -62
- package/dist/src/mcp/adapters/codex-runtime.js +366 -56
- package/dist/src/mcp/claude-install.d.mts +4 -0
- package/dist/src/mcp/claude-install.mjs +41 -0
- package/dist/src/mcp/cli.d.mts +1 -0
- package/dist/src/mcp/cli.mjs +620 -85
- package/dist/src/mcp/config-file.d.mts +28 -0
- package/dist/src/mcp/config-file.mjs +279 -0
- package/dist/src/mcp/config-layers.d.mts +36 -0
- package/dist/src/mcp/config-layers.mjs +348 -0
- package/dist/src/mcp/credentials.d.mts +51 -0
- package/dist/src/mcp/credentials.mjs +484 -0
- package/dist/src/mcp/grok-build-config.d.mts +6 -0
- package/dist/src/mcp/grok-build-config.mjs +17 -27
- package/dist/src/mcp/helpers.mjs +109 -4
- package/dist/src/mcp/muse-native-config.d.mts +13 -0
- package/dist/src/mcp/muse-native-config.mjs +1 -0
- package/dist/src/mcp/omp-config.d.mts +4 -0
- package/dist/src/mcp/omp-config.mjs +50 -29
- package/dist/src/mcp/profiles.js +97 -23
- package/dist/src/mcp/profiles.mjs +99 -27
- package/dist/src/mcp/registry.js +248 -131
- package/dist/src/mcp/registry.mjs +169 -100
- package/dist/src/mcp/server-config.d.mts +3 -0
- package/dist/src/mcp/server-config.mjs +89 -0
- package/dist/src/mcp/server.mjs +127 -82
- package/dist/src/mcp/test-simple.mjs +2 -1
- package/dist/src/mcp/toml-editor.d.mts +4 -0
- package/dist/src/mcp/toml-string.d.mts +1 -0
- package/dist/src/mcp/toml-string.mjs +9 -0
- package/dist/src/mcp/toml-strip-mcp.d.mts +1 -0
- package/dist/src/mcp/toml-strip-mcp.mjs +135 -0
- package/dist/src/mcp/tool-filters.d.mts +46 -0
- package/dist/src/mcp/tool-filters.mjs +357 -0
- package/dist/src/mcp/tools/agentic-sandbox.mjs +3 -1
- package/dist/src/mcp/tools/decision.mjs +22 -3
- package/dist/src/mcp/tools/discovery.mjs +62 -55
- package/dist/src/mcp/tools/orchestration.mjs +50 -2
- package/dist/src/mcp/tools/subsystems.mjs +39 -8
- package/dist/src/mcp/tools/worker-invoke.mjs +2856 -0
- package/dist/src/mcp/tools/worker-shell-control.mjs +289 -0
- package/dist/src/mcp/tools/worker-stdin-runtime.mjs +79 -0
- package/dist/src/memory/project-registry.js +2 -2
- package/dist/src/mission-protocol/codecs.js +647 -1
- package/dist/src/mission-protocol/types.js +110 -0
- package/dist/src/mission-protocol/worker-status.js +2 -0
- package/dist/src/models/config-loader.js +76 -14
- package/dist/src/models/grok-build-models.js +93 -41
- package/dist/src/models/model-capabilities.v1.json +3183 -24
- package/dist/src/models/model-discovery.js +931 -67
- package/dist/src/models/provider-policy.js +719 -11
- package/dist/src/models/qualification-digest.d.mts +2 -0
- package/dist/src/models/qualification-digest.mjs +17 -0
- package/dist/src/models/resolver.js +261 -0
- package/dist/src/models/worker-direct-readiness.js +550 -0
- package/dist/src/models/worker-dispatch-offer.js +169 -0
- package/dist/src/models/worker-health-readiness.js +144 -0
- package/dist/src/models/worker-installation.d.mts +39 -0
- package/dist/src/models/worker-installation.mjs +986 -0
- package/dist/src/models/wrapper-route.js +18 -0
- package/dist/src/ops/registry.js +9 -14
- package/dist/src/plugins/standalone-packager.js +4 -3
- package/dist/src/process/bounded-child-process.d.mts +84 -0
- package/dist/src/process/bounded-child-process.mjs +430 -0
- package/dist/src/process/cli-command.d.mts +16 -0
- package/dist/src/process/cli-command.mjs +75 -0
- package/dist/src/process/signal-child.d.mts +6 -0
- package/dist/src/process/signal-child.mjs +7 -0
- package/dist/src/providers/capability-matrix.js +8 -0
- package/dist/src/providers/capability-matrix.yaml +270 -0
- package/dist/src/providers/deployed-skill-roots.js +20 -0
- package/dist/src/providers/grok-build-acp.js +3 -2
- package/dist/src/providers/grok-build-headless.js +53 -23
- package/dist/src/providers/grok-build-inspect.js +1 -0
- package/dist/src/providers/omp-agent.d.mts +8 -0
- package/dist/src/providers/omp-diagnostics.d.mts +1 -0
- package/dist/src/providers/omp-paths.d.mts +13 -0
- package/dist/src/providers/provider-definitions.js +9 -1
- package/dist/src/providers/provider-definitions.mjs +9 -2
- package/dist/src/providers/skill-ownership.d.mts +9 -0
- package/dist/src/providers/skill-ownership.mjs +88 -0
- package/dist/src/rules/activation.d.mts +21 -0
- package/dist/src/rules/activation.mjs +62 -0
- package/dist/src/rules/inline-budget.d.mts +26 -0
- package/dist/src/rules/inline-budget.mjs +66 -0
- package/dist/src/rules/inventory.js +129 -0
- package/dist/src/rules/pin-state.js +73 -0
- package/dist/src/rules/pins.d.mts +14 -0
- package/dist/src/rules/pins.mjs +112 -0
- package/dist/src/rules/rule-frontmatter.schema.json +197 -0
- package/dist/src/serve/executor-registry.js +16 -24
- package/dist/src/serve/fleet-mission-conductor.js +9 -0
- package/dist/src/serve/mission-conductor.js +47 -12
- package/dist/src/serve/shared-host-scheduler.js +2 -0
- package/dist/src/serve/worker-invocation.js +558 -0
- package/dist/src/serve/worker-stdin-frame.d.mts +10 -0
- package/dist/src/serve/worker-stdin-frame.mjs +107 -0
- package/dist/src/sessions/adapter-registry.js +49 -0
- package/dist/src/sessions/adapters/claude.js +39 -54
- package/dist/src/sessions/adapters/codex.js +82 -67
- package/dist/src/sessions/adapters/copilot.js +4 -4
- package/dist/src/sessions/adapters/cursor.js +40 -57
- package/dist/src/sessions/adapters/deepseek-harness.js +15 -12
- package/dist/src/sessions/adapters/factory.js +31 -27
- package/dist/src/sessions/adapters/generic.js +43 -9
- package/dist/src/sessions/adapters/grok-build.js +11 -11
- package/dist/src/sessions/adapters/grokbot-locator.js +111 -0
- package/dist/src/sessions/adapters/grokbot.js +434 -24
- package/dist/src/sessions/adapters/hermes.js +27 -29
- package/dist/src/sessions/adapters/muse-workspace-scan.js +128 -0
- package/dist/src/sessions/adapters/muse.js +200 -104
- package/dist/src/sessions/adapters/omp.js +28 -14
- package/dist/src/sessions/adapters/openclaw.js +89 -79
- package/dist/src/sessions/adapters/opencode.js +27 -24
- package/dist/src/sessions/adapters/openhuman.js +18 -60
- package/dist/src/sessions/adapters/pi.js +30 -14
- package/dist/src/sessions/adapters/warp.js +3 -3
- package/dist/src/sessions/adapters/windsurf.js +19 -48
- package/dist/src/sessions/batch-contracts.js +25 -5
- package/dist/src/sessions/batch-import.js +72 -51
- package/dist/src/sessions/candidates.js +47 -11
- package/dist/src/sessions/contracts.js +75 -2
- package/dist/src/sessions/coverage-preflight.js +134 -0
- package/dist/src/sessions/discovery.js +3 -0
- package/dist/src/sessions/export-plan.js +4 -3
- package/dist/src/sessions/grok-build-cli.js +67 -5
- package/dist/src/sessions/import-exclusions.js +72 -0
- package/dist/src/sessions/import-lease.js +34 -18
- package/dist/src/sessions/import-limits.js +37 -0
- package/dist/src/sessions/importer.js +84 -46
- package/dist/src/sessions/index.js +2 -0
- package/dist/src/sessions/lifecycle.js +45 -0
- package/dist/src/sessions/policy.js +133 -25
- package/dist/src/sessions/readers.js +106 -53
- package/dist/src/sessions/refresh.js +106 -0
- package/dist/src/sessions/repository.js +199 -63
- package/dist/src/sessions/workspace-discovery.js +315 -88
- package/dist/src/sessions/workspace-matching.js +107 -0
- package/dist/src/skills/adapters/clawhub.js +10 -8
- package/dist/src/skills/adapters/openclaw.js +10 -7
- package/dist/src/skills/importer.js +1 -0
- package/dist/src/smiths/context-pipeline/aiwg-md.js +11 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +3 -26
- package/dist/src/smiths/context-pipeline/finalization.js +6 -5
- package/dist/src/smiths/context-pipeline/generator.js +21 -4
- package/dist/src/smiths/context-pipeline/parallelism-section.js +195 -14
- package/dist/src/smiths/context-pipeline/workspace-context.js +116 -9
- package/dist/src/smiths/hook-bridge/codex-translator.js +6 -5
- package/dist/src/smiths/mcpsmith/example.js +1 -1
- package/dist/src/smiths/mcpsmith/generator.js +1 -1
- package/dist/src/smiths/toolsmith/runtime-discovery.d.mts +10 -0
- package/dist/src/smiths/toolsmith/runtime-discovery.mjs +85 -31
- package/dist/src/storage/backends/fs.js +18 -76
- package/dist/src/storage/backends/logseq.js +68 -7
- package/dist/src/storage/backends/obsidian.js +1 -0
- package/dist/src/storage/fortemi-qualification-receipt.js +2 -2
- package/dist/src/testing/generators/test-code-generator.js +57 -30
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/uhp/client.js +11 -1
- package/dist/src/uhp/mission.js +5 -0
- package/dist/src/update/checker.d.mts +2 -0
- package/dist/src/update/checker.mjs +5 -5
- package/dist/src/update/notifier.mjs +54 -2
- package/dist/src/update/service.d.mts +22 -0
- package/dist/src/utils/contained-filesystem.d.mts +37 -0
- package/dist/src/utils/contained-filesystem.mjs +683 -0
- package/dist/src/utils/temporary-directory.js +36 -0
- package/dist/src/writing/example-generator.js +1 -1
- package/dist/src/writing/fidelity.js +18 -1
- package/package.json +32 -2
- package/schemas/mission-v1.schema.json +2429 -0
- package/schemas/models/model-catalog.v1.schema.json +301 -0
- package/schemas/models/model-config-compatibility.v1.schema.json +281 -0
- package/schemas/models/model-policy.v1.schema.json +14 -0
- package/schemas/models/provider-model-capabilities.v1.schema.json +1072 -0
- package/tools/_resolve-impl.mjs +39 -2
- package/tools/agents/deploy-agents.mjs +64 -23
- package/tools/agents/providers/base.mjs +153 -166
- package/tools/agents/providers/claude.mjs +8 -24
- package/tools/agents/providers/codex.mjs +18 -11
- package/tools/agents/providers/cursor.mjs +19 -18
- package/tools/agents/providers/grok-build.mjs +3 -1
- package/tools/agents/providers/grokbot.mjs +11 -12
- package/tools/agents/providers/hermes.mjs +62 -49
- package/tools/agents/providers/omp.mjs +5 -2
- package/tools/agents/providers/openclaw-translator.mjs +19 -5
- package/tools/agents/providers/openclaw.mjs +9 -4
- package/tools/agents/providers/pi.mjs +5 -0
- package/tools/agents/providers/provider-prepare-channel.mjs +5 -0
- package/tools/agents/providers/provider-prepare-coordinator.mjs +247 -0
- package/tools/agents/providers/provider-prepare-worker.mjs +84 -0
- package/tools/agents/providers/rule-delivery.mjs +1270 -0
- package/tools/agents/providers/warp.mjs +20 -26
- package/tools/cli/decision-offload-report.mjs +40 -0
- package/tools/cli/workspace-status.mjs +862 -0
- package/tools/plugin/package-plugins.mjs +186 -8
- package/tools/plugin/plugin-links.mjs +114 -0
- package/tools/providers/antigravity-transport.mjs +3 -1
- package/tools/providers/deepseek-harness-transport.mjs +360 -0
- package/tools/providers/omp-transport.mjs +194 -0
- package/tools/ralph-external/lib/claude-adapter.mjs +389 -0
- package/tools/ralph-external/lib/codex-adapter.mjs +432 -0
- package/tools/ralph-external/lib/consecutive-failure-circuit-breaker.mjs +1748 -0
- package/tools/ralph-external/lib/deepseek-harness-adapter.mjs +397 -0
- package/tools/ralph-external/lib/factory-adapter.mjs +503 -0
- package/tools/ralph-external/lib/launcher-recovery-evidence.mjs +55 -0
- package/tools/ralph-external/lib/muse-adapter.mjs +364 -0
- package/tools/ralph-external/lib/omp-adapter.mjs +315 -0
- package/tools/ralph-external/lib/opencode-adapter.mjs +575 -0
- package/tools/ralph-external/lib/openhuman-adapter.mjs +75 -0
- package/tools/ralph-external/lib/pi-adapter.mjs +329 -0
- package/tools/ralph-external/lib/provider-adapter.mjs +748 -0
- package/tools/ralph-external/lib/recovery-probe.mjs +72 -0
- package/tools/ralph-external/lib/session-environment.mjs +28 -0
- package/tools/ralph-external/lib/systemd-client.mjs +49 -0
- package/tools/ralph-external/lib/worker-health.mjs +439 -0
- package/tools/ralph-external/lib/worker-isolation.mjs +717 -0
- package/tools/ralph-external/lib/worker-overflow.mjs +50 -0
- package/tools/ralph-external/process-monitor.mjs +1017 -0
- package/tools/ralph-external/session-launcher.mjs +5057 -0
- package/tools/scripts/resource-preflight.mjs +541 -0
- package/tools/skills/deploy-skills-codex.mjs +2 -1
- package/vscode-extension/schemas/aiwg.config.v1.json +2916 -0
|
@@ -17,6 +17,7 @@ import { getFrameworkRoot } from '../../channel/manager.mjs';
|
|
|
17
17
|
import { updateInstallation } from '../../update/service.mjs';
|
|
18
18
|
import { useHandler as useFrameworkHandler } from './use.js';
|
|
19
19
|
import { projectAiwgPath } from '../../config/project-artifacts.js';
|
|
20
|
+
import { argsTerminatorIndex, hasPositionalOrSwitch, requireFlagValue, valueTokenIndexes } from '../flag-parsing.js';
|
|
20
21
|
import { checkCollisions, } from '../../smiths/skillsmith/collision-detector.js';
|
|
21
22
|
import { renderUseDeploymentResult, verifyConfiguredDeployments, } from '../services/deployment-verification.js';
|
|
22
23
|
/**
|
|
@@ -326,6 +327,62 @@ export const validateMetadataHandler = {
|
|
|
326
327
|
return result;
|
|
327
328
|
},
|
|
328
329
|
};
|
|
330
|
+
/**
|
|
331
|
+
* A directory is a deployed skill only if it carries a SKILL.md manifest —
|
|
332
|
+
* the same marker `isOwnedByNamespace()` in collision-detector.ts reads for
|
|
333
|
+
* ownership. Harness container/bucket directories (e.g. Claude Code's own
|
|
334
|
+
* `.claude/skills/synced/` sync storage, which holds UUID-named dirs with
|
|
335
|
+
* `manifest.json`, not SKILL.md) have no manifest of their own and must
|
|
336
|
+
* never be reported as a colliding skill (#278).
|
|
337
|
+
*
|
|
338
|
+
* A container directory without its own SKILL.md is still descended exactly
|
|
339
|
+
* one level: a real skill nested inside it (`<container>/<skill>/SKILL.md`)
|
|
340
|
+
* is reported as `<container>/<skill>`, while the container itself never is.
|
|
341
|
+
*/
|
|
342
|
+
async function hasSkillManifest(dirPath) {
|
|
343
|
+
try {
|
|
344
|
+
await fsp.access(path.join(dirPath, 'SKILL.md'));
|
|
345
|
+
return true;
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return false;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
async function collectDeployedSkillDirNames(skillsDir) {
|
|
352
|
+
let topEntries;
|
|
353
|
+
try {
|
|
354
|
+
topEntries = await fsp.readdir(skillsDir, { withFileTypes: true });
|
|
355
|
+
}
|
|
356
|
+
catch {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
const names = [];
|
|
360
|
+
for (const entry of topEntries) {
|
|
361
|
+
if (!entry.isDirectory())
|
|
362
|
+
continue;
|
|
363
|
+
const dirPath = path.join(skillsDir, entry.name);
|
|
364
|
+
if (await hasSkillManifest(dirPath)) {
|
|
365
|
+
names.push(entry.name);
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
let nestedEntries;
|
|
369
|
+
try {
|
|
370
|
+
nestedEntries = await fsp.readdir(dirPath, { withFileTypes: true });
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
for (const nested of nestedEntries) {
|
|
376
|
+
if (!nested.isDirectory())
|
|
377
|
+
continue;
|
|
378
|
+
const nestedPath = path.join(dirPath, nested.name);
|
|
379
|
+
if (await hasSkillManifest(nestedPath)) {
|
|
380
|
+
names.push(path.join(entry.name, nested.name));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return names;
|
|
385
|
+
}
|
|
329
386
|
/**
|
|
330
387
|
* #1156 Phase 1 — Validate the per-user registry at `~/.aiwg/installed.json`.
|
|
331
388
|
*
|
|
@@ -450,8 +507,14 @@ Options:
|
|
|
450
507
|
--bundle <name> Limit deployment verification to one bundle
|
|
451
508
|
--scope <scope> Verification scope: project or user
|
|
452
509
|
--user Alias for --scope user
|
|
510
|
+
--qualify With --probe-workers, record installation and configured model/role approval
|
|
511
|
+
--yes Confirm worker qualification without a terminal
|
|
512
|
+
--dry-run With --probe-workers, preview qualification without writes
|
|
513
|
+
--cli NAME Limit worker probes/qualification to one configured CLI
|
|
514
|
+
--decision-offload Show offline advisory decision readiness and adoption report
|
|
515
|
+
--probe-workers Run bounded worker CLI version probes (default: config-only, no subprocess)
|
|
453
516
|
--project-local Include project-local artifact diagnostics
|
|
454
|
-
--json Emit machine-readable deployment verification
|
|
517
|
+
--json Emit machine-readable output (with --probe-workers: one worker-probe record per CLI; with --deployment: deployment verification; with --decision-offload: offline snapshot)
|
|
455
518
|
--verbose, -v Include verbose diagnostics
|
|
456
519
|
--help, -h Show this help
|
|
457
520
|
`;
|
|
@@ -477,28 +540,63 @@ export const doctorHandler = {
|
|
|
477
540
|
return { exitCode: 0, message: DOCTOR_HELP, rawOutput: true };
|
|
478
541
|
},
|
|
479
542
|
async execute(ctx) {
|
|
480
|
-
|
|
543
|
+
// Validate before any early-return mode: deployment and user-scope doctor
|
|
544
|
+
// never invoke doctor.mjs, so they must enforce the same flag contract.
|
|
545
|
+
const valueFlags = ['--provider', '--bundle', '--scope', '--context-baseline', '--context-budget-tokens', '--cli'];
|
|
546
|
+
const knownFlags = new Set([
|
|
547
|
+
...valueFlags, '--all-providers', '--probe-workers', '--qualify', '--yes', '--dry-run', '--no-budget-check', '--strict-context', '--json',
|
|
548
|
+
'--decision-offload', '--deployment', '--user', '--verbose', '-v', '--project-local', '--quiet', '--help', '-h',
|
|
549
|
+
]);
|
|
550
|
+
const hasSwitch = (name) => hasPositionalOrSwitch(ctx.args, name, valueFlags);
|
|
551
|
+
const values = new Map();
|
|
552
|
+
try {
|
|
553
|
+
for (const flag of valueFlags) {
|
|
554
|
+
values.set(flag, requireFlagValue(ctx.args, { rejectEmpty: true, precedence: 'last' }, flag));
|
|
555
|
+
}
|
|
556
|
+
const consumed = valueTokenIndexes(ctx.args, valueFlags);
|
|
557
|
+
for (let i = 0; i < argsTerminatorIndex(ctx.args); i += 1) {
|
|
558
|
+
const token = ctx.args[i];
|
|
559
|
+
if (consumed.has(i) || !token.startsWith('-'))
|
|
560
|
+
continue;
|
|
561
|
+
const name = token.split('=')[0];
|
|
562
|
+
if (!knownFlags.has(name) || (token.includes('=') && !valueFlags.includes(name))) {
|
|
563
|
+
throw new Error(`Unknown flag: ${name}`);
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (hasSwitch('--decision-offload') && (hasSwitch('--probe-workers') || hasSwitch('--deployment') || hasSwitch('--user') || values.get('--scope') !== undefined)) {
|
|
567
|
+
throw new Error('--decision-offload is a separate offline mode; do not combine it with worker, deployment or user-scope checks');
|
|
568
|
+
}
|
|
569
|
+
if (['--qualify', '--cli', '--yes', '--dry-run'].some(flag => hasSwitch(flag) || values.get(flag)) && !hasSwitch('--probe-workers')) {
|
|
570
|
+
throw new Error('--qualify, --cli, --yes and --dry-run require --probe-workers');
|
|
571
|
+
}
|
|
572
|
+
if (hasSwitch('--json') && !hasSwitch('--probe-workers') && !hasSwitch('--deployment') && !hasSwitch('--decision-offload')) {
|
|
573
|
+
throw new Error('--json requires --probe-workers or --deployment or --decision-offload');
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
catch (error) {
|
|
577
|
+
return { exitCode: 2, message: `${error instanceof Error ? error.message : String(error)}. See 'aiwg doctor --help'.` };
|
|
578
|
+
}
|
|
579
|
+
if (hasSwitch('--help') || hasSwitch('-h')) {
|
|
481
580
|
return { exitCode: 0, message: DOCTOR_HELP, rawOutput: true };
|
|
482
581
|
}
|
|
483
|
-
if (
|
|
484
|
-
const
|
|
485
|
-
const bundleIndex = ctx.args.indexOf('--bundle');
|
|
486
|
-
const scopeIndex = ctx.args.indexOf('--scope');
|
|
487
|
-
const scopeValue = scopeIndex >= 0 ? ctx.args[scopeIndex + 1] : undefined;
|
|
582
|
+
if (hasSwitch('--deployment')) {
|
|
583
|
+
const scopeValue = values.get('--scope');
|
|
488
584
|
if (scopeValue && scopeValue !== 'project' && scopeValue !== 'user') {
|
|
489
585
|
return { exitCode: 2, message: `Invalid deployment verification scope: ${scopeValue}` };
|
|
490
586
|
}
|
|
491
587
|
const result = await verifyConfiguredDeployments(ctx.cwd || process.cwd(), {
|
|
492
|
-
provider:
|
|
493
|
-
bundle:
|
|
588
|
+
provider: values.get('--provider'),
|
|
589
|
+
bundle: values.get('--bundle'),
|
|
494
590
|
scope: scopeValue,
|
|
495
591
|
}, ctx.frameworkRoot);
|
|
592
|
+
const { rulePinState } = await import('../../rules/pin-state.js');
|
|
593
|
+
const pins = rulePinState(ctx.cwd, ctx.frameworkRoot);
|
|
496
594
|
return {
|
|
497
595
|
exitCode: result.exitCode,
|
|
498
|
-
message:
|
|
499
|
-
? JSON.stringify(result, null, 2)
|
|
500
|
-
: renderUseDeploymentResult(result),
|
|
501
|
-
rawOutput:
|
|
596
|
+
message: hasSwitch('--json')
|
|
597
|
+
? JSON.stringify({ ...result, rule_pins: { rules: pins.rules, warnings: pins.warnings } }, null, 2)
|
|
598
|
+
: renderUseDeploymentResult(result) + '\n' + pins.rules.map(rule => `${rule.name}: pinned kernel (canonical ${rule.canonical_activation})`).concat(pins.warnings).join('\n'),
|
|
599
|
+
rawOutput: hasSwitch('--json'),
|
|
502
600
|
};
|
|
503
601
|
}
|
|
504
602
|
// #1156 Phase 1 — `aiwg doctor --scope user` / `aiwg doctor --user`
|
|
@@ -506,15 +604,20 @@ export const doctorHandler = {
|
|
|
506
604
|
// running the project-scope diagnostics. Operators need this to verify
|
|
507
605
|
// their user-scope deployments from any cwd, including shells with no
|
|
508
606
|
// project at all.
|
|
509
|
-
const userScopeRequested =
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
return await runUserScopeDoctor(ctx.args.includes('--verbose') || ctx.args.includes('-v'));
|
|
607
|
+
const userScopeRequested = hasSwitch('--user') || values.get('--scope') === 'user';
|
|
608
|
+
if (userScopeRequested && !hasSwitch('--probe-workers')) {
|
|
609
|
+
return await runUserScopeDoctor(hasSwitch('--verbose') || hasSwitch('-v'));
|
|
513
610
|
}
|
|
514
|
-
const frameworkRoot = await getFrameworkRoot();
|
|
611
|
+
const frameworkRoot = hasSwitch('--decision-offload') ? ctx.frameworkRoot : await getFrameworkRoot();
|
|
515
612
|
const runner = createScriptRunner(frameworkRoot);
|
|
516
613
|
// Run core doctor diagnostics
|
|
517
614
|
const result = await runner.run('tools/cli/doctor.mjs', ctx.args, { cwd: ctx.cwd });
|
|
615
|
+
// Machine-readable worker probes (#3066): tools/cli/doctor.mjs already
|
|
616
|
+
// printed exactly one JSON document (or a usage error) on its own
|
|
617
|
+
// stdio — every section below writes human-readable text, so returning
|
|
618
|
+
// here keeps stdout to the JSON document alone.
|
|
619
|
+
if (hasSwitch('--decision-offload') || hasSwitch('--json') || hasSwitch('--qualify') || hasSwitch('--cli') || hasSwitch('--dry-run') || result.exitCode === 2)
|
|
620
|
+
return result;
|
|
518
621
|
let agentSkillsFailure = false;
|
|
519
622
|
try {
|
|
520
623
|
const { inspectGrokBuildNative } = await import('../../mcp/grok-build-config.mjs');
|
|
@@ -562,14 +665,7 @@ export const doctorHandler = {
|
|
|
562
665
|
try {
|
|
563
666
|
const projectDir = ctx.cwd || process.cwd();
|
|
564
667
|
const skillsDir = path.join(projectDir, '.claude', 'skills');
|
|
565
|
-
|
|
566
|
-
try {
|
|
567
|
-
const entries = await fsp.readdir(skillsDir, { withFileTypes: true });
|
|
568
|
-
deployedSkillNames = entries.filter(e => e.isDirectory()).map(e => e.name);
|
|
569
|
-
}
|
|
570
|
-
catch {
|
|
571
|
-
// No .claude/skills — nothing to check
|
|
572
|
-
}
|
|
668
|
+
const deployedSkillNames = await collectDeployedSkillDirNames(skillsDir);
|
|
573
669
|
if (deployedSkillNames.length > 0) {
|
|
574
670
|
const collisions = await checkCollisions({
|
|
575
671
|
platform: 'claude',
|
|
@@ -718,6 +814,9 @@ export const contextFirewallHandler = {
|
|
|
718
814
|
description: 'Audit provider context and manage its reviewed baseline',
|
|
719
815
|
category: 'maintenance',
|
|
720
816
|
aliases: ['-context-firewall', '--context-firewall'],
|
|
817
|
+
async help() {
|
|
818
|
+
return { exitCode: 0, message: CONTEXT_FIREWALL_HELP, rawOutput: true };
|
|
819
|
+
},
|
|
721
820
|
async execute(ctx) {
|
|
722
821
|
if (ctx.args.includes('--help') || ctx.args.includes('-h')) {
|
|
723
822
|
return { exitCode: 0, message: CONTEXT_FIREWALL_HELP };
|
|
@@ -55,6 +55,9 @@ function collectFingerprint(versionInfo) {
|
|
|
55
55
|
const loggerInfo = getLoggerInfo();
|
|
56
56
|
const fp = {
|
|
57
57
|
version: versionInfo.version,
|
|
58
|
+
launcherVersion: versionInfo.launcherVersion ?? versionInfo.version,
|
|
59
|
+
runtimeVersion: versionInfo.runtimeVersion ?? versionInfo.version,
|
|
60
|
+
runtimePath: versionInfo.runtimePath ?? versionInfo.packageRoot,
|
|
58
61
|
channel: versionInfo.devMode ? 'dev' : versionInfo.channel,
|
|
59
62
|
packageRoot: versionInfo.packageRoot,
|
|
60
63
|
node: process.version,
|
|
@@ -132,6 +135,11 @@ async function displayVersion(opts) {
|
|
|
132
135
|
}
|
|
133
136
|
ui.blank();
|
|
134
137
|
console.log(` ${ui.brandMark()} ${ui.bold('aiwg')} ${ui.bold(fp.version)} ${ui.channelLabel(fp.channel)}`);
|
|
138
|
+
if (info.devMode || fp.launcherVersion !== fp.runtimeVersion) {
|
|
139
|
+
ui.dim(` launcher: ${fp.launcherVersion}`);
|
|
140
|
+
ui.dim(` runtime: ${fp.runtimeVersion}`);
|
|
141
|
+
ui.dim(` runtime path: ${fp.runtimePath}`);
|
|
142
|
+
}
|
|
135
143
|
if (!opts.verbose) {
|
|
136
144
|
if (fp.git)
|
|
137
145
|
ui.dim(` git: ${fp.git.sha} (${fp.git.branch})`);
|
|
@@ -127,6 +127,78 @@ export async function askChoice(rl, prompt, options, fallback, signal) {
|
|
|
127
127
|
return pick;
|
|
128
128
|
}, pick, label, promptTimeoutMs(), signal);
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Prompt for a strict, distinguishable consent answer. Two differences from
|
|
132
|
+
* {@link askYesNo}, both deliberately scoped to this helper so no existing
|
|
133
|
+
* `askYesNo` call site changes behavior:
|
|
134
|
+
*
|
|
135
|
+
* 1. **Strict parsing**: only a trimmed, case-insensitive `y` or `yes`
|
|
136
|
+
* counts as yes. `askYesNo`'s `startsWith('y')` would also accept
|
|
137
|
+
* `yesterday` or `yolo` — too loose for an irreversible opt-in.
|
|
138
|
+
* 2. **Answered vs. not-answered**: the caller gets a {@link ConsentOutcome}
|
|
139
|
+
* instead of a bare boolean, so a timeout or a closed/EOF'd stdin (the
|
|
140
|
+
* `rl.on('close', ...)` listener settles immediately — it does not wait
|
|
141
|
+
* out the timeout) is distinguishable from an actual "no" answer. A
|
|
142
|
+
* caller that records a persistent decline must only do so for
|
|
143
|
+
* `{ kind: 'answered', value: false }`.
|
|
144
|
+
*
|
|
145
|
+
* Signal abort still rejects (same contract as {@link askWithTimeout}).
|
|
146
|
+
*/
|
|
147
|
+
export function askConsent(rl, question, timeoutMs = promptTimeoutMs(), signal) {
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
let settled = false;
|
|
150
|
+
const cleanup = () => {
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
rl.removeListener('close', onClose);
|
|
153
|
+
signal?.removeEventListener('abort', onAbort);
|
|
154
|
+
};
|
|
155
|
+
const timer = setTimeout(() => {
|
|
156
|
+
if (settled)
|
|
157
|
+
return;
|
|
158
|
+
settled = true;
|
|
159
|
+
ui.warn(` No input within ${Math.round(timeoutMs / 1000)}s — leaving the setting unchanged.`);
|
|
160
|
+
cleanup();
|
|
161
|
+
resolve({ kind: 'timeout' });
|
|
162
|
+
}, timeoutMs);
|
|
163
|
+
// See askWithTimeout: unref so a closed event loop never waits on this.
|
|
164
|
+
timer.unref?.();
|
|
165
|
+
// Stdin closing (EOF, piped input exhausted, or the interface being
|
|
166
|
+
// closed elsewhere) must settle immediately, not after the full
|
|
167
|
+
// timeout — a closed stdin must never hang a consent prompt.
|
|
168
|
+
const onClose = () => {
|
|
169
|
+
if (settled)
|
|
170
|
+
return;
|
|
171
|
+
settled = true;
|
|
172
|
+
ui.warn(' Input closed before an answer — leaving the setting unchanged.');
|
|
173
|
+
cleanup();
|
|
174
|
+
resolve({ kind: 'closed' });
|
|
175
|
+
};
|
|
176
|
+
rl.on('close', onClose);
|
|
177
|
+
const onAbort = () => {
|
|
178
|
+
if (settled)
|
|
179
|
+
return;
|
|
180
|
+
settled = true;
|
|
181
|
+
cleanup();
|
|
182
|
+
try {
|
|
183
|
+
rl.close();
|
|
184
|
+
}
|
|
185
|
+
catch { /* already closed */ }
|
|
186
|
+
reject(signal.reason ?? new Error('Aborted'));
|
|
187
|
+
};
|
|
188
|
+
if (signal?.aborted) {
|
|
189
|
+
onAbort();
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
193
|
+
rl.question(question, (answer) => {
|
|
194
|
+
if (settled)
|
|
195
|
+
return;
|
|
196
|
+
settled = true;
|
|
197
|
+
cleanup();
|
|
198
|
+
resolve({ kind: 'answered', value: ['y', 'yes'].includes(answer.trim().toLowerCase()) });
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
}
|
|
130
202
|
/**
|
|
131
203
|
* Prompt for a labeled selection from a list of options. Renders each option
|
|
132
204
|
* as a numbered line before asking. Users can respond by number (1-based) or
|
|
@@ -19,6 +19,17 @@ function uniqueProviders(providers) {
|
|
|
19
19
|
}
|
|
20
20
|
return result;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Sources that say which harness this process is actually running under.
|
|
24
|
+
* `config`, `deployment` and `default` describe the project, not the session:
|
|
25
|
+
* a project deployed for one provider is still not "inside" that provider
|
|
26
|
+
* when a command is run from a plain terminal.
|
|
27
|
+
*/
|
|
28
|
+
const SESSION_PROVIDER_SOURCES = new Set(['explicit', 'env', 'runtime-env', 'process']);
|
|
29
|
+
/** True when a resolution came from the running session rather than project state. */
|
|
30
|
+
export function isSessionProviderResolution(resolution) {
|
|
31
|
+
return resolution.provider != null && SESSION_PROVIDER_SOURCES.has(resolution.source);
|
|
32
|
+
}
|
|
22
33
|
function detectProviderFromRuntimeEnv(env) {
|
|
23
34
|
const definitions = [...listProviderDefinitions()].sort((a, b) => (a.detection.runtimeEnvPriority ?? Number.MAX_SAFE_INTEGER) - (b.detection.runtimeEnvPriority ?? Number.MAX_SAFE_INTEGER));
|
|
24
35
|
for (const definition of definitions) {
|
package/dist/src/cli/router.js
CHANGED
|
@@ -75,6 +75,15 @@ export function getHookRegistry() {
|
|
|
75
75
|
* ```
|
|
76
76
|
*/
|
|
77
77
|
export async function run(args, options = {}) {
|
|
78
|
+
// Scheduled index maintenance has no hooks, telemetry, or deployment side effects.
|
|
79
|
+
if (args[0] === 'index' && args[1] === 'refresh'
|
|
80
|
+
&& !args.includes('--help') && !args.includes('-h')) {
|
|
81
|
+
const { runIndexRefresh } = await import('../artifacts/index-refresh.js');
|
|
82
|
+
const report = await runIndexRefresh(args.slice(2), options.cwd ?? process.cwd(), options.signal);
|
|
83
|
+
if (report.totals.errors)
|
|
84
|
+
process.exit(1);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
78
87
|
const started = process.hrtime.bigint();
|
|
79
88
|
const registry = await initRouter();
|
|
80
89
|
// Normalize `help <command>` into the same non-executing help path.
|
|
@@ -320,7 +329,12 @@ async function logCommandInvocation(input) {
|
|
|
320
329
|
* @returns Handler context
|
|
321
330
|
*/
|
|
322
331
|
async function buildContext(args, rawArgs, options) {
|
|
323
|
-
const
|
|
332
|
+
const readOnlyRuleInventory = rawArgs[0] === 'rules' && ['inventory', 'list'].includes(args[0]);
|
|
333
|
+
const readOnlyOffloadReport = (['doctor', '-doctor', '--doctor'].includes(rawArgs[0] ?? '') && args.includes('--decision-offload'))
|
|
334
|
+
|| (rawArgs[0] === 'steward' && args[0] === 'decision-offload');
|
|
335
|
+
const frameworkRoot = await getFrameworkRoot({
|
|
336
|
+
createIfMissing: !args.includes('--dry-run') && !readOnlyRuleInventory && !readOnlyOffloadReport,
|
|
337
|
+
});
|
|
324
338
|
const ctx = {
|
|
325
339
|
args,
|
|
326
340
|
rawArgs,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { access, readFile, readdir, stat } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { loadPrebuiltDeploymentIndex } from '../../artifacts/prebuilt-deployment.js';
|
|
3
4
|
import { loadGraphIndexFile } from '../../artifacts/index-reader.js';
|
|
4
5
|
import { readAiwgConfig } from '../../config/aiwg-config.js';
|
|
5
6
|
import { readUserRegistry } from '../../config/user-registry.js';
|
|
@@ -102,7 +103,7 @@ export function normalizeFrameworkDiscoveryInventory(stats) {
|
|
|
102
103
|
};
|
|
103
104
|
}
|
|
104
105
|
function frameworkDiscoveryInventory(frameworkRoot) {
|
|
105
|
-
const stats = loadGraphIndexFile(frameworkRoot, 'stats.json', 'framework');
|
|
106
|
+
const stats = loadPrebuiltDeploymentIndex(frameworkRoot, { strictRoot: true })?.stats ?? loadGraphIndexFile(frameworkRoot, 'stats.json', 'framework');
|
|
106
107
|
return stats ? normalizeFrameworkDiscoveryInventory(stats) : null;
|
|
107
108
|
}
|
|
108
109
|
const BUNDLE_INDEX_TOKENS = {
|
|
@@ -510,9 +511,11 @@ export async function verifyProviderDeployment(options) {
|
|
|
510
511
|
const frameworkBundles = options.requestedBundles.filter((bundle) => !projectLocalBundles.includes(bundle));
|
|
511
512
|
const indexesToVerify = [];
|
|
512
513
|
if (frameworkBundles.length > 0) {
|
|
514
|
+
const prebuilt = loadPrebuiltDeploymentIndex(options.frameworkRoot, { strictRoot: true });
|
|
513
515
|
indexesToVerify.push({
|
|
514
|
-
index: loadGraphIndexFile(options.frameworkRoot, 'metadata.json', 'framework'),
|
|
515
|
-
stats: loadGraphIndexFile(options.frameworkRoot, 'stats.json', 'framework'),
|
|
516
|
+
index: prebuilt?.index ?? loadGraphIndexFile(options.frameworkRoot, 'metadata.json', 'framework'),
|
|
517
|
+
stats: prebuilt?.stats ?? loadGraphIndexFile(options.frameworkRoot, 'stats.json', 'framework'),
|
|
518
|
+
prebuiltValidated: Boolean(prebuilt),
|
|
516
519
|
graph: 'framework',
|
|
517
520
|
bundles: frameworkBundles,
|
|
518
521
|
});
|
|
@@ -521,11 +524,12 @@ export async function verifyProviderDeployment(options) {
|
|
|
521
524
|
const graph = options.scope === 'user' ? 'user' : 'project';
|
|
522
525
|
indexesToVerify.push({
|
|
523
526
|
index: loadGraphIndexFile(options.projectRoot, 'metadata.json', graph),
|
|
527
|
+
stats: loadGraphIndexFile(options.projectRoot, 'stats.json', graph),
|
|
524
528
|
graph,
|
|
525
529
|
bundles: projectLocalBundles,
|
|
526
530
|
});
|
|
527
531
|
}
|
|
528
|
-
for (const { index, stats, graph, bundles } of indexesToVerify) {
|
|
532
|
+
for (const { index, stats, graph, bundles, prebuiltValidated } of indexesToVerify) {
|
|
529
533
|
if (!index || !index.entries || Object.keys(index.entries).length === 0) {
|
|
530
534
|
findings.push(finding(normalized, `index-unreadable:${graph}`, 'blocking', `The ${graph} capability index is missing, unreadable, or empty.`, `Run aiwg index build --graph ${graph}, then re-run the same aiwg use command.`));
|
|
531
535
|
continue;
|
|
@@ -550,11 +554,14 @@ export async function verifyProviderDeployment(options) {
|
|
|
550
554
|
if (!surfacePresent) {
|
|
551
555
|
findings.push(finding(normalized, `index-surface-missing:${graph}`, 'blocking', `The ${graph} capability index does not contain the requested bundle surface.`, `Rebuild the ${graph} index from the selected AIWG source and re-run aiwg use.`, { requestedBundles: bundles, entryCount: entryPaths.length }));
|
|
552
556
|
}
|
|
553
|
-
if (options.invocationStartedAt) {
|
|
554
|
-
|
|
557
|
+
if (options.invocationStartedAt && !prebuiltValidated) {
|
|
558
|
+
// No-op builds preserve metadata bytes and record the refresh in stats.
|
|
559
|
+
const refreshedAt = Math.max(...[index.builtAt, stats?.builtAt]
|
|
560
|
+
.map((timestamp) => Date.parse(timestamp ?? ''))
|
|
561
|
+
.filter(Number.isFinite));
|
|
555
562
|
const startedAt = Date.parse(options.invocationStartedAt);
|
|
556
|
-
if (!Number.isFinite(
|
|
557
|
-
findings.push(finding(normalized, `index-stale:${graph}`, 'blocking', `The ${graph} capability index was not refreshed during this deployment.`, `Re-run aiwg use after correcting the ${graph} index build failure.`, { graph, builtAt: index.builtAt, invocationStartedAt: options.invocationStartedAt }));
|
|
563
|
+
if (!Number.isFinite(refreshedAt) || refreshedAt + 2_000 < startedAt) {
|
|
564
|
+
findings.push(finding(normalized, `index-stale:${graph}`, 'blocking', `The ${graph} capability index was not refreshed during this deployment.`, `Re-run aiwg use after correcting the ${graph} index build failure.`, { graph, builtAt: index.builtAt, statsBuiltAt: stats?.builtAt, invocationStartedAt: options.invocationStartedAt }));
|
|
558
565
|
}
|
|
559
566
|
}
|
|
560
567
|
}
|
|
@@ -569,7 +576,7 @@ export async function verifyProviderDeployment(options) {
|
|
|
569
576
|
}
|
|
570
577
|
const requiredContext = [
|
|
571
578
|
path.join(options.projectRoot, 'WORKSPACE.md'),
|
|
572
|
-
path.join(options.projectRoot, 'AIWG.md'),
|
|
579
|
+
...(definition?.paths.contextFiles.aiwgMd === false ? [] : [path.join(options.projectRoot, 'AIWG.md')]),
|
|
573
580
|
path.join(options.projectRoot, '.aiwg', 'AIWG.md'),
|
|
574
581
|
];
|
|
575
582
|
for (const contextPath of requiredContext) {
|
|
@@ -773,9 +780,12 @@ export async function buildDeploymentStatusProbe(projectRoot, frameworkRoot = pr
|
|
|
773
780
|
const notConfigured = result.requestedBundles.length === 0
|
|
774
781
|
&& result.findings.length > 0
|
|
775
782
|
&& result.findings.every((item) => item.id === 'deployment-not-configured');
|
|
783
|
+
const { rulePinState } = await import('../../rules/pin-state.js');
|
|
784
|
+
const rulePins = rulePinState(projectRoot, frameworkRoot);
|
|
776
785
|
const engaged = result.outcome === 'ready' || result.outcome === 'ready-restart-required' || result.outcome === 'degraded';
|
|
777
786
|
return {
|
|
778
787
|
schema: 'aiwg.status.probe.v1',
|
|
788
|
+
rule_pins: { rules: rulePins.rules, warnings: rulePins.warnings },
|
|
779
789
|
generated_at: result.generatedAt,
|
|
780
790
|
project_root: result.projectRoot,
|
|
781
791
|
engaged,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
export async function prepareProviderDeployments(frameworkRoot, jobs) {
|
|
4
|
+
const deployerUrl = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'deploy-agents.mjs')).href;
|
|
5
|
+
const deployer = await import(deployerUrl);
|
|
6
|
+
// Commands-to-skills migration is interactive and changes provider inputs.
|
|
7
|
+
// Run it serially in the coordinator before the shared snapshot is created;
|
|
8
|
+
// finalization then only applies post-deploy mirrors/pruning/config writes.
|
|
9
|
+
for (const job of jobs)
|
|
10
|
+
await deployer.main(job.args, { preflightOnly: true });
|
|
11
|
+
const url = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'providers', 'provider-prepare-coordinator.mjs')).href;
|
|
12
|
+
const coordinator = await import(url);
|
|
13
|
+
const sourceIndex = jobs[0]?.args.findIndex(arg => arg === '--source') ?? -1;
|
|
14
|
+
const srcRoot = sourceIndex >= 0 && jobs[0]?.args[sourceIndex + 1]
|
|
15
|
+
? path.resolve(jobs[0].args[sourceIndex + 1])
|
|
16
|
+
: frameworkRoot;
|
|
17
|
+
return coordinator.prepareProviderDeployments({ srcRoot, jobs, maxConcurrency: 2 });
|
|
18
|
+
}
|
|
19
|
+
export async function finalizePreparedProvider(frameworkRoot, args) {
|
|
20
|
+
const url = pathToFileURL(path.join(frameworkRoot, 'tools', 'agents', 'deploy-agents.mjs')).href;
|
|
21
|
+
const deployer = await import(url);
|
|
22
|
+
await deployer.main(args, { finalizeOnly: true });
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=provider-prepare-coordinator.js.map
|
|
@@ -3,7 +3,7 @@ import { createReadStream, existsSync } from 'fs';
|
|
|
3
3
|
import { createHash } from 'crypto';
|
|
4
4
|
import { createInterface } from 'readline';
|
|
5
5
|
import path from 'path';
|
|
6
|
-
import
|
|
6
|
+
import { getUserStateDir } from '../config/user-state.js';
|
|
7
7
|
import { readAiwgConfig } from '../config/aiwg-config.js';
|
|
8
8
|
import { PROJECT_AIWG_LOCATION_FILE, projectAiwgPath, projectControlPath, } from '../config/project-artifacts.js';
|
|
9
9
|
const DEFAULT_MAX_BYTES = 1_048_576;
|
|
@@ -487,8 +487,7 @@ function resolveUsagePath(scope, projectRoot, env) {
|
|
|
487
487
|
return null;
|
|
488
488
|
return projectAiwgPath(projectRoot, 'telemetry', 'skill-usage.jsonl');
|
|
489
489
|
}
|
|
490
|
-
|
|
491
|
-
return path.join(stateHome, 'aiwg', 'skill-usage.jsonl');
|
|
490
|
+
return path.join(getUserStateDir(env), 'skill-usage.jsonl');
|
|
492
491
|
}
|
|
493
492
|
async function appendBoundedJsonl(filePath, event, maxBytes) {
|
|
494
493
|
await mkdir(path.dirname(filePath), { recursive: true });
|