@aiwg/cli 2026.8.18 → 2026.8.20
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/THIRD_PARTY_NOTICES.md +12 -0
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.js +2 -0
- package/dist/src/artifacts/backend-runtime.js +26 -0
- package/dist/src/artifacts/backends/sqlite-backend.js +204 -28
- package/dist/src/artifacts/dep-graph.js +27 -5
- package/dist/src/artifacts/graph-backend.js +2 -2
- package/dist/src/artifacts/graph-query.js +21 -9
- package/dist/src/artifacts/index-builder.js +78 -12
- package/dist/src/artifacts/index-files.js +26 -5
- package/dist/src/artifacts/index-status.js +4 -1
- package/dist/src/artifacts/query-engine.js +67 -67
- package/dist/src/artifacts/stats.js +9 -2
- package/dist/src/artifacts/types.js +14 -2
- package/dist/src/cli/handlers/help.js +2 -0
- package/dist/src/cli/handlers/index.js +6 -2
- package/dist/src/cli/handlers/installation.js +1 -1
- package/dist/src/cli/handlers/mission.js +27 -0
- package/dist/src/cli/handlers/refresh.js +6 -4
- package/dist/src/cli/handlers/runtime-info.js +29 -0
- package/dist/src/cli/handlers/steward.js +12 -0
- package/dist/src/cli/handlers/uhp.js +88 -0
- package/dist/src/cli/handlers/use.js +19 -4
- package/dist/src/config/aiwg-config.js +10 -0
- package/dist/src/extensions/commands/definitions.js +38 -0
- package/dist/src/installation/manager-command.mjs +31 -0
- package/dist/src/installation/manager.mjs +21 -0
- package/dist/src/mission-protocol/codecs.js +265 -0
- package/dist/src/mission-protocol/index.js +3 -0
- package/dist/src/mission-protocol/types.js +2 -0
- package/dist/src/smiths/context-pipeline/claude-hook.js +8 -5
- package/dist/src/smiths/context-pipeline/line-endings.js +12 -0
- package/dist/src/smiths/context-pipeline/managed-hook.js +8 -5
- package/dist/src/smiths/context-pipeline/workspace-context.js +3 -1
- package/dist/src/storage/backend-contract.js +64 -0
- package/dist/src/storage/index.js +2 -0
- package/dist/src/storage/migration-protocol.js +378 -0
- package/dist/src/uhp/client.js +374 -0
- package/dist/src/uhp/config.js +130 -0
- package/dist/src/uhp/errors.js +63 -0
- package/dist/src/uhp/index.js +7 -0
- package/dist/src/uhp/mission.js +111 -0
- package/dist/src/uhp/sse.js +76 -0
- package/dist/src/uhp/types.js +2 -0
- package/dist/src/update/service.mjs +3 -1
- package/package.json +1 -1
- package/tools/agents/deploy-agents.mjs +28 -8
- package/tools/agents/providers/base.mjs +5 -3
|
@@ -32,6 +32,7 @@ import { regenerateHandler, regenerateHandlers } from './regenerate.js';
|
|
|
32
32
|
import { workspaceContextHandler, workspaceContextHandlers } from './workspace-context.js';
|
|
33
33
|
import { artifactsHandler, artifactsHandlers } from './artifacts.js';
|
|
34
34
|
import { mcHandler, mcHandlers } from './mc.js';
|
|
35
|
+
import { missionHandlers } from './mission.js';
|
|
35
36
|
import { sdlcAccelerateHandler } from './sdlc-accelerate.js';
|
|
36
37
|
import { teamHandler, teamHandlers } from './team.js';
|
|
37
38
|
import { installHandler } from './install.js';
|
|
@@ -64,6 +65,7 @@ import { evidenceHandler } from './evidence.js';
|
|
|
64
65
|
import { artifactVerifyHandler } from './artifact-verify.js';
|
|
65
66
|
import { outputModeHandler } from './output-mode.js';
|
|
66
67
|
import { installationHandler } from './installation.js';
|
|
68
|
+
import { uhpHandler } from './uhp.js';
|
|
67
69
|
// Re-export individual handlers
|
|
68
70
|
export {
|
|
69
71
|
// Maintenance
|
|
@@ -75,7 +77,7 @@ newBundleHandler, quickrefHandler, newProjectHandler, sessionHandler, sessionsHa
|
|
|
75
77
|
// Workspace
|
|
76
78
|
statusHandler, wizardHandler, migrateWorkspaceHandler, rollbackWorkspaceHandler,
|
|
77
79
|
// Subcommands
|
|
78
|
-
mcpHandler, catalogHandler, modelsHandler, versionsHandler, indexHandler, artifactsHandler, corpusHandler, discoverHandler, showHandler, featuresHandler, skillsHandler, configHandler, opsHandler, storageHandler, activityLogHandler, commandLogHandler, skillUsageHandler, kbHandler, memoryHandler, reflectionsHandler, provenanceHandler, researchStoreHandler, researchQueryHandler, runtimeInfoHandler, agentcardHandler,
|
|
80
|
+
mcpHandler, catalogHandler, modelsHandler, versionsHandler, indexHandler, artifactsHandler, corpusHandler, discoverHandler, showHandler, featuresHandler, skillsHandler, configHandler, opsHandler, storageHandler, activityLogHandler, commandLogHandler, skillUsageHandler, kbHandler, memoryHandler, reflectionsHandler, provenanceHandler, researchStoreHandler, researchQueryHandler, runtimeInfoHandler, agentcardHandler, uhpHandler,
|
|
79
81
|
// Agentic Tools (RLM)
|
|
80
82
|
chunkHandler, fanoutHandler, rlmPrepHandler, rlmSearchHandler, rlmStatusCliHandler, rlmCacheHandler,
|
|
81
83
|
// Utilities
|
|
@@ -111,7 +113,7 @@ repoAccessHandler,
|
|
|
111
113
|
// Lint
|
|
112
114
|
lintHandler, };
|
|
113
115
|
// Re-export handler arrays
|
|
114
|
-
export { workspaceHandlers, utilityHandlers, scaffoldingHandlers, ralphHandlers, subcommandHandlers, mcHandlers, teamHandlers, stewardHandlers, regenerateHandlers, workspaceContextHandlers, artifactsHandlers, daemonHandlers, sandboxHandlers, repoAccessHandlers, };
|
|
116
|
+
export { workspaceHandlers, utilityHandlers, scaffoldingHandlers, ralphHandlers, subcommandHandlers, mcHandlers, missionHandlers, teamHandlers, stewardHandlers, regenerateHandlers, workspaceContextHandlers, artifactsHandlers, daemonHandlers, sandboxHandlers, repoAccessHandlers, };
|
|
115
117
|
/**
|
|
116
118
|
* All registered command handlers
|
|
117
119
|
*
|
|
@@ -170,6 +172,7 @@ export const allHandlers = [
|
|
|
170
172
|
skillsHandler,
|
|
171
173
|
runtimeInfoHandler,
|
|
172
174
|
agentcardHandler,
|
|
175
|
+
uhpHandler,
|
|
173
176
|
// Utilities
|
|
174
177
|
prefillCardsHandler,
|
|
175
178
|
contributeStartHandler,
|
|
@@ -188,6 +191,7 @@ export const allHandlers = [
|
|
|
188
191
|
...ralphHandlers,
|
|
189
192
|
// Mission Control
|
|
190
193
|
...mcHandlers,
|
|
194
|
+
...missionHandlers,
|
|
191
195
|
// Agent Teams
|
|
192
196
|
...teamHandlers,
|
|
193
197
|
// Steward (capability awareness)
|
|
@@ -45,7 +45,7 @@ export const installationHandler = {
|
|
|
45
45
|
};
|
|
46
46
|
if (action === 'show') {
|
|
47
47
|
const identity = loadInstallationIdentity({ ...common, createIfMissing: true });
|
|
48
|
-
display(inspectInstallation({ ...common, identity }), json);
|
|
48
|
+
display(inspectInstallation({ ...common, identity, probeManager: true }), json);
|
|
49
49
|
return { exitCode: 0 };
|
|
50
50
|
}
|
|
51
51
|
if (action === 'adopt') {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const usage = `Usage: aiwg mission migrate [--dry-run] [--root <workspace>]
|
|
2
|
+
aiwg mission migrate --apply --target mission.aiwg.io/v1 [--id <id>]
|
|
3
|
+
aiwg mission migrate --verify <id> | --resume <id> | --rollback <id>
|
|
4
|
+
|
|
5
|
+
Preview is the default. Apply is backup-first and requires an explicit target.`;
|
|
6
|
+
export const missionHandler = {
|
|
7
|
+
id: 'mission',
|
|
8
|
+
name: 'Mission Protocol',
|
|
9
|
+
description: 'Preview, apply, verify, resume, or roll back Mission Protocol migrations',
|
|
10
|
+
category: 'orchestration',
|
|
11
|
+
aliases: [],
|
|
12
|
+
async execute(ctx) {
|
|
13
|
+
if (ctx.args[0] !== 'migrate' || ctx.args.includes('--help') || ctx.args.includes('-h')) {
|
|
14
|
+
return { exitCode: ctx.args[0] === 'migrate' ? 0 : 2, message: usage, rawOutput: true };
|
|
15
|
+
}
|
|
16
|
+
const { spawn } = await import('node:child_process');
|
|
17
|
+
const path = await import('node:path');
|
|
18
|
+
const script = path.join(ctx.frameworkRoot, 'tools/mission-protocol/migrate.mjs');
|
|
19
|
+
return await new Promise(resolve => {
|
|
20
|
+
const child = spawn(process.execPath, [script, ...ctx.args.slice(1), '--root', ctx.cwd], { stdio: 'inherit', signal: ctx.signal });
|
|
21
|
+
child.once('error', error => resolve({ exitCode: 1, error, message: error.message }));
|
|
22
|
+
child.once('exit', code => resolve({ exitCode: code ?? 1 }));
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
export const missionHandlers = [missionHandler];
|
|
27
|
+
//# sourceMappingURL=mission.js.map
|
|
@@ -205,6 +205,7 @@ export const refreshHandler = {
|
|
|
205
205
|
if (!quiet)
|
|
206
206
|
ui.info(dryRun ? 'Would refresh remote packages...' : 'Refreshing remote packages...');
|
|
207
207
|
const deploymentFailures = [];
|
|
208
|
+
let updateFailure = null;
|
|
208
209
|
if (!dryRun) {
|
|
209
210
|
try {
|
|
210
211
|
const refreshed = await refreshAllPackages();
|
|
@@ -242,10 +243,10 @@ export const refreshHandler = {
|
|
|
242
243
|
ui.success('Package up to date');
|
|
243
244
|
}
|
|
244
245
|
else {
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
246
|
+
updateFailure = { exitCode: updateResult.exitCode };
|
|
247
|
+
if (!quiet) {
|
|
248
|
+
ui.warn('Installation update failed; continuing with re-deployment. Run `aiwg installation show` for canonical-install diagnostics.');
|
|
249
|
+
}
|
|
249
250
|
}
|
|
250
251
|
}
|
|
251
252
|
}
|
|
@@ -465,6 +466,7 @@ export const refreshHandler = {
|
|
|
465
466
|
channel: channel || undefined,
|
|
466
467
|
staleAgentRemovals,
|
|
467
468
|
deploymentFailures,
|
|
469
|
+
updateFailure,
|
|
468
470
|
});
|
|
469
471
|
console.log(output);
|
|
470
472
|
}
|
|
@@ -53,8 +53,37 @@ async function handleRuntimeInfo(args, cwd = process.cwd()) {
|
|
|
53
53
|
const hasCheck = checkIndex >= 0;
|
|
54
54
|
const hasCapabilities = args.includes('--capabilities');
|
|
55
55
|
const hasProviders = args.includes('--providers');
|
|
56
|
+
const hasTransports = args.includes('--transports');
|
|
56
57
|
const featureIndex = args.indexOf('--feature');
|
|
57
58
|
const hasFeature = featureIndex >= 0;
|
|
59
|
+
if (hasTransports) {
|
|
60
|
+
const { readAiwgConfig } = await import('../../config/aiwg-config.js');
|
|
61
|
+
const config = await readAiwgConfig(cwd);
|
|
62
|
+
const profiles = Object.entries(config?.uhp?.profiles ?? {}).map(([name, profile]) => ({
|
|
63
|
+
name,
|
|
64
|
+
transport: 'uhp',
|
|
65
|
+
protocolVersion: profile.version,
|
|
66
|
+
experimental: true,
|
|
67
|
+
configured: true,
|
|
68
|
+
enabled: config?.uhp?.enabled === true,
|
|
69
|
+
endpointOrigin: new URL(profile.endpoint).origin,
|
|
70
|
+
credentialSource: profile.credential.source,
|
|
71
|
+
credentialReference: profile.credential.name,
|
|
72
|
+
}));
|
|
73
|
+
const output = { providersAreTransports: false, transports: { uhp: { experimental: true, enabled: config?.uhp?.enabled === true, profiles } } };
|
|
74
|
+
if (hasJson)
|
|
75
|
+
console.log(JSON.stringify(output, null, 2));
|
|
76
|
+
else {
|
|
77
|
+
console.log('\nTransport Inventory');
|
|
78
|
+
console.log('===================');
|
|
79
|
+
console.log('UHP is a remote execution transport, not an AIWG provider.');
|
|
80
|
+
if (!profiles.length)
|
|
81
|
+
console.log(' UHP: not configured (experimental)');
|
|
82
|
+
for (const profile of profiles)
|
|
83
|
+
console.log(` UHP/${profile.name}: ${profile.enabled ? 'enabled' : 'disabled'}, ${profile.protocolVersion}, ${profile.endpointOrigin}`);
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
58
87
|
// --- Capability matrix queries (no RuntimeDiscovery needed) ---
|
|
59
88
|
if (hasProviders) {
|
|
60
89
|
const { collectProviderInventory } = await import('../../providers/provider-inventory.js');
|
|
@@ -182,6 +182,7 @@ async function handleSteward(args, ctx) {
|
|
|
182
182
|
aiwg steward capabilities --feature <name> Provider support matrix for a feature
|
|
183
183
|
aiwg steward capabilities --all Full matrix (all providers x features)
|
|
184
184
|
aiwg steward find --capability <name> Routing advice for your current provider
|
|
185
|
+
aiwg steward transports Report transport capabilities separately from providers
|
|
185
186
|
aiwg steward models [--complex|--high-impact] Model policy/discovery routing advice
|
|
186
187
|
aiwg steward models --route --capability-type <agent|skill|rule|workflow>
|
|
187
188
|
--capability <id> --assignment <text> [--provider <name>] [--json]
|
|
@@ -263,6 +264,17 @@ async function handleSteward(args, ctx) {
|
|
|
263
264
|
exitCode: EXIT_CODES.USAGE,
|
|
264
265
|
});
|
|
265
266
|
}
|
|
267
|
+
if (subcommand === 'transports') {
|
|
268
|
+
const projectDir = ctx ? getProjectDir(ctx, args) : process.cwd();
|
|
269
|
+
const config = await readAiwgConfig(projectDir);
|
|
270
|
+
const profiles = Object.keys(config?.uhp?.profiles ?? {});
|
|
271
|
+
console.log('\n Remote execution transports');
|
|
272
|
+
console.log(' ───────────────────────────');
|
|
273
|
+
console.log(` UHP ${config?.uhp?.enabled ? 'enabled' : 'disabled'} (experimental client transport; not a provider capability)`);
|
|
274
|
+
console.log(` Profiles: ${profiles.length ? profiles.join(', ') : 'none'}`);
|
|
275
|
+
console.log(' Routing: explicit `aiwg uhp <operation> --profile <name>`; no UHP↔A2A fallback.');
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
266
278
|
const matrix = loadCapabilityMatrix();
|
|
267
279
|
if (subcommand === 'capabilities') {
|
|
268
280
|
const providerFlag = args.indexOf('--provider');
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { readAiwgConfig } from '../../config/aiwg-config.js';
|
|
2
|
+
import { resolveUhpProfile } from '../../uhp/config.js';
|
|
3
|
+
import { UhpClient } from '../../uhp/client.js';
|
|
4
|
+
import { projectUhpResponseToCanonicalMission, projectUhpResponseToMission, unknownUhpMissionEvidence } from '../../uhp/mission.js';
|
|
5
|
+
import { UhpError } from '../../uhp/errors.js';
|
|
6
|
+
function valueAfter(args, name) {
|
|
7
|
+
const index = args.indexOf(name);
|
|
8
|
+
return index >= 0 ? args[index + 1] : undefined;
|
|
9
|
+
}
|
|
10
|
+
function usage() {
|
|
11
|
+
return `Usage: aiwg uhp <discover|harnesses|models|run> --profile <name> [options]
|
|
12
|
+
|
|
13
|
+
Experimental UHP ${'2026-08-11'} client (client support only; no server conformance claim)
|
|
14
|
+
|
|
15
|
+
discover Inspect unauthenticated capability discovery
|
|
16
|
+
harnesses List configured remote harnesses
|
|
17
|
+
models [--harness <id>] List global or per-harness model availability
|
|
18
|
+
run --input <text> [--harness <id>] [--model <id>] [--stream]
|
|
19
|
+
Run an explicit smoke task
|
|
20
|
+
|
|
21
|
+
All commands require --profile. Credentials are resolved from the profile's
|
|
22
|
+
secret reference at request time; bearer values are never accepted as CLI arguments.`;
|
|
23
|
+
}
|
|
24
|
+
async function executeUhp(ctx) {
|
|
25
|
+
const [operation] = ctx.args;
|
|
26
|
+
if (!operation || operation === 'help' || operation === '--help')
|
|
27
|
+
return { exitCode: 0, message: usage(), rawOutput: true };
|
|
28
|
+
const profileName = valueAfter(ctx.args, '--profile');
|
|
29
|
+
if (!profileName)
|
|
30
|
+
return { exitCode: 2, message: 'UHP routing requires explicit --profile <name> selection.' };
|
|
31
|
+
const config = await readAiwgConfig(ctx.cwd);
|
|
32
|
+
const profile = resolveUhpProfile(config?.uhp, profileName);
|
|
33
|
+
const client = new UhpClient(profileName, profile);
|
|
34
|
+
if (operation === 'discover')
|
|
35
|
+
return { exitCode: 0, message: JSON.stringify(await client.discover(), null, 2), rawOutput: true };
|
|
36
|
+
if (operation === 'harnesses')
|
|
37
|
+
return { exitCode: 0, message: JSON.stringify(await client.listHarnesses(), null, 2), rawOutput: true };
|
|
38
|
+
if (operation === 'models')
|
|
39
|
+
return { exitCode: 0, message: JSON.stringify(await client.listModels(valueAfter(ctx.args, '--harness')), null, 2), rawOutput: true };
|
|
40
|
+
if (operation !== 'run')
|
|
41
|
+
return { exitCode: 2, message: `Unknown UHP operation '${operation}'.\n${usage()}`, rawOutput: true };
|
|
42
|
+
const input = valueAfter(ctx.args, '--input');
|
|
43
|
+
if (!input)
|
|
44
|
+
return { exitCode: 2, message: 'aiwg uhp run requires --input <text>.' };
|
|
45
|
+
const request = {
|
|
46
|
+
input,
|
|
47
|
+
...(valueAfter(ctx.args, '--model') ? { model: valueAfter(ctx.args, '--model') } : {}),
|
|
48
|
+
metadata: { ...(valueAfter(ctx.args, '--harness') ? { harness_id: valueAfter(ctx.args, '--harness') } : {}) },
|
|
49
|
+
};
|
|
50
|
+
if (ctx.args.includes('--stream')) {
|
|
51
|
+
const events = [];
|
|
52
|
+
let terminal;
|
|
53
|
+
try {
|
|
54
|
+
for await (const event of client.streamResponse(request, { signal: ctx.signal })) {
|
|
55
|
+
events.push(event);
|
|
56
|
+
if (event.response)
|
|
57
|
+
terminal = event.response;
|
|
58
|
+
}
|
|
59
|
+
const canonical = terminal ? projectUhpResponseToCanonicalMission(profileName, terminal, request, events.at(-1)) : undefined;
|
|
60
|
+
return { exitCode: 0, message: JSON.stringify({ events, evidence: terminal ? projectUhpResponseToMission(profileName, terminal, request, events.at(-1)) : unknownUhpMissionEvidence(profileName, 'Stream ended without a response'), ...(canonical ? { mission: canonical.value, adapter: { sourceVersion: canonical.sourceVersion, warnings: canonical.warnings, lossReport: canonical.lossReport } } : {}) }, null, 2), rawOutput: true };
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
if (error instanceof UhpError && error.options.remoteState === 'unknown') {
|
|
64
|
+
return { exitCode: 1, message: JSON.stringify({ error: { code: error.code, message: error.message }, evidence: unknownUhpMissionEvidence(profileName, error.message, terminal?.id, events.at(-1)?.sequence_number) }, null, 2), rawOutput: true };
|
|
65
|
+
}
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const response = await client.createResponse(request, { signal: ctx.signal });
|
|
70
|
+
const canonical = projectUhpResponseToCanonicalMission(profileName, response, request);
|
|
71
|
+
return { exitCode: 0, message: JSON.stringify({ response, evidence: projectUhpResponseToMission(profileName, response, request), mission: canonical.value, adapter: { sourceVersion: canonical.sourceVersion, warnings: canonical.warnings, lossReport: canonical.lossReport } }, null, 2), rawOutput: true };
|
|
72
|
+
}
|
|
73
|
+
export const uhpHandler = {
|
|
74
|
+
id: 'uhp',
|
|
75
|
+
name: 'Unified Harness Protocol',
|
|
76
|
+
description: 'Inspect and smoke-test an explicitly selected experimental UHP endpoint profile',
|
|
77
|
+
category: 'toolsmith',
|
|
78
|
+
aliases: [],
|
|
79
|
+
async execute(ctx) {
|
|
80
|
+
try {
|
|
81
|
+
return await executeUhp(ctx);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
return { exitCode: error instanceof UhpError || error instanceof Error ? 1 : 1, message: error instanceof Error ? error.message : 'UHP operation failed' };
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=uhp.js.map
|
|
@@ -1873,11 +1873,13 @@ async function deploySourceDirectory(opts) {
|
|
|
1873
1873
|
args.push('--force');
|
|
1874
1874
|
if (opts.copyAll)
|
|
1875
1875
|
args.push('--copy-all');
|
|
1876
|
+
if (opts.kernelOnly)
|
|
1877
|
+
args.push('--kernel-only');
|
|
1876
1878
|
if (opts.quiet)
|
|
1877
1879
|
args.unshift('--quiet');
|
|
1878
1880
|
const runner = createScriptRunner(opts.frameworkRoot);
|
|
1879
1881
|
const result = await runner.run('tools/agents/deploy-agents.mjs', args, opts.quiet ? { capture: true } : {});
|
|
1880
|
-
if (result.exitCode === 0) {
|
|
1882
|
+
if (result.exitCode === 0 && !opts.kernelOnly) {
|
|
1881
1883
|
try {
|
|
1882
1884
|
await registerSourceCliCommands({
|
|
1883
1885
|
source: opts.source,
|
|
@@ -2436,6 +2438,7 @@ export class UseHandler {
|
|
|
2436
2438
|
}
|
|
2437
2439
|
ui.dim(' Use `aiwg use all` for the full deployment.');
|
|
2438
2440
|
for (const providerName of providersForFiltered) {
|
|
2441
|
+
const kernelOnly = !copyAll;
|
|
2439
2442
|
for (const selected of selectedFrameworks) {
|
|
2440
2443
|
const frameworkDir = resolveFrameworkDir(selected);
|
|
2441
2444
|
if (!frameworkDir)
|
|
@@ -2450,6 +2453,7 @@ export class UseHandler {
|
|
|
2450
2453
|
verbose,
|
|
2451
2454
|
force,
|
|
2452
2455
|
copyAll,
|
|
2456
|
+
kernelOnly,
|
|
2453
2457
|
quiet,
|
|
2454
2458
|
modelArgs: modelDeployArgs,
|
|
2455
2459
|
});
|
|
@@ -2467,6 +2471,7 @@ export class UseHandler {
|
|
|
2467
2471
|
verbose,
|
|
2468
2472
|
force,
|
|
2469
2473
|
copyAll,
|
|
2474
|
+
kernelOnly,
|
|
2470
2475
|
quiet,
|
|
2471
2476
|
modelArgs: modelDeployArgs,
|
|
2472
2477
|
});
|
|
@@ -2484,6 +2489,7 @@ export class UseHandler {
|
|
|
2484
2489
|
verbose,
|
|
2485
2490
|
force,
|
|
2486
2491
|
copyAll,
|
|
2492
|
+
kernelOnly,
|
|
2487
2493
|
quiet,
|
|
2488
2494
|
modelArgs: modelDeployArgs,
|
|
2489
2495
|
});
|
|
@@ -2985,6 +2991,11 @@ export class UseHandler {
|
|
|
2985
2991
|
const providerDeployArgs = builtInProviderResolution.requestedProvider
|
|
2986
2992
|
? withProviderOverride(deployFilteredArgs, provider)
|
|
2987
2993
|
: deployFilteredArgs;
|
|
2994
|
+
const bulkKernelOnly = framework === 'all'
|
|
2995
|
+
&& !remainingArgs.includes('--copy-all')
|
|
2996
|
+
&& !remainingArgs.includes('--copy-standard-skills');
|
|
2997
|
+
if (bulkKernelOnly)
|
|
2998
|
+
providerDeployArgs.push('--kernel-only');
|
|
2988
2999
|
const targetIdx = remainingArgs.findIndex(a => a === '--target');
|
|
2989
3000
|
const target = targetIdx >= 0 && remainingArgs[targetIdx + 1] ? remainingArgs[targetIdx + 1] : process.cwd();
|
|
2990
3001
|
if ((verbose || dryRun) && projectLocalProviderResolution.requestedProvider) {
|
|
@@ -3084,11 +3095,15 @@ export class UseHandler {
|
|
|
3084
3095
|
}
|
|
3085
3096
|
// Build common args for addon deployments (inherit provider and target)
|
|
3086
3097
|
const addonBaseArgs = ['--deploy-commands', '--deploy-skills', '--deploy-rules'];
|
|
3098
|
+
if (bulkKernelOnly)
|
|
3099
|
+
addonBaseArgs.push('--kernel-only');
|
|
3087
3100
|
addonBaseArgs.push(...modelDeployArgs);
|
|
3088
3101
|
if (provider)
|
|
3089
3102
|
addonBaseArgs.push('--provider', provider);
|
|
3090
3103
|
if (target)
|
|
3091
3104
|
addonBaseArgs.push('--target', target);
|
|
3105
|
+
if (dryRun)
|
|
3106
|
+
addonBaseArgs.push('--dry-run');
|
|
3092
3107
|
if (verbose)
|
|
3093
3108
|
addonBaseArgs.push('--verbose');
|
|
3094
3109
|
// Forward --copy-all to addon deploys so the legacy mirror behavior
|
|
@@ -3182,7 +3197,7 @@ export class UseHandler {
|
|
|
3182
3197
|
}
|
|
3183
3198
|
await ensureProviderGeneratedDirsIgnored(target, provider, { dryRun, verbose });
|
|
3184
3199
|
const paths = getProviderPaths(provider);
|
|
3185
|
-
if (!dryRun && !skipUtils) {
|
|
3200
|
+
if (!dryRun && !skipUtils && !bulkKernelOnly) {
|
|
3186
3201
|
const wrapperValidation = await validateDeployedModelWrappers({
|
|
3187
3202
|
provider,
|
|
3188
3203
|
target,
|
|
@@ -3200,7 +3215,7 @@ export class UseHandler {
|
|
|
3200
3215
|
const targetKernelSkillsDir = kernelSkillsPath ? resolveProviderPath(target, kernelSkillsPath) : '';
|
|
3201
3216
|
// Translate deployed skills to commands for providers that require legacy command format.
|
|
3202
3217
|
// (#550) Skills are canonical; commands are generated deployment artifacts.
|
|
3203
|
-
if (providerNeedsCommands(provider) && targetCommandsDir) {
|
|
3218
|
+
if (!bulkKernelOnly && providerNeedsCommands(provider) && targetCommandsDir) {
|
|
3204
3219
|
try {
|
|
3205
3220
|
const translationResult = await translateSkillsToCommands(targetSkillsDir, {
|
|
3206
3221
|
provider,
|
|
@@ -3222,7 +3237,7 @@ export class UseHandler {
|
|
|
3222
3237
|
// provider loads skills natively: users still expect setup, update,
|
|
3223
3238
|
// status, intake, and flow workflows to show up in the provider's `/`
|
|
3224
3239
|
// command picker where supported.
|
|
3225
|
-
if (targetCommandsDir) {
|
|
3240
|
+
if (!bulkKernelOnly && targetCommandsDir) {
|
|
3226
3241
|
try {
|
|
3227
3242
|
const standardMirrored = await mirrorStandardCommandSkills({
|
|
3228
3243
|
provider,
|
|
@@ -17,6 +17,7 @@ import { validateAuthorization, } from '../policy/authorization.js';
|
|
|
17
17
|
import { projectAiwgPath, projectControlPath, resolveProjectAiwgDir, } from './project-artifacts.js';
|
|
18
18
|
import { defaultThreatAssessmentConfig, validateThreatAssessmentConfig, } from '../security/threat-assessment-config.js';
|
|
19
19
|
import { defaultArtifactOutputs, validateArtifactOutputs } from '../artifacts/output-policy.js';
|
|
20
|
+
import { validateUhpConfig } from '../uhp/config.js';
|
|
20
21
|
const CONFIG_FILENAME = 'aiwg.config';
|
|
21
22
|
/**
|
|
22
23
|
* Operations that a workspace may authorize for one member repository.
|
|
@@ -159,6 +160,9 @@ export function validateIndexConfig(index) {
|
|
|
159
160
|
return ['index: must be an object'];
|
|
160
161
|
}
|
|
161
162
|
const indexObject = index;
|
|
163
|
+
if (indexObject.graphBackend !== undefined && !GRAPH_BACKENDS.includes(indexObject.graphBackend)) {
|
|
164
|
+
errors.push(`index.graphBackend: must be one of ${GRAPH_BACKENDS.join(' | ')}`);
|
|
165
|
+
}
|
|
162
166
|
const isStringArray = (v) => Array.isArray(v) && v.every((x) => typeof x === 'string');
|
|
163
167
|
const graphOverrides = indexObject.graphOverrides;
|
|
164
168
|
if (graphOverrides !== undefined) {
|
|
@@ -772,6 +776,9 @@ export async function readAiwgConfig(projectDir) {
|
|
|
772
776
|
const artifactOutputErrors = validateArtifactOutputs(parsed.artifact_outputs);
|
|
773
777
|
if (artifactOutputErrors.length > 0)
|
|
774
778
|
throw new Error(`Invalid .aiwg/aiwg.config:\n${artifactOutputErrors.join('\n')}`);
|
|
779
|
+
const uhpErrors = validateUhpConfig(parsed.uhp);
|
|
780
|
+
if (uhpErrors.length > 0)
|
|
781
|
+
throw new Error(`Invalid .aiwg/aiwg.config:\n${uhpErrors.join('\n')}`);
|
|
775
782
|
return parsed;
|
|
776
783
|
}
|
|
777
784
|
/**
|
|
@@ -787,6 +794,9 @@ export async function writeAiwgConfig(projectDir, config) {
|
|
|
787
794
|
const artifactOutputErrors = validateArtifactOutputs(config.artifact_outputs);
|
|
788
795
|
if (artifactOutputErrors.length > 0)
|
|
789
796
|
throw new Error(`Invalid .aiwg/aiwg.config:\n${artifactOutputErrors.join('\n')}`);
|
|
797
|
+
const uhpErrors = validateUhpConfig(config.uhp);
|
|
798
|
+
if (uhpErrors.length > 0)
|
|
799
|
+
throw new Error(`Invalid .aiwg/aiwg.config:\n${uhpErrors.join('\n')}`);
|
|
790
800
|
const localPath = getConfigPath(projectDir);
|
|
791
801
|
const artifactDir = resolveProjectAiwgDir(projectDir);
|
|
792
802
|
const artifactPath = join(artifactDir, CONFIG_FILENAME);
|
|
@@ -1663,6 +1663,24 @@ export const agentcardCommand = {
|
|
|
1663
1663
|
},
|
|
1664
1664
|
},
|
|
1665
1665
|
};
|
|
1666
|
+
export const uhpCommand = {
|
|
1667
|
+
id: 'uhp',
|
|
1668
|
+
type: 'command',
|
|
1669
|
+
name: 'Unified Harness Protocol',
|
|
1670
|
+
description: 'Inspect discovery and run smoke tasks through an explicit experimental UHP endpoint profile',
|
|
1671
|
+
version: '1.0.0',
|
|
1672
|
+
capabilities: ['cli', 'uhp', 'remote-harness', 'transport'],
|
|
1673
|
+
keywords: ['uhp', 'unified harness protocol', 'remote harness', 'responses'],
|
|
1674
|
+
category: 'toolsmith',
|
|
1675
|
+
platforms: { claude: 'full', generic: 'full' },
|
|
1676
|
+
deployment: { pathTemplate: '.{platform}/commands/{id}.md', core: true },
|
|
1677
|
+
metadata: {
|
|
1678
|
+
type: 'command',
|
|
1679
|
+
template: 'utility',
|
|
1680
|
+
argumentHint: '<discover|harnesses|models|run> --profile <name> [--harness <id>] [--model <id>] [--input <text>] [--stream]',
|
|
1681
|
+
allowedTools: ['Read', 'Bash'],
|
|
1682
|
+
},
|
|
1683
|
+
};
|
|
1666
1684
|
// Utility Commands
|
|
1667
1685
|
export const prefillCardsCommand = {
|
|
1668
1686
|
id: 'prefill-cards',
|
|
@@ -2371,6 +2389,24 @@ export const mcCommand = {
|
|
|
2371
2389
|
},
|
|
2372
2390
|
},
|
|
2373
2391
|
};
|
|
2392
|
+
export const missionCommand = {
|
|
2393
|
+
id: 'mission',
|
|
2394
|
+
type: 'command',
|
|
2395
|
+
name: 'Mission Protocol',
|
|
2396
|
+
description: 'Preview, apply, verify, resume, and roll back versioned Mission workspace migrations',
|
|
2397
|
+
version: '1.0.0',
|
|
2398
|
+
capabilities: ['cli', 'orchestration', 'mission-protocol', 'migration', 'rollback'],
|
|
2399
|
+
keywords: ['mission', 'migrate', 'migration', 'preview', 'resume', 'rollback'],
|
|
2400
|
+
category: 'orchestration',
|
|
2401
|
+
platforms: { claude: 'full', generic: 'full' },
|
|
2402
|
+
deployment: { pathTemplate: '.{platform}/commands/{id}.md', core: true },
|
|
2403
|
+
metadata: {
|
|
2404
|
+
type: 'command',
|
|
2405
|
+
template: 'orchestration',
|
|
2406
|
+
allowedTools: ['Bash', 'Read', 'Write'],
|
|
2407
|
+
argumentHint: 'migrate [--dry-run|--apply|--verify|--resume|--rollback]',
|
|
2408
|
+
},
|
|
2409
|
+
};
|
|
2374
2410
|
// Steward Commands
|
|
2375
2411
|
export const stewardCommand = {
|
|
2376
2412
|
id: 'steward',
|
|
@@ -3631,6 +3667,7 @@ export const commandDefinitions = [
|
|
|
3631
3667
|
// Toolsmith (1)
|
|
3632
3668
|
runtimeInfoCommand,
|
|
3633
3669
|
agentcardCommand,
|
|
3670
|
+
uhpCommand,
|
|
3634
3671
|
// Utility (5)
|
|
3635
3672
|
prefillCardsCommand,
|
|
3636
3673
|
contributeStartCommand,
|
|
@@ -3663,6 +3700,7 @@ export const commandDefinitions = [
|
|
|
3663
3700
|
ralphConfigCommand,
|
|
3664
3701
|
// Mission Control (1)
|
|
3665
3702
|
mcCommand,
|
|
3703
|
+
missionCommand,
|
|
3666
3704
|
// Steward (1)
|
|
3667
3705
|
stewardCommand,
|
|
3668
3706
|
// Agent Teams (1)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
|
|
3
|
+
function quoteCmdArgument(value) {
|
|
4
|
+
return `"${String(value).replace(/%/g, '%%').replace(/"/g, '""')}"`;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Resolve a package-manager invocation without asking Node to execute a
|
|
9
|
+
* Windows command script directly. Node rejects direct .cmd/.bat execution on
|
|
10
|
+
* current Windows releases; cmd.exe is the native interpreter for those files.
|
|
11
|
+
*/
|
|
12
|
+
export function resolveManagerCommand(file, args, options = {}) {
|
|
13
|
+
const platform = options.platform ?? process.platform;
|
|
14
|
+
if (platform !== 'win32' || !/\.(?:cmd|bat)$/i.test(file)) {
|
|
15
|
+
return { file, args };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const env = options.env ?? process.env;
|
|
19
|
+
const commandInterpreter = env.ComSpec || env.COMSPEC || 'cmd.exe';
|
|
20
|
+
const command = `"${[file, ...args].map(quoteCmdArgument).join(' ')}"`;
|
|
21
|
+
return {
|
|
22
|
+
file: commandInterpreter,
|
|
23
|
+
args: ['/d', '/s', '/c', command],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function executeManagerCommand(file, args, options = {}) {
|
|
28
|
+
const invocation = resolveManagerCommand(file, args, options);
|
|
29
|
+
const execute = options.execute ?? execFileSync;
|
|
30
|
+
return execute(invocation.file, invocation.args, options.execOptions ?? { stdio: 'inherit' });
|
|
31
|
+
}
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from 'node:fs';
|
|
13
13
|
import path from 'node:path';
|
|
14
14
|
import { resolveUserConfigDir } from '../config/user-config-dir.mjs';
|
|
15
|
+
import { executeManagerCommand } from './manager-command.mjs';
|
|
15
16
|
|
|
16
17
|
export const INSTALLATION_IDENTITY_VERSION = 1;
|
|
17
18
|
export const INSTALLATION_FILE = 'installation.json';
|
|
@@ -188,6 +189,25 @@ export function inspectInstallation(options = {}) {
|
|
|
188
189
|
if (identity.managerExecutable && !executableIsUsable(identity.managerExecutable)) {
|
|
189
190
|
drift.push(`recorded manager executable is missing or not executable: ${identity.managerExecutable}`);
|
|
190
191
|
}
|
|
192
|
+
let managerProbe = null;
|
|
193
|
+
if (
|
|
194
|
+
options.probeManager === true &&
|
|
195
|
+
identity.managerExecutable &&
|
|
196
|
+
executableIsUsable(identity.managerExecutable)
|
|
197
|
+
) {
|
|
198
|
+
try {
|
|
199
|
+
executeManagerCommand(identity.managerExecutable, ['--version'], {
|
|
200
|
+
...options,
|
|
201
|
+
execute: options.executeManager,
|
|
202
|
+
execOptions: { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10_000 },
|
|
203
|
+
});
|
|
204
|
+
managerProbe = { state: 'usable' };
|
|
205
|
+
} catch (error) {
|
|
206
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
207
|
+
managerProbe = { state: 'failed', error: message };
|
|
208
|
+
drift.push(`recorded manager executable cannot be invoked: ${message}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
191
211
|
return {
|
|
192
212
|
state: drift.length === 0 ? 'aligned' : (existsSync(canonicalRoot) ? 'mismatch' : 'stale'),
|
|
193
213
|
identity,
|
|
@@ -195,6 +215,7 @@ export function inspectInstallation(options = {}) {
|
|
|
195
215
|
actualRoot,
|
|
196
216
|
actualMethod,
|
|
197
217
|
drift,
|
|
218
|
+
managerProbe,
|
|
198
219
|
};
|
|
199
220
|
}
|
|
200
221
|
|