@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
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ATTRIBUTION_FIELD_PATTERN, DecisionAskUsageError, decisionCapabilities, DecisionLedgerSinceError, decisionLedgerHistory, decisionLedgerStats, evaluateRequestPath, listPatterns, livePlan, MAX_ATTRIBUTION_FIELD_LENGTH, materializeSyntheticClassificationSetup, parseDecisionLedgerSince, readDecisionContextFile, runDecisionOffloadCheckpoint, runOfflinePattern, setupJev, showPattern, syntheticClassificationSetup, validateDecisionInput, } from '../../decision/driver.js';
|
|
2
2
|
function jsonResult(value, exitCode = 0) {
|
|
3
3
|
return { exitCode, message: JSON.stringify(value, null, 2), rawOutput: true };
|
|
4
4
|
}
|
|
5
5
|
function usage() {
|
|
6
6
|
return [
|
|
7
|
-
'Usage: aiwg decision <capabilities|status|patterns|validate|evaluate|setup> [options]',
|
|
8
|
-
' aiwg decision ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5) [--context <text> | --context-file <path> | --context-stdin] [--threshold 0.8] [--timeout-ms 15000] [--json]',
|
|
7
|
+
'Usage: aiwg decision <capabilities|status|patterns|validate|evaluate|setup|history|stats> [options]',
|
|
8
|
+
' aiwg decision ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5) [--context <text> | --context-file <path> | --context-stdin] [--threshold 0.8] [--timeout-ms 15000] [--passes N] [--escalation-passes N] [--provider <id>] [--session <id>] [--caller <tag>] [--record-text] [--json]',
|
|
9
9
|
'',
|
|
10
10
|
'Commands:',
|
|
11
11
|
' capabilities|status Show offline readiness, primitives, config and feature availability',
|
|
@@ -17,7 +17,33 @@ function usage() {
|
|
|
17
17
|
' evaluate --request <path> [--host-policy-module <path>]',
|
|
18
18
|
' setup synthetic-classification [--output-dir <dir>]',
|
|
19
19
|
' setup jev [--token-stdin] [--region <r>] [--endpoint <url>] [--verify] [--remove]',
|
|
20
|
-
' ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5)',
|
|
20
|
+
' ask --question "<q>" (--yes-no | --choices a,b,c | --scale 1-5) [--provider <id>] [--session <id>] [--caller <tag>] [--record-text]',
|
|
21
|
+
' history [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--json]',
|
|
22
|
+
' stats [--since <date>] [--provider <id>] [--session <id>] [--kind yes-no|choices|scale] [--status answered|fallback] [--caller <tag>|<prefix>* | --no-caller] [--group-by provider|session|kind|caller|passes|escalation] [--json]',
|
|
23
|
+
'',
|
|
24
|
+
'Notes:',
|
|
25
|
+
' Every COMPLETED `ask` call (CLI and MCP) appends one record to the decision',
|
|
26
|
+
' ledger (.aiwg/decision/ledger.jsonl, resolved like `aiwg artifacts path`).',
|
|
27
|
+
' Usage errors (bad flags, oversized context) are never recorded. Question',
|
|
28
|
+
' and context text are never written unless --record-text is passed, and even',
|
|
29
|
+
' then only after redaction and truncation to a documented size cap. Every',
|
|
30
|
+
' other persisted field (session, caller, choice ids, answer, model, provider,',
|
|
31
|
+
' project root) is also redacted before being written. `questionDigest` and',
|
|
32
|
+
' `contextDigest` are plain SHA-256 over the raw text: a short, predictable',
|
|
33
|
+
' question can still be matched by hashing candidate guesses, so a digest is',
|
|
34
|
+
' not a confidentiality guarantee on its own.',
|
|
35
|
+
' `history` and `stats` read that ledger offline — no network, no Jev call.',
|
|
36
|
+
' `--since` is strict ISO-8601: a bare date or an offsetless timestamp is',
|
|
37
|
+
' interpreted as UTC; invalid calendar dates (e.g. 2026-02-30) are rejected,',
|
|
38
|
+
' including when an explicit offset is present.',
|
|
39
|
+
` --session and --caller must match ${ATTRIBUTION_FIELD_PATTERN.source} (<= ${MAX_ATTRIBUTION_FIELD_LENGTH} characters).`,
|
|
40
|
+
' `history`/`stats` accept `--caller <tag>` (exact), `--caller \'<prefix>*\'` (prefix; the only wildcard), or `--no-caller` (records with no tag; not combinable with `--caller`).',
|
|
41
|
+
' `history`/`stats` reject unknown flags and positional arguments with exit 2.',
|
|
42
|
+
' The ledger has no built-in retention: it grows without bound and the',
|
|
43
|
+
' operator may truncate or delete it at any time; readers tolerate a missing',
|
|
44
|
+
' file. The ledger trusts only the local filesystem under the project',
|
|
45
|
+
' artifact root, owned by the same user running aiwg — it is not a defense',
|
|
46
|
+
' against a hostile process already running as that user.',
|
|
21
47
|
].join('\n');
|
|
22
48
|
}
|
|
23
49
|
function takeOption(args, name) {
|
|
@@ -62,6 +88,16 @@ function parseScale(value) {
|
|
|
62
88
|
throw new DecisionAskUsageError('invalid-scale', '--scale requires a range like 1-5');
|
|
63
89
|
return { low: Number(match[1]), high: Number(match[2]) };
|
|
64
90
|
}
|
|
91
|
+
/** Shared by --session and --caller (review r1 finding 1): a conservative identifier shape, rejected with exit 2. */
|
|
92
|
+
function takeAttributionOption(args, name, reason) {
|
|
93
|
+
const value = takeOption(args, name);
|
|
94
|
+
if (value === undefined)
|
|
95
|
+
return undefined;
|
|
96
|
+
if (!ATTRIBUTION_FIELD_PATTERN.test(value)) {
|
|
97
|
+
throw new DecisionAskUsageError(reason, `${name} must match ${ATTRIBUTION_FIELD_PATTERN.source} (<= ${MAX_ATTRIBUTION_FIELD_LENGTH} characters)`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
65
101
|
async function decisionSetupJev(rest) {
|
|
66
102
|
const token = rest.includes('--token-stdin') ? (await readStdin()).trim() : undefined;
|
|
67
103
|
const result = await setupJev({
|
|
@@ -81,6 +117,9 @@ async function decisionAsk(ctx) {
|
|
|
81
117
|
const contextModes = flagCount(args, ['--context', '--context-file', '--context-stdin']);
|
|
82
118
|
if (contextModes > 1)
|
|
83
119
|
throw new DecisionAskUsageError('invalid-context', 'Select at most one context source');
|
|
120
|
+
// Validated before any Jev call, so a malformed attribution flag never wastes one.
|
|
121
|
+
const explicitSessionId = takeAttributionOption(args, '--session', 'invalid-session');
|
|
122
|
+
const caller = takeAttributionOption(args, '--caller', 'invalid-caller');
|
|
84
123
|
const question = args.includes('--question') ? takeRequiredOption(args, '--question') : '';
|
|
85
124
|
let context = takeOption(args, '--context');
|
|
86
125
|
if (args.includes('--context') && (context === undefined || context.startsWith('--'))) {
|
|
@@ -100,16 +139,186 @@ async function decisionAsk(ctx) {
|
|
|
100
139
|
: choices !== undefined ? { kind: 'choices', choices: choices.split(',').map(value => value.trim()).filter(Boolean) }
|
|
101
140
|
: { kind: 'scale', ...scale },
|
|
102
141
|
...(context === undefined ? {} : { context }),
|
|
142
|
+
...(args.includes('--passes') ? { passes: parseNumber(takeRequiredOption(args, '--passes'), '--passes') } : {}),
|
|
143
|
+
...(args.includes('--escalation-passes') ? { escalationPasses: parseNumber(takeRequiredOption(args, '--escalation-passes'), '--escalation-passes') } : {}),
|
|
103
144
|
...(args.includes('--threshold') ? { threshold: parseNumber(takeOption(args, '--threshold'), '--threshold') } : {}),
|
|
104
145
|
...(args.includes('--timeout-ms') ? { timeoutMs: parseNumber(takeOption(args, '--timeout-ms'), '--timeout-ms') } : {}),
|
|
105
146
|
};
|
|
106
|
-
const
|
|
147
|
+
const invocation = await runDecisionOffloadCheckpoint(input, {
|
|
148
|
+
transport: 'cli',
|
|
149
|
+
projectRoot: ctx.cwd,
|
|
150
|
+
env: process.env,
|
|
151
|
+
explicitProvider: takeOption(args, '--provider'),
|
|
152
|
+
explicitSessionId,
|
|
153
|
+
caller: caller ?? 'decision-cli:ask',
|
|
154
|
+
ledgerCaller: caller ?? null,
|
|
155
|
+
category: caller ? undefined : 'unattributed',
|
|
156
|
+
recordText: args.includes('--record-text'),
|
|
157
|
+
});
|
|
158
|
+
if (!invocation.result)
|
|
159
|
+
throw invocation.outcome === 'unknown' ? invocation.error : new Error('Decision ask was skipped');
|
|
160
|
+
const result = invocation.result;
|
|
107
161
|
if (args.includes('--json'))
|
|
108
162
|
return jsonResult(result);
|
|
109
163
|
if (result.status === 'fallback')
|
|
110
164
|
return { exitCode: 0, message: `FALLBACK to LLM: ${result.reason}`, rawOutput: true };
|
|
111
165
|
return { exitCode: 0, message: `${String(result.answer)} (confidence ${result.confidence?.toFixed(2) ?? 'unknown'}, ${result.model ?? 'unknown-model'})`, rawOutput: true };
|
|
112
166
|
}
|
|
167
|
+
function parseSince(value) {
|
|
168
|
+
if (value === undefined)
|
|
169
|
+
return undefined;
|
|
170
|
+
try {
|
|
171
|
+
return parseDecisionLedgerSince(value);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error instanceof DecisionLedgerSinceError)
|
|
175
|
+
throw new DecisionAskUsageError('invalid-since', error.message);
|
|
176
|
+
throw error;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const DECISION_LEDGER_KINDS = ['yes-no', 'choices', 'scale'];
|
|
180
|
+
const DECISION_LEDGER_STATUSES = ['answered', 'fallback'];
|
|
181
|
+
const DECISION_LEDGER_GROUP_BYS = ['provider', 'session', 'kind', 'caller', 'passes', 'escalation'];
|
|
182
|
+
function parseKindFilter(value) {
|
|
183
|
+
if (value === undefined)
|
|
184
|
+
return undefined;
|
|
185
|
+
if (!DECISION_LEDGER_KINDS.includes(value)) {
|
|
186
|
+
throw new DecisionAskUsageError('invalid-kind', `--kind must be one of ${DECISION_LEDGER_KINDS.join(', ')}`);
|
|
187
|
+
}
|
|
188
|
+
return value;
|
|
189
|
+
}
|
|
190
|
+
function parseStatusFilter(value) {
|
|
191
|
+
if (value === undefined)
|
|
192
|
+
return undefined;
|
|
193
|
+
if (!DECISION_LEDGER_STATUSES.includes(value)) {
|
|
194
|
+
throw new DecisionAskUsageError('invalid-status', `--status must be one of ${DECISION_LEDGER_STATUSES.join(', ')}`);
|
|
195
|
+
}
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
function parseGroupBy(value) {
|
|
199
|
+
if (value === undefined)
|
|
200
|
+
return undefined;
|
|
201
|
+
if (!DECISION_LEDGER_GROUP_BYS.includes(value)) {
|
|
202
|
+
throw new DecisionAskUsageError('invalid-group-by', `--group-by must be one of ${DECISION_LEDGER_GROUP_BYS.join(', ')}`);
|
|
203
|
+
}
|
|
204
|
+
return value;
|
|
205
|
+
}
|
|
206
|
+
const HISTORY_VALUE_FLAGS = ['--since', '--provider', '--session', '--kind', '--status', '--caller'];
|
|
207
|
+
const HISTORY_BOOL_FLAGS = ['--json', '--no-caller'];
|
|
208
|
+
const STATS_VALUE_FLAGS = [...HISTORY_VALUE_FLAGS, '--group-by'];
|
|
209
|
+
const STATS_BOOL_FLAGS = HISTORY_BOOL_FLAGS;
|
|
210
|
+
/**
|
|
211
|
+
* Strict allow-list for `history`/`stats`: unknown `--flags` and positional
|
|
212
|
+
* arguments are usage errors (exit 2) naming the offending token, instead of
|
|
213
|
+
* being silently ignored. `ask`/`setup` parsing is intentionally untouched.
|
|
214
|
+
*/
|
|
215
|
+
function assertLedgerArgs(args, valueFlags, boolFlags) {
|
|
216
|
+
let index = 0;
|
|
217
|
+
while (index < args.length) {
|
|
218
|
+
const token = args[index];
|
|
219
|
+
if (valueFlags.includes(token)) {
|
|
220
|
+
if (args[index + 1] === undefined)
|
|
221
|
+
throw new DecisionAskUsageError(`missing-${token.slice(2)}`, `${token} requires a value`);
|
|
222
|
+
index += 2;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (boolFlags.includes(token)) {
|
|
226
|
+
index += 1;
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (token.startsWith('--'))
|
|
230
|
+
throw new DecisionAskUsageError('unknown-flag', `unknown flag ${token}`);
|
|
231
|
+
throw new DecisionAskUsageError('unexpected-argument', `unexpected argument ${token}`);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Parses `--caller <tag>` for `history`/`stats`: an exact match, except a
|
|
236
|
+
* single trailing `*` means prefix match (`--caller 'address-issues:*'`).
|
|
237
|
+
* The tag itself must match the attribution shape; `--no-caller` (records
|
|
238
|
+
* with no caller tag) is parsed separately and cannot be combined with it.
|
|
239
|
+
*/
|
|
240
|
+
function parseCallerFilter(args) {
|
|
241
|
+
const raw = takeOption(args, '--caller');
|
|
242
|
+
const noCaller = args.includes('--no-caller');
|
|
243
|
+
if (raw !== undefined && noCaller) {
|
|
244
|
+
throw new DecisionAskUsageError('invalid-caller-filter', '--caller and --no-caller cannot be used together');
|
|
245
|
+
}
|
|
246
|
+
if (noCaller)
|
|
247
|
+
return { noCaller: true };
|
|
248
|
+
if (raw === undefined)
|
|
249
|
+
return {};
|
|
250
|
+
if (raw === '' || raw.startsWith('--')) {
|
|
251
|
+
throw new DecisionAskUsageError('invalid-caller', '--caller requires a non-empty value');
|
|
252
|
+
}
|
|
253
|
+
const prefix = raw.endsWith('*');
|
|
254
|
+
const tag = prefix ? raw.slice(0, -1) : raw;
|
|
255
|
+
if (tag === '' || !ATTRIBUTION_FIELD_PATTERN.test(tag)) {
|
|
256
|
+
throw new DecisionAskUsageError('invalid-caller', `--caller must match ${ATTRIBUTION_FIELD_PATTERN.source} (<= ${MAX_ATTRIBUTION_FIELD_LENGTH} characters), allowing one trailing *`);
|
|
257
|
+
}
|
|
258
|
+
return prefix ? { callerPrefix: tag } : { caller: tag };
|
|
259
|
+
}
|
|
260
|
+
/** Shared by `history` and `stats` (review r1 finding 9): the same filters, parsed the same way. */
|
|
261
|
+
function parseLedgerFilters(args) {
|
|
262
|
+
return {
|
|
263
|
+
since: parseSince(takeOption(args, '--since')),
|
|
264
|
+
provider: takeOption(args, '--provider'),
|
|
265
|
+
sessionId: takeOption(args, '--session'),
|
|
266
|
+
kind: parseKindFilter(takeOption(args, '--kind')),
|
|
267
|
+
status: parseStatusFilter(takeOption(args, '--status')),
|
|
268
|
+
...parseCallerFilter(args),
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
/** One header line stating the caller filter, shown only when one is set. */
|
|
272
|
+
function callerFilterHeader(filters) {
|
|
273
|
+
if (filters.noCaller)
|
|
274
|
+
return 'Caller filter: no caller (records with no caller tag)';
|
|
275
|
+
if (filters.caller !== undefined)
|
|
276
|
+
return `Caller filter: ${filters.caller}`;
|
|
277
|
+
if (filters.callerPrefix !== undefined)
|
|
278
|
+
return `Caller filter: ${filters.callerPrefix}*`;
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
async function decisionHistory(ctx) {
|
|
282
|
+
const args = ctx.args.slice(1);
|
|
283
|
+
assertLedgerArgs(args, HISTORY_VALUE_FLAGS, HISTORY_BOOL_FLAGS);
|
|
284
|
+
const filters = parseLedgerFilters(args);
|
|
285
|
+
const result = await decisionLedgerHistory(ctx.cwd, filters);
|
|
286
|
+
if (args.includes('--json'))
|
|
287
|
+
return jsonResult(result);
|
|
288
|
+
const header = result.skipped > 0 ? [`(${result.skipped} invalid line(s) skipped)`] : [];
|
|
289
|
+
const callerHeader = callerFilterHeader(filters);
|
|
290
|
+
if (callerHeader)
|
|
291
|
+
header.push(callerHeader);
|
|
292
|
+
if (result.count === 0)
|
|
293
|
+
return { exitCode: 0, message: [...header, 'No decision ledger records match the filters.'].join('\n'), rawOutput: true };
|
|
294
|
+
const lines = result.records.map(record => `${record.timestamp} ${record.status.padEnd(8)} provider=${record.provider} kind=${record.decisionKind} confidence=${record.confidence ?? '-'} caller=${record.caller ?? '-'} id=${record.id}`);
|
|
295
|
+
return { exitCode: 0, message: [...header, ...lines].join('\n'), rawOutput: true };
|
|
296
|
+
}
|
|
297
|
+
async function decisionStats(ctx) {
|
|
298
|
+
const args = ctx.args.slice(1);
|
|
299
|
+
assertLedgerArgs(args, STATS_VALUE_FLAGS, STATS_BOOL_FLAGS);
|
|
300
|
+
const filters = { ...parseLedgerFilters(args), groupBy: parseGroupBy(takeOption(args, '--group-by')) };
|
|
301
|
+
const result = await decisionLedgerStats(ctx.cwd, filters);
|
|
302
|
+
if (args.includes('--json'))
|
|
303
|
+
return jsonResult(result);
|
|
304
|
+
const header = result.skipped > 0 ? [`(${result.skipped} invalid line(s) skipped)`] : [];
|
|
305
|
+
const callerHeader = callerFilterHeader(filters);
|
|
306
|
+
if (callerHeader)
|
|
307
|
+
header.push(callerHeader);
|
|
308
|
+
if (result.groups.length === 0)
|
|
309
|
+
return { exitCode: 0, message: [...header, 'No decision ledger records match the filters.'].join('\n'), rawOutput: true };
|
|
310
|
+
const lines = result.groups.flatMap(group => [
|
|
311
|
+
`${result.groupBy ?? 'all'}=${group.key ?? 'null'}: ${group.totalCalls} calls (${group.answered} answered, ${group.fallback} fallback, hit rate=${group.hitRate.toFixed(2)}, fallback rate=${group.fallbackRate.toFixed(2)})`,
|
|
312
|
+
` confidence: mean=${group.confidence.mean?.toFixed(2) ?? '-'} min=${group.confidence.min?.toFixed(2) ?? '-'} max=${group.confidence.max?.toFixed(2) ?? '-'} (n=${group.confidence.count})`,
|
|
313
|
+
` agreement: mean=${group.agreement.mean?.toFixed(2) ?? '-'} escalated=${group.escalatedCalls} passes run=${group.passesRun}`,
|
|
314
|
+
` jev usage: input=${group.jevUsage.inputTokens} output=${group.jevUsage.outputTokens}`,
|
|
315
|
+
` tokens per answered decision=${group.tokensPerAnsweredDecision?.toFixed(2) ?? '-'}`,
|
|
316
|
+
` llm_tokens_avoided=${group.llm_tokens_avoided} jev_tokens=${group.jev_tokens} cost_weighted_net_usd=${group.cost_weighted_net_usd.toFixed(6)}`,
|
|
317
|
+
` v1 comparison only: estimated LLM tokens avoided=${group.estimatedLlmTokensAvoidedTotal} net savings=${group.netSavingsTokens}`,
|
|
318
|
+
...(group.legacyReestimatedCalls ? [` v1 records re-estimated=${group.legacyReestimatedCalls} weights=${JSON.stringify(result.legacyEstimationWeights)}`] : []),
|
|
319
|
+
]);
|
|
320
|
+
return { exitCode: 0, message: [...header, ...lines].join('\n'), rawOutput: true };
|
|
321
|
+
}
|
|
113
322
|
async function executeDecision(ctx) {
|
|
114
323
|
const [command, subcommand, ...rest] = ctx.args;
|
|
115
324
|
const options = { cwd: ctx.cwd, frameworkRoot: ctx.frameworkRoot, env: process.env };
|
|
@@ -120,6 +329,10 @@ async function executeDecision(ctx) {
|
|
|
120
329
|
return jsonResult(decisionCapabilities(options));
|
|
121
330
|
if (command === 'ask')
|
|
122
331
|
return await decisionAsk(ctx);
|
|
332
|
+
if (command === 'history')
|
|
333
|
+
return await decisionHistory(ctx);
|
|
334
|
+
if (command === 'stats')
|
|
335
|
+
return await decisionStats(ctx);
|
|
123
336
|
if (command === 'patterns') {
|
|
124
337
|
if (subcommand === 'list')
|
|
125
338
|
return jsonResult(listPatterns());
|
|
@@ -26,6 +26,8 @@ import { getLoggerInfo } from '../log.js';
|
|
|
26
26
|
import { readAiwgConfig, getProjectDir } from '../../config/aiwg-config.js';
|
|
27
27
|
import { getLogger } from '../log.js';
|
|
28
28
|
import { spawnSync } from 'child_process';
|
|
29
|
+
import { boundedSpawnSync } from '../../process/bounded-child-process.mjs';
|
|
30
|
+
import { exitCodeForSpawnResult } from '../child-process-result.js';
|
|
29
31
|
import { readFileSync, writeFileSync, existsSync, statSync, readdirSync, mkdtempSync, rmSync } from 'fs';
|
|
30
32
|
import path from 'path';
|
|
31
33
|
import os from 'os';
|
|
@@ -85,9 +87,14 @@ export const diagnoseHandler = {
|
|
|
85
87
|
}
|
|
86
88
|
// tar it up via system tar. We rely on GNU/BSD tar being present;
|
|
87
89
|
// degrade gracefully if not.
|
|
88
|
-
|
|
90
|
+
// Packaging a small local diagnostics bundle; quick tier (#3062).
|
|
91
|
+
const tar = boundedSpawnSync('tar', ['-czf', outPath, '-C', stage, '.'], 'quick', { stdio: 'pipe' });
|
|
89
92
|
if (tar.status !== 0) {
|
|
90
|
-
|
|
93
|
+
// #3062 review item 7: already correctly treats a null status
|
|
94
|
+
// (timeout/signal) as failure; surface the bounded helper's
|
|
95
|
+
// diagnostic (e.g. the enriched timeout message) ahead of stderr.
|
|
96
|
+
const detail = exitCodeForSpawnResult(tar).message ?? tar.stderr?.toString() ?? '(no stderr)';
|
|
97
|
+
ui.error(`tar failed: ${detail}`);
|
|
91
98
|
ui.info(`Bundle contents staged at: ${stage}`);
|
|
92
99
|
ui.info(`You can tar it manually: tar -czf ${outName} -C ${stage} .`);
|
|
93
100
|
return { exitCode: 1, error: new Error('tar failed') };
|
|
@@ -200,9 +207,9 @@ function redactSecretsInObject(obj) {
|
|
|
200
207
|
}
|
|
201
208
|
function collectGitInfo(cwd) {
|
|
202
209
|
try {
|
|
203
|
-
const branch = spawnSync('git', ['-C', cwd, 'rev-parse', '--abbrev-ref', 'HEAD'], { stdio: 'pipe', timeout: 5000 });
|
|
204
|
-
const log = spawnSync('git', ['-C', cwd, 'log', '-10', '--oneline'], { stdio: 'pipe', timeout: 5000 });
|
|
205
|
-
const remote = spawnSync('git', ['-C', cwd, 'remote', '-v'], { stdio: 'pipe', timeout: 5000 });
|
|
210
|
+
const branch = spawnSync('git', ['-C', cwd, 'rev-parse', '--abbrev-ref', 'HEAD'], { stdio: 'pipe', timeout: 5000, killSignal: 'SIGKILL' });
|
|
211
|
+
const log = spawnSync('git', ['-C', cwd, 'log', '-10', '--oneline'], { stdio: 'pipe', timeout: 5000, killSignal: 'SIGKILL' });
|
|
212
|
+
const remote = spawnSync('git', ['-C', cwd, 'remote', '-v'], { stdio: 'pipe', timeout: 5000, killSignal: 'SIGKILL' });
|
|
206
213
|
if (branch.status !== 0)
|
|
207
214
|
return null;
|
|
208
215
|
return [
|
|
@@ -225,6 +232,7 @@ function collectDoctorOutput() {
|
|
|
225
232
|
stdio: 'pipe',
|
|
226
233
|
timeout: 30_000,
|
|
227
234
|
env: { ...process.env, AIWG_LOG_DISABLE: '1', NO_COLOR: '1' },
|
|
235
|
+
killSignal: 'SIGKILL',
|
|
228
236
|
});
|
|
229
237
|
const out = r.stdout?.toString() ?? '';
|
|
230
238
|
const err = r.stderr?.toString() ?? '';
|
|
@@ -243,7 +243,7 @@ function openLedger(session, registry) {
|
|
|
243
243
|
* `kinds`, `record`, `reconcile` and `probe` all use it, so `kinds` lists
|
|
244
244
|
* exactly what the registry contains. Tracker authority is resolved lazily at
|
|
245
245
|
* verification time, so a project without tracker configuration still lists
|
|
246
|
-
* the tracker kinds and answers `unknown`
|
|
246
|
+
* the tracker kinds and answers `unknown` with a tracker precondition reason.
|
|
247
247
|
*/
|
|
248
248
|
export function buildCliVerifierRegistry(projectRoot, extensions = [], tracker = { config: null, remoteUrls: {} }) {
|
|
249
249
|
const injected = new Set(extensions.map(verifier => verifier.kind));
|
|
@@ -425,7 +425,9 @@ function expectationsFrom(parsed) {
|
|
|
425
425
|
return { expected, ...(timeoutMs !== undefined ? { timeoutMs } : {}), ...(verifierVersion ? { verifierVersion } : {}) };
|
|
426
426
|
}
|
|
427
427
|
function emit(rendered, format) {
|
|
428
|
-
const
|
|
428
|
+
const evidence = rendered.output.evidence;
|
|
429
|
+
const hint = typeof evidence?.hint === 'string' ? `\n${evidence.hint}` : '';
|
|
430
|
+
const message = format === 'text' ? rendered.text + hint : effectOutputJson(rendered.output);
|
|
429
431
|
return { exitCode: rendered.output.exitCode, message, rawOutput: true };
|
|
430
432
|
}
|
|
431
433
|
function errorOutput(error) {
|
|
@@ -28,6 +28,9 @@ function usage() {
|
|
|
28
28
|
}
|
|
29
29
|
export const evidenceHandler = {
|
|
30
30
|
id: 'evidence', name: 'Evidence', description: 'Export and verify portable evaluation evidence bundles', category: 'utility', aliases: [],
|
|
31
|
+
async help() {
|
|
32
|
+
return { exitCode: 0, message: usage(), rawOutput: true };
|
|
33
|
+
},
|
|
31
34
|
async execute(ctx) {
|
|
32
35
|
const [subcommand] = ctx.args;
|
|
33
36
|
if (!subcommand || subcommand === '--help' || subcommand === '-h')
|
|
@@ -19,11 +19,12 @@
|
|
|
19
19
|
*
|
|
20
20
|
* @issue #885
|
|
21
21
|
*/
|
|
22
|
-
import {
|
|
22
|
+
import { boundedSpawnSync } from '../../process/bounded-child-process.mjs';
|
|
23
23
|
import os from 'os';
|
|
24
24
|
import { readAiwgConfig } from '../../config/aiwg-config.js';
|
|
25
25
|
import { createPromptInterface, askString, askChoice } from '../prompt-utils.js';
|
|
26
26
|
import { debug } from '../log.js';
|
|
27
|
+
import { exitCodeForSpawnResult } from '../child-process-result.js';
|
|
27
28
|
// ── GitHub repo ───────────────────────────────────────────────────────────────
|
|
28
29
|
const GITHUB_REPO = 'jmagly/aiwg';
|
|
29
30
|
const GITHUB_ISSUES_URL = `https://github.com/${GITHUB_REPO}/issues/new`;
|
|
@@ -57,7 +58,7 @@ async function collectSystemContext(cwd) {
|
|
|
57
58
|
// aiwg version from package.json if available
|
|
58
59
|
let aiwgVersion = 'unknown';
|
|
59
60
|
try {
|
|
60
|
-
const r =
|
|
61
|
+
const r = boundedSpawnSync(process.execPath, [process.argv[1], 'version'], 'quick', {
|
|
61
62
|
encoding: 'utf-8',
|
|
62
63
|
stdio: 'pipe',
|
|
63
64
|
});
|
|
@@ -235,7 +236,7 @@ async function promptSelect(question, options, signal) {
|
|
|
235
236
|
// ── Submission ────────────────────────────────────────────────────────────────
|
|
236
237
|
function hasGhCli() {
|
|
237
238
|
try {
|
|
238
|
-
const r =
|
|
239
|
+
const r = boundedSpawnSync('gh', ['--version'], 'quick', { stdio: 'pipe' });
|
|
239
240
|
return r.status === 0;
|
|
240
241
|
}
|
|
241
242
|
catch {
|
|
@@ -244,7 +245,14 @@ function hasGhCli() {
|
|
|
244
245
|
}
|
|
245
246
|
function submitViaGh(title, body, type) {
|
|
246
247
|
const label = type === 'bug' ? 'bug' : type === 'feature' ? 'enhancement' : type === 'doc' ? 'documentation' : 'feedback';
|
|
247
|
-
|
|
248
|
+
// Creates a GitHub issue via the `gh` CLI (network call); network tier (#3062).
|
|
249
|
+
const result = boundedSpawnSync('gh', ['issue', 'create', '--repo', GITHUB_REPO, '--title', title, '--body', body, '--label', label], 'network', { stdio: 'inherit' });
|
|
250
|
+
// #3062 review item 7: already correctly treats a null status
|
|
251
|
+
// (timeout/signal) as failure; surface the bounded helper's diagnostic
|
|
252
|
+
// under AIWG_DEBUG — the caller falls back to the browser either way.
|
|
253
|
+
const { message } = exitCodeForSpawnResult(result, 'gh issue create');
|
|
254
|
+
if (message)
|
|
255
|
+
debug('cli:feedback:gh', message);
|
|
248
256
|
return result.status === 0;
|
|
249
257
|
}
|
|
250
258
|
function submitViaBrowser(title, body) {
|
|
@@ -260,7 +268,8 @@ function submitViaBrowser(title, body) {
|
|
|
260
268
|
: process.platform === 'win32'
|
|
261
269
|
? 'start'
|
|
262
270
|
: 'xdg-open';
|
|
263
|
-
|
|
271
|
+
// Fire-and-forget local browser launch; quick tier (#3062).
|
|
272
|
+
boundedSpawnSync(openCmd, [urlStr], 'quick', { stdio: 'ignore' });
|
|
264
273
|
console.log(`\n Opened GitHub in your browser to file the issue.`);
|
|
265
274
|
console.log(` If the browser did not open, visit:\n ${urlStr}`);
|
|
266
275
|
}
|
|
@@ -92,6 +92,7 @@ function displayHelp() {
|
|
|
92
92
|
['show <type> <name>', 'Stream the body of an indexed artifact'],
|
|
93
93
|
['versions <list|resolve|show>', 'Browse and resolve signed AIWG web resource releases'],
|
|
94
94
|
['auth <login|status|logout>', 'Authenticate for paid AIWG web resources'],
|
|
95
|
+
['corpus <subcommand>', 'Research corpus tools (snapshot, radar, profiles, curator)'],
|
|
95
96
|
['index <subcommand>', 'Manage the artifact index (build/query/discover/deps/stats)'],
|
|
96
97
|
['artifacts move --to <path>', 'Move/rename the project AIWG artifact root and reindex'],
|
|
97
98
|
]);
|
|
@@ -73,6 +73,7 @@ import { installationHandler } from './installation.js';
|
|
|
73
73
|
import { uhpHandler } from './uhp.js';
|
|
74
74
|
import { schemaHandler } from './schema.js';
|
|
75
75
|
import { datasetHandler } from './dataset.js';
|
|
76
|
+
import { rulesHandler } from './rules.js';
|
|
76
77
|
import { decisionHandler } from './decision.js';
|
|
77
78
|
import { gatesHandler } from './gates.js';
|
|
78
79
|
// Re-export individual handlers
|
|
@@ -80,7 +81,7 @@ export {
|
|
|
80
81
|
// Maintenance
|
|
81
82
|
helpHandler, versionHandler, authHandler, doctorHandler, contextFirewallHandler, updateHandler, refreshHandler, regenerateHandler, workspaceContextHandler,
|
|
82
83
|
// Framework management
|
|
83
|
-
useHandler, listHandler, removeHandler, promoteHandler, installHandler, packagesHandler, marketplaceHandler, initHandler, setupHandler, setupGenerateHandler, setupRunHandler, setupValidateHandler, issueHandler, issueAuditHandler, runHandler, jobHandler, costReportHandler, evidenceHandler, artifactVerifyHandler, outputModeHandler, writerProfileHandler, botHandoffHandler, buildVerifyHandler, writingHandler, schemaHandler, datasetHandler, decisionHandler, gatesHandler, installationHandler,
|
|
84
|
+
useHandler, listHandler, removeHandler, promoteHandler, installHandler, packagesHandler, marketplaceHandler, initHandler, setupHandler, setupGenerateHandler, setupRunHandler, setupValidateHandler, issueHandler, issueAuditHandler, runHandler, jobHandler, costReportHandler, evidenceHandler, artifactVerifyHandler, outputModeHandler, writerProfileHandler, botHandoffHandler, buildVerifyHandler, writingHandler, schemaHandler, datasetHandler, decisionHandler, rulesHandler, gatesHandler, installationHandler,
|
|
84
85
|
// Project
|
|
85
86
|
newBundleHandler, quickrefHandler, newProjectHandler, sessionHandler, sessionsHandler,
|
|
86
87
|
// Workspace
|
|
@@ -172,6 +173,7 @@ export const allHandlers = [
|
|
|
172
173
|
schemaHandler,
|
|
173
174
|
datasetHandler,
|
|
174
175
|
decisionHandler,
|
|
176
|
+
rulesHandler,
|
|
175
177
|
gatesHandler,
|
|
176
178
|
// Workspace management
|
|
177
179
|
...workspaceHandlers,
|