@aiwg/cli 2026.8.0 → 2026.8.1

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.
Files changed (61) hide show
  1. package/README.md +33 -0
  2. package/agentic/code/providers/capability-matrix.yaml +511 -0
  3. package/agentic/code/providers/model-capabilities.v1.json +120 -0
  4. package/agentic/code/providers/model-catalog.v1.json +96 -0
  5. package/agentic/code/providers/model-policy-evaluations.v1.json +50 -0
  6. package/agentic/code/providers/premium-model-allowlist.v1.json +36 -0
  7. package/bin/aiwg.mjs +14 -10
  8. package/dist/src/api/index.d.ts +1 -0
  9. package/dist/src/api/index.js +1 -0
  10. package/dist/src/artifacts/cli.js +2 -0
  11. package/dist/src/artifacts/types.js +4 -0
  12. package/dist/src/auth/client.js +209 -0
  13. package/dist/src/auth/config.js +38 -0
  14. package/dist/src/auth/credential-store.js +141 -0
  15. package/dist/src/auth/resource-credentials.js +25 -0
  16. package/dist/src/auth/types.js +2 -0
  17. package/dist/src/channel/manager.mjs +5 -5
  18. package/dist/src/cli/handlers/auth.js +125 -0
  19. package/dist/src/cli/handlers/help.js +1 -0
  20. package/dist/src/cli/handlers/index.js +3 -1
  21. package/dist/src/cli/handlers/resource-versions.js +2 -0
  22. package/dist/src/cli/handlers/sessions.js +23 -5
  23. package/dist/src/cli/handlers/subcommands.js +10 -1
  24. package/dist/src/cli/handlers/use.js +342 -43
  25. package/dist/src/config/gitignore.js +1 -0
  26. package/dist/src/extensions/commands/definitions.js +19 -0
  27. package/dist/src/memory/canonical-context.js +342 -0
  28. package/dist/src/memory/context-pack.js +282 -0
  29. package/dist/src/memory/index.js +4 -0
  30. package/dist/src/memory/intake.js +118 -0
  31. package/dist/src/resources/resolver.js +1 -0
  32. package/dist/src/resources/web-release.d.ts +3 -1
  33. package/dist/src/resources/web-release.js +14 -6
  34. package/dist/src/serve/agentic-sandbox-fleet-client.js +213 -0
  35. package/dist/src/serve/fleet-mission-conductor.js +293 -0
  36. package/dist/src/sessions/index.js +1 -0
  37. package/dist/src/sessions/output-registration.js +338 -0
  38. package/dist/src/sessions/promotion.js +73 -2
  39. package/dist/src/sessions/repository.js +2 -1
  40. package/dist/src/update/notifier.mjs +13 -2
  41. package/package.json +8 -1
  42. package/tools/_resolve-impl.mjs +74 -0
  43. package/tools/agents/deploy-agents.mjs +962 -0
  44. package/tools/agents/providers/base.mjs +2954 -0
  45. package/tools/agents/providers/claude.mjs +711 -0
  46. package/tools/agents/providers/codex.mjs +699 -0
  47. package/tools/agents/providers/copilot.mjs +659 -0
  48. package/tools/agents/providers/cursor.mjs +714 -0
  49. package/tools/agents/providers/factory.mjs +1130 -0
  50. package/tools/agents/providers/hermes.mjs +663 -0
  51. package/tools/agents/providers/hook-capabilities.mjs +85 -0
  52. package/tools/agents/providers/model-role.mjs +56 -0
  53. package/tools/agents/providers/openclaw-translator.mjs +348 -0
  54. package/tools/agents/providers/openclaw.mjs +680 -0
  55. package/tools/agents/providers/opencode.mjs +675 -0
  56. package/tools/agents/providers/openhuman.mjs +292 -0
  57. package/tools/agents/providers/warp.mjs +413 -0
  58. package/tools/agents/providers/windsurf.mjs +748 -0
  59. package/tools/commands/deploy-prompts-codex.mjs +336 -0
  60. package/tools/plugin/package-plugins.mjs +1013 -0
  61. package/tools/skills/deploy-skills-codex.mjs +571 -0
@@ -12,7 +12,7 @@ export class MemoryPromotionGateway {
12
12
  throw new SessionContractError('MALFORMED_SOURCE', 'candidate version does not exist');
13
13
  }
14
14
  const existing = this.store.getPromotionReceipt(input.candidateId, input.version, input.destination.consumer);
15
- if (candidate.reviewState !== 'accepted' && !(candidate.reviewState === 'promoted' && existing)) {
15
+ if (candidate.reviewState !== 'accepted' && candidate.reviewState !== 'promoted') {
16
16
  throw new SessionContractError('OPERATION_NOT_AUTHORIZED', 'promotion requires an accepted exact candidate version');
17
17
  }
18
18
  const security = candidateSecurity(candidate);
@@ -165,7 +165,7 @@ export class FilesystemPromotionDispositionCoordinator {
165
165
  if (!decision) {
166
166
  throw new SessionContractError('OPERATION_NOT_AUTHORIZED', 'every promoted artifact requires an explicit disposition');
167
167
  }
168
- this.authorizedPath(dependent.destinationRef);
168
+ this.authorizedDispositionRef(dependent.destinationRef);
169
169
  return {
170
170
  dependentId: dependent.dependentId,
171
171
  destinationRef: dependent.destinationRef,
@@ -194,6 +194,12 @@ export class FilesystemPromotionDispositionCoordinator {
194
194
  for (const effect of journal.effects) {
195
195
  if (effect.outcome !== 'pending')
196
196
  continue;
197
+ const lineMemory = this.lineMemoryRef(effect.destinationRef);
198
+ if (lineMemory) {
199
+ effect.outcome = this.applyLineMemoryDisposition(lineMemory.metadataPath, lineMemory.handle, purge.operationId, effect);
200
+ this.writeJournal(journalPath, journal);
201
+ continue;
202
+ }
197
203
  const target = this.authorizedPath(effect.destinationRef);
198
204
  const marker = dispositionMarker(purge.operationId, effect);
199
205
  if (effect.action === 'delete') {
@@ -252,6 +258,65 @@ export class FilesystemPromotionDispositionCoordinator {
252
258
  }
253
259
  return target;
254
260
  }
261
+ authorizedDispositionRef(destinationRef) {
262
+ if (this.lineMemoryRef(destinationRef))
263
+ return;
264
+ this.authorizedPath(destinationRef);
265
+ }
266
+ lineMemoryRef(destinationRef) {
267
+ const separator = destinationRef.lastIndexOf('#');
268
+ if (separator < 1)
269
+ return null;
270
+ const metadataRef = destinationRef.slice(0, separator);
271
+ const handle = destinationRef.slice(separator + 1);
272
+ if (!/^lm_[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(handle)) {
273
+ return null;
274
+ }
275
+ return { metadataPath: this.authorizedPath(metadataRef), handle };
276
+ }
277
+ applyLineMemoryDisposition(metadataPath, handle, operationId, effect) {
278
+ if (!existsSync(metadataPath))
279
+ return 'already-applied';
280
+ const metadata = JSON.parse(readFileSync(metadataPath, 'utf8'));
281
+ if (metadata.schemaVersion !== 'aiwg.line-memory.v1' || !metadata.entries) {
282
+ throw new SessionContractError('IMPORT_CONFLICT', 'line-memory metadata schema is invalid');
283
+ }
284
+ const entry = metadata.entries[handle];
285
+ if (!entry)
286
+ return 'already-applied';
287
+ const priorOperation = entry.disposition?.operationId;
288
+ if (priorOperation === operationId)
289
+ return 'already-applied';
290
+ const memoryRef = metadata.store?.memoryPath ?? '.aiwg/memory/line-memory.txt';
291
+ const memoryPath = this.authorizedPath(memoryRef);
292
+ const lines = existsSync(memoryPath)
293
+ ? readFileSync(memoryPath, 'utf8').split(/\r?\n/).filter(Boolean)
294
+ : [];
295
+ const removesActiveFact = ['delete', 'revoke', 'supersede'].includes(effect.action);
296
+ const nextLines = removesActiveFact
297
+ ? removeFirstExact(lines, entry.value)
298
+ : lines;
299
+ if (effect.action === 'delete')
300
+ delete metadata.entries[handle];
301
+ else {
302
+ entry.status = effect.action === 'revoke' ? 'revoked'
303
+ : effect.action === 'supersede' ? 'superseded'
304
+ : effect.action === 'origin_unavailable' ? 'origin-unavailable'
305
+ : 'active';
306
+ entry.updatedAt = new Date().toISOString();
307
+ entry.disposition = {
308
+ operationId,
309
+ action: effect.action,
310
+ effect: effect.effect,
311
+ originAvailable: effect.action !== 'origin_unavailable',
312
+ };
313
+ }
314
+ if (removesActiveFact) {
315
+ this.atomicWrite(memoryPath, nextLines.length ? `${nextLines.join('\n')}\n` : '');
316
+ }
317
+ this.atomicWrite(metadataPath, `${JSON.stringify(metadata, null, 2)}\n`);
318
+ return 'applied';
319
+ }
255
320
  journalPath(operationId) {
256
321
  return resolve(this.journalRoot, `${operationId.replace(':', '-')}.json`);
257
322
  }
@@ -290,6 +355,12 @@ function requireJournalFiles(root) {
290
355
  .sort()
291
356
  .map((name) => resolve(root, name));
292
357
  }
358
+ function removeFirstExact(lines, value) {
359
+ const index = lines.indexOf(value);
360
+ return index < 0
361
+ ? [...lines]
362
+ : lines.filter((_, candidate) => candidate !== index);
363
+ }
293
364
  export function resolveMemoryConsumerManifest(projectRoot, consumer) {
294
365
  const safeConsumer = assertConsumerId(consumer);
295
366
  const candidates = [
@@ -1219,7 +1219,8 @@ export class SessionRepository {
1219
1219
  if (existing)
1220
1220
  return { ...existing, duplicate: true };
1221
1221
  const candidate = this.getCandidate(receipt.candidateId, receipt.candidateVersion);
1222
- if (!candidate || candidate.reviewState !== 'accepted') {
1222
+ if (!candidate
1223
+ || (candidate.reviewState !== 'accepted' && candidate.reviewState !== 'promoted')) {
1223
1224
  throw new SessionContractError('OPERATION_NOT_AUTHORIZED', 'promotion requires an accepted exact candidate version');
1224
1225
  }
1225
1226
  const evidenceIds = [...new Set(candidate.evidence.map((item) => item.eventId))].sort();
@@ -157,6 +157,16 @@ function readCurrentVersion(packageRoot) {
157
157
  }
158
158
  }
159
159
 
160
+ /**
161
+ * Return true when a cached check belongs to the package currently handling
162
+ * the command. A global launcher can dispatch into a newer development
163
+ * checkout, so cache age alone is not sufficient.
164
+ */
165
+ export function cacheMatchesPackage(cache, packageRoot) {
166
+ const currentVersion = readCurrentVersion(packageRoot);
167
+ return !!(currentVersion && cache?.current === currentVersion);
168
+ }
169
+
160
170
  /**
161
171
  * Run the actual update check and write the cache file. Invoked by the
162
172
  * spawned background child via `node src/update/notifier.mjs --check`.
@@ -183,7 +193,7 @@ export function scheduleBackgroundCheck(packageRoot) {
183
193
  if (isDisabled()) return;
184
194
 
185
195
  const cache = readCache();
186
- if (cache?.lastCheckAt) {
196
+ if (cacheMatchesPackage(cache, packageRoot) && cache?.lastCheckAt) {
187
197
  const age = Date.now() - new Date(cache.lastCheckAt).getTime();
188
198
  if (age < CHECK_INTERVAL_MS) return; // recent enough — skip
189
199
  }
@@ -213,9 +223,10 @@ export function scheduleBackgroundCheck(packageRoot) {
213
223
  * is interactive, print a single-line notice to stderr. Never prompts.
214
224
  * Safe to call unconditionally from `bin/aiwg.mjs` — gated by isDisabled().
215
225
  */
216
- export function maybePrintNotice() {
226
+ export function maybePrintNotice(packageRoot) {
217
227
  if (isDisabled()) return;
218
228
  const cache = readCache();
229
+ if (!cacheMatchesPackage(cache, packageRoot)) return;
219
230
  if (!cache?.hasUpdate || !cache.current || !cache.latest) return;
220
231
  // One-line, non-intrusive. Users who want to update run `aiwg update`.
221
232
  const msg = `aiwg: update available ${cache.current} → ${cache.latest} (run: aiwg update)`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwg/cli",
3
- "version": "2026.8.0",
3
+ "version": "2026.8.1",
4
4
  "description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,12 +25,19 @@
25
25
  "files": [
26
26
  "LICENSE",
27
27
  "bin/",
28
+ "agentic/code/providers/",
28
29
  "dist/src/",
29
30
  "!dist/**/*.d.ts",
30
31
  "!dist/**/*.map",
31
32
  "dist/src/api/index.d.ts",
32
33
  "dist/src/resources/index.d.ts",
33
34
  "dist/src/resources/web-release.d.ts",
35
+ "tools/_resolve-impl.mjs",
36
+ "tools/agents/deploy-agents.mjs",
37
+ "tools/agents/providers/",
38
+ "tools/commands/deploy-prompts-codex.mjs",
39
+ "tools/plugin/package-plugins.mjs",
40
+ "tools/skills/deploy-skills-codex.mjs",
34
41
  "README.md"
35
42
  ],
36
43
  "repository": {
@@ -0,0 +1,74 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, extname, join, resolve } from 'node:path';
3
+ import { fileURLToPath, pathToFileURL } from 'node:url';
4
+
5
+ function findPackageRoot(callerUrl) {
6
+ let dir = dirname(fileURLToPath(callerUrl));
7
+ for (let i = 0; i < 12; i += 1) {
8
+ const pkgPath = join(dir, 'package.json');
9
+ if (existsSync(pkgPath)) {
10
+ try {
11
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
12
+ if (pkg.name === 'aiwg' || pkg.name === '@aiwg/cli') return dir;
13
+ } catch {
14
+ // Keep walking.
15
+ }
16
+ }
17
+
18
+ const parent = dirname(dir);
19
+ if (parent === dir) break;
20
+ dir = parent;
21
+ }
22
+
23
+ throw new Error(`Could not locate AIWG package root from ${callerUrl}`);
24
+ }
25
+
26
+ function candidatesFor(root, relativeFromSrc, base) {
27
+ const primary = resolve(root, base, relativeFromSrc);
28
+ const candidates = [primary];
29
+
30
+ if (base === 'src' && extname(primary) === '.js') {
31
+ candidates.push(primary.slice(0, -3) + '.ts');
32
+ }
33
+
34
+ return candidates;
35
+ }
36
+
37
+ function resolveCandidate(root, relativeFromSrc, base) {
38
+ for (const candidate of candidatesFor(root, relativeFromSrc, base)) {
39
+ if (existsSync(candidate)) return candidate;
40
+ }
41
+ return null;
42
+ }
43
+
44
+ /**
45
+ * Resolve a module that may live under compiled dist/src/ or source src/.
46
+ *
47
+ * Prefers dist/src/ when present. Set AIWG_RESOLVE_IMPL_FROM=dist or src to
48
+ * force a side during CI/package-layout checks.
49
+ */
50
+ export function resolveImpl(callerUrl, relativeFromSrc) {
51
+ const root = findPackageRoot(callerUrl);
52
+ const forced = process.env.AIWG_RESOLVE_IMPL_FROM;
53
+
54
+ const order = forced === 'src'
55
+ ? ['src']
56
+ : forced === 'dist'
57
+ ? ['dist/src']
58
+ : ['dist/src', 'src'];
59
+
60
+ for (const base of order) {
61
+ const candidate = resolveCandidate(root, relativeFromSrc, base);
62
+ if (candidate) return candidate;
63
+ }
64
+
65
+ const attempted = order
66
+ .flatMap((base) => candidatesFor(root, relativeFromSrc, base))
67
+ .join(', ');
68
+ throw new Error(`Could not resolve ${relativeFromSrc}; attempted: ${attempted}`);
69
+ }
70
+
71
+ export async function importImpl(callerUrl, relativeFromSrc) {
72
+ const modulePath = resolveImpl(callerUrl, relativeFromSrc);
73
+ return import(pathToFileURL(modulePath).href);
74
+ }