@aiwg/cli 2026.10.10 → 2026.10.12
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/agentic/code/providers/model-capabilities.v1.json +78 -14
- package/agentic/code/providers/model-catalog.v1.json +62 -12
- package/dist/src/artifacts/binding-target-identity.js +51 -0
- package/dist/src/artifacts/checksum-manifest.js +12 -0
- package/dist/src/artifacts/index-builder.js +11 -13
- package/dist/src/artifacts/query-engine.js +5 -11
- package/dist/src/cli/handlers/doctor-help.js +32 -0
- package/dist/src/cli/handlers/gates.js +19 -18
- package/dist/src/cli/handlers/models-help.js +7 -1
- package/dist/src/cli/handlers/models.js +3 -3
- package/dist/src/cli/handlers/script-runner.js +8 -5
- package/dist/src/cli/handlers/sessions-intake.js +104 -0
- package/dist/src/cli/handlers/sessions-tail.js +172 -0
- package/dist/src/cli/handlers/sessions.js +287 -31
- package/dist/src/cli/handlers/skill-lint.js +10 -3
- package/dist/src/cli/handlers/steward-format.js +100 -0
- package/dist/src/cli/handlers/steward-models.js +167 -0
- package/dist/src/cli/handlers/steward.js +14 -248
- package/dist/src/cli/handlers/use-bundle-counts.js +61 -0
- package/dist/src/cli/handlers/use.js +18 -28
- package/dist/src/cli/handlers/utilities.js +1 -24
- package/dist/src/config/aiwg-config.js +7 -0
- package/dist/src/config/authorization-cli.js +89 -0
- package/dist/src/config/cli-help.js +1 -0
- package/dist/src/config/cli.js +10 -1
- package/dist/src/config/worker-context.js +337 -0
- package/dist/src/decision/context-pruning.js +3 -2
- package/dist/src/decision/ensemble/contract.js +15 -4
- package/dist/src/decision/ensemble-study/artifacts.js +5 -0
- package/dist/src/decision/ensemble-study/score.js +4 -3
- package/dist/src/decision/feature-export.js +3 -9
- package/dist/src/decision/heldout/collector.js +2 -2
- package/dist/src/decision/issue-triage/runtime.js +3 -9
- package/dist/src/decision/qualification/gates.js +2 -1
- package/dist/src/decision/qualification/release.js +2 -3
- package/dist/src/decision/routing/report.js +2 -0
- package/dist/src/decision/sdlc-screening.js +3 -5
- package/dist/src/decision/sensitivity/comparative.js +5 -3
- package/dist/src/gates/driver.js +6 -77
- package/dist/src/gates/evaluate.js +4 -11
- package/dist/src/gates/floors.js +4 -4
- package/dist/src/gates/index.js +3 -3
- package/dist/src/gates/lattice.js +26 -0
- package/dist/src/gates/registry.js +2 -1
- package/dist/src/gates/report.js +19 -7
- package/dist/src/issues/audit-cli.js +120 -0
- package/dist/src/issues/audit-contract.js +64 -0
- package/dist/src/issues/audit-local.js +82 -0
- package/dist/src/issues/audit.js +220 -0
- package/dist/src/lint/rule-activation.js +15 -1
- package/dist/src/mcp/tools/worker-invoke.mjs +108 -10
- package/dist/src/mission-protocol/canonical-codecs.js +270 -0
- package/dist/src/mission-protocol/codecs.js +22 -550
- package/dist/src/mission-protocol/health-trace-codecs.js +281 -0
- package/dist/src/mission-protocol/health-trace-types.js +43 -0
- package/dist/src/mission-protocol/types.js +2 -42
- package/dist/src/mission-protocol/worker-contract-json.js +10 -0
- package/dist/src/mission-protocol/worker-review-gate.js +100 -0
- package/dist/src/mission-protocol/worker-review-types.js +2 -0
- package/dist/src/models/catalog-policy.js +280 -0
- package/dist/src/models/index.js +1 -1
- package/dist/src/models/model-capabilities.v1.json +78 -14
- package/dist/src/models/model-catalog.v1.json +62 -12
- package/dist/src/models/policy-resources.js +28 -0
- package/dist/src/models/provider-policy.js +10 -539
- package/dist/src/models/resolver.js +26 -8
- package/dist/src/models/router.js +15 -2
- package/dist/src/models/tiers.js +13 -0
- package/dist/src/models/types.js +0 -6
- package/dist/src/models/worker-ceilings.js +59 -0
- package/dist/src/models/worker-invocation-policy.js +243 -0
- package/dist/src/models/worker-plan.js +16 -20
- package/dist/src/models/worker-review-lineage.js +55 -0
- package/dist/src/models/worker-selection-policy.js +1 -1
- package/dist/src/models/wrapper-route.js +6 -3
- package/dist/src/policy/authorization.js +30 -1
- package/dist/src/policy/hitl-config.js +63 -0
- package/dist/src/policy/hitl-receipt.js +57 -0
- package/dist/src/policy/hitl-types.js +4 -0
- package/dist/src/policy/hitl-validation.js +39 -0
- package/dist/src/policy/hitl.js +117 -0
- package/dist/src/process/aiwg-probe-command.d.mts +15 -0
- package/dist/src/process/aiwg-probe-command.mjs +37 -0
- package/dist/src/rules/activation.d.mts +1 -1
- package/dist/src/rules/activation.mjs +0 -2
- package/dist/src/rules/gate-coverage.js +51 -0
- package/dist/src/rules/gate-references.js +16 -0
- package/dist/src/rules/rule-frontmatter.schema.json +7 -1
- package/dist/src/serve/worker-command-request.js +21 -4
- package/dist/src/serve/worker-invocation-preparation.js +3 -1
- package/dist/src/serve/worker-invocation.js +21 -10
- package/dist/src/sessions/adapters/deepseek-harness.js +1 -0
- package/dist/src/sessions/adapters/grok-build-native.js +269 -0
- package/dist/src/sessions/adapters/grok-build.js +57 -15
- package/dist/src/sessions/adapters/grokbot.js +7 -0
- package/dist/src/sessions/adapters/hermes-state-db.js +252 -0
- package/dist/src/sessions/adapters/hermes.js +42 -3
- package/dist/src/sessions/adapters/warp.js +1 -1
- package/dist/src/sessions/batch-import.js +44 -6
- package/dist/src/sessions/contracts.js +20 -1
- package/dist/src/sessions/coverage-preflight.js +7 -1
- package/dist/src/sessions/discovery-capability.js +38 -0
- package/dist/src/sessions/fortemi-export-mapping.js +33 -3
- package/dist/src/sessions/host-catalog.js +157 -0
- package/dist/src/sessions/image-blobs.js +141 -0
- package/dist/src/sessions/importer.js +9 -232
- package/dist/src/sessions/index.js +6 -0
- package/dist/src/sessions/intake-dir.js +71 -0
- package/dist/src/sessions/normalization.js +251 -0
- package/dist/src/sessions/refresh.js +25 -2
- package/dist/src/sessions/repository.js +164 -22
- package/dist/src/sessions/tail.js +91 -0
- package/dist/src/sessions/workspace-discovery.js +88 -9
- package/dist/src/skills/agent-skill-sidecar.js +28 -0
- package/dist/src/skills/agent-skills.js +4 -23
- package/dist/src/skills/claude-surface-projection.js +25 -0
- package/dist/src/skills/deployer.js +8 -288
- package/dist/src/skills/deployment-policy.js +114 -0
- package/dist/src/skills/deployment-projection.js +152 -0
- package/dist/src/skills/deployment-types.js +20 -0
- package/dist/src/skills/exporter.js +8 -31
- package/dist/src/skills/provider-extensions.js +41 -0
- package/dist/src/skills/run.js +6 -0
- package/dist/src/skills/types.js +0 -8
- package/dist/src/skills/validator-resources.js +68 -0
- package/dist/src/skills/validator.js +6 -55
- package/dist/src/storage/cli-migrate-options.js +125 -0
- package/dist/src/storage/cli-migrate.js +111 -0
- package/dist/src/storage/cli.js +4 -279
- package/dist/src/storage/migration-adapter.js +79 -0
- package/dist/src/storage/migration-copy.js +108 -0
- package/dist/src/storage/migration-protocol.js +14 -197
- package/dist/src/storage/migration-records.js +186 -0
- package/dist/src/storage/migration-types.js +12 -0
- package/dist/src/tracker/forge-http.js +2 -1
- package/dist/src/tracker/issue-pages.js +110 -0
- package/package.json +7 -1
- package/schemas/mission-v1.schema.json +335 -0
- package/schemas/models/model-catalog.v1.schema.json +19 -1
- package/schemas/models/model-config-compatibility.v1.schema.json +3 -2
- package/schemas/models/model-policy.v1.schema.json +1 -1
- package/tools/agents/providers/provider-paths-staging.mjs +35 -0
- package/tools/agents/providers/rule-binding-targets.mjs +146 -0
- package/tools/agents/providers/rule-delivery.mjs +7 -126
- package/tools/ralph-external/lib/muse-adapter.mjs +10 -0
- package/tools/ralph-external/lib/worker-context.mjs +237 -0
- package/tools/ralph-external/lib/worker-invocation-ancestry.mjs +132 -0
- package/tools/ralph-external/lib/worker-invocation-processes.mjs +123 -0
- package/tools/ralph-external/lib/worker-isolation-status.mjs +48 -0
- package/tools/ralph-external/lib/worker-isolation.mjs +17 -29
- package/tools/ralph-external/lib/worker-launch-cli.mjs +3 -1
- package/tools/ralph-external/lib/worker-overflow.mjs +48 -13
- package/tools/ralph-external/lib/worker-retry-evidence.mjs +103 -0
- package/tools/ralph-external/lib/worker-termination.mjs +82 -0
- package/tools/ralph-external/session-launcher.mjs +51 -96
- package/vscode-extension/schemas/aiwg.config.v1.json +177 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Formats the steward capability matrix and permission command usage.
|
|
2
|
+
import { isExternalStrategy } from '../../providers/capability-matrix.js';
|
|
3
|
+
export function printFullMatrix(matrix) {
|
|
4
|
+
const { providers, features } = matrix;
|
|
5
|
+
const providerIds = Object.keys(providers);
|
|
6
|
+
const featureIds = Object.keys(features);
|
|
7
|
+
console.log(`\n Provider Capability Matrix (v${matrix.version})`);
|
|
8
|
+
console.log(` ✓ = native ~ = AIWG emulation - = not supported\n`);
|
|
9
|
+
const featureColW = 20;
|
|
10
|
+
const provColW = 14;
|
|
11
|
+
const header = ' ' + 'Feature'.padEnd(featureColW) + providerIds.map(p => p.padEnd(provColW)).join('');
|
|
12
|
+
console.log(header);
|
|
13
|
+
console.log(' ' + '─'.repeat(featureColW + providerIds.length * provColW));
|
|
14
|
+
for (const featureId of featureIds) {
|
|
15
|
+
const feat = features[featureId];
|
|
16
|
+
let row = ' ' + featureId.padEnd(featureColW);
|
|
17
|
+
for (const providerId of providerIds) {
|
|
18
|
+
const provider = providers[providerId];
|
|
19
|
+
const isNative = provider?.native_features?.[featureId] === true;
|
|
20
|
+
const emulation = provider?.emulation?.[featureId] ?? null;
|
|
21
|
+
const mark = isNative ? '✓' : (emulation ? '~' : '-');
|
|
22
|
+
row += mark.padEnd(provColW);
|
|
23
|
+
}
|
|
24
|
+
console.log(row);
|
|
25
|
+
if (feat?.description) {
|
|
26
|
+
console.log(' ' + ' '.repeat(featureColW) + feat.description);
|
|
27
|
+
}
|
|
28
|
+
console.log('');
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
// ── Main execution ─────────────────────────────────────────────────────────────
|
|
32
|
+
export function permissionsUsage() {
|
|
33
|
+
return `
|
|
34
|
+
aiwg steward permissions — authorization model audit and normalization
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
aiwg steward permissions audit Find normalized-model errors and legacy grants
|
|
38
|
+
aiwg steward permissions migrate --dry-run Preview legacy permission normalization
|
|
39
|
+
aiwg steward permissions migrate --apply Back up and atomically normalize config
|
|
40
|
+
|
|
41
|
+
Reads .aiwg/aiwg.config authorization block. Migration backs up before writing.
|
|
42
|
+
`;
|
|
43
|
+
}
|
|
44
|
+
const NATIVE_MARK = '✓ native';
|
|
45
|
+
const EMULATED_MARK = '~ emulated';
|
|
46
|
+
const EXTERNAL_MARK = '↗ external';
|
|
47
|
+
const UNSUPPORTED_MARK = '- not supported';
|
|
48
|
+
export function emulationLabel(strategy) {
|
|
49
|
+
if (!strategy)
|
|
50
|
+
return 'none';
|
|
51
|
+
if (strategy === 'native')
|
|
52
|
+
return 'native (no fallback needed)';
|
|
53
|
+
return strategy;
|
|
54
|
+
}
|
|
55
|
+
export function formatProvider(id, provider, matrix, meta) {
|
|
56
|
+
const lines = [];
|
|
57
|
+
lines.push(`\n Provider: ${provider.display_name} (${id})`);
|
|
58
|
+
if (meta) {
|
|
59
|
+
lines.push(` Project-local: yes`);
|
|
60
|
+
lines.push(` Base adapter: ${meta.baseAdapter}`);
|
|
61
|
+
}
|
|
62
|
+
lines.push(` Status: ${provider.status}`);
|
|
63
|
+
lines.push(` Daemon: ${provider.daemon_tier}${provider.daemon_pty_adapter ? ' (+ pty-adapter)' : ''}`);
|
|
64
|
+
lines.push(` ${'─'.repeat(60)}`);
|
|
65
|
+
const featureKeys = Object.keys(matrix.features);
|
|
66
|
+
for (const featureId of featureKeys) {
|
|
67
|
+
const isNative = provider.native_features?.[featureId] === true;
|
|
68
|
+
const emulation = provider.emulation?.[featureId] ?? null;
|
|
69
|
+
const status = isNative
|
|
70
|
+
? NATIVE_MARK
|
|
71
|
+
: isExternalStrategy(emulation) ? EXTERNAL_MARK : (emulation ? EMULATED_MARK : UNSUPPORTED_MARK);
|
|
72
|
+
const feat = matrix.features[featureId];
|
|
73
|
+
lines.push(`\n ${featureId} — ${status}`);
|
|
74
|
+
if (feat?.description)
|
|
75
|
+
lines.push(` ${feat.description}`);
|
|
76
|
+
if (isNative) {
|
|
77
|
+
if (id === 'omp' && featureId === 'mcp') {
|
|
78
|
+
lines.push(' OMP supplies the native client. AIWG persistent injection/removal is available for project and profile scope; ephemeral injection is unsupported.');
|
|
79
|
+
lines.push(' example: aiwg mcp inject --provider omp --servers local-tools');
|
|
80
|
+
}
|
|
81
|
+
else if (id === 'omp' && featureId === 'behaviors') {
|
|
82
|
+
lines.push(' AIWG bridges selected handlers through an OMP extension; no default policy is installed. Permission-request and pre-compaction enforcement are unsupported.');
|
|
83
|
+
}
|
|
84
|
+
else if (id === 'omp' && (featureId === 'tasks' || featureId === 'agent_teams')) {
|
|
85
|
+
lines.push(' OMP native leaf tasks use AIWG workspace admission limits and verified child results; nested requests share the same scheduler.');
|
|
86
|
+
lines.push(' example: aiwg team run --provider omp --body-file tasks.json');
|
|
87
|
+
}
|
|
88
|
+
else if (feat?.native_example)
|
|
89
|
+
lines.push(` example: ${feat.native_example}`);
|
|
90
|
+
}
|
|
91
|
+
else if (isExternalStrategy(emulation)) {
|
|
92
|
+
lines.push(` trigger: system cron, systemd timer, or CI; AIWG does not own the clock`);
|
|
93
|
+
}
|
|
94
|
+
else if (emulation) {
|
|
95
|
+
lines.push(` fallback: ${emulationLabel(emulation)}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=steward-format.js.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { AiwgError, EXIT_CODES } from '../errors.js';
|
|
4
|
+
import { getProjectDir } from '../../config/aiwg-config.js';
|
|
5
|
+
import { capabilityProviderId, normalizeProviderId, resolveActiveProvider } from '../provider-resolution.js';
|
|
6
|
+
import { routeModelTier } from '../../models/router.js';
|
|
7
|
+
import { buildWrapperRouteEnvelope } from '../../models/wrapper-route.js';
|
|
8
|
+
import { loadProviderModelCatalog } from '../../models/provider-policy.js';
|
|
9
|
+
import { CapabilityResolutionError, resolveRoutableCapability } from '../../artifacts/capability-resolver.js';
|
|
10
|
+
function isModelPolicyProvider(provider) {
|
|
11
|
+
return Object.hasOwn(loadProviderModelCatalog().providers, provider);
|
|
12
|
+
}
|
|
13
|
+
export async function handleStewardModels(args, matrix, ctx) {
|
|
14
|
+
const flagValue = (name) => {
|
|
15
|
+
const index = args.indexOf(name);
|
|
16
|
+
if (index < 0)
|
|
17
|
+
return undefined;
|
|
18
|
+
const value = args[index + 1];
|
|
19
|
+
if (!value || value.startsWith('--'))
|
|
20
|
+
throw new AiwgError({
|
|
21
|
+
code: 'ERR_USAGE_MISSING_VALUE',
|
|
22
|
+
message: `${name} requires a value.`,
|
|
23
|
+
exitCode: EXIT_CODES.USAGE,
|
|
24
|
+
});
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
if (args.includes('--route')) {
|
|
28
|
+
const rawProvider = flagValue('--provider') ?? await resolveActiveProvider({
|
|
29
|
+
cwd: ctx ? getProjectDir(ctx, ctx.args) : process.cwd(),
|
|
30
|
+
detectProcess: true,
|
|
31
|
+
}).then(result => result.provider ?? undefined);
|
|
32
|
+
const provider = normalizeProviderId(rawProvider);
|
|
33
|
+
if (!provider || provider === 'generic')
|
|
34
|
+
throw new AiwgError({
|
|
35
|
+
code: 'ERR_USAGE_UNKNOWN_PROVIDER',
|
|
36
|
+
message: `Cannot compile a wrapper route for provider: ${rawProvider ?? '(undetected)'}`,
|
|
37
|
+
hint: 'Pass --provider with a supported provider id.',
|
|
38
|
+
exitCode: EXIT_CODES.USAGE,
|
|
39
|
+
});
|
|
40
|
+
if (!isModelPolicyProvider(provider))
|
|
41
|
+
throw new AiwgError({
|
|
42
|
+
code: 'ERR_USAGE_UNSUPPORTED_PROVIDER',
|
|
43
|
+
message: `Model wrapper routing is not implemented for provider: ${provider}`,
|
|
44
|
+
hint: 'Use `aiwg steward capabilities --provider pi` for current Pi capability routing; model routing is tracked separately.',
|
|
45
|
+
exitCode: EXIT_CODES.USAGE,
|
|
46
|
+
});
|
|
47
|
+
const capabilityType = flagValue('--capability-type');
|
|
48
|
+
const capability = flagValue('--capability');
|
|
49
|
+
const assignment = flagValue('--assignment');
|
|
50
|
+
if (!capabilityType || !['agent', 'skill', 'rule', 'workflow'].includes(capabilityType))
|
|
51
|
+
throw new AiwgError({
|
|
52
|
+
code: 'ERR_USAGE_MISSING_VALUE',
|
|
53
|
+
message: '--capability-type requires agent, skill, rule, or workflow.',
|
|
54
|
+
exitCode: EXIT_CODES.USAGE,
|
|
55
|
+
});
|
|
56
|
+
if (!capability || !assignment)
|
|
57
|
+
throw new AiwgError({
|
|
58
|
+
code: 'ERR_USAGE_MISSING_VALUE',
|
|
59
|
+
message: '--route requires both --capability <id> and --assignment <bounded text>.',
|
|
60
|
+
exitCode: EXIT_CODES.USAGE,
|
|
61
|
+
});
|
|
62
|
+
const capabilityProvider = capabilityProviderId(provider);
|
|
63
|
+
const providerCapabilities = capabilityProvider ? matrix.providers[capabilityProvider] : undefined;
|
|
64
|
+
const launchMechanism = providerCapabilities?.native_features.tasks
|
|
65
|
+
? 'native-subagent'
|
|
66
|
+
: providerCapabilities?.emulation.tasks === 'aiwg-mc' ? 'aiwg-mc' : 'manual';
|
|
67
|
+
const premiumAuthorized = args.includes('--allow-premium');
|
|
68
|
+
const { collectProviderInventory } = await import('../../providers/provider-inventory.js');
|
|
69
|
+
const { resolveDynamicModelCatalog } = await import('../../models/model-discovery.js');
|
|
70
|
+
const projectDir = ctx ? getProjectDir(ctx, ctx.args) : process.cwd();
|
|
71
|
+
const requestedAiwgRoot = ctx?.frameworkRoot ?? process.cwd();
|
|
72
|
+
const aiwgRoot = await access(join(requestedAiwgRoot, 'agentic/code/providers/model-catalog.v1.json')).then(() => requestedAiwgRoot).catch(() => process.cwd());
|
|
73
|
+
const resolvedCapability = await resolveRoutableCapability(aiwgRoot, capabilityType, capability).catch(error => {
|
|
74
|
+
if (!(error instanceof CapabilityResolutionError))
|
|
75
|
+
throw error;
|
|
76
|
+
throw new AiwgError({
|
|
77
|
+
code: error.kind === 'ambiguous'
|
|
78
|
+
? 'ERR_USAGE_AMBIGUOUS_CAPABILITY'
|
|
79
|
+
: 'ERR_USAGE_UNKNOWN_CAPABILITY',
|
|
80
|
+
message: error.message,
|
|
81
|
+
hint: 'Run aiwg discover "<capability>" --json and pass an exact name or stable id.',
|
|
82
|
+
exitCode: EXIT_CODES.USAGE,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
const catalog = await resolveDynamicModelCatalog({
|
|
86
|
+
aiwgRoot,
|
|
87
|
+
inventory: await collectProviderInventory(projectDir),
|
|
88
|
+
allowNetwork: false,
|
|
89
|
+
});
|
|
90
|
+
const baselineCatalog = loadProviderModelCatalog();
|
|
91
|
+
const effectiveCatalog = {
|
|
92
|
+
...baselineCatalog,
|
|
93
|
+
...catalog,
|
|
94
|
+
refreshedAt: catalog.refreshedAt ?? baselineCatalog.refreshedAt,
|
|
95
|
+
staleAfterDays: baselineCatalog.staleAfterDays,
|
|
96
|
+
providers: { ...baselineCatalog.providers, ...catalog.providers },
|
|
97
|
+
};
|
|
98
|
+
const envelope = buildWrapperRouteEnvelope({
|
|
99
|
+
provider,
|
|
100
|
+
capability: resolvedCapability,
|
|
101
|
+
assignment,
|
|
102
|
+
launchMechanism,
|
|
103
|
+
deterministic: args.includes('--deterministic'),
|
|
104
|
+
routine: args.includes('--routine'),
|
|
105
|
+
complex: args.includes('--complex'),
|
|
106
|
+
highImpact: args.includes('--high-impact'),
|
|
107
|
+
requestedPremium: args.includes('--premium'),
|
|
108
|
+
unattended: args.includes('--unattended'),
|
|
109
|
+
premiumAuthorized,
|
|
110
|
+
maxAutoTier: premiumAuthorized ? 3 : undefined,
|
|
111
|
+
catalog: effectiveCatalog,
|
|
112
|
+
});
|
|
113
|
+
if (args.includes('--json'))
|
|
114
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
115
|
+
else {
|
|
116
|
+
console.log('\n Model wrapper route');
|
|
117
|
+
console.log(` Provider: ${envelope.provider}`);
|
|
118
|
+
console.log(` Capability: ${envelope.capability.type} ${envelope.capability.name} (${envelope.capability.id})`);
|
|
119
|
+
console.log(` Tier/role: ${envelope.tier ?? 'deterministic'}/${envelope.role ?? 'none'}`);
|
|
120
|
+
console.log(` Wrapper: ${envelope.wrapper ?? 'none'}`);
|
|
121
|
+
console.log(` Model: ${envelope.model?.effectiveModel ?? 'inherited or no model call'} (${envelope.model?.outcome ?? 'deterministic'})`);
|
|
122
|
+
console.log(` Launch: ${envelope.launch.mechanism}`);
|
|
123
|
+
console.log(` Confirmation: ${envelope.decision.requiresConfirmation ? 'required' : 'not required'}`);
|
|
124
|
+
console.log('\n Wrapper prompt:\n');
|
|
125
|
+
console.log(envelope.launch.prompt);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const tiers = Object.fromEntries(Object.entries(loadProviderModelCatalog().providers)
|
|
130
|
+
.filter(([, entry]) => entry.tiers)
|
|
131
|
+
.map(([provider, entry]) => [provider, Object.fromEntries(Object.entries(entry.tiers)
|
|
132
|
+
.map(([tier, model]) => [tier, { ...model, label: model.selection === 'user-elected' ? 'user-elected only' : tier }]))]));
|
|
133
|
+
const decision = routeModelTier({
|
|
134
|
+
deterministic: args.includes('--deterministic'),
|
|
135
|
+
routine: args.includes('--routine'),
|
|
136
|
+
complex: args.includes('--complex'),
|
|
137
|
+
highImpact: args.includes('--high-impact'),
|
|
138
|
+
requestedPremium: args.includes('--premium'),
|
|
139
|
+
unattended: args.includes('--unattended'),
|
|
140
|
+
premiumAuthorized: args.includes('--allow-premium'),
|
|
141
|
+
maxAutoTier: args.includes('--allow-premium') ? 3 : undefined,
|
|
142
|
+
});
|
|
143
|
+
if (args.includes('--json')) {
|
|
144
|
+
console.log(JSON.stringify({ decision, tiers }, null, 2));
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
for (const [provider, ladder] of Object.entries(tiers)) {
|
|
148
|
+
for (const [tier, entry] of Object.entries(ladder))
|
|
149
|
+
console.log(` ${provider} ${tier}: ${entry.id} (${entry.label})`);
|
|
150
|
+
}
|
|
151
|
+
console.log('\n Model policy routing');
|
|
152
|
+
console.log(` Default stance: cheap-first role/tier intent, compiled per provider from the effective catalog.`);
|
|
153
|
+
console.log(` Suggested tier: ${decision.tier}${decision.modelTier ? ` (${decision.modelTier})` : ' (no model call)'}`);
|
|
154
|
+
console.log(` Confirmation: ${decision.requiresConfirmation ? 'required' : 'not required'}`);
|
|
155
|
+
console.log(` Summary before escalation: ${decision.summaryRequired ? 'required' : 'not required'}`);
|
|
156
|
+
console.log(` Rationale: ${decision.rationale.join('; ')}`);
|
|
157
|
+
console.log('\n Commands:');
|
|
158
|
+
console.log(' aiwg models sources --json # inspect effective cache/static/remote catalog provenance');
|
|
159
|
+
console.log(' aiwg models refresh --json # refresh dynamic provider catalog where supported');
|
|
160
|
+
console.log(' aiwg models audit --provider P # compile artifact policy and diagnostics');
|
|
161
|
+
console.log(' aiwg models resolve --provider P # show selected provider model for matching artifacts');
|
|
162
|
+
console.log('\n Authoring:');
|
|
163
|
+
console.log(' Agents: use model-role/model-tier; avoid exact provider IDs in source scaffolds.');
|
|
164
|
+
console.log(' Skills/commands: use commandHint.modelRole and commandHint.modelTier.');
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=steward-models.js.map
|
|
@@ -16,22 +16,15 @@
|
|
|
16
16
|
* @source @src/cli/router.ts
|
|
17
17
|
* @issue #599 #1261 #1262
|
|
18
18
|
*/
|
|
19
|
-
import { access } from 'node:fs/promises';
|
|
20
|
-
import { join } from 'node:path';
|
|
21
19
|
import { AiwgError, EXIT_CODES, handlerResultFromError } from '../errors.js';
|
|
22
20
|
import { loadCapabilityMatrix, isExternalStrategy, } from '../../providers/capability-matrix.js';
|
|
23
21
|
import { getProjectDir, readAiwgConfig, writeAiwgConfig } from '../../config/aiwg-config.js';
|
|
24
22
|
import { auditLegacyPermissions, archiveLegacyPermissionManifests, backupConfig, normalizeProjectPermissions, } from '../../policy/authorization.js';
|
|
25
23
|
import { capabilityProviderId, normalizeProviderId, resolveActiveProvider } from '../provider-resolution.js';
|
|
26
24
|
import { discoverProjectLocalBundles, } from '../../extensions/project-local-discovery.js';
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import { loadProviderModelCatalog, } from '../../models/provider-policy.js';
|
|
30
|
-
import { CapabilityResolutionError, resolveRoutableCapability, } from '../../artifacts/capability-resolver.js';
|
|
25
|
+
import { printFullMatrix, permissionsUsage, formatProvider, emulationLabel } from './steward-format.js';
|
|
26
|
+
import { handleStewardModels } from './steward-models.js';
|
|
31
27
|
const BASELINE_PROVIDER = 'claude-code';
|
|
32
|
-
function isModelPolicyProvider(provider) {
|
|
33
|
-
return Object.hasOwn(loadProviderModelCatalog().providers, provider);
|
|
34
|
-
}
|
|
35
28
|
// ── Feature name normalization ────────────────────────────────────────────────
|
|
36
29
|
/**
|
|
37
30
|
* Accept both hyphenated (agent-teams) and underscored (agent_teams) feature
|
|
@@ -49,62 +42,6 @@ async function detectProvider(ctx) {
|
|
|
49
42
|
return capabilityProviderId(resolution.provider);
|
|
50
43
|
}
|
|
51
44
|
// ── Formatters ────────────────────────────────────────────────────────────────
|
|
52
|
-
const NATIVE_MARK = '✓ native';
|
|
53
|
-
const EMULATED_MARK = '~ emulated';
|
|
54
|
-
const EXTERNAL_MARK = '↗ external';
|
|
55
|
-
const UNSUPPORTED_MARK = '- not supported';
|
|
56
|
-
function emulationLabel(strategy) {
|
|
57
|
-
if (!strategy)
|
|
58
|
-
return 'none';
|
|
59
|
-
if (strategy === 'native')
|
|
60
|
-
return 'native (no fallback needed)';
|
|
61
|
-
return strategy;
|
|
62
|
-
}
|
|
63
|
-
function formatProvider(id, provider, matrix, meta) {
|
|
64
|
-
const lines = [];
|
|
65
|
-
lines.push(`\n Provider: ${provider.display_name} (${id})`);
|
|
66
|
-
if (meta) {
|
|
67
|
-
lines.push(` Project-local: yes`);
|
|
68
|
-
lines.push(` Base adapter: ${meta.baseAdapter}`);
|
|
69
|
-
}
|
|
70
|
-
lines.push(` Status: ${provider.status}`);
|
|
71
|
-
lines.push(` Daemon: ${provider.daemon_tier}${provider.daemon_pty_adapter ? ' (+ pty-adapter)' : ''}`);
|
|
72
|
-
lines.push(` ${'─'.repeat(60)}`);
|
|
73
|
-
const featureKeys = Object.keys(matrix.features);
|
|
74
|
-
for (const featureId of featureKeys) {
|
|
75
|
-
const isNative = provider.native_features?.[featureId] === true;
|
|
76
|
-
const emulation = provider.emulation?.[featureId] ?? null;
|
|
77
|
-
const status = isNative
|
|
78
|
-
? NATIVE_MARK
|
|
79
|
-
: isExternalStrategy(emulation) ? EXTERNAL_MARK : (emulation ? EMULATED_MARK : UNSUPPORTED_MARK);
|
|
80
|
-
const feat = matrix.features[featureId];
|
|
81
|
-
lines.push(`\n ${featureId} — ${status}`);
|
|
82
|
-
if (feat?.description)
|
|
83
|
-
lines.push(` ${feat.description}`);
|
|
84
|
-
if (isNative) {
|
|
85
|
-
if (id === 'omp' && featureId === 'mcp') {
|
|
86
|
-
lines.push(' OMP supplies the native client. AIWG persistent injection/removal is available for project and profile scope; ephemeral injection is unsupported.');
|
|
87
|
-
lines.push(' example: aiwg mcp inject --provider omp --servers local-tools');
|
|
88
|
-
}
|
|
89
|
-
else if (id === 'omp' && featureId === 'behaviors') {
|
|
90
|
-
lines.push(' AIWG bridges selected handlers through an OMP extension; no default policy is installed. Permission-request and pre-compaction enforcement are unsupported.');
|
|
91
|
-
}
|
|
92
|
-
else if (id === 'omp' && (featureId === 'tasks' || featureId === 'agent_teams')) {
|
|
93
|
-
lines.push(' OMP native leaf tasks use AIWG workspace admission limits and verified child results; nested requests share the same scheduler.');
|
|
94
|
-
lines.push(' example: aiwg team run --provider omp --body-file tasks.json');
|
|
95
|
-
}
|
|
96
|
-
else if (feat?.native_example)
|
|
97
|
-
lines.push(` example: ${feat.native_example}`);
|
|
98
|
-
}
|
|
99
|
-
else if (isExternalStrategy(emulation)) {
|
|
100
|
-
lines.push(` trigger: system cron, systemd timer, or CI; AIWG does not own the clock`);
|
|
101
|
-
}
|
|
102
|
-
else if (emulation) {
|
|
103
|
-
lines.push(` fallback: ${emulationLabel(emulation)}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return lines.join('\n');
|
|
107
|
-
}
|
|
108
45
|
async function findProjectLocalProvider(projectDir, requestedProvider) {
|
|
109
46
|
const discovery = await discoverProjectLocalBundles(projectDir);
|
|
110
47
|
const requested = requestedProvider.trim().toLowerCase();
|
|
@@ -156,47 +93,6 @@ async function resolveStewardProvider(matrix, requestedProvider, ctx) {
|
|
|
156
93
|
},
|
|
157
94
|
};
|
|
158
95
|
}
|
|
159
|
-
function printFullMatrix(matrix) {
|
|
160
|
-
const { providers, features } = matrix;
|
|
161
|
-
const providerIds = Object.keys(providers);
|
|
162
|
-
const featureIds = Object.keys(features);
|
|
163
|
-
console.log(`\n Provider Capability Matrix (v${matrix.version})`);
|
|
164
|
-
console.log(` ✓ = native ~ = AIWG emulation - = not supported\n`);
|
|
165
|
-
const featureColW = 20;
|
|
166
|
-
const provColW = 14;
|
|
167
|
-
const header = ' ' + 'Feature'.padEnd(featureColW) + providerIds.map(p => p.padEnd(provColW)).join('');
|
|
168
|
-
console.log(header);
|
|
169
|
-
console.log(' ' + '─'.repeat(featureColW + providerIds.length * provColW));
|
|
170
|
-
for (const featureId of featureIds) {
|
|
171
|
-
const feat = features[featureId];
|
|
172
|
-
let row = ' ' + featureId.padEnd(featureColW);
|
|
173
|
-
for (const providerId of providerIds) {
|
|
174
|
-
const provider = providers[providerId];
|
|
175
|
-
const isNative = provider?.native_features?.[featureId] === true;
|
|
176
|
-
const emulation = provider?.emulation?.[featureId] ?? null;
|
|
177
|
-
const mark = isNative ? '✓' : (emulation ? '~' : '-');
|
|
178
|
-
row += mark.padEnd(provColW);
|
|
179
|
-
}
|
|
180
|
-
console.log(row);
|
|
181
|
-
if (feat?.description) {
|
|
182
|
-
console.log(' ' + ' '.repeat(featureColW) + feat.description);
|
|
183
|
-
}
|
|
184
|
-
console.log('');
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
// ── Main execution ─────────────────────────────────────────────────────────────
|
|
188
|
-
function permissionsUsage() {
|
|
189
|
-
return `
|
|
190
|
-
aiwg steward permissions — authorization model audit and normalization
|
|
191
|
-
|
|
192
|
-
Usage:
|
|
193
|
-
aiwg steward permissions audit Find normalized-model errors and legacy grants
|
|
194
|
-
aiwg steward permissions migrate --dry-run Preview legacy permission normalization
|
|
195
|
-
aiwg steward permissions migrate --apply Back up and atomically normalize config
|
|
196
|
-
|
|
197
|
-
Reads .aiwg/aiwg.config authorization block. Migration backs up before writing.
|
|
198
|
-
`;
|
|
199
|
-
}
|
|
200
96
|
async function handleSteward(args, ctx) {
|
|
201
97
|
const subcommand = args[0];
|
|
202
98
|
if (!subcommand || subcommand === '--help' || subcommand === 'help') {
|
|
@@ -214,6 +110,7 @@ async function handleSteward(args, ctx) {
|
|
|
214
110
|
aiwg steward models --route --capability-type <agent|skill|rule|workflow>
|
|
215
111
|
--capability <id> --assignment <text> [--provider <name>] [--json]
|
|
216
112
|
Emit a capability-bound wrapper launch envelope
|
|
113
|
+
aiwg steward authorization Bounded HITL policy: inspect/validate/preview/enable/revoke
|
|
217
114
|
aiwg steward permissions audit Find normalized-model errors and legacy grants
|
|
218
115
|
aiwg steward permissions migrate --dry-run Preview legacy permission normalization
|
|
219
116
|
aiwg steward permissions migrate --apply Back up and atomically normalize config
|
|
@@ -242,6 +139,11 @@ async function handleSteward(args, ctx) {
|
|
|
242
139
|
console.log(JSON.stringify(args.includes('--json') ? { decisionOffload } : decisionOffload, null, 2));
|
|
243
140
|
return;
|
|
244
141
|
}
|
|
142
|
+
if (subcommand === 'authorization') {
|
|
143
|
+
const { authorizationCli } = await import('../../config/authorization-cli.js');
|
|
144
|
+
await authorizationCli(args.slice(1), ctx?.cwd);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
245
147
|
if (subcommand === 'permissions') {
|
|
246
148
|
const operation = args[1];
|
|
247
149
|
// `<namespace> --help` must reach the same usage block bare invocation prints (#2533).
|
|
@@ -478,148 +380,8 @@ async function handleSteward(args, ctx) {
|
|
|
478
380
|
}
|
|
479
381
|
return;
|
|
480
382
|
}
|
|
481
|
-
if (subcommand === 'models' || subcommand === 'model-routing')
|
|
482
|
-
|
|
483
|
-
const index = args.indexOf(name);
|
|
484
|
-
if (index < 0)
|
|
485
|
-
return undefined;
|
|
486
|
-
const value = args[index + 1];
|
|
487
|
-
if (!value || value.startsWith('--'))
|
|
488
|
-
throw new AiwgError({
|
|
489
|
-
code: 'ERR_USAGE_MISSING_VALUE',
|
|
490
|
-
message: `${name} requires a value.`,
|
|
491
|
-
exitCode: EXIT_CODES.USAGE,
|
|
492
|
-
});
|
|
493
|
-
return value;
|
|
494
|
-
};
|
|
495
|
-
if (args.includes('--route')) {
|
|
496
|
-
const rawProvider = flagValue('--provider') ?? await resolveActiveProvider({
|
|
497
|
-
cwd: ctx ? getProjectDir(ctx, ctx.args) : process.cwd(),
|
|
498
|
-
detectProcess: true,
|
|
499
|
-
}).then(result => result.provider ?? undefined);
|
|
500
|
-
const provider = normalizeProviderId(rawProvider);
|
|
501
|
-
if (!provider || provider === 'generic')
|
|
502
|
-
throw new AiwgError({
|
|
503
|
-
code: 'ERR_USAGE_UNKNOWN_PROVIDER',
|
|
504
|
-
message: `Cannot compile a wrapper route for provider: ${rawProvider ?? '(undetected)'}`,
|
|
505
|
-
hint: 'Pass --provider with a supported provider id.',
|
|
506
|
-
exitCode: EXIT_CODES.USAGE,
|
|
507
|
-
});
|
|
508
|
-
if (!isModelPolicyProvider(provider))
|
|
509
|
-
throw new AiwgError({
|
|
510
|
-
code: 'ERR_USAGE_UNSUPPORTED_PROVIDER',
|
|
511
|
-
message: `Model wrapper routing is not implemented for provider: ${provider}`,
|
|
512
|
-
hint: 'Use `aiwg steward capabilities --provider pi` for current Pi capability routing; model routing is tracked separately.',
|
|
513
|
-
exitCode: EXIT_CODES.USAGE,
|
|
514
|
-
});
|
|
515
|
-
const capabilityType = flagValue('--capability-type');
|
|
516
|
-
const capability = flagValue('--capability');
|
|
517
|
-
const assignment = flagValue('--assignment');
|
|
518
|
-
if (!capabilityType || !['agent', 'skill', 'rule', 'workflow'].includes(capabilityType))
|
|
519
|
-
throw new AiwgError({
|
|
520
|
-
code: 'ERR_USAGE_MISSING_VALUE',
|
|
521
|
-
message: '--capability-type requires agent, skill, rule, or workflow.',
|
|
522
|
-
exitCode: EXIT_CODES.USAGE,
|
|
523
|
-
});
|
|
524
|
-
if (!capability || !assignment)
|
|
525
|
-
throw new AiwgError({
|
|
526
|
-
code: 'ERR_USAGE_MISSING_VALUE',
|
|
527
|
-
message: '--route requires both --capability <id> and --assignment <bounded text>.',
|
|
528
|
-
exitCode: EXIT_CODES.USAGE,
|
|
529
|
-
});
|
|
530
|
-
const capabilityProvider = capabilityProviderId(provider);
|
|
531
|
-
const providerCapabilities = capabilityProvider ? matrix.providers[capabilityProvider] : undefined;
|
|
532
|
-
const launchMechanism = providerCapabilities?.native_features.tasks
|
|
533
|
-
? 'native-subagent'
|
|
534
|
-
: providerCapabilities?.emulation.tasks === 'aiwg-mc' ? 'aiwg-mc' : 'manual';
|
|
535
|
-
const premiumAuthorized = args.includes('--allow-premium');
|
|
536
|
-
const { collectProviderInventory } = await import('../../providers/provider-inventory.js');
|
|
537
|
-
const { resolveDynamicModelCatalog } = await import('../../models/model-discovery.js');
|
|
538
|
-
const projectDir = ctx ? getProjectDir(ctx, ctx.args) : process.cwd();
|
|
539
|
-
const requestedAiwgRoot = ctx?.frameworkRoot ?? process.cwd();
|
|
540
|
-
const aiwgRoot = await access(join(requestedAiwgRoot, 'agentic/code/providers/model-catalog.v1.json')).then(() => requestedAiwgRoot).catch(() => process.cwd());
|
|
541
|
-
const resolvedCapability = await resolveRoutableCapability(aiwgRoot, capabilityType, capability).catch(error => {
|
|
542
|
-
if (!(error instanceof CapabilityResolutionError))
|
|
543
|
-
throw error;
|
|
544
|
-
throw new AiwgError({
|
|
545
|
-
code: error.kind === 'ambiguous'
|
|
546
|
-
? 'ERR_USAGE_AMBIGUOUS_CAPABILITY'
|
|
547
|
-
: 'ERR_USAGE_UNKNOWN_CAPABILITY',
|
|
548
|
-
message: error.message,
|
|
549
|
-
hint: 'Run aiwg discover "<capability>" --json and pass an exact name or stable id.',
|
|
550
|
-
exitCode: EXIT_CODES.USAGE,
|
|
551
|
-
});
|
|
552
|
-
});
|
|
553
|
-
const catalog = await resolveDynamicModelCatalog({
|
|
554
|
-
aiwgRoot,
|
|
555
|
-
inventory: await collectProviderInventory(projectDir),
|
|
556
|
-
allowNetwork: false,
|
|
557
|
-
});
|
|
558
|
-
const baselineCatalog = loadProviderModelCatalog();
|
|
559
|
-
const effectiveCatalog = {
|
|
560
|
-
...baselineCatalog,
|
|
561
|
-
...catalog,
|
|
562
|
-
refreshedAt: catalog.refreshedAt ?? baselineCatalog.refreshedAt,
|
|
563
|
-
staleAfterDays: baselineCatalog.staleAfterDays,
|
|
564
|
-
providers: { ...baselineCatalog.providers, ...catalog.providers },
|
|
565
|
-
};
|
|
566
|
-
const envelope = buildWrapperRouteEnvelope({
|
|
567
|
-
provider,
|
|
568
|
-
capability: resolvedCapability,
|
|
569
|
-
assignment,
|
|
570
|
-
launchMechanism,
|
|
571
|
-
deterministic: args.includes('--deterministic'),
|
|
572
|
-
routine: args.includes('--routine'),
|
|
573
|
-
complex: args.includes('--complex'),
|
|
574
|
-
highImpact: args.includes('--high-impact'),
|
|
575
|
-
requestedPremium: args.includes('--premium'),
|
|
576
|
-
unattended: args.includes('--unattended'),
|
|
577
|
-
premiumAuthorized,
|
|
578
|
-
maxAutoTier: premiumAuthorized ? 3 : undefined,
|
|
579
|
-
catalog: effectiveCatalog,
|
|
580
|
-
});
|
|
581
|
-
if (args.includes('--json'))
|
|
582
|
-
console.log(JSON.stringify(envelope, null, 2));
|
|
583
|
-
else {
|
|
584
|
-
console.log('\n Model wrapper route');
|
|
585
|
-
console.log(` Provider: ${envelope.provider}`);
|
|
586
|
-
console.log(` Capability: ${envelope.capability.type} ${envelope.capability.name} (${envelope.capability.id})`);
|
|
587
|
-
console.log(` Tier/role: ${envelope.tier ?? 'deterministic'}/${envelope.role ?? 'none'}`);
|
|
588
|
-
console.log(` Wrapper: ${envelope.wrapper ?? 'none'}`);
|
|
589
|
-
console.log(` Model: ${envelope.model?.effectiveModel ?? 'inherited or no model call'} (${envelope.model?.outcome ?? 'deterministic'})`);
|
|
590
|
-
console.log(` Launch: ${envelope.launch.mechanism}`);
|
|
591
|
-
console.log(` Confirmation: ${envelope.decision.requiresConfirmation ? 'required' : 'not required'}`);
|
|
592
|
-
console.log('\n Wrapper prompt:\n');
|
|
593
|
-
console.log(envelope.launch.prompt);
|
|
594
|
-
}
|
|
595
|
-
return;
|
|
596
|
-
}
|
|
597
|
-
const decision = routeModelTier({
|
|
598
|
-
deterministic: args.includes('--deterministic'),
|
|
599
|
-
routine: args.includes('--routine'),
|
|
600
|
-
complex: args.includes('--complex'),
|
|
601
|
-
highImpact: args.includes('--high-impact'),
|
|
602
|
-
requestedPremium: args.includes('--premium'),
|
|
603
|
-
unattended: args.includes('--unattended'),
|
|
604
|
-
premiumAuthorized: args.includes('--allow-premium'),
|
|
605
|
-
maxAutoTier: args.includes('--allow-premium') ? 3 : undefined,
|
|
606
|
-
});
|
|
607
|
-
console.log('\n Model policy routing');
|
|
608
|
-
console.log(` Default stance: cheap-first role/tier intent, compiled per provider from the effective catalog.`);
|
|
609
|
-
console.log(` Suggested tier: ${decision.tier}${decision.modelTier ? ` (${decision.modelTier})` : ' (no model call)'}`);
|
|
610
|
-
console.log(` Confirmation: ${decision.requiresConfirmation ? 'required' : 'not required'}`);
|
|
611
|
-
console.log(` Summary before escalation: ${decision.summaryRequired ? 'required' : 'not required'}`);
|
|
612
|
-
console.log(` Rationale: ${decision.rationale.join('; ')}`);
|
|
613
|
-
console.log('\n Commands:');
|
|
614
|
-
console.log(' aiwg models sources --json # inspect effective cache/static/remote catalog provenance');
|
|
615
|
-
console.log(' aiwg models refresh --json # refresh dynamic provider catalog where supported');
|
|
616
|
-
console.log(' aiwg models audit --provider P # compile artifact policy and diagnostics');
|
|
617
|
-
console.log(' aiwg models resolve --provider P # show selected provider model for matching artifacts');
|
|
618
|
-
console.log('\n Authoring:');
|
|
619
|
-
console.log(' Agents: use model-role/model-tier; avoid exact provider IDs in source scaffolds.');
|
|
620
|
-
console.log(' Skills/commands: use commandHint.modelRole and commandHint.modelTier.');
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
383
|
+
if (subcommand === 'models' || subcommand === 'model-routing')
|
|
384
|
+
return handleStewardModels(args, matrix, ctx);
|
|
623
385
|
throw new AiwgError({
|
|
624
386
|
code: 'ERR_USAGE_UNKNOWN_SUBCOMMAND',
|
|
625
387
|
message: `Unknown steward subcommand: ${subcommand}`,
|
|
@@ -640,6 +402,10 @@ export const stewardHandler = {
|
|
|
640
402
|
// sub-namespace help reachable, without executing anything (#2533).
|
|
641
403
|
async help(ctx) {
|
|
642
404
|
const positional = ctx.args.filter((arg) => !arg.startsWith('-'));
|
|
405
|
+
if (positional[0] === 'authorization') {
|
|
406
|
+
const { authorizationUsage } = await import('../../config/authorization-cli.js');
|
|
407
|
+
return { exitCode: 0, message: authorizationUsage, rawOutput: true };
|
|
408
|
+
}
|
|
643
409
|
if (positional[0] === 'permissions') {
|
|
644
410
|
return { exitCode: 0, message: permissionsUsage(), rawOutput: true };
|
|
645
411
|
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// Count bundle artifacts from native files and activation-selected rule receipts.
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
export async function countDeployedBundleRules(bundlePath, target, deployPath) {
|
|
5
|
+
if (!deployPath)
|
|
6
|
+
return 0;
|
|
7
|
+
const destination = path.resolve(target, deployPath);
|
|
8
|
+
let selected = [];
|
|
9
|
+
try {
|
|
10
|
+
const receipt = JSON.parse(await fs.readFile(path.join(destination, '.aiwg-manifest.json'), 'utf8'));
|
|
11
|
+
selected = Array.isArray(receipt.ruleSources) ? receipt.ruleSources : [];
|
|
12
|
+
}
|
|
13
|
+
catch { /* Legacy deployments have only native files. */ }
|
|
14
|
+
let sources;
|
|
15
|
+
try {
|
|
16
|
+
sources = (await fs.readdir(path.join(bundlePath, 'rules'))).filter(name => name.endsWith('.md'));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return 0;
|
|
20
|
+
}
|
|
21
|
+
let count = 0;
|
|
22
|
+
for (const name of sources) {
|
|
23
|
+
if (selected.includes(path.resolve(bundlePath, 'rules', name))) {
|
|
24
|
+
count++;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
for (const extension of ['.md', '.mdc']) {
|
|
28
|
+
try {
|
|
29
|
+
await fs.access(path.join(destination, path.basename(name, '.md') + extension));
|
|
30
|
+
count++;
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
catch { /* A catalog-only, unselected rule is not deployed. */ }
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return count;
|
|
37
|
+
}
|
|
38
|
+
export async function countDeployedBundleFiles(bundlePath, subdir, target, deployPath, extensions) {
|
|
39
|
+
if (!deployPath)
|
|
40
|
+
return 0;
|
|
41
|
+
let names;
|
|
42
|
+
try {
|
|
43
|
+
names = (await fs.readdir(path.join(bundlePath, subdir))).filter(name => name.endsWith('.md'));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
let count = 0;
|
|
49
|
+
for (const name of names) {
|
|
50
|
+
for (const extension of extensions) {
|
|
51
|
+
try {
|
|
52
|
+
await fs.access(path.join(path.resolve(target, deployPath), path.basename(name, '.md') + extension));
|
|
53
|
+
count++;
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
catch { /* Only count artifacts actually written by this bundle. */ }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return count;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=use-bundle-counts.js.map
|