@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.
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/tool-packs.md +35 -24
- package/assets/docs/reference/troubleshooting.md +22 -4
- package/assets/public-package-versions.json +4 -4
- package/dist/commands/doctor/index.d.ts +7 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +44 -23
- package/dist/commands/pjm/index.d.ts +0 -2
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +5 -4
- package/dist/commands/pjm/migrate.d.ts +2 -1
- package/dist/commands/pjm/migrate.d.ts.map +1 -1
- package/dist/commands/pjm/migrate.js +23 -17
- package/dist/commands/status/index.d.ts +3 -1
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +77 -10
- package/dist/commands/tools/shared/pack-inventory.d.ts +10 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-inventory.js +71 -21
- package/package.json +2 -2
|
@@ -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
|
|
193
|
-
|
|
194
|
-
Canonical **agents** are installed at either scope
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
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
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
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**
|
|
326
|
-
`partial-initialization` and `none`. They write nothing and return an error
|
|
327
|
-
naming the repository path and `oat pjm init` as the recovery.
|
|
328
|
-
|
|
329
|
-
|
|
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
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
|
@@ -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":"AAWA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAO9B,OAAO,
|
|
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)
|
|
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('
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
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
|
|
232
|
-
const
|
|
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
|
-
|
|
309
|
-
|
|
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
|
-
|
|
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":"AAEA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,yBAAyB,EAC/B,MAAM,wBAAwB,CAAC;AAMhC,OAAO,EACL,KAAK,cAAc,EAIpB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EAGlB,MAAM,iCAAiC,CAAC;AAKzC,OAAO,
|
|
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 {
|
|
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
|
-
|
|
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 {
|
|
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 {
|
|
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.
|
|
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,
|
|
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;
|
|
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
|
|
176
|
-
* provider
|
|
177
|
-
*
|
|
178
|
-
* managed role file set (`USER_SCOPE_MANAGED_AGENT_FILES`)
|
|
179
|
-
*
|
|
180
|
-
*
|
|
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
|
-
!
|
|
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
|
|
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.
|
|
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.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.2.50"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/node": "^22.10.0",
|