@open-agent-toolkit/cli 0.2.49 → 0.2.50

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.
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.2.49"
3
+ "oatVersion": "0.2.50"
4
4
  }
@@ -189,23 +189,30 @@ creates `~/.oat/ideas/backlog.md` and `~/.oat/ideas/scratchpad.md`. Only the
189
189
  `workflows` project-scaffold seeds — `.oat/projects-root`, `.oat/config.json`,
190
190
  and the project `.gitkeep` files — are pinned to project scope.
191
191
 
192
- #### User-scope agents reach no provider
193
-
194
- Canonical **agents** are installed at either scope, but only project scope
195
- materializes a provider view for them. At user scope the sync pipeline
196
- enumerates skills only, and the sole user-scope agent materialization is the
197
- bundled managed role file set (`oat-phase-implementer.md` and
198
- `oat-reviewer.md`). A pack installed at user scope therefore writes its agents
199
- to `~/.agents/agents/` where no provider can see them — for example
200
- `oat tools install workflows --scope user` leaves `oat-codebase-mapper` without
201
- a provider agent, and `oat tools install research --scope user` does the same
202
- for `skeptical-evaluator`.
192
+ #### User-scope agents have limited native materialization
193
+
194
+ Canonical **agents** are installed at either scope. At user scope, native
195
+ Codex or Cursor role materialization is active only when that adapter is active
196
+ under the resolved sync config: explicit enablement wins without filesystem
197
+ detection, explicit disablement wins despite detection, and an unset adapter
198
+ follows detection. That native materialization supplies the bundled managed
199
+ role files (`oat-phase-implementer.md` and `oat-reviewer.md`); it does not
200
+ materialize other pack-owned user agents. For example, a user-scope workflows
201
+ install leaves `oat-codebase-mapper` without a native provider role, and a
202
+ user-scope research install does the same for `skeptical-evaluator`. When no
203
+ Codex or Cursor adapter is active, even the bundled managed roles lack native
204
+ materialization.
205
+
206
+ This diagnostic concerns native provider roles only. Providers may read
207
+ canonical agent instructions through a separate loaded, user, and project
208
+ lookup contract; that read availability does not establish native
209
+ materialization and does not suppress this finding.
203
210
 
204
211
  `oat status` and `oat doctor` name the affected agents with a
205
212
  `user-agent-unmaterialized` finding rather than reporting the pack as complete
206
213
  without qualification. Install the pack at **project scope** when you need its
207
- agents; `oat tools update` cannot repair this, because it is a scope limitation
208
- rather than drift.
214
+ native provider roles; `oat tools update` cannot repair this, because it is a
215
+ scope limitation rather than drift.
209
216
 
210
217
  Repository templates under `.oat/templates/` are **owner-owned seeds**. OAT
211
218
  compares a source-backed seed with its bundled default: a byte-equivalent copy
@@ -299,12 +306,14 @@ The canonical surface splits active operational state (under `pjm/`) from durabl
299
306
 
300
307
  Decisions are now file-per-record under `reference/decisions/` (created and indexed with the [`oat decision`](config-and-local-state.md#oat-decision-) command group), replacing the legacy single `decision-record.md`. Repos still on the old `reference/` layout can migrate with `oat pjm migrate`.
301
308
 
302
- > **Current migration prerequisite:** In CLI `0.2.37`, `oat pjm migrate` still
303
- > requires project-scope `tools.project-management: true` in `.oat/config.json`;
304
- > a user-only pack install does not satisfy that gate. In an adopted legacy
305
- > repository, run `oat config set tools.project-management true` before the
306
- > migration preview. Removing this temporary coupling is tracked by
307
- > `BL-260827-correct-scope-and-adoption`.
309
+ Migration eligibility is independent of where the `project-management` pack is
310
+ installed. `oat pjm migrate` resolves the repository's adoption state for
311
+ diagnostic context, then inventories recognized legacy sources before writing.
312
+ A complete current layout returns `already-migrated`; recognized legacy input
313
+ can be previewed or applied from any adoption state; and a repository with
314
+ neither recognized legacy input nor a complete current layout is skipped with
315
+ an `oat pjm init` recovery. `--print-prompt` only reads the bundled prompt and
316
+ does not inspect adoption or modify the repository.
308
317
 
309
318
  Decision records still require repository PJM adoption. Run `oat pjm init` first: like every repository-mutating PJM command, `oat decision init` fails closed in an unadopted repository, writes nothing, and returns `oat pjm init` as the recovery. Once the repository is adopted, `oat decision init` scaffolds only the decision surface — the decision directory, generated index, and decision-specific AGENTS guidance — without touching current state, roadmap, or backlog artifacts. It does not require the `project-management` pack. If the pack is installed later, its root guidance is maintained as a separate managed section so the decision instructions remain independently reusable.
310
319
 
@@ -322,11 +331,13 @@ repository-mutating PJM command checks it before writing anything:
322
331
  | `partial-initialization` | Some canonical scaffold files exist but the surface is incomplete | `oat pjm init` |
323
332
  | `none` | The repository has not adopted PJM | `oat pjm init` |
324
333
 
325
- `oat pjm`, `oat backlog`, and `oat decision` mutations **fail closed** for
326
- `partial-initialization` and `none`. They write nothing and return an error
327
- naming the repository path and `oat pjm init` as the recovery. `oat backlog
328
- init` and `oat decision init` are no longer alternate adoption paths for the
329
- full PJM surface.
334
+ Normal `oat pjm`, `oat backlog`, and `oat decision` mutations **fail closed**
335
+ for `partial-initialization` and `none`. They write nothing and return an error
336
+ naming the repository path and `oat pjm init` as the recovery. The explicit
337
+ `oat pjm migrate` command is the bounded exception: recognized legacy sources
338
+ authorize that migration regardless of the adoption label. `oat backlog init`
339
+ and `oat decision init` are no longer alternate adoption paths for the full PJM
340
+ surface.
330
341
 
331
342
  Run `oat pjm doctor` to inspect an existing surface. It is read-only, reports
332
343
  missing canonical files, leftover template frontmatter, and
@@ -167,12 +167,30 @@ Both commands report managed pack state with a scoped recovery command:
167
167
  place and your edits are gone. The finding is informational and carries no
168
168
  recovery command for exactly that reason.
169
169
  - `user-agent-unmaterialized` — the pack installed canonical agents into
170
- `~/.agents/agents/`, but user scope materializes no provider view for them
171
- beyond the bundled managed role files. `oat tools update` cannot fix this.
172
- Install the pack at project scope (`oat tools install <pack> --scope project`)
173
- when you need its agents. See
170
+ `~/.agents/agents/`, but active native Codex/Cursor adapters materialize only
171
+ the bundled managed role files at user scope. Other pack-owned agents remain
172
+ unmaterialized; when neither adapter is active, the managed roles do too.
173
+ Provider access to canonical instructions through loaded, user, and project
174
+ reads is a separate contract and does not clear this native-role finding.
175
+ `oat tools update` cannot fix it. Install the pack at project scope
176
+ (`oat tools install <pack> --scope project`) when you need its native roles. See
174
177
  [Tool packs](../cli-utilities/tool-packs.md) for the full limitation.
175
178
 
179
+ ## `status` or `doctor` reports `packs:inventory`
180
+
181
+ OAT could not read the canonical managed-pack inventory. `oat status` keeps the
182
+ rest of the report available and returns `packs.availability.status` as
183
+ `unavailable` in JSON, with an empty `packs.states` array and a structured
184
+ diagnostic. `oat doctor` emits the same condition as a warning instead of
185
+ stopping its other checks. Reported project and home paths remain redacted.
186
+
187
+ Rebuild the CLI workspace, then rerun the command named in the diagnostic:
188
+
189
+ ```bash
190
+ pnpm build
191
+ oat status # or: oat doctor
192
+ ```
193
+
176
194
  ## `status` or `doctor` reports `legacy-false-conflict`
177
195
 
178
196
  An older repository left `tools.<pack>: false` in shared config while managed
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.2.49",
3
- "docs-config": "0.2.49",
4
- "docs-theme": "0.2.49",
5
- "docs-transforms": "0.2.49"
2
+ "cli": "0.2.50",
3
+ "docs-config": "0.2.50",
4
+ "docs-theme": "0.2.50",
5
+ "docs-transforms": "0.2.50"
6
6
  }
@@ -2,10 +2,12 @@ import { type CommandContext, type GlobalOptions } from '../../app/command-conte
2
2
  import { type PjmAdoption, type ResolvePjmAdoptionOptions } from '../pjm/adoption.js';
3
3
  import { type PjmDoctorOptions } from '../pjm/doctor.js';
4
4
  import { type InventoryPackInput, type PackInventory } from '../tools/shared/pack-inventory.js';
5
+ import type { SyncConfig } from '../../config/index.js';
5
6
  import { type OatConfig, type OatLocalConfig, type UserConfig } from '../../config/oat-config.js';
6
7
  import { type Manifest } from '../../manifest/index.js';
7
8
  import { type CursorMaterializedModelDiagnostic, type MatrixCellAvailabilityResponse, type ValidateMatrixCellOptions } from '../../providers/identity/availability.js';
8
9
  import { createDispatchValidationPassContext, validateDispatchMatrixRefs } from '../../providers/identity/dispatch-validation.js';
10
+ import { type ProviderAdapter } from '../../providers/shared/index.js';
9
11
  import type { ConcreteScope } from '../../shared/types.js';
10
12
  import { type DoctorCheck } from '../../ui/output.js';
11
13
  import { Command } from 'commander';
@@ -22,6 +24,11 @@ interface DoctorDependencies {
22
24
  }>>;
23
25
  readFile: (path: string) => Promise<string>;
24
26
  resolveAssetsRoot: () => Promise<string>;
27
+ resolveUserSyncConfig: (userConfigDir: string) => Promise<SyncConfig>;
28
+ getAdapters: () => ProviderAdapter[];
29
+ getConfigAwareAdapters: (adapters: ProviderAdapter[], scopeRoot: string, config: SyncConfig) => Promise<{
30
+ activeAdapters: ProviderAdapter[];
31
+ }>;
25
32
  readOatConfig: (repoRoot: string) => Promise<OatConfig>;
26
33
  readOatConfigForDefaultScopeRepair: (repoRoot: string) => Promise<OatConfig>;
27
34
  readOatLocalConfig: (repoRoot: string) => Promise<OatLocalConfig>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/doctor/index.ts"],"names":[],"mappings":"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"}
@@ -8,11 +8,12 @@ import { runPjmDoctorChecks, } from '../pjm/doctor.js';
8
8
  import { getSkillVersion } from '../shared/frontmatter.js';
9
9
  import { withScopeOption } from '../shared/scope-option.js';
10
10
  import { readGlobalOptions, resolveConcreteScopes, } from '../shared/shared.utils.js';
11
- import { hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
11
+ import { attributeSharedOwnerDiagnostics, hasScopedPackPlacementEvidence, inventoryPack, } from '../tools/shared/pack-inventory.js';
12
12
  import { PACK_NAMES } from '../tools/shared/pack-manifest.js';
13
13
  import { formatPackPaths, updatePackRecovery, } from '../tools/shared/pack-paths.js';
14
14
  import { walkDispatchMatrix, } from '../../config/dispatch-matrix.js';
15
15
  import { readOatConfig, readOatConfigForDefaultScopeRepair, readOatLocalConfig, readUserConfig, } from '../../config/oat-config.js';
16
+ import { resolveUserSyncConfig } from '../../config/user-sync-config.js';
16
17
  import { resolveAssetsRoot } from '../../fs/assets.js';
17
18
  import { resolveProjectRoot, resolveScopeRoot } from '../../fs/paths.js';
18
19
  import TOML from '@iarna/toml';
@@ -26,6 +27,7 @@ import { CURSOR_MODEL_PIN_MAPPINGS } from '../../providers/cursor/codec/catalog.
26
27
  import { geminiAdapter } from '../../providers/gemini/index.js';
27
28
  import { diagnoseCursorMaterializedModels, validateMatrixCell, } from '../../providers/identity/availability.js';
28
29
  import { createDispatchValidationPassContext, validateDispatchMatrixRefs, } from '../../providers/identity/dispatch-validation.js';
30
+ import { getConfigAwareAdapters, } from '../../providers/shared/index.js';
29
31
  import { formatDoctorResults } from '../../ui/output.js';
30
32
  import { Command } from 'commander';
31
33
  import { checkStaleInvocations } from './stale-invocations.js';
@@ -139,6 +141,15 @@ function createDependencies() {
139
141
  checkProviders: checkProvidersDefault,
140
142
  readFile: async (path) => readFile(path, 'utf8'),
141
143
  resolveAssetsRoot,
144
+ resolveUserSyncConfig,
145
+ getAdapters: () => [
146
+ claudeAdapter,
147
+ cursorAdapter,
148
+ codexAdapter,
149
+ copilotAdapter,
150
+ geminiAdapter,
151
+ ],
152
+ getConfigAwareAdapters,
142
153
  readOatConfig,
143
154
  readOatConfigForDefaultScopeRepair,
144
155
  readOatLocalConfig,
@@ -477,18 +488,6 @@ function collectPackStateFindings(inventories) {
477
488
  for (const scoped of inventory.scopes) {
478
489
  const { scope } = scoped;
479
490
  if (!hasScopedPackPlacementEvidence(scoped)) {
480
- const sharedPresent = scoped.assets.filter((asset) => asset.definition.sharedOwner !== undefined &&
481
- asset.status !== 'missing');
482
- if (sharedPresent.length > 0) {
483
- findings.push({
484
- pack: inventory.pack,
485
- scope,
486
- code: 'shared-owner-observation',
487
- detail: 'shared managed assets are present without pack ownership evidence',
488
- paths: sharedPresent.map(({ path }) => path),
489
- recovery: null,
490
- });
491
- }
492
491
  continue;
493
492
  }
494
493
  const managed = scoped.assets.filter((asset) => asset.definition.ownership[scope] === 'managed');
@@ -560,7 +559,18 @@ function collectPackStateFindings(inventories) {
560
559
  pack: inventory.pack,
561
560
  scope,
562
561
  code: 'user-agent-unmaterialized',
563
- detail: `${diagnostic.paths.length} user-scope agent(s) reach no provider; user-scope agent materialization is limited to the bundled managed role files, so install this pack at project scope to use them`,
562
+ detail: `${diagnostic.paths.length} user-scope agent(s) lack native provider-role materialization; canonical instruction reads are unaffected, and active Codex or Cursor materialization supplies only the bundled managed roles, so install this pack at project scope to materialize the affected agents`,
563
+ paths: diagnostic.paths,
564
+ recovery: null,
565
+ });
566
+ continue;
567
+ }
568
+ if (diagnostic.code === 'shared-owner-observation') {
569
+ findings.push({
570
+ pack: inventory.pack,
571
+ scope,
572
+ code: 'shared-owner-observation',
573
+ detail: diagnostic.message,
564
574
  paths: diagnostic.paths,
565
575
  recovery: null,
566
576
  });
@@ -610,10 +620,10 @@ function createScopedPackStateCheck(scope, findings, roots) {
610
620
  name: `${scope}:pack_state`,
611
621
  description: 'Managed pack completeness and drift',
612
622
  status: recoveries.length > 0 ? 'warn' : 'pass',
613
- message: scoped
614
- .map((finding) => formatPackFinding(finding, roots))
615
- .join('; '),
616
- fix: recoveries.length > 0 ? recoveries.join('; ') : undefined,
623
+ message: `Findings:\n${scoped
624
+ .map((finding) => ` - ${formatPackFinding(finding, roots)}`)
625
+ .join('\n')}`,
626
+ fix: recoveries.length > 0 ? recoveries.join('\n Fix: ') : undefined,
617
627
  };
618
628
  }
619
629
  function createPackDuplicationCheck(findings, roots) {
@@ -630,10 +640,10 @@ function createPackDuplicationCheck(findings, roots) {
630
640
  name: 'packs:scope_duplication',
631
641
  description: 'Cross-scope pack duplication',
632
642
  status: 'warn',
633
- message: duplicates
634
- .map((finding) => formatPackFinding(finding, roots))
635
- .join('; '),
636
- fix: uniqueRecoveries(duplicates).join('; '),
643
+ message: `Findings:\n${duplicates
644
+ .map((finding) => ` - ${formatPackFinding(finding, roots)}`)
645
+ .join('\n')}`,
646
+ fix: uniqueRecoveries(duplicates).join('\n Fix: '),
637
647
  };
638
648
  }
639
649
  async function createPackStateChecks(scopeRoots, dependencies) {
@@ -649,7 +659,18 @@ async function createPackStateChecks(scopeRoots, dependencies) {
649
659
  let findings;
650
660
  try {
651
661
  const assetsRoot = await dependencies.resolveAssetsRoot();
652
- const inventories = await Promise.all(PACK_NAMES.map((pack) => dependencies.inventoryPack({ pack, assetsRoot, ...roots })));
662
+ const userRoot = scopeRoots.get('user');
663
+ const userManagedRoleMaterialization = userRoot
664
+ ? await dependencies
665
+ .getConfigAwareAdapters(dependencies.getAdapters(), userRoot, await dependencies.resolveUserSyncConfig(join(userRoot, '.oat')))
666
+ .then(({ activeAdapters }) => activeAdapters.some(({ name }) => name === 'codex' || name === 'cursor'))
667
+ : false;
668
+ const inventories = attributeSharedOwnerDiagnostics(await Promise.all(PACK_NAMES.map((pack) => dependencies.inventoryPack({
669
+ pack,
670
+ assetsRoot,
671
+ ...roots,
672
+ ...(userRoot ? { userManagedRoleMaterialization } : {}),
673
+ }))));
653
674
  findings = collectPackStateFindings(inventories);
654
675
  }
655
676
  catch (error) {
@@ -1,5 +1,4 @@
1
1
  import { buildCommandContext } from '../../app/command-context.js';
2
- import { readOatConfig } from '../../config/oat-config.js';
3
2
  import { resolveAssetsRoot } from '../../fs/assets.js';
4
3
  import { resolveProjectRoot } from '../../fs/paths.js';
5
4
  import { Command } from 'commander';
@@ -11,7 +10,6 @@ interface PjmCommandDependencies {
11
10
  buildCommandContext: typeof buildCommandContext;
12
11
  resolveProjectRoot: typeof resolveProjectRoot;
13
12
  resolveAssetsRoot: typeof resolveAssetsRoot;
14
- readOatConfig: typeof readOatConfig;
15
13
  resolvePjmAdoption: typeof resolvePjmAdoption;
16
14
  initializeRepoReference: typeof initializeRepoReference;
17
15
  runPjmDoctorChecks: typeof runPjmDoctorChecks;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/pjm/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAA0B,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAiBnE,UAAU,sBAAsB;IAC9B,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;CACvD;AA8FD,wBAAgB,gBAAgB,CAC9B,SAAS,GAAE,OAAO,CAAC,sBAAsB,CAAM,GAC9C,OAAO,CA4JT"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/pjm/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,sBAAsB,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,uBAAuB,EAA0B,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAiBnE,UAAU,sBAAsB;IAC9B,mBAAmB,EAAE,OAAO,mBAAmB,CAAC;IAChD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,kBAAkB,EAAE,OAAO,kBAAkB,CAAC;IAC9C,cAAc,EAAE,OAAO,cAAc,CAAC;IACtC,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;CACvD;AA6FD,wBAAgB,gBAAgB,CAC9B,SAAS,GAAE,OAAO,CAAC,sBAAsB,CAAM,GAC9C,OAAO,CA8JT"}
@@ -1,7 +1,6 @@
1
1
  import { resolve } from 'node:path';
2
2
  import { buildCommandContext } from '../../app/command-context.js';
3
3
  import { readGlobalOptions } from '../shared/shared.utils.js';
4
- import { readOatConfig } from '../../config/oat-config.js';
5
4
  import { resolveAssetsRoot } from '../../fs/assets.js';
6
5
  import { resolveProjectRoot } from '../../fs/paths.js';
7
6
  import { formatDoctorResults } from '../../ui/output.js';
@@ -14,7 +13,6 @@ const DEFAULT_DEPENDENCIES = {
14
13
  buildCommandContext,
15
14
  resolveProjectRoot,
16
15
  resolveAssetsRoot,
17
- readOatConfig,
18
16
  resolvePjmAdoption,
19
17
  initializeRepoReference,
20
18
  runPjmDoctorChecks,
@@ -176,13 +174,16 @@ export function createPjmCommand(overrides = {}) {
176
174
  process.exitCode = 0;
177
175
  return;
178
176
  }
179
- const config = await dependencies.readOatConfig(projectRoot);
177
+ const adoption = await dependencies.resolvePjmAdoption({
178
+ projectRoot,
179
+ repoRoot,
180
+ });
180
181
  const result = await dependencies.migratePjmRepo({
181
182
  repoRoot,
182
183
  assetsRoot,
183
184
  templatesRoot: resolve(projectRoot, '.oat', 'templates'),
184
185
  home: context.home,
185
- projectManagementEnabled: config.tools?.['project-management'] === true,
186
+ adoption,
186
187
  apply: options.dryRun ? false : (options.apply ?? false),
187
188
  });
188
189
  if (context.json) {
@@ -1,4 +1,5 @@
1
1
  import { type DecisionMigrationMapping } from '../decision/migrate.js';
2
+ import type { PjmAdoption } from './adoption.js';
2
3
  export type PjmMigrationActionType = 'move' | 'create' | 'migrate-backlog' | 'migrate-decisions' | 'propose';
3
4
  export type PjmMigrationActionResult = 'planned' | 'applied' | 'skipped';
4
5
  export interface PjmMigrationAction {
@@ -29,7 +30,7 @@ export interface PjmMigrationOptions {
29
30
  assetsRoot: string;
30
31
  templatesRoot?: string;
31
32
  home?: string;
32
- projectManagementEnabled: boolean;
33
+ adoption: PjmAdoption;
33
34
  apply?: boolean;
34
35
  }
35
36
  export declare function migratePjmRepo(options: PjmMigrationOptions): Promise<PjmMigrationResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/pjm/migrate.ts"],"names":[],"mappings":"AAeA,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAMpC,MAAM,MAAM,sBAAsB,GAC9B,MAAM,GACN,QAAQ,GACR,iBAAiB,GACjB,mBAAmB,GACnB,SAAS,CAAC;AAEd,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,kBAAkB,GAAG,UAAU,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,eAAe,EAAE,0BAA0B,EAAE,CAAC;IAC9C,gBAAgB,EAAE,wBAAwB,EAAE,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB,EAAE,OAAO,CAAC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAoZD,wBAAsB,cAAc,CAClC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAmG7B;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../../src/commands/pjm/migrate.ts"],"names":[],"mappings":"AAeA,OAAO,EAEL,KAAK,wBAAwB,EAC9B,MAAM,4BAA4B,CAAC;AAIpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,MAAM,MAAM,sBAAsB,GAC9B,MAAM,GACN,QAAQ,GACR,iBAAiB,GACjB,mBAAmB,GACnB,SAAS,CAAC;AAEd,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,MAAM,EAAE,wBAAwB,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,kBAAkB,GAAG,UAAU,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,eAAe,EAAE,0BAA0B,EAAE,CAAC;IAC9C,gBAAgB,EAAE,wBAAwB,EAAE,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAsZD,wBAAsB,cAAc,CAClC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAoG7B;AAED,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
@@ -7,7 +7,7 @@ import { initializeDecisionRecords } from '../decision/init.js';
7
7
  import { migrateDecisionRecords, } from '../decision/migrate.js';
8
8
  import { stripTemplateFrontmatter } from '../shared/strip-template-frontmatter.js';
9
9
  import YAML from 'yaml';
10
- import { initializeRepoReference } from './init.js';
10
+ import { CANONICAL_REPO_REFERENCE_PATHS, initializeRepoReference, } from './init.js';
11
11
  const ACTIVE_MOVES = [
12
12
  { source: 'reference/current-state.md', target: 'pjm/current-state.md' },
13
13
  { source: 'reference/roadmap.md', target: 'pjm/roadmap.md' },
@@ -17,6 +17,10 @@ const JUDGMENT_TARGETS = [
17
17
  'reference/backlog.md',
18
18
  'reference/backlog-completed.md',
19
19
  ];
20
+ const LEGACY_MIGRATION_PATHS = [
21
+ ...ACTIVE_MOVES.map((move) => move.source),
22
+ 'reference/decision-record.md',
23
+ ];
20
24
  async function pathExists(path) {
21
25
  try {
22
26
  await access(path);
@@ -228,19 +232,17 @@ async function collectJudgmentProposals(repoRoot) {
228
232
  }
229
233
  return actions;
230
234
  }
231
- async function isAlreadyMigrated(repoRoot) {
232
- const hasPjm = await pathExists(join(repoRoot, 'pjm'));
233
- const hasDecisions = await pathExists(join(repoRoot, 'reference', 'decisions'));
234
- if (!hasPjm || !hasDecisions) {
235
- return false;
236
- }
237
- for (const legacyPath of [
238
- 'reference/current-state.md',
239
- 'reference/roadmap.md',
240
- 'reference/backlog',
241
- 'reference/decision-record.md',
242
- ]) {
235
+ async function hasRecognizedLegacySources(repoRoot) {
236
+ for (const legacyPath of LEGACY_MIGRATION_PATHS) {
243
237
  if (await pathExists(join(repoRoot, legacyPath))) {
238
+ return true;
239
+ }
240
+ }
241
+ return false;
242
+ }
243
+ async function isAlreadyMigrated(repoRoot) {
244
+ for (const relativePath of CANONICAL_REPO_REFERENCE_PATHS) {
245
+ if (!(await pathExists(join(repoRoot, relativePath)))) {
244
246
  return false;
245
247
  }
246
248
  }
@@ -305,12 +307,16 @@ function buildEmptyResult(options, status, reason) {
305
307
  };
306
308
  }
307
309
  export async function migratePjmRepo(options) {
308
- if (!options.projectManagementEnabled) {
309
- return buildEmptyResult(options, 'skipped', 'project-management pack is disabled');
310
- }
311
- if (await isAlreadyMigrated(options.repoRoot)) {
310
+ const hasLegacySources = await hasRecognizedLegacySources(options.repoRoot);
311
+ if (!hasLegacySources && (await isAlreadyMigrated(options.repoRoot))) {
312
312
  return buildEmptyResult(options, 'already-migrated');
313
313
  }
314
+ if (!hasLegacySources) {
315
+ const reason = options.adoption.state === 'partial-initialization'
316
+ ? 'PJM initialization is partial and no recognized legacy migration input was found; run oat pjm init to complete initialization'
317
+ : 'No recognized PJM migration input was found; run oat pjm init to initialize this repository';
318
+ return buildEmptyResult(options, 'skipped', reason);
319
+ }
314
320
  const apply = options.apply ?? false;
315
321
  const activeMoves = await planActiveMoves(options.repoRoot);
316
322
  const judgmentProposals = await collectJudgmentProposals(options.repoRoot);
@@ -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.50",
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.50"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.10.0",