@open-agent-toolkit/cli 0.2.49 → 0.2.51

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 (77) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/cli-utilities/tool-packs.md +35 -24
  3. package/assets/docs/reference/cli-reference.md +20 -5
  4. package/assets/docs/reference/file-locations.md +8 -2
  5. package/assets/docs/reference/oat-directory-structure.md +14 -5
  6. package/assets/docs/reference/troubleshooting.md +22 -4
  7. package/assets/docs/workflows/projects/artifacts.md +9 -4
  8. package/assets/docs/workflows/projects/lifecycle.md +17 -5
  9. package/assets/docs/workflows/projects/picking-up-projects.md +26 -9
  10. package/assets/docs/workflows/projects/pr-flow.md +5 -3
  11. package/assets/docs/workflows/projects/reviewing-oat-prs.md +12 -8
  12. package/assets/public-package-versions.json +4 -4
  13. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +2 -2
  14. package/assets/skills/oat-project-complete/SKILL.md +193 -26
  15. package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +306 -0
  16. package/assets/skills/oat-project-complete/scripts/finalize-synced-archive.mjs +125 -0
  17. package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +106 -0
  18. package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +110 -0
  19. package/assets/skills/oat-project-complete/scripts/resolve-synced-archive-entry.mjs +164 -0
  20. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +2 -2
  21. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +2 -2
  22. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +2 -2
  23. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +2 -2
  24. package/dist/commands/doctor/index.d.ts +7 -0
  25. package/dist/commands/doctor/index.d.ts.map +1 -1
  26. package/dist/commands/doctor/index.js +44 -23
  27. package/dist/commands/pjm/index.d.ts +0 -2
  28. package/dist/commands/pjm/index.d.ts.map +1 -1
  29. package/dist/commands/pjm/index.js +5 -4
  30. package/dist/commands/pjm/migrate.d.ts +2 -1
  31. package/dist/commands/pjm/migrate.d.ts.map +1 -1
  32. package/dist/commands/pjm/migrate.js +23 -17
  33. package/dist/commands/project/archive/archive-utils.d.ts +8 -1
  34. package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
  35. package/dist/commands/project/archive/archive-utils.js +147 -50
  36. package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
  37. package/dist/commands/project/archive/push-runner.js +15 -2
  38. package/dist/commands/project/links/compute.d.ts +1 -0
  39. package/dist/commands/project/links/compute.d.ts.map +1 -1
  40. package/dist/commands/project/links/compute.js +5 -4
  41. package/dist/commands/project/links/index.d.ts +9 -0
  42. package/dist/commands/project/links/index.d.ts.map +1 -1
  43. package/dist/commands/project/links/index.js +71 -2
  44. package/dist/commands/project/list.d.ts +10 -2
  45. package/dist/commands/project/list.d.ts.map +1 -1
  46. package/dist/commands/project/list.js +205 -29
  47. package/dist/commands/project/open/index.d.ts +2 -0
  48. package/dist/commands/project/open/index.d.ts.map +1 -1
  49. package/dist/commands/project/open/index.js +16 -1
  50. package/dist/commands/project/prune/index.d.ts +10 -4
  51. package/dist/commands/project/prune/index.d.ts.map +1 -1
  52. package/dist/commands/project/prune/index.js +85 -15
  53. package/dist/commands/project/pull/index.d.ts +4 -0
  54. package/dist/commands/project/pull/index.d.ts.map +1 -1
  55. package/dist/commands/project/pull/index.js +82 -3
  56. package/dist/commands/project/sync/git.d.ts +9 -0
  57. package/dist/commands/project/sync/git.d.ts.map +1 -1
  58. package/dist/commands/project/sync/git.js +18 -0
  59. package/dist/commands/project/sync/ref-sync.d.ts +16 -1
  60. package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
  61. package/dist/commands/project/sync/ref-sync.js +288 -17
  62. package/dist/commands/project/sync/resolve-target.d.ts +10 -0
  63. package/dist/commands/project/sync/resolve-target.d.ts.map +1 -1
  64. package/dist/commands/project/sync/resolve-target.js +56 -1
  65. package/dist/commands/shared/project-scope.d.ts +2 -0
  66. package/dist/commands/shared/project-scope.d.ts.map +1 -1
  67. package/dist/commands/shared/project-scope.js +5 -0
  68. package/dist/commands/state/generate.d.ts +2 -0
  69. package/dist/commands/state/generate.d.ts.map +1 -1
  70. package/dist/commands/state/generate.js +93 -28
  71. package/dist/commands/status/index.d.ts +3 -1
  72. package/dist/commands/status/index.d.ts.map +1 -1
  73. package/dist/commands/status/index.js +77 -10
  74. package/dist/commands/tools/shared/pack-inventory.d.ts +10 -0
  75. package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
  76. package/dist/commands/tools/shared/pack-inventory.js +71 -21
  77. package/package.json +2 -2
@@ -1,8 +1,14 @@
1
1
  import { execSync } from 'node:child_process';
2
2
  import { readdir, writeFile } from 'node:fs/promises';
3
- import { basename, join } from 'node:path';
3
+ import { basename, dirname, join, resolve } from 'node:path';
4
+ import { classifyLegacySyncedRecord, probeAuthoritativeCompletedRef, } from '../project/list.js';
5
+ import { defaultGitRunner } from '../project/sync/git.js';
6
+ import { listSyncedRecords } from '../project/sync/record.js';
7
+ import { buildSyncTarget } from '../project/sync/ref-sync.js';
8
+ import { probeSyncedTerminalRefs } from '../project/sync/resolve-target.js';
4
9
  import { parseFrontmatterField } from '../shared/frontmatter.js';
5
10
  import { resolveProjectsRoot } from '../shared/oat-paths.js';
11
+ import { resolveScopeRoot } from '../shared/project-scope.js';
6
12
  import { readOatLocalConfig } from '../../config/oat-config.js';
7
13
  import { ensureDir, fileExists } from '../../fs/io.js';
8
14
  const defaultGit = {
@@ -310,22 +316,41 @@ function isTerminalCoordinationProject(kind, phase, phaseStatus) {
310
316
  phase === 'decomposition' &&
311
317
  phaseStatus === 'complete');
312
318
  }
313
- async function listAvailableProjects(repoRoot, projectsRoot) {
314
- const fullRoot = join(repoRoot, projectsRoot);
315
- try {
316
- const entries = await readdir(fullRoot, { withFileTypes: true });
317
- const dirs = entries.filter((e) => e.isDirectory());
318
- if (dirs.length === 0) {
319
- return {
320
- active: '*(No projects found)*',
321
- decompositions: '*(No decompositions found)*',
322
- };
319
+ async function listAvailableProjects(repoRoot, projectsRoot, gitRunner) {
320
+ const lines = [];
321
+ const decompositions = [];
322
+ const materializedSynced = new Set();
323
+ for (const scope of ['shared', 'synced', 'local']) {
324
+ const scopeRoot = resolveScopeRoot(repoRoot, projectsRoot, scope);
325
+ let entries;
326
+ try {
327
+ entries = await readdir(scopeRoot, { withFileTypes: true });
323
328
  }
324
- const lines = [];
325
- const decompositions = [];
326
- for (const dir of dirs) {
327
- const stateFile = join(fullRoot, dir.name, 'state.md');
329
+ catch {
330
+ continue;
331
+ }
332
+ for (const dir of entries.filter((entry) => entry.isDirectory())) {
333
+ const stateFile = join(scopeRoot, dir.name, 'state.md');
328
334
  if (await fileExists(stateFile)) {
335
+ if (scope === 'synced') {
336
+ materializedSynced.add(dir.name);
337
+ const target = buildSyncTarget(repoRoot, projectsRoot, dir.name);
338
+ const terminal = await probeAuthoritativeCompletedRef(target, gitRunner);
339
+ if (terminal) {
340
+ const row = classifyLegacySyncedRecord({
341
+ schemaVersion: 1,
342
+ slug: dir.name,
343
+ scope: 'synced',
344
+ ref: target.ref,
345
+ remote: 'origin',
346
+ status: 'active',
347
+ createdAt: new Date(0).toISOString(),
348
+ completedAt: null,
349
+ }, target.projectPath, terminal);
350
+ lines.push(`- **${dir.name}** - ${row.recommendation.reason}`);
351
+ continue;
352
+ }
353
+ }
329
354
  const phase = (await parseFrontmatterField(stateFile, 'oat_phase')) || 'unknown';
330
355
  const phaseStatus = (await parseFrontmatterField(stateFile, 'oat_phase_status')) ||
331
356
  'in_progress';
@@ -340,19 +365,29 @@ async function listAvailableProjects(repoRoot, projectsRoot) {
340
365
  }
341
366
  }
342
367
  }
343
- return {
344
- active: lines.length > 0 ? lines.join('\n') : '*(No projects found)*',
345
- decompositions: decompositions.length > 0
346
- ? decompositions.join('\n')
347
- : '*(No decompositions found)*',
348
- };
349
368
  }
350
- catch {
351
- return {
352
- active: '*(No projects directory found)*',
353
- decompositions: '*(No decompositions found)*',
354
- };
369
+ const syncedRoot = resolveScopeRoot(repoRoot, projectsRoot, 'synced');
370
+ const records = await listSyncedRecords(syncedRoot);
371
+ for (const record of records) {
372
+ if (materializedSynced.has(record.slug))
373
+ continue;
374
+ const target = buildSyncTarget(repoRoot, projectsRoot, record.slug);
375
+ const authoritative = await probeAuthoritativeCompletedRef(target, gitRunner);
376
+ const probe = authoritative ??
377
+ (record.archiveSourceRefSha
378
+ ? await probeSyncedTerminalRefs(target, record.archiveSourceRefSha, gitRunner)
379
+ : undefined);
380
+ const row = classifyLegacySyncedRecord(record, target.projectPath, probe);
381
+ lines.push(row.kind === 'recorded-absent'
382
+ ? `- **${record.slug}** - checkout absent; oat project pull ${record.slug}`
383
+ : `- **${record.slug}** - ${row.recommendation.reason}`);
355
384
  }
385
+ return {
386
+ active: lines.length > 0 ? lines.join('\n') : '*(No projects found)*',
387
+ decompositions: decompositions.length > 0
388
+ ? decompositions.join('\n')
389
+ : '*(No decompositions found)*',
390
+ };
356
391
  }
357
392
  function buildDashboardMarkdown(project, state, knowledge, staleness, nextStep, projectsList, generatedDate) {
358
393
  const timestamp = `${generatedDate}`;
@@ -453,18 +488,48 @@ export async function generateStateDashboard(options) {
453
488
  const env = options.env ?? process.env;
454
489
  const today = options.today ?? new Date().toISOString().slice(0, 10);
455
490
  const git = options.git ?? defaultGit;
491
+ const gitRunner = options.gitRunner ?? defaultGitRunner;
456
492
  const dashboardPath = join(repoRoot, '.oat', 'state.md');
457
493
  const projectsRoot = await resolveProjectsRoot(repoRoot, env);
458
494
  const hasProjects = await hasAnyProjects(join(repoRoot, projectsRoot));
459
495
  const project = await readActiveProject(repoRoot);
496
+ let terminalNextStep = null;
497
+ if (project.status === 'active' && project.path) {
498
+ const activePath = resolve(repoRoot, project.path);
499
+ const syncedRoot = resolveScopeRoot(repoRoot, projectsRoot, 'synced');
500
+ if (dirname(activePath) === syncedRoot) {
501
+ const target = buildSyncTarget(repoRoot, projectsRoot, project.name);
502
+ const terminal = await probeAuthoritativeCompletedRef(target, gitRunner);
503
+ if (terminal) {
504
+ const row = classifyLegacySyncedRecord({
505
+ schemaVersion: 1,
506
+ slug: project.name,
507
+ scope: 'synced',
508
+ ref: target.ref,
509
+ remote: 'origin',
510
+ status: 'active',
511
+ createdAt: new Date(0).toISOString(),
512
+ completedAt: null,
513
+ }, activePath, terminal);
514
+ project.status =
515
+ row.kind === 'terminal-invalid'
516
+ ? 'terminal ref mismatch'
517
+ : 'terminal cleanup pending';
518
+ terminalNextStep = {
519
+ step: 'oat-project-complete',
520
+ reason: row.recommendation.reason,
521
+ };
522
+ }
523
+ }
524
+ }
460
525
  let state = null;
461
526
  if (project.status === 'active') {
462
527
  state = await readProjectState(repoRoot, project.path);
463
528
  }
464
529
  const knowledge = await readKnowledgeStatus(repoRoot);
465
530
  const staleness = calculateStaleness(knowledge, git, repoRoot, today);
466
- const nextStep = computeNextStep(project, hasProjects, state);
467
- const projectsList = await listAvailableProjects(repoRoot, projectsRoot);
531
+ const nextStep = terminalNextStep ?? computeNextStep(project, hasProjects, state);
532
+ const projectsList = await listAvailableProjects(repoRoot, projectsRoot, gitRunner);
468
533
  const markdown = buildDashboardMarkdown(project, state, knowledge, staleness, nextStep, projectsList, today);
469
534
  await ensureDir(join(repoRoot, '.oat'));
470
535
  await writeFile(dashboardPath, markdown, 'utf8');
@@ -24,7 +24,9 @@ interface StatusDependencies {
24
24
  scanCanonical: (scopeRoot: string, scope: ConcreteScope) => Promise<CanonicalEntry[]>;
25
25
  scanBundledManagedAgents: () => Promise<CanonicalEntry[]>;
26
26
  getAdapters: () => ProviderAdapter[];
27
- getActiveAdapters: (adapters: ProviderAdapter[], scopeRoot: string) => Promise<ProviderAdapter[]>;
27
+ getConfigAwareAdapters: (adapters: ProviderAdapter[], scopeRoot: string, config: SyncConfig) => Promise<{
28
+ activeAdapters: ProviderAdapter[];
29
+ }>;
28
30
  getSyncMappings: (adapter: ProviderAdapter, scope: Scope) => PathMapping[];
29
31
  getAdoptionSources: (adapter: ProviderAdapter, scope: Scope) => AdoptionSource[];
30
32
  detectDrift: (entry: Manifest['entries'][number], scopeRoot: string, copyTransform?: CopyTransform) => Promise<DriftReport>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/status/index.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ import { applyNativeSkillDisposition, getNativeSkillProviderDetails, isNativeSki
7
7
  import { withScopeOption } from '../shared/scope-option.js';
8
8
  import { confirmAction, selectManyWithAbort, selectWithAbort, } from '../shared/shared.prompts.js';
9
9
  import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
10
- import { hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
10
+ import { attributeSharedOwnerDiagnostics, hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
11
11
  import { PACK_NAMES } from '../tools/shared/pack-manifest.js';
12
12
  import { formatPackPath, formatPackPaths, updatePackRecovery, } from '../tools/shared/pack-paths.js';
13
13
  import { DEFAULT_SYNC_CONFIG, loadSyncConfig, } from '../../config/index.js';
@@ -24,12 +24,45 @@ import { copilotAdapter } from '../../providers/copilot/index.js';
24
24
  import { cursorAdapter } from '../../providers/cursor/index.js';
25
25
  import { applyCursorProjectExtensionPlan, computeCursorProjectExtensionPlan, } from '../../providers/cursor/codec/sync-extension.js';
26
26
  import { geminiAdapter } from '../../providers/gemini/index.js';
27
- import { getActiveAdapters, getSyncMappings, } from '../../providers/shared/index.js';
27
+ import { getConfigAwareAdapters, getSyncMappings, } from '../../providers/shared/index.js';
28
28
  import { getAdoptionSources } from '../../providers/shared/adapter.utils.js';
29
29
  import { SCOPE_CONTENT_TYPES, } from '../../shared/types.js';
30
30
  import { formatStatusTable } from '../../ui/output.js';
31
31
  import { Command } from 'commander';
32
32
  const DEFAULT_REMEDIATION = 'Run "oat init" to adopt stray entries.';
33
+ function unavailablePackReport(error, roots, unavailableScopes) {
34
+ let detail = error instanceof Error ? error.message : 'Unknown error.';
35
+ const replacements = [
36
+ ...(roots.projectRoot
37
+ ? [
38
+ [`${roots.projectRoot}/`, ''],
39
+ [roots.projectRoot, '.'],
40
+ ]
41
+ : []),
42
+ ...(roots.userRoot
43
+ ? [
44
+ [`${roots.userRoot}/`, '~/'],
45
+ [roots.userRoot, '~'],
46
+ ]
47
+ : []),
48
+ ].sort(([left], [right]) => right.length - left.length);
49
+ for (const [root, replacement] of replacements) {
50
+ detail = detail.replaceAll(root, replacement);
51
+ }
52
+ return {
53
+ availability: {
54
+ status: 'unavailable',
55
+ diagnostic: {
56
+ code: 'packs:inventory',
57
+ message: `Unable to inventory managed packs: ${detail}`,
58
+ recovery: 'Run `pnpm build` and rerun `oat status`.',
59
+ },
60
+ },
61
+ states: [],
62
+ unavailableScopes,
63
+ pjm: null,
64
+ };
65
+ }
33
66
  const DEFAULT_DEPENDENCIES = {
34
67
  buildCommandContext,
35
68
  async resolveScopeRoot(scope, context) {
@@ -55,7 +88,7 @@ const DEFAULT_DEPENDENCIES = {
55
88
  geminiAdapter,
56
89
  ];
57
90
  },
58
- getActiveAdapters,
91
+ getConfigAwareAdapters,
59
92
  getSyncMappings,
60
93
  getAdoptionSources,
61
94
  detectDrift,
@@ -210,7 +243,7 @@ function shouldReportPjmAdoption(adoption, states) {
210
243
  const pjm = states.find(({ pack }) => pack === 'project-management');
211
244
  return (pjm?.scopes ?? []).some(({ scope }) => scope === 'project');
212
245
  }
213
- async function collectPackReport(scopeRoots, unavailableScopes, dependencies) {
246
+ async function collectPackReport(scopeRoots, unavailableScopes, userManagedRoleMaterialization, dependencies) {
214
247
  const roots = {
215
248
  ...(scopeRoots.has('project')
216
249
  ? { projectRoot: scopeRoots.get('project') }
@@ -218,22 +251,46 @@ async function collectPackReport(scopeRoots, unavailableScopes, dependencies) {
218
251
  ...(scopeRoots.has('user') ? { userRoot: scopeRoots.get('user') } : {}),
219
252
  };
220
253
  if (scopeRoots.size === 0) {
221
- return { states: [], unavailableScopes, pjm: null };
254
+ return {
255
+ availability: { status: 'available' },
256
+ states: [],
257
+ unavailableScopes,
258
+ pjm: null,
259
+ };
260
+ }
261
+ let inventories;
262
+ try {
263
+ const assetsRoot = await dependencies.resolveAssetsRoot();
264
+ inventories = attributeSharedOwnerDiagnostics(await Promise.all(PACK_NAMES.map((pack) => dependencies.inventoryPack({
265
+ pack,
266
+ assetsRoot,
267
+ ...roots,
268
+ ...(scopeRoots.has('user')
269
+ ? { userManagedRoleMaterialization }
270
+ : {}),
271
+ }))));
272
+ }
273
+ catch (error) {
274
+ return unavailablePackReport(error, roots, unavailableScopes);
222
275
  }
223
- const assetsRoot = await dependencies.resolveAssetsRoot();
224
- const inventories = await Promise.all(PACK_NAMES.map((pack) => dependencies.inventoryPack({ pack, assetsRoot, ...roots })));
225
276
  const states = inventories
226
277
  .map((inventory) => toStatusPackState(inventory, roots))
227
278
  .filter((state) => state !== null);
228
279
  const projectRoot = scopeRoots.get('project');
229
280
  if (!projectRoot) {
230
- return { states, unavailableScopes, pjm: null };
281
+ return {
282
+ availability: { status: 'available' },
283
+ states,
284
+ unavailableScopes,
285
+ pjm: null,
286
+ };
231
287
  }
232
288
  const adoption = await dependencies.resolvePjmAdoption({
233
289
  projectRoot,
234
290
  repoRoot: join(projectRoot, '.oat', 'repo'),
235
291
  });
236
292
  return {
293
+ availability: { status: 'available' },
237
294
  states,
238
295
  unavailableScopes,
239
296
  pjm: {
@@ -262,6 +319,9 @@ function describePackScope(state) {
262
319
  }
263
320
  function formatPackReport(report) {
264
321
  const lines = [];
322
+ if (report.availability.diagnostic) {
323
+ lines.push(`${report.availability.diagnostic.code}: ${report.availability.diagnostic.message}`, ` Fix: ${report.availability.diagnostic.recovery}`);
324
+ }
265
325
  if (report.states.length > 0) {
266
326
  lines.push('Pack state:');
267
327
  for (const state of report.states) {
@@ -275,6 +335,9 @@ function formatPackReport(report) {
275
335
  }
276
336
  for (const diagnostic of scope.diagnostics) {
277
337
  lines.push(` ${diagnostic.code}: ${diagnostic.message}`);
338
+ if (diagnostic.paths.length > 0) {
339
+ lines.push(` Affected: ${formatPackPaths(diagnostic.paths, {})}`);
340
+ }
278
341
  if (diagnostic.recovery) {
279
342
  lines.push(` Fix: ${diagnostic.recovery}`);
280
343
  }
@@ -285,6 +348,9 @@ function formatPackReport(report) {
285
348
  }
286
349
  for (const diagnostic of state.diagnostics) {
287
350
  lines.push(` ${diagnostic.code}: ${diagnostic.message}`);
351
+ if (diagnostic.paths.length > 0) {
352
+ lines.push(` Affected: ${formatPackPaths(diagnostic.paths, {})}`);
353
+ }
288
354
  if (diagnostic.recovery) {
289
355
  lines.push(` Fix: ${diagnostic.recovery}`);
290
356
  }
@@ -316,7 +382,7 @@ async function collectScopeReports(scope, context, dependencies) {
316
382
  dependencies.resolveUserSyncConfig(userConfigDir),
317
383
  ]);
318
384
  const adapters = dependencies.getAdapters();
319
- const activeAdapters = await dependencies.getActiveAdapters(adapters, scopeRoot);
385
+ const { activeAdapters } = await dependencies.getConfigAwareAdapters(adapters, scopeRoot, scope === 'user' ? userSyncConfig : syncConfig);
320
386
  const reports = [];
321
387
  const strayCandidates = [];
322
388
  const trackedCanonicalByProvider = new Set(manifest.entries.map((entry) => `${entry.provider}|${normalizeToPosixPath(entry.canonicalPath)}`));
@@ -526,7 +592,8 @@ async function runStatusCommand(context, dependencies, options = {}) {
526
592
  }
527
593
  return;
528
594
  }
529
- const packReport = await collectPackReport(scopeRoots, unavailableScopes, dependencies);
595
+ const packReport = await collectPackReport(scopeRoots, unavailableScopes, scopeCollections.some(({ scope, activeAdapterNames }) => scope === 'user' &&
596
+ activeAdapterNames.some((name) => name === 'codex' || name === 'cursor')), dependencies);
530
597
  if (context.json) {
531
598
  const payload = {
532
599
  scope: context.scope,
@@ -33,14 +33,24 @@ export interface InventoryScopedPackInput {
33
33
  scope: ConcreteScope;
34
34
  scopeRoot: string;
35
35
  assetsRoot: string;
36
+ managedRoleMaterialization?: boolean;
36
37
  }
37
38
  export interface InventoryPackInput {
38
39
  pack: PackName;
39
40
  assetsRoot: string;
40
41
  projectRoot?: string;
41
42
  userRoot?: string;
43
+ userManagedRoleMaterialization?: boolean;
42
44
  }
43
45
  export declare function inventoryScopedPack(input: InventoryScopedPackInput): Promise<ScopedPackInventory>;
44
46
  export declare function hasScopedPackPlacementEvidence(inventory: ScopedPackInventory): boolean;
47
+ /**
48
+ * Attribute each present shared asset only after every candidate pack has been
49
+ * inventoried. Shared presence cannot establish placement, so applicable
50
+ * owners are limited to packs with independent intent or non-shared managed
51
+ * assets. The observation is attached once to the first applicable owner in
52
+ * canonical pack order while naming the complete applicable owner set.
53
+ */
54
+ export declare function attributeSharedOwnerDiagnostics(inventories: PackInventory[]): PackInventory[];
45
55
  export declare function inventoryPack(input: InventoryPackInput): Promise<PackInventory>;
46
56
  //# sourceMappingURL=pack-inventory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-inventory.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,uBAAuB,GACvB,iBAAiB,GACjB,0BAA0B,GAC1B,2BAA2B,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA8QD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAmC9B;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAUT;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CA0DxB"}
1
+ {"version":3,"file":"pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-inventory.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,KAAK,aAAa,EAEnB,MAAM,eAAe,CAAC;AAIvB,OAAO,EAEL,KAAK,gBAAgB,EAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,QAAQ,EACT,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,mBAAmB,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EACA,uBAAuB,GACvB,iBAAiB,GACjB,0BAA0B,GAC1B,2BAA2B,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,YAAY,EAAE,gBAAgB,CAAC;IAC/B,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAC7B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IACvD,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B,CAAC,EAAE,OAAO,CAAC;CAC1C;AAiRD,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,mBAAmB,CAAC,CAwC9B;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,mBAAmB,GAC7B,OAAO,CAUT;AAED;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAC7C,WAAW,EAAE,aAAa,EAAE,GAC3B,aAAa,EAAE,CAgEjB;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
@@ -6,7 +6,7 @@ import { readOatConfig } from '../../../config/oat-config.js';
6
6
  import { resolveManagedScopeRoots, validateManagedPath, validateRealPathWithinScope, } from '../../../fs/paths.js';
7
7
  import { USER_SCOPE_MANAGED_AGENT_FILES, } from '../../../shared/types.js';
8
8
  import { digestDirectory, digestFile } from './content-digest.js';
9
- import { getPackDefinition } from './pack-manifest.js';
9
+ import { getPackDefinition, PACK_NAMES } from './pack-manifest.js';
10
10
  import { readScopedPackIntent, } from './scoped-pack-intent.js';
11
11
  async function pathExists(path) {
12
12
  try {
@@ -172,27 +172,29 @@ function intentDiagnostic(diagnostic) {
172
172
  return { ...diagnostic };
173
173
  }
174
174
  /**
175
- * User-scope canonical agents are installed into `~/.agents/agents/` but no
176
- * provider view is generated for them: `SCOPE_CONTENT_TYPES.user` enumerates
177
- * skills only, and the sole user-scope agent materialization is the bundled
178
- * managed role file set (`USER_SCOPE_MANAGED_AGENT_FILES`). Completeness alone
179
- * therefore reports such a pack as complete while the declared agent surface is
180
- * unreachable, so the gap is named here instead of staying silent.
175
+ * User-scope canonical agents are installed into `~/.agents/agents/`, while
176
+ * native provider-role materialization is caller-resolved from the active
177
+ * config-aware adapter set. When that capability is active, only the bundled
178
+ * managed role file set (`USER_SCOPE_MANAGED_AGENT_FILES`) is supplied to the
179
+ * extension. Completeness alone therefore cannot describe native
180
+ * materialization, so the remaining gap is named here instead of staying
181
+ * silent. Canonical instruction-read availability is a separate contract.
181
182
  */
182
- function userAgentMaterializationDiagnostics(pack, scope, assets) {
183
+ function userAgentMaterializationDiagnostics(pack, scope, assets, managedRoleMaterialization) {
183
184
  if (scope !== 'user')
184
185
  return [];
185
186
  const bundledRoleFiles = new Set(USER_SCOPE_MANAGED_AGENT_FILES);
186
187
  const unmaterialized = assets.filter(({ definition, status }) => definition.kind === 'agent' &&
187
188
  definition.ownership.user === 'managed' &&
188
189
  status !== 'missing' &&
189
- !bundledRoleFiles.has(definition.destination.split('/').at(-1) ?? ''));
190
+ (!managedRoleMaterialization ||
191
+ !bundledRoleFiles.has(definition.destination.split('/').at(-1) ?? '')));
190
192
  if (unmaterialized.length === 0)
191
193
  return [];
192
194
  return [
193
195
  {
194
196
  code: 'user-agent-unmaterialized',
195
- message: `Pack ${pack} installs user-scope canonical agents that no provider view materializes; user-scope agent materialization is limited to the bundled managed role files (${USER_SCOPE_MANAGED_AGENT_FILES.join(', ')}). Install this pack at project scope to make these agents available to providers.`,
197
+ message: `Pack ${pack} installs user-scope canonical agents without native provider-role materialization for the active provider set; canonical instruction reads are unaffected. Active Codex or Cursor materialization supplies only the bundled managed role files (${USER_SCOPE_MANAGED_AGENT_FILES.join(', ')}). Install this pack at project scope to materialize the affected agents.`,
196
198
  paths: unmaterialized.map(({ path }) => path),
197
199
  },
198
200
  ];
@@ -210,7 +212,7 @@ export async function inventoryScopedPack(input) {
210
212
  ]);
211
213
  const diagnostics = [
212
214
  ...intent.diagnostics.map(intentDiagnostic),
213
- ...userAgentMaterializationDiagnostics(input.pack, input.scope, assets),
215
+ ...userAgentMaterializationDiagnostics(input.pack, input.scope, assets, input.managedRoleMaterialization ?? false),
214
216
  ];
215
217
  return {
216
218
  pack: input.pack,
@@ -227,6 +229,61 @@ export function hasScopedPackPlacementEvidence(inventory) {
227
229
  definition.ownership[inventory.scope] === 'managed' &&
228
230
  status !== 'missing'));
229
231
  }
232
+ /**
233
+ * Attribute each present shared asset only after every candidate pack has been
234
+ * inventoried. Shared presence cannot establish placement, so applicable
235
+ * owners are limited to packs with independent intent or non-shared managed
236
+ * assets. The observation is attached once to the first applicable owner in
237
+ * canonical pack order while naming the complete applicable owner set.
238
+ */
239
+ export function attributeSharedOwnerDiagnostics(inventories) {
240
+ const attributed = inventories.map((inventory) => ({
241
+ ...inventory,
242
+ scopes: inventory.scopes.map((scoped) => ({
243
+ ...scoped,
244
+ diagnostics: scoped.diagnostics.filter(({ code }) => code !== 'shared-owner-observation'),
245
+ })),
246
+ diagnostics: inventory.diagnostics.filter(({ code }) => code !== 'shared-owner-observation'),
247
+ }));
248
+ const groups = new Map();
249
+ for (const inventory of attributed) {
250
+ for (const scoped of inventory.scopes) {
251
+ for (const asset of scoped.assets) {
252
+ const owner = asset.definition.sharedOwner;
253
+ if (!owner || asset.status === 'missing')
254
+ continue;
255
+ const key = `${scoped.scope}:${owner}:${asset.definition.destination}`;
256
+ const group = groups.get(key) ?? {
257
+ owner,
258
+ destination: asset.definition.destination,
259
+ scope: scoped.scope,
260
+ candidates: [],
261
+ paths: new Set(),
262
+ };
263
+ group.candidates.push({ pack: inventory.pack, scoped });
264
+ group.paths.add(asset.path);
265
+ groups.set(key, group);
266
+ }
267
+ }
268
+ }
269
+ const packOrder = new Map(PACK_NAMES.map((pack, index) => [pack, index]));
270
+ for (const group of groups.values()) {
271
+ const applicable = group.candidates
272
+ .filter(({ scoped }) => hasScopedPackPlacementEvidence(scoped))
273
+ .sort((left, right) => packOrder.get(left.pack) - packOrder.get(right.pack));
274
+ if (applicable.length === 0)
275
+ continue;
276
+ const applicableOwners = applicable.map(({ pack }) => pack);
277
+ const diagnostic = {
278
+ code: 'shared-owner-observation',
279
+ message: `Shared managed asset ${group.destination} (${group.owner}) at ${group.scope} scope applies to installed or intended pack owner(s): ${applicableOwners.join(', ')}`,
280
+ paths: [...group.paths].sort(),
281
+ };
282
+ const selected = applicable[0];
283
+ selected.scoped.diagnostics.push(diagnostic);
284
+ }
285
+ return attributed;
286
+ }
230
287
  export async function inventoryPack(input) {
231
288
  const definition = getPackDefinition(input.pack);
232
289
  const roots = {
@@ -242,6 +299,9 @@ export async function inventoryPack(input) {
242
299
  scope,
243
300
  scopeRoot,
244
301
  assetsRoot: input.assetsRoot,
302
+ managedRoleMaterialization: scope === 'user'
303
+ ? (input.userManagedRoleMaterialization ?? false)
304
+ : false,
245
305
  }),
246
306
  ]
247
307
  : [];
@@ -255,16 +315,6 @@ export async function inventoryPack(input) {
255
315
  ? 'user'
256
316
  : 'unavailable';
257
317
  const diagnostics = scopes.flatMap(({ diagnostics: values }) => values);
258
- for (const scoped of scopes) {
259
- const shared = scoped.assets.filter(({ definition: asset, status }) => asset.sharedOwner !== undefined && status !== 'missing');
260
- if (shared.length > 0 && !hasScopedPackPlacementEvidence(scoped)) {
261
- diagnostics.push({
262
- code: 'shared-owner-observation',
263
- message: `Pack ${input.pack} has shared managed assets at ${scoped.scope} scope without pack ownership evidence`,
264
- paths: shared.map(({ path }) => path),
265
- });
266
- }
267
- }
268
318
  if (placement === 'both') {
269
319
  const assets = active.flatMap(({ assets: values }) => values.filter(({ status }) => status !== 'missing'));
270
320
  diagnostics.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-agent-toolkit/cli",
3
- "version": "0.2.49",
3
+ "version": "0.2.51",
4
4
  "private": false,
5
5
  "description": "Open Agent Toolkit CLI",
6
6
  "homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
@@ -34,7 +34,7 @@
34
34
  "ora": "^9.0.0",
35
35
  "yaml": "2.8.2",
36
36
  "zod": "^3.25.76",
37
- "@open-agent-toolkit/control-plane": "0.2.49"
37
+ "@open-agent-toolkit/control-plane": "0.2.51"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.10.0",