@open-agent-toolkit/cli 0.2.36 → 0.2.37
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/backlog-lifecycle.md +18 -0
- package/assets/docs/cli-utilities/bootstrap.md +6 -3
- package/assets/docs/cli-utilities/config-and-local-state.md +26 -12
- package/assets/docs/cli-utilities/configuration.md +36 -13
- package/assets/docs/cli-utilities/tool-packs.md +423 -51
- package/assets/docs/provider-sync/scope-and-surface.md +4 -1
- package/assets/docs/reference/cli-reference.md +5 -3
- package/assets/docs/reference/file-locations.md +28 -4
- package/assets/docs/reference/troubleshooting.md +132 -2
- package/assets/docs/workflows/projects/lifecycle.md +21 -2
- package/assets/public-package-versions.json +4 -4
- package/assets/scripts/generate-oat-state.sh +441 -0
- package/assets/scripts/generate-thin-index.sh +200 -0
- package/assets/skills/oat-agent-instructions-analyze/SKILL.md +10 -5
- package/assets/skills/oat-agent-instructions-apply/SKILL.md +30 -5
- package/assets/skills/oat-brainstorm/SKILL.md +34 -8
- package/assets/skills/oat-brainstorm/references/destinations.md +6 -1
- package/assets/skills/oat-docs-analyze/SKILL.md +9 -4
- package/assets/skills/oat-docs-apply/SKILL.md +6 -3
- package/assets/skills/oat-pjm-add-backlog-item/SKILL.md +14 -1
- package/assets/skills/oat-pjm-decision/SKILL.md +22 -10
- package/assets/skills/oat-pjm-review-backlog/SKILL.md +20 -3
- package/assets/skills/oat-pjm-update-repo-reference/SKILL.md +20 -10
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
- package/assets/skills/oat-project-document/SKILL.md +21 -3
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
- package/assets/skills/oat-project-summary/SKILL.md +23 -11
- package/assets/skills/oat-repo-knowledge-index/SKILL.md +6 -3
- package/dist/commands/backlog/index.d.ts +2 -0
- package/dist/commands/backlog/index.d.ts.map +1 -1
- package/dist/commands/backlog/index.js +67 -23
- package/dist/commands/backlog/new.d.ts +3 -0
- package/dist/commands/backlog/new.d.ts.map +1 -1
- package/dist/commands/backlog/new.js +8 -21
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +2 -1
- package/dist/commands/decision/index.d.ts +2 -0
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +19 -3
- package/dist/commands/decision/new.d.ts +4 -0
- package/dist/commands/decision/new.d.ts.map +1 -1
- package/dist/commands/decision/new.js +11 -30
- package/dist/commands/doctor/index.d.ts +4 -0
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +254 -9
- package/dist/commands/init/tools/brainstorm/index.d.ts.map +1 -1
- package/dist/commands/init/tools/brainstorm/index.js +20 -6
- package/dist/commands/init/tools/docs/index.d.ts.map +1 -1
- package/dist/commands/init/tools/docs/index.js +4 -1
- package/dist/commands/init/tools/ideas/index.d.ts.map +1 -1
- package/dist/commands/init/tools/ideas/index.js +4 -1
- package/dist/commands/init/tools/index.d.ts +11 -2
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +459 -351
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-management/agents-guidance.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/agents-guidance.js +3 -1
- package/dist/commands/init/tools/project-management/index.d.ts +1 -0
- package/dist/commands/init/tools/project-management/index.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/index.js +24 -55
- package/dist/commands/init/tools/project-management/install-project-management.d.ts +4 -0
- package/dist/commands/init/tools/project-management/install-project-management.d.ts.map +1 -1
- package/dist/commands/init/tools/project-management/install-project-management.js +4 -1
- package/dist/commands/init/tools/research/index.d.ts.map +1 -1
- package/dist/commands/init/tools/research/index.js +4 -1
- package/dist/commands/init/tools/shared/copy-helpers.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/copy-helpers.js +10 -0
- package/dist/commands/init/tools/shared/skill-manifest.d.ts +15 -15
- package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.js +17 -122
- package/dist/commands/init/tools/utility/index.d.ts.map +1 -1
- package/dist/commands/init/tools/utility/index.js +4 -1
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +4 -1
- package/dist/commands/init/tools/workflows/install-workflows.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/install-workflows.js +2 -4
- package/dist/commands/pjm/adoption.d.ts +12 -0
- package/dist/commands/pjm/adoption.d.ts.map +1 -0
- package/dist/commands/pjm/adoption.js +47 -0
- package/dist/commands/pjm/doctor.d.ts +3 -2
- package/dist/commands/pjm/doctor.d.ts.map +1 -1
- package/dist/commands/pjm/doctor.js +28 -13
- package/dist/commands/pjm/index.d.ts +2 -0
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +11 -3
- package/dist/commands/pjm/init.d.ts +3 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +37 -32
- package/dist/commands/pjm/migrate.d.ts +1 -0
- package/dist/commands/pjm/migrate.d.ts.map +1 -1
- package/dist/commands/pjm/migrate.js +1 -0
- package/dist/commands/pjm/template-source.d.ts +14 -0
- package/dist/commands/pjm/template-source.d.ts.map +1 -0
- package/dist/commands/pjm/template-source.js +56 -0
- package/dist/commands/remove/skills/remove-skills.d.ts.map +1 -1
- package/dist/commands/remove/skills/remove-skills.js +10 -19
- package/dist/commands/status/index.d.ts +5 -0
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +203 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +40 -7
- package/dist/commands/sync/sync.types.d.ts +4 -0
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/tools/has/has-pack.d.ts +11 -2
- package/dist/commands/tools/has/has-pack.d.ts.map +1 -1
- package/dist/commands/tools/has/has-pack.js +33 -20
- package/dist/commands/tools/index.d.ts.map +1 -1
- package/dist/commands/tools/index.js +3 -1
- package/dist/commands/tools/info/info-tool.d.ts +3 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +29 -4
- package/dist/commands/tools/list/list-tools.d.ts +3 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +31 -4
- package/dist/commands/tools/migrate/index.d.ts +26 -0
- package/dist/commands/tools/migrate/index.d.ts.map +1 -0
- package/dist/commands/tools/migrate/index.js +312 -0
- package/dist/commands/tools/migrate/migrate-pack.d.ts +81 -0
- package/dist/commands/tools/migrate/migrate-pack.d.ts.map +1 -0
- package/dist/commands/tools/migrate/migrate-pack.js +324 -0
- package/dist/commands/tools/outdated/outdated-tools.d.ts +11 -0
- package/dist/commands/tools/outdated/outdated-tools.d.ts.map +1 -1
- package/dist/commands/tools/outdated/outdated-tools.js +33 -5
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +73 -20
- package/dist/commands/tools/remove/remove-tools.d.ts +28 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +156 -26
- package/dist/commands/tools/shared/apply-pack-reconcile.d.ts +41 -0
- package/dist/commands/tools/shared/apply-pack-reconcile.d.ts.map +1 -0
- package/dist/commands/tools/shared/apply-pack-reconcile.js +126 -0
- package/dist/commands/tools/shared/auto-sync.d.ts +5 -2
- package/dist/commands/tools/shared/auto-sync.d.ts.map +1 -1
- package/dist/commands/tools/shared/auto-sync.js +1 -0
- package/dist/commands/tools/shared/content-digest.d.ts +3 -0
- package/dist/commands/tools/shared/content-digest.d.ts.map +1 -0
- package/dist/commands/tools/shared/content-digest.js +57 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +3 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -0
- package/dist/commands/tools/shared/format-pack-inventory.js +21 -0
- package/dist/commands/tools/shared/install-sync-context.d.ts.map +1 -1
- package/dist/commands/tools/shared/install-sync-context.js +2 -25
- package/dist/commands/tools/shared/pack-inventory.d.ts +46 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-inventory.js +207 -0
- package/dist/commands/tools/shared/pack-lifecycle.d.ts +34 -0
- package/dist/commands/tools/shared/pack-lifecycle.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle.js +67 -0
- package/dist/commands/tools/shared/pack-manifest.d.ts +11 -0
- package/dist/commands/tools/shared/pack-manifest.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-manifest.js +384 -0
- package/dist/commands/tools/shared/pack-paths.d.ts +21 -0
- package/dist/commands/tools/shared/pack-paths.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-paths.js +35 -0
- package/dist/commands/tools/shared/pack-reconcile.d.ts +64 -0
- package/dist/commands/tools/shared/pack-reconcile.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-reconcile.js +158 -0
- package/dist/commands/tools/shared/project-tools-config.d.ts.map +1 -1
- package/dist/commands/tools/shared/project-tools-config.js +12 -38
- package/dist/commands/tools/shared/scan-tools.js +2 -2
- package/dist/commands/tools/shared/scoped-pack-intent.d.ts +34 -0
- package/dist/commands/tools/shared/scoped-pack-intent.d.ts.map +1 -0
- package/dist/commands/tools/shared/scoped-pack-intent.js +116 -0
- package/dist/commands/tools/shared/types.d.ts +22 -0
- package/dist/commands/tools/shared/types.d.ts.map +1 -1
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +30 -5
- package/dist/commands/tools/update/update-tools.d.ts +9 -1
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +176 -64
- package/dist/config/oat-config.d.ts +6 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +49 -20
- package/dist/fs/paths.d.ts +12 -0
- package/dist/fs/paths.d.ts.map +1 -1
- package/dist/fs/paths.js +87 -1
- package/package.json +2 -2
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import {
|
|
2
|
+
import { PACK_MANIFEST } from '../../tools/shared/pack-manifest.js';
|
|
3
|
+
import { resolveSharedOwnerRetentions } from '../../tools/shared/pack-reconcile.js';
|
|
4
|
+
import { resolveManagedScopeRoots, validateManagedPath, } from '../../../fs/paths.js';
|
|
3
5
|
function matchesTarget(tool, target) {
|
|
4
6
|
switch (target.kind) {
|
|
5
7
|
case 'name':
|
|
@@ -22,43 +24,171 @@ async function removeTool(tool, scopeRoot, dryRun, deps) {
|
|
|
22
24
|
await deps.removeDirectory(skillPath);
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
function isDirectoryAsset(asset) {
|
|
28
|
+
return asset.kind === 'skill' || asset.kind === 'directory';
|
|
29
|
+
}
|
|
30
|
+
function selectedPacks(target) {
|
|
31
|
+
return target.kind === 'pack'
|
|
32
|
+
? [target.pack]
|
|
33
|
+
: PACK_MANIFEST.map(({ name }) => name);
|
|
34
|
+
}
|
|
35
|
+
function selectedManagedAssets(packs, scope) {
|
|
36
|
+
return PACK_MANIFEST.filter(({ name }) => packs.includes(name)).flatMap(({ name, assets }) => assets
|
|
37
|
+
.filter((asset) => asset.scopes.includes(scope) &&
|
|
38
|
+
asset.ownership[scope] === 'managed')
|
|
39
|
+
.map((asset) => ({ pack: name, asset })));
|
|
40
|
+
}
|
|
41
|
+
function managedRootName(asset) {
|
|
42
|
+
const name = asset.destination.split('/')[0];
|
|
43
|
+
if (name !== '.agents' && name !== '.oat') {
|
|
44
|
+
throw new Error(`Pack asset ${asset.id} has unsupported managed root: ${asset.destination}`);
|
|
28
45
|
}
|
|
29
|
-
|
|
30
|
-
|
|
46
|
+
return name;
|
|
47
|
+
}
|
|
48
|
+
async function planManagedPackRemoval(packs, scope, scopeRoot, dryRun, deps) {
|
|
49
|
+
const retentions = await resolveSharedOwnerRetentions({
|
|
50
|
+
packs,
|
|
51
|
+
scope,
|
|
52
|
+
scopeRoot,
|
|
53
|
+
hasOwnershipEvidence: deps.hasPackOwnershipEvidence,
|
|
54
|
+
});
|
|
55
|
+
const retainedPaths = new Set(retentions.map(({ path }) => path));
|
|
56
|
+
const managedAssets = selectedManagedAssets(packs, scope);
|
|
57
|
+
// Sampled before anything is deleted, because that is the only moment at
|
|
58
|
+
// which a pack's physical footprint is still observable. Retained
|
|
59
|
+
// shared-owner assets count: the pack declares them, so a removal that had to
|
|
60
|
+
// consider them is not a no-op for that pack.
|
|
61
|
+
const assetPaths = new Map();
|
|
62
|
+
for (const { asset } of managedAssets) {
|
|
63
|
+
assetPaths.set(asset.destination, join(scopeRoot, asset.destination));
|
|
31
64
|
}
|
|
32
|
-
|
|
33
|
-
|
|
65
|
+
const existence = new Map(await Promise.all([...assetPaths.values()].map(async (path) => [
|
|
66
|
+
path,
|
|
67
|
+
await deps.pathExists(path),
|
|
68
|
+
])));
|
|
69
|
+
const presentPacks = [
|
|
70
|
+
...new Set(managedAssets
|
|
71
|
+
.filter(({ asset }) => existence.get(assetPaths.get(asset.destination)))
|
|
72
|
+
.map(({ pack }) => pack)),
|
|
73
|
+
];
|
|
74
|
+
const targets = new Map();
|
|
75
|
+
for (const { asset } of managedAssets) {
|
|
76
|
+
const path = join(scopeRoot, asset.destination);
|
|
77
|
+
if (targets.has(path) || retainedPaths.has(path))
|
|
78
|
+
continue;
|
|
79
|
+
targets.set(path, { asset, isDirectory: isDirectoryAsset(asset) });
|
|
34
80
|
}
|
|
35
|
-
|
|
36
|
-
|
|
81
|
+
const retained = [...retainedPaths].map((path) => ({
|
|
82
|
+
path,
|
|
83
|
+
reason: 'retained shared owner data',
|
|
84
|
+
}));
|
|
85
|
+
if (dryRun) {
|
|
86
|
+
return {
|
|
87
|
+
targets: [...targets.entries()].map(([path, { isDirectory }]) => ({
|
|
88
|
+
path,
|
|
89
|
+
isDirectory,
|
|
90
|
+
})),
|
|
91
|
+
retained,
|
|
92
|
+
presentPacks,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const roots = await resolveManagedScopeRoots(scopeRoot);
|
|
96
|
+
return {
|
|
97
|
+
targets: await Promise.all([...targets.entries()].map(async ([path, { asset, isDirectory },]) => {
|
|
98
|
+
await validateManagedPath(path, roots[managedRootName(asset)]);
|
|
99
|
+
return { path, isDirectory };
|
|
100
|
+
})),
|
|
101
|
+
retained,
|
|
102
|
+
presentPacks,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async function executeManagedPackRemoval(targets, deps) {
|
|
106
|
+
for (const target of targets) {
|
|
107
|
+
if (target.isDirectory) {
|
|
108
|
+
await deps.removeDirectory(target.path);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
await deps.removeFile(target.path);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const remaining = (await Promise.all(targets.map(async ({ path }) => (await deps.pathExists(path)) ? path : null))).filter((path) => path !== null);
|
|
115
|
+
if (remaining.length > 0) {
|
|
116
|
+
throw new Error(`Managed pack removal incomplete; assets remain: ${remaining.join(', ')}`);
|
|
37
117
|
}
|
|
38
118
|
}
|
|
39
119
|
export async function removeTools(target, scopes, cwd, home, dryRun, deps) {
|
|
40
120
|
const removed = [];
|
|
121
|
+
const removedAssets = [];
|
|
122
|
+
const retainedOwnerData = [];
|
|
41
123
|
const assetsRoot = await deps.resolveAssetsRoot();
|
|
124
|
+
if (target.kind === 'name') {
|
|
125
|
+
for (const scope of scopes) {
|
|
126
|
+
const scopeRoot = await deps.resolveScopeRoot(scope, cwd, home);
|
|
127
|
+
const tools = await deps.scanTools({ scope, scopeRoot, assetsRoot });
|
|
128
|
+
const matched = tools.filter((tool) => matchesTarget(tool, target));
|
|
129
|
+
for (const tool of matched) {
|
|
130
|
+
await removeTool(tool, scopeRoot, dryRun, deps);
|
|
131
|
+
removed.push({ name: tool.name, type: tool.type, scope: tool.scope });
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
removed,
|
|
136
|
+
removedAssets,
|
|
137
|
+
retainedOwnerData,
|
|
138
|
+
packOutcomes: [],
|
|
139
|
+
notInstalled: removed.length === 0 ? [target.name] : [],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const packOutcomes = [];
|
|
143
|
+
const plans = [];
|
|
42
144
|
for (const scope of scopes) {
|
|
43
145
|
const scopeRoot = await deps.resolveScopeRoot(scope, cwd, home);
|
|
44
146
|
const tools = await deps.scanTools({ scope, scopeRoot, assetsRoot });
|
|
45
|
-
const matched = tools.filter((
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
147
|
+
const matched = tools.filter((tool) => matchesTarget(tool, target));
|
|
148
|
+
const managedPlan = await planManagedPackRemoval(selectedPacks(target), scope, scopeRoot, dryRun, deps);
|
|
149
|
+
const seedData = PACK_MANIFEST.filter(({ name }) => selectedPacks(target).includes(name)).flatMap(({ assets }) => assets
|
|
150
|
+
.filter((asset) => asset.scopes.includes(scope) &&
|
|
151
|
+
asset.ownership[scope] === 'seed-if-missing')
|
|
152
|
+
.map(({ destination }) => ({
|
|
153
|
+
path: join(scopeRoot, destination),
|
|
154
|
+
reason: 'repository or scope owner data',
|
|
155
|
+
})));
|
|
156
|
+
plans.push({
|
|
157
|
+
scope,
|
|
158
|
+
scopeRoot,
|
|
159
|
+
matched,
|
|
160
|
+
managedTargets: managedPlan.targets,
|
|
161
|
+
retainedOwnerData: [...managedPlan.retained, ...seedData],
|
|
162
|
+
presentPacks: managedPlan.presentPacks,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
for (const plan of plans) {
|
|
166
|
+
if (target.kind === 'all') {
|
|
167
|
+
for (const tool of plan.matched.filter(({ pack }) => pack === 'custom')) {
|
|
168
|
+
await removeTool(tool, plan.scopeRoot, dryRun, deps);
|
|
56
169
|
}
|
|
57
170
|
}
|
|
171
|
+
if (!dryRun) {
|
|
172
|
+
await executeManagedPackRemoval(plan.managedTargets, deps);
|
|
173
|
+
}
|
|
174
|
+
removed.push(...plan.matched.map(({ name, type, scope }) => ({ name, type, scope })));
|
|
175
|
+
removedAssets.push(...plan.managedTargets.map(({ path }) => ({ path, scope: plan.scope })));
|
|
176
|
+
retainedOwnerData.push(...plan.retainedOwnerData.map((entry) => ({
|
|
177
|
+
...entry,
|
|
178
|
+
scope: plan.scope,
|
|
179
|
+
})));
|
|
180
|
+
packOutcomes.push(...selectedPacks(target).map((pack) => ({
|
|
181
|
+
pack,
|
|
182
|
+
scope: plan.scope,
|
|
183
|
+
removed: plan.matched.some((tool) => tool.pack === pack) ||
|
|
184
|
+
plan.presentPacks.includes(pack),
|
|
185
|
+
})));
|
|
58
186
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
187
|
+
return {
|
|
188
|
+
removed,
|
|
189
|
+
removedAssets,
|
|
190
|
+
retainedOwnerData,
|
|
191
|
+
packOutcomes,
|
|
192
|
+
notInstalled: [],
|
|
193
|
+
};
|
|
64
194
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ManagedRootName, type ResolvedManagedRoot } from '../../../fs/paths.js';
|
|
2
|
+
import type { ScopedPackInventory } from './pack-inventory.js';
|
|
3
|
+
import type { PackReconcileOperation, PackReconcilePlan } from './pack-reconcile.js';
|
|
4
|
+
export interface ApplyPackReconcileDependencies {
|
|
5
|
+
resolveManagedRoots?: (scopeRoot: string) => Promise<Record<ManagedRootName, ResolvedManagedRoot>>;
|
|
6
|
+
validatePath?: (candidatePath: string, managedRoot: ResolvedManagedRoot) => Promise<{
|
|
7
|
+
realManagedRoot: string;
|
|
8
|
+
realPath: string;
|
|
9
|
+
}>;
|
|
10
|
+
copyDirectory?: (source: string, destination: string, force: boolean) => Promise<unknown>;
|
|
11
|
+
copyFile?: (source: string, destination: string, force: boolean) => Promise<unknown>;
|
|
12
|
+
removePath?: (path: string, directory: boolean) => Promise<void>;
|
|
13
|
+
chmodPath?: (path: string, mode: number) => Promise<void>;
|
|
14
|
+
writeGenerated: (operation: Extract<PackReconcileOperation, {
|
|
15
|
+
kind: 'write-generated';
|
|
16
|
+
}>) => Promise<void>;
|
|
17
|
+
writeIntent: (operation: Extract<PackReconcileOperation, {
|
|
18
|
+
kind: 'write-intent';
|
|
19
|
+
}>) => Promise<void>;
|
|
20
|
+
inventory: () => Promise<ScopedPackInventory>;
|
|
21
|
+
sync?: (input: {
|
|
22
|
+
scope: PackReconcilePlan['scope'];
|
|
23
|
+
action: PackReconcilePlan['action'];
|
|
24
|
+
changedCanonicalPaths: readonly string[];
|
|
25
|
+
}) => Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
export interface ApplyPackReconcileResult {
|
|
28
|
+
applied: readonly PackReconcileOperation[];
|
|
29
|
+
inventory: ScopedPackInventory;
|
|
30
|
+
synced: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface PackReconcilePreflightDependencies {
|
|
33
|
+
resolveManagedRoots?: ApplyPackReconcileDependencies['resolveManagedRoots'];
|
|
34
|
+
validatePath?: ApplyPackReconcileDependencies['validatePath'];
|
|
35
|
+
}
|
|
36
|
+
export declare function preflightPackReconcilePlans(entries: readonly {
|
|
37
|
+
plan: PackReconcilePlan;
|
|
38
|
+
scopeRoot: string;
|
|
39
|
+
}[], dependencies?: PackReconcilePreflightDependencies): Promise<void>;
|
|
40
|
+
export declare function applyPackReconcilePlan(plan: PackReconcilePlan, scopeRoot: string, dependencies: ApplyPackReconcileDependencies): Promise<ApplyPackReconcileResult>;
|
|
41
|
+
//# sourceMappingURL=apply-pack-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-pack-reconcile.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/apply-pack-reconcile.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAGzB,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EACV,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,WAAW,8BAA8B;IAC7C,mBAAmB,CAAC,EAAE,CACpB,SAAS,EAAE,MAAM,KACd,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;IAC3D,YAAY,CAAC,EAAE,CACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,mBAAmB,KAC7B,OAAO,CAAC;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,aAAa,CAAC,EAAE,CACd,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,QAAQ,CAAC,EAAE,CACT,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,OAAO,KACX,OAAO,CAAC,OAAO,CAAC,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,cAAc,EAAE,CACd,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAA;KAAE,CAAC,KACpE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,EAAE,CACX,SAAS,EAAE,OAAO,CAAC,sBAAsB,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,KACjE,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE;QACb,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACpC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;KAC1C,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC3C,SAAS,EAAE,mBAAmB,CAAC;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kCAAkC;IACjD,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,qBAAqB,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,8BAA8B,CAAC,cAAc,CAAC,CAAC;CAC/D;AAwBD,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,EAClE,YAAY,GAAE,kCAAuC,GACpD,OAAO,CAAC,IAAI,CAAC,CAsBf;AA2BD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,iBAAiB,EACvB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,8BAA8B,GAC3C,OAAO,CAAC,wBAAwB,CAAC,CAoFnC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { chmod, rm } from 'node:fs/promises';
|
|
2
|
+
import { copyDirWithStatus, copyFileWithStatus, } from '../../init/tools/shared/copy-helpers.js';
|
|
3
|
+
import { resolveManagedScopeRoots, validateManagedPath, } from '../../../fs/paths.js';
|
|
4
|
+
function operationPath(operation) {
|
|
5
|
+
switch (operation.kind) {
|
|
6
|
+
case 'copy-dir':
|
|
7
|
+
case 'copy-file':
|
|
8
|
+
case 'write-generated':
|
|
9
|
+
return operation.destination;
|
|
10
|
+
case 'chmod':
|
|
11
|
+
case 'remove-dir':
|
|
12
|
+
case 'remove-file':
|
|
13
|
+
return operation.path;
|
|
14
|
+
case 'write-intent':
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function managedRootForPath(path) {
|
|
19
|
+
const normalized = path.replaceAll('\\', '/');
|
|
20
|
+
if (normalized.includes('/.agents/'))
|
|
21
|
+
return '.agents';
|
|
22
|
+
if (normalized.includes('/.oat/'))
|
|
23
|
+
return '.oat';
|
|
24
|
+
throw new Error(`Pack reconcile path is outside a managed root: ${path}`);
|
|
25
|
+
}
|
|
26
|
+
export async function preflightPackReconcilePlans(entries, dependencies = {}) {
|
|
27
|
+
const resolveRoots = dependencies.resolveManagedRoots ?? resolveManagedScopeRoots;
|
|
28
|
+
const validate = dependencies.validatePath ?? validateManagedPath;
|
|
29
|
+
const rootsByScope = new Map();
|
|
30
|
+
for (const { plan, scopeRoot } of entries) {
|
|
31
|
+
let roots = rootsByScope.get(scopeRoot);
|
|
32
|
+
if (!roots) {
|
|
33
|
+
roots = await resolveRoots(scopeRoot);
|
|
34
|
+
rootsByScope.set(scopeRoot, roots);
|
|
35
|
+
}
|
|
36
|
+
const seen = new Set();
|
|
37
|
+
for (const operation of plan.operations) {
|
|
38
|
+
const path = operationPath(operation);
|
|
39
|
+
if (!path || seen.has(path))
|
|
40
|
+
continue;
|
|
41
|
+
await validate(path, roots[managedRootForPath(path)]);
|
|
42
|
+
seen.add(path);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function assertExpectedInventory(plan, inventory) {
|
|
47
|
+
if (inventory.pack !== plan.pack ||
|
|
48
|
+
inventory.scope !== plan.scope ||
|
|
49
|
+
inventory.completeness !== plan.expectedCompleteness) {
|
|
50
|
+
throw new Error(`Pack ${plan.pack} ${plan.scope} verification expected ${plan.expectedCompleteness} but found ${inventory.completeness}`);
|
|
51
|
+
}
|
|
52
|
+
if (plan.action === 'remove')
|
|
53
|
+
return;
|
|
54
|
+
const drifted = inventory.assets.filter(({ definition, status }) => definition.ownership[plan.scope] === 'managed' && status !== 'current');
|
|
55
|
+
if (drifted.length > 0) {
|
|
56
|
+
throw new Error(`Pack ${plan.pack} ${plan.scope} verification found drifted managed assets: ${drifted.map(({ definition, status }) => `${definition.id} (${status})`).join(', ')}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export async function applyPackReconcilePlan(plan, scopeRoot, dependencies) {
|
|
60
|
+
const resolveRoots = dependencies.resolveManagedRoots ?? resolveManagedScopeRoots;
|
|
61
|
+
const validate = dependencies.validatePath ?? validateManagedPath;
|
|
62
|
+
const roots = await resolveRoots(scopeRoot);
|
|
63
|
+
const validatedPaths = new Map();
|
|
64
|
+
// Validate every planned filesystem target before the first mutation.
|
|
65
|
+
for (const operation of plan.operations) {
|
|
66
|
+
const path = operationPath(operation);
|
|
67
|
+
if (!path || validatedPaths.has(path))
|
|
68
|
+
continue;
|
|
69
|
+
const { realPath } = await validate(path, roots[managedRootForPath(path)]);
|
|
70
|
+
validatedPaths.set(path, realPath);
|
|
71
|
+
}
|
|
72
|
+
const applied = [];
|
|
73
|
+
const intents = [];
|
|
74
|
+
for (const operation of plan.operations) {
|
|
75
|
+
if (operation.kind === 'write-intent') {
|
|
76
|
+
intents.push(operation);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const path = operationPath(operation);
|
|
80
|
+
if (!path)
|
|
81
|
+
continue;
|
|
82
|
+
const realPath = validatedPaths.get(path);
|
|
83
|
+
if (!realPath)
|
|
84
|
+
throw new Error(`Missing validated path for ${path}`);
|
|
85
|
+
switch (operation.kind) {
|
|
86
|
+
case 'copy-dir':
|
|
87
|
+
await (dependencies.copyDirectory ?? copyDirWithStatus)(operation.source, realPath, operation.force);
|
|
88
|
+
break;
|
|
89
|
+
case 'copy-file':
|
|
90
|
+
await (dependencies.copyFile ?? copyFileWithStatus)(operation.source, realPath, operation.force);
|
|
91
|
+
break;
|
|
92
|
+
case 'write-generated':
|
|
93
|
+
await dependencies.writeGenerated({
|
|
94
|
+
...operation,
|
|
95
|
+
destination: realPath,
|
|
96
|
+
});
|
|
97
|
+
break;
|
|
98
|
+
case 'chmod':
|
|
99
|
+
await (dependencies.chmodPath ?? chmod)(realPath, operation.mode);
|
|
100
|
+
break;
|
|
101
|
+
case 'remove-dir':
|
|
102
|
+
case 'remove-file':
|
|
103
|
+
await (dependencies.removePath ??
|
|
104
|
+
(async (target, directory) => rm(target, { recursive: directory, force: true })))(realPath, operation.kind === 'remove-dir');
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
applied.push(operation);
|
|
108
|
+
}
|
|
109
|
+
const verifiedInventory = await dependencies.inventory();
|
|
110
|
+
assertExpectedInventory(plan, verifiedInventory);
|
|
111
|
+
for (const intent of intents) {
|
|
112
|
+
await dependencies.writeIntent(intent);
|
|
113
|
+
applied.push(intent);
|
|
114
|
+
}
|
|
115
|
+
const inventory = intents.length > 0 ? await dependencies.inventory() : verifiedInventory;
|
|
116
|
+
assertExpectedInventory(plan, inventory);
|
|
117
|
+
const shouldSync = plan.changedCanonicalPaths.length > 0 && dependencies.sync;
|
|
118
|
+
if (shouldSync) {
|
|
119
|
+
await dependencies.sync({
|
|
120
|
+
scope: plan.scope,
|
|
121
|
+
action: plan.action,
|
|
122
|
+
changedCanonicalPaths: plan.changedCanonicalPaths,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return { applied, inventory, synced: Boolean(shouldSync) };
|
|
126
|
+
}
|
|
@@ -6,6 +6,7 @@ export interface AutoSyncDependencies {
|
|
|
6
6
|
cwd: string;
|
|
7
7
|
home: string;
|
|
8
8
|
installedCanonicalPaths?: string[];
|
|
9
|
+
removedCanonicalPaths?: string[];
|
|
9
10
|
}) => Promise<void>;
|
|
10
11
|
}
|
|
11
12
|
export interface AutoSyncResult {
|
|
@@ -13,7 +14,9 @@ export interface AutoSyncResult {
|
|
|
13
14
|
scopes: ConcreteScope[];
|
|
14
15
|
error: string | null;
|
|
15
16
|
}
|
|
16
|
-
export
|
|
17
|
+
export interface AutoSyncOptions {
|
|
17
18
|
installedCanonicalPaths?: string[];
|
|
18
|
-
|
|
19
|
+
removedCanonicalPaths?: string[];
|
|
20
|
+
}
|
|
21
|
+
export declare function autoSync(scopes: ConcreteScope[], cwd: string, home: string, logger: CliLogger, dependencies: AutoSyncDependencies, options?: AutoSyncOptions): Promise<AutoSyncResult>;
|
|
19
22
|
//# sourceMappingURL=auto-sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/auto-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,OAAO,EAAE;QACjB,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"auto-sync.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/auto-sync.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,CAAC,OAAO,EAAE;QACjB,KAAK,EAAE,aAAa,CAAC;QACrB,GAAG,EAAE,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;QACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;KAClC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,aAAa,EAAE,EACvB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,oBAAoB,EAClC,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,cAAc,CAAC,CAsBzB"}
|
|
@@ -9,6 +9,7 @@ export async function autoSync(scopes, cwd, home, logger, dependencies, options)
|
|
|
9
9
|
cwd,
|
|
10
10
|
home,
|
|
11
11
|
installedCanonicalPaths: options?.installedCanonicalPaths,
|
|
12
|
+
removedCanonicalPaths: options?.removedCanonicalPaths,
|
|
12
13
|
});
|
|
13
14
|
}
|
|
14
15
|
logger.info('Auto-sync completed.');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-digest.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/content-digest.ts"],"names":[],"mappings":"AAaA,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4CnE"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { lstat, readFile, readdir, readlink } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
function executableMode(mode) {
|
|
5
|
+
return (mode & 0o111).toString(8);
|
|
6
|
+
}
|
|
7
|
+
function updateField(hash, value) {
|
|
8
|
+
hash.update(`${Buffer.byteLength(value)}:`);
|
|
9
|
+
hash.update(value);
|
|
10
|
+
}
|
|
11
|
+
export async function digestFile(path, normalizedMode) {
|
|
12
|
+
const [content, metadata] = await Promise.all([readFile(path), lstat(path)]);
|
|
13
|
+
const hash = createHash('sha256');
|
|
14
|
+
updateField(hash, 'file');
|
|
15
|
+
updateField(hash, executableMode(normalizedMode ?? metadata.mode));
|
|
16
|
+
hash.update(`${content.length}:`);
|
|
17
|
+
hash.update(content);
|
|
18
|
+
return hash.digest('hex');
|
|
19
|
+
}
|
|
20
|
+
export async function digestDirectory(root) {
|
|
21
|
+
const hash = createHash('sha256');
|
|
22
|
+
async function visit(directory, relativeRoot) {
|
|
23
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
24
|
+
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
const path = join(directory, entry.name);
|
|
27
|
+
const relativePath = relativeRoot
|
|
28
|
+
? `${relativeRoot}/${entry.name}`
|
|
29
|
+
: entry.name;
|
|
30
|
+
const metadata = await lstat(path);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
updateField(hash, 'directory');
|
|
33
|
+
updateField(hash, relativePath);
|
|
34
|
+
await visit(path, relativePath);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (entry.isFile()) {
|
|
38
|
+
const content = await readFile(path);
|
|
39
|
+
updateField(hash, 'file');
|
|
40
|
+
updateField(hash, relativePath);
|
|
41
|
+
updateField(hash, executableMode(metadata.mode));
|
|
42
|
+
hash.update(`${content.length}:`);
|
|
43
|
+
hash.update(content);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (entry.isSymbolicLink()) {
|
|
47
|
+
updateField(hash, 'symlink');
|
|
48
|
+
updateField(hash, relativePath);
|
|
49
|
+
updateField(hash, await readlink(path));
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`Unsupported filesystem entry in pack asset: ${path}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
await visit(root, '');
|
|
56
|
+
return hash.digest('hex');
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/format-pack-inventory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUtD,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,aAAa,EACxB,MAAM,SAAO,GACZ,MAAM,EAAE,CAuBV"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function versionEvidence(installed, bundled) {
|
|
2
|
+
if (installed === null && bundled === null)
|
|
3
|
+
return '';
|
|
4
|
+
return `; versions=${installed ?? '-'} -> ${bundled ?? '-'}`;
|
|
5
|
+
}
|
|
6
|
+
export function formatPackInventoryDetails(inventory, indent = ' ') {
|
|
7
|
+
const lines = [];
|
|
8
|
+
for (const scoped of inventory.scopes) {
|
|
9
|
+
lines.push(`${indent}${scoped.scope}: ${scoped.completeness}; intent=${scoped.intent.source}`);
|
|
10
|
+
for (const asset of scoped.assets) {
|
|
11
|
+
lines.push(`${indent} ${asset.definition.id} [${asset.definition.kind}] ${asset.status}; path=${asset.path}${versionEvidence(asset.installedVersion, asset.bundledVersion)}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
for (const diagnostic of inventory.diagnostics) {
|
|
15
|
+
lines.push(`${indent}diagnostic ${diagnostic.code}: ${diagnostic.message}; paths=${diagnostic.paths.join(', ') || '-'}`);
|
|
16
|
+
if (diagnostic.versions) {
|
|
17
|
+
lines.push(`${indent} versions=${diagnostic.versions.map((version) => version ?? '-').join(', ')}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return lines;
|
|
21
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-sync-context.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/install-sync-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"install-sync-context.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/install-sync-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUzC,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,EAAE,CAE9D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,EAAE,CAI3E;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,IAAI,CAMN;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAGrE"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getCanonicalProviderPaths } from './pack-manifest.js';
|
|
2
2
|
const INSTALL_SYNC_CANONICAL_PATHS = Symbol('oat.installSyncCanonicalPaths');
|
|
3
3
|
function uniqueCanonicalPaths(paths) {
|
|
4
4
|
return [...new Set(paths)];
|
|
@@ -10,30 +10,7 @@ export function canonicalAgentPaths(agentNames) {
|
|
|
10
10
|
return uniqueCanonicalPaths(agentNames.map((agentName) => `.agents/agents/${agentName}`));
|
|
11
11
|
}
|
|
12
12
|
export function canonicalPathsForPack(pack) {
|
|
13
|
-
|
|
14
|
-
case 'core':
|
|
15
|
-
return canonicalSkillPaths(CORE_SKILLS);
|
|
16
|
-
case 'ideas':
|
|
17
|
-
return canonicalSkillPaths(IDEA_SKILLS);
|
|
18
|
-
case 'docs':
|
|
19
|
-
return canonicalSkillPaths(DOCS_SKILLS);
|
|
20
|
-
case 'workflows':
|
|
21
|
-
return uniqueCanonicalPaths([
|
|
22
|
-
...canonicalSkillPaths(WORKFLOW_SKILLS),
|
|
23
|
-
...canonicalAgentPaths(WORKFLOW_AGENTS),
|
|
24
|
-
]);
|
|
25
|
-
case 'utility':
|
|
26
|
-
return canonicalSkillPaths(UTILITY_SKILLS);
|
|
27
|
-
case 'project-management':
|
|
28
|
-
return canonicalSkillPaths(PROJECT_MANAGEMENT_SKILLS);
|
|
29
|
-
case 'research':
|
|
30
|
-
return uniqueCanonicalPaths([
|
|
31
|
-
...canonicalSkillPaths(RESEARCH_SKILLS),
|
|
32
|
-
...canonicalAgentPaths(RESEARCH_AGENTS),
|
|
33
|
-
]);
|
|
34
|
-
case 'brainstorm':
|
|
35
|
-
return canonicalSkillPaths(BRAINSTORM_SKILLS);
|
|
36
|
-
}
|
|
13
|
+
return getCanonicalProviderPaths(pack);
|
|
37
14
|
}
|
|
38
15
|
export function canonicalPathsForPacks(packs) {
|
|
39
16
|
return uniqueCanonicalPaths(packs.flatMap((pack) => canonicalPathsForPack(pack)));
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ConcreteScope } from '../../../shared/types.js';
|
|
2
|
+
import { type ScopedPackIntent } from './scoped-pack-intent.js';
|
|
3
|
+
import type { PackAssetDefinition, PackAssetStatus, PackCompleteness, PackName } from './types.js';
|
|
4
|
+
export interface PackAssetInventory {
|
|
5
|
+
definition: PackAssetDefinition;
|
|
6
|
+
path: string;
|
|
7
|
+
status: PackAssetStatus;
|
|
8
|
+
installedVersion: string | null;
|
|
9
|
+
bundledVersion: string | null;
|
|
10
|
+
}
|
|
11
|
+
export interface PackDiagnostic {
|
|
12
|
+
code: 'legacy-false-conflict' | 'duplicate-scope' | 'shared-owner-observation' | 'user-agent-unmaterialized';
|
|
13
|
+
message: string;
|
|
14
|
+
paths: string[];
|
|
15
|
+
versions?: Array<string | null>;
|
|
16
|
+
}
|
|
17
|
+
export interface ScopedPackInventory {
|
|
18
|
+
pack: PackName;
|
|
19
|
+
scope: ConcreteScope;
|
|
20
|
+
intent: ScopedPackIntent;
|
|
21
|
+
completeness: PackCompleteness;
|
|
22
|
+
assets: PackAssetInventory[];
|
|
23
|
+
diagnostics: PackDiagnostic[];
|
|
24
|
+
}
|
|
25
|
+
export interface PackInventory {
|
|
26
|
+
pack: PackName;
|
|
27
|
+
placement: 'project' | 'user' | 'both' | 'unavailable';
|
|
28
|
+
scopes: ScopedPackInventory[];
|
|
29
|
+
diagnostics: PackDiagnostic[];
|
|
30
|
+
}
|
|
31
|
+
export interface InventoryScopedPackInput {
|
|
32
|
+
pack: PackName;
|
|
33
|
+
scope: ConcreteScope;
|
|
34
|
+
scopeRoot: string;
|
|
35
|
+
assetsRoot: string;
|
|
36
|
+
}
|
|
37
|
+
export interface InventoryPackInput {
|
|
38
|
+
pack: PackName;
|
|
39
|
+
assetsRoot: string;
|
|
40
|
+
projectRoot?: string;
|
|
41
|
+
userRoot?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function inventoryScopedPack(input: InventoryScopedPackInput): Promise<ScopedPackInventory>;
|
|
44
|
+
export declare function hasScopedPackPlacementEvidence(inventory: ScopedPackInventory): boolean;
|
|
45
|
+
export declare function inventoryPack(input: InventoryPackInput): Promise<PackInventory>;
|
|
46
|
+
//# sourceMappingURL=pack-inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack-inventory.d.ts","sourceRoot":"","sources":["../../../../src/commands/tools/shared/pack-inventory.ts"],"names":[],"mappings":"AAWA,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;AA0KD,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"}
|