@aiwg/cli 2026.8.17 → 2026.8.18
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/bin/aiwg.mjs +24 -2
- package/dist/src/a2a/agent-card.js +4 -1
- package/dist/src/a2a/client.js +148 -68
- package/dist/src/a2a/codecs.js +480 -0
- package/dist/src/a2a/events.js +226 -0
- package/dist/src/a2a/hitl-driver.js +8 -6
- package/dist/src/a2a/hitl.js +2 -1
- package/dist/src/a2a/http.js +85 -5
- package/dist/src/a2a/protocol.js +136 -0
- package/dist/src/a2a/types.js +4 -14
- package/dist/src/a2a/webhook.js +101 -4
- package/dist/src/audit/operator-decision.js +15 -1
- package/dist/src/channel/manager.mjs +89 -17
- package/dist/src/cli/handlers/index.js +3 -1
- package/dist/src/cli/handlers/installation.js +79 -0
- package/dist/src/cli/handlers/refresh.js +4 -2
- package/dist/src/cli/handlers/runtime-info.js +9 -1
- package/dist/src/cli/handlers/serve.js +107 -4
- package/dist/src/cli/handlers/session.js +12 -26
- package/dist/src/cli/handlers/utilities.js +4 -0
- package/dist/src/cli/handlers/version.js +4 -0
- package/dist/src/config/user-config-dir.mjs +29 -0
- package/dist/src/config/user-config.js +4 -22
- package/dist/src/extensions/commands/definitions.js +20 -1
- package/dist/src/features/catalog.js +2 -1
- package/dist/src/flow/graph-metadata.js +56 -0
- package/dist/src/installation/manager.mjs +243 -0
- package/dist/src/serve/a2a-terminal-observer.js +28 -5
- package/dist/src/serve/dispatch-router.js +32 -4
- package/dist/src/serve/executor-registry.js +29 -0
- package/dist/src/serve/mission-conductor.js +15 -1
- package/dist/src/serve/stack-adapters.js +2 -1
- package/dist/src/serve/telemetry.js +5 -1
- package/dist/src/update/checker.mjs +16 -15
- package/dist/src/update/notifier.mjs +8 -3
- package/dist/src/update/service.mjs +49 -5
- package/package.json +1 -1
|
@@ -27,12 +27,13 @@
|
|
|
27
27
|
|
|
28
28
|
import https from 'https';
|
|
29
29
|
import path from 'path';
|
|
30
|
-
import os from 'os';
|
|
31
30
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
32
31
|
import { spawn } from 'child_process';
|
|
33
32
|
import { fileURLToPath } from 'url';
|
|
33
|
+
import { resolveUserConfigDir } from '../config/user-config-dir.mjs';
|
|
34
|
+
import { loadInstallationIdentity } from '../installation/manager.mjs';
|
|
34
35
|
|
|
35
|
-
const CACHE_DIR =
|
|
36
|
+
const CACHE_DIR = resolveUserConfigDir();
|
|
36
37
|
const CACHE_FILE = path.join(CACHE_DIR, 'update-notifier.json');
|
|
37
38
|
|
|
38
39
|
/**
|
|
@@ -191,11 +192,13 @@ async function runCheck(packageRoot) {
|
|
|
191
192
|
*/
|
|
192
193
|
export function scheduleBackgroundCheck(packageRoot) {
|
|
193
194
|
if (isDisabled()) return;
|
|
195
|
+
const installation = loadInstallationIdentity({ actualRoot: packageRoot, createIfMissing: false });
|
|
196
|
+
if (installation?.checkOnStartup === false) return;
|
|
194
197
|
|
|
195
198
|
const cache = readCache();
|
|
196
199
|
if (cacheMatchesPackage(cache, packageRoot) && cache?.lastCheckAt) {
|
|
197
200
|
const age = Date.now() - new Date(cache.lastCheckAt).getTime();
|
|
198
|
-
if (age < CHECK_INTERVAL_MS) return; // recent enough — skip
|
|
201
|
+
if (age < (installation?.updateCheckInterval ?? CHECK_INTERVAL_MS)) return; // recent enough — skip
|
|
199
202
|
}
|
|
200
203
|
|
|
201
204
|
try {
|
|
@@ -225,6 +228,8 @@ export function scheduleBackgroundCheck(packageRoot) {
|
|
|
225
228
|
*/
|
|
226
229
|
export function maybePrintNotice(packageRoot) {
|
|
227
230
|
if (isDisabled()) return;
|
|
231
|
+
const installation = loadInstallationIdentity({ actualRoot: packageRoot, createIfMissing: false });
|
|
232
|
+
if (installation?.checkOnStartup === false) return;
|
|
228
233
|
const cache = readCache();
|
|
229
234
|
if (!cacheMatchesPackage(cache, packageRoot)) return;
|
|
230
235
|
if (!cache?.hasUpdate || !cache.current || !cache.latest) return;
|
|
@@ -10,6 +10,12 @@ import { execFileSync } from 'node:child_process';
|
|
|
10
10
|
import { existsSync, readFileSync } from 'node:fs';
|
|
11
11
|
import path from 'node:path';
|
|
12
12
|
import { getPackageRoot, loadConfig } from '../channel/manager.mjs';
|
|
13
|
+
import {
|
|
14
|
+
assertCanonicalInstallation,
|
|
15
|
+
createInstallationIdentity,
|
|
16
|
+
loadInstallationIdentity,
|
|
17
|
+
saveInstallationIdentity,
|
|
18
|
+
} from '../installation/manager.mjs';
|
|
13
19
|
|
|
14
20
|
const VALID_MODES = new Set(['npm', 'web', 'source']);
|
|
15
21
|
|
|
@@ -24,14 +30,42 @@ function readPackageName(packageRoot) {
|
|
|
24
30
|
export async function detectInstallMode(options = {}) {
|
|
25
31
|
const packageRoot = options.packageRoot ?? getPackageRoot();
|
|
26
32
|
const override = options.env?.AIWG_INSTALL_MODE ?? process.env.AIWG_INSTALL_MODE;
|
|
33
|
+
const config = options.config ?? await loadConfig(options);
|
|
34
|
+
let identity = options.identity ?? config.installation ?? null;
|
|
35
|
+
let identityPersistent = Boolean(config.installation) || options.identityPersistent === true;
|
|
36
|
+
if (!identity && options.config) {
|
|
37
|
+
const method = override ?? (readPackageName(packageRoot) === '@aiwg/cli'
|
|
38
|
+
? 'web'
|
|
39
|
+
: (config.devMode || config.channel === 'edge' || existsSync(path.join(packageRoot, '.git'))) ? 'source' : 'npm');
|
|
40
|
+
identity = createInstallationIdentity({
|
|
41
|
+
...options,
|
|
42
|
+
actualRoot: packageRoot,
|
|
43
|
+
method,
|
|
44
|
+
channel: config.channel,
|
|
45
|
+
runMode: config.devMode ? 'development' : undefined,
|
|
46
|
+
});
|
|
47
|
+
} else if (!identity) {
|
|
48
|
+
identity = loadInstallationIdentity({ ...options, actualRoot: packageRoot });
|
|
49
|
+
identityPersistent = Boolean(identity);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (override && !VALID_MODES.has(override)) {
|
|
53
|
+
throw new Error(`AIWG_INSTALL_MODE must be one of: ${[...VALID_MODES].join(', ')}`);
|
|
54
|
+
}
|
|
55
|
+
if (override && identity && override !== identity.method) {
|
|
56
|
+
throw new Error(`AIWG_INSTALL_MODE=${override} conflicts with the canonical installation method ${identity.method}. Use \`aiwg installation switch\` instead.`);
|
|
57
|
+
}
|
|
58
|
+
if (identity) {
|
|
59
|
+
const status = assertCanonicalInstallation({ ...options, actualRoot: packageRoot, identity });
|
|
60
|
+
return { mode: identity.method, packageRoot, packageName: readPackageName(packageRoot), identity, identityPersistent, installation: status };
|
|
61
|
+
}
|
|
62
|
+
|
|
27
63
|
if (override) {
|
|
28
64
|
if (!VALID_MODES.has(override)) {
|
|
29
65
|
throw new Error(`AIWG_INSTALL_MODE must be one of: ${[...VALID_MODES].join(', ')}`);
|
|
30
66
|
}
|
|
31
67
|
return { mode: override, packageRoot, packageName: readPackageName(packageRoot) };
|
|
32
68
|
}
|
|
33
|
-
|
|
34
|
-
const config = options.config ?? await loadConfig();
|
|
35
69
|
const packageName = readPackageName(packageRoot);
|
|
36
70
|
if (packageName === '@aiwg/cli') return { mode: 'web', packageRoot, packageName };
|
|
37
71
|
if (config.devMode || config.channel === 'edge' || existsSync(path.join(packageRoot, '.git'))) {
|
|
@@ -56,7 +90,7 @@ function npmTag(channel) {
|
|
|
56
90
|
export async function updateInstallation(options = {}) {
|
|
57
91
|
const config = options.config ?? await loadConfig();
|
|
58
92
|
const detected = await detectInstallMode({ ...options, config });
|
|
59
|
-
const channel = options.channel ?? config.channel ?? 'stable';
|
|
93
|
+
const channel = options.channel ?? detected.identity?.channel ?? config.channel ?? 'stable';
|
|
60
94
|
const dryRun = options.dryRun === true;
|
|
61
95
|
const offline = options.offline === true;
|
|
62
96
|
|
|
@@ -84,6 +118,9 @@ export async function updateInstallation(options = {}) {
|
|
|
84
118
|
return resolveWebRelease({ selector });
|
|
85
119
|
});
|
|
86
120
|
const release = await refreshWebResources(channel);
|
|
121
|
+
if (detected.identity && detected.identityPersistent && options.persistIdentity !== false) {
|
|
122
|
+
saveInstallationIdentity({ ...detected.identity, channel }, options);
|
|
123
|
+
}
|
|
87
124
|
return {
|
|
88
125
|
...detected,
|
|
89
126
|
channel,
|
|
@@ -106,16 +143,23 @@ export async function updateInstallation(options = {}) {
|
|
|
106
143
|
|
|
107
144
|
const tag = npmTag(channel);
|
|
108
145
|
const command = ['install', '--global', `aiwg@${tag}`];
|
|
146
|
+
const managerExecutable = detected.identity?.managerExecutable;
|
|
147
|
+
if (!managerExecutable) {
|
|
148
|
+
throw new Error('Canonical npm installation has no package-manager executable. Run `aiwg installation adopt --manager <absolute-path-to-npm>`.');
|
|
149
|
+
}
|
|
109
150
|
if (!dryRun) {
|
|
110
151
|
const execute = options.execute ?? ((file, args) => execFileSync(file, args, { stdio: 'inherit' }));
|
|
111
|
-
execute(
|
|
152
|
+
execute(managerExecutable, command);
|
|
153
|
+
if (detected.identity && detected.identityPersistent && options.persistIdentity !== false) {
|
|
154
|
+
saveInstallationIdentity({ ...detected.identity, channel }, options);
|
|
155
|
+
}
|
|
112
156
|
}
|
|
113
157
|
return {
|
|
114
158
|
...detected,
|
|
115
159
|
channel,
|
|
116
160
|
status: dryRun ? 'dry-run' : 'updated',
|
|
117
161
|
changed: !dryRun,
|
|
118
|
-
command:
|
|
162
|
+
command: `${managerExecutable} ${command.join(' ')}`,
|
|
119
163
|
message: dryRun
|
|
120
164
|
? `Would update the full AIWG npm distribution on the '${tag}' channel.`
|
|
121
165
|
: `Updated the full AIWG npm distribution on the '${tag}' channel.`,
|