@ai-outfitter/outfitter 1.13.0 → 1.15.0
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/README.md +4 -1
- package/code/pi-extension/src/outfitter-extension.js +2 -2
- package/dist/cli/OutfitterCli.js +2 -0
- package/dist/cli/OutfitterCli.js.map +1 -1
- package/dist/cli/commands/DumpCommand.js +17 -4
- package/dist/cli/commands/DumpCommand.js.map +1 -1
- package/dist/cli/commands/LinkCommand.d.ts +27 -0
- package/dist/cli/commands/LinkCommand.js +137 -0
- package/dist/cli/commands/LinkCommand.js.map +1 -0
- package/dist/cli/commands/ListCommand.js +8 -2
- package/dist/cli/commands/ListCommand.js.map +1 -1
- package/dist/cli/commands/RunAgentCommand.js +6 -1
- package/dist/cli/commands/RunAgentCommand.js.map +1 -1
- package/dist/cli/commands/ValidateCommand.js +5 -2
- package/dist/cli/commands/ValidateCommand.js.map +1 -1
- package/dist/cli.js +14 -6
- package/dist/cli.js.map +1 -1
- package/dist/composer/Chain.d.ts +10 -0
- package/dist/composer/Chain.js +47 -0
- package/dist/composer/Chain.js.map +1 -0
- package/dist/composer/Composer.d.ts +6 -0
- package/dist/composer/Composer.js +42 -141
- package/dist/composer/Composer.js.map +1 -1
- package/dist/composer/Composition.d.ts +16 -0
- package/dist/composer/Defaults.d.ts +33 -0
- package/dist/composer/Defaults.js +103 -0
- package/dist/composer/Defaults.js.map +1 -0
- package/dist/composer/Mcp.d.ts +3 -0
- package/dist/composer/Mcp.js +68 -0
- package/dist/composer/Mcp.js.map +1 -0
- package/dist/dump/Dump.d.ts +2 -1
- package/dist/dump/Dump.js +67 -4
- package/dist/dump/Dump.js.map +1 -1
- package/dist/dump/WorkflowDump.d.ts +9 -1
- package/dist/dump/WorkflowDump.js +4 -3
- package/dist/dump/WorkflowDump.js.map +1 -1
- package/dist/links/HarnessHome.d.ts +15 -0
- package/dist/links/HarnessHome.js +23 -0
- package/dist/links/HarnessHome.js.map +1 -0
- package/dist/links/HarnessLinkApply.d.ts +26 -0
- package/dist/links/HarnessLinkApply.js +356 -0
- package/dist/links/HarnessLinkApply.js.map +1 -0
- package/dist/links/HarnessLinkPlan.d.ts +70 -0
- package/dist/links/HarnessLinkPlan.js +224 -0
- package/dist/links/HarnessLinkPlan.js.map +1 -0
- package/dist/links/HarnessMcp.d.ts +9 -0
- package/dist/links/HarnessMcp.js +67 -0
- package/dist/links/HarnessMcp.js.map +1 -0
- package/dist/projection/CodexSettings.d.ts +3 -0
- package/dist/projection/CodexSettings.js +17 -0
- package/dist/projection/CodexSettings.js.map +1 -0
- package/dist/projection/Materialize.d.ts +20 -2
- package/dist/projection/Materialize.js +66 -33
- package/dist/projection/Materialize.js.map +1 -1
- package/dist/projection/ProjectHarness.js +58 -14
- package/dist/projection/ProjectHarness.js.map +1 -1
- package/dist/projection/Projection.d.ts +3 -1
- package/dist/resolver/ResolverValidation.d.ts +7 -0
- package/dist/resolver/ResolverValidation.js +46 -14
- package/dist/resolver/ResolverValidation.js.map +1 -1
- package/dist/schemas/settings.schema.json +54 -1
- package/dist/settings/Settings.d.ts +24 -0
- package/dist/settings/Settings.js +15 -0
- package/dist/settings/Settings.js.map +1 -1
- package/dist/settings/SettingsLoader.js +18 -0
- package/dist/settings/SettingsLoader.js.map +1 -1
- package/dist/settings/SettingsMerger.js +43 -0
- package/dist/settings/SettingsMerger.js.map +1 -1
- package/dist/setup/DefaultCatalog.d.ts +4 -2
- package/dist/setup/DefaultCatalog.js +5 -3
- package/dist/setup/DefaultCatalog.js.map +1 -1
- package/dist/setup/Setup.js +34 -12
- package/dist/setup/Setup.js.map +1 -1
- package/dist/version/NodeVersionGuard.d.ts +13 -0
- package/dist/version/NodeVersionGuard.js +50 -0
- package/dist/version/NodeVersionGuard.js.map +1 -0
- package/docs/architecture/state_writeback_strategy.md +1 -1
- package/docs/documentation/README.md +1 -1
- package/docs/documentation/cli.md +35 -1
- package/docs/documentation/conventions.md +1 -1
- package/docs/documentation/getting-started.md +4 -2
- package/docs/documentation/linking-harnesses.md +88 -0
- package/docs/documentation/local-development.md +5 -7
- package/docs/documentation/migration.md +1 -1
- package/docs/documentation/settings.md +75 -4
- package/docs/documentation/state.md +1 -1
- package/docs/documentation/support-matrix.md +3 -1
- package/docs/documentation/switching-to-outfitter.md +1 -1
- package/docs/documentation/usecases/shared-conventions.md +1 -1
- package/package.json +2 -1
- package/src/schemas/settings.schema.json +54 -1
- package/docs/documentation/porting-claude.md +0 -58
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
// Reconciles a harness link plan against the harness home without touching anything unmanaged.
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, readdirSync, rmSync, rmdirSync, statSync, symlinkSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
|
|
6
|
+
import { mcpAddArgs, mcpGetArgs, mcpRemoveArgs } from './HarnessMcp.js';
|
|
7
|
+
/* v8 ignore start -- spawning the real harness CLI is exercised by smoke tests; unit tests inject a runner. */
|
|
8
|
+
export const spawnHarnessCommand = (harness, args) => {
|
|
9
|
+
const result = spawnSync(harness, [...args], { encoding: 'utf8', timeout: 30_000 });
|
|
10
|
+
const missing = result.error !== undefined && 'code' in result.error && result.error.code === 'ENOENT';
|
|
11
|
+
return { found: !missing, ok: result.status === 0, output: `${result.stdout ?? ''}${result.stderr ?? ''}`.trim() };
|
|
12
|
+
};
|
|
13
|
+
const manifestPath = (home) => join(home, '.outfitter', 'links.json');
|
|
14
|
+
const readManifest = (home, harness) => {
|
|
15
|
+
const path = manifestPath(home);
|
|
16
|
+
if (!existsSync(path))
|
|
17
|
+
return { version: 1, harness, entries: [] };
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
20
|
+
return { version: 1, harness, entries: Array.isArray(parsed.entries) ? parsed.entries : [] };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { version: 1, harness, entries: [] };
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
const writeManifest = (home, manifest) => {
|
|
27
|
+
const path = manifestPath(home);
|
|
28
|
+
if (manifest.entries.length === 0) {
|
|
29
|
+
rmSync(path, { force: true });
|
|
30
|
+
try {
|
|
31
|
+
rmdirSync(dirname(path));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// The directory is absent or holds other files; either way it is not ours to remove.
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
39
|
+
writeFileSync(path, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
40
|
+
};
|
|
41
|
+
const isSymlink = (path) => {
|
|
42
|
+
try {
|
|
43
|
+
return lstatSync(path).isSymbolicLink();
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const directoryTarget = (path) => {
|
|
50
|
+
try {
|
|
51
|
+
return statSync(path).isDirectory();
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const isRegularFile = (path) => {
|
|
58
|
+
try {
|
|
59
|
+
return lstatSync(path).isFile();
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
/** A managed leaf must never be created through a link the user owns, so every ancestor is checked. */
|
|
66
|
+
const symlinkedAncestor = (home, relativePath) => {
|
|
67
|
+
const segments = relativePath.split('/').slice(0, -1);
|
|
68
|
+
for (let depth = 1; depth <= segments.length; depth += 1) {
|
|
69
|
+
const ancestor = segments.slice(0, depth).join('/');
|
|
70
|
+
if (isSymlink(join(home, ancestor)))
|
|
71
|
+
return ancestor;
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
};
|
|
75
|
+
const firstLine = (output) => output.split('\n')[0];
|
|
76
|
+
const conflict = (detail) => ({ status: 'conflict', detail });
|
|
77
|
+
const isSettingsDocument = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
78
|
+
const settingLocation = (home, entry) => join(home, entry.setting.file);
|
|
79
|
+
const readSettingsDocument = (path, file) => {
|
|
80
|
+
if (!existsSync(path))
|
|
81
|
+
return {};
|
|
82
|
+
const parsed = file.endsWith('.toml')
|
|
83
|
+
? parseToml(readFileSync(path, 'utf8'))
|
|
84
|
+
: JSON.parse(readFileSync(path, 'utf8'));
|
|
85
|
+
if (!isSettingsDocument(parsed))
|
|
86
|
+
throw new Error('settings document is not an object');
|
|
87
|
+
return parsed;
|
|
88
|
+
};
|
|
89
|
+
const writeSettingsDocument = (path, file, document) => {
|
|
90
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
91
|
+
const content = file.endsWith('.toml') ? stringifyToml(document) : `${JSON.stringify(document, null, 2)}\n`;
|
|
92
|
+
writeFileSync(path, content);
|
|
93
|
+
};
|
|
94
|
+
const locateSetting = (document, keys) => {
|
|
95
|
+
let parent = document;
|
|
96
|
+
for (const [index, key] of keys.entries()) {
|
|
97
|
+
if (!Object.hasOwn(parent, key))
|
|
98
|
+
return { status: 'missing' };
|
|
99
|
+
const value = parent[key];
|
|
100
|
+
if (index === keys.length - 1)
|
|
101
|
+
return { status: 'found', value };
|
|
102
|
+
if (!isSettingsDocument(value))
|
|
103
|
+
return { status: 'blocked' };
|
|
104
|
+
parent = value;
|
|
105
|
+
}
|
|
106
|
+
return { status: 'missing' };
|
|
107
|
+
};
|
|
108
|
+
const defineOwn = (document, key, value) => {
|
|
109
|
+
Object.defineProperty(document, key, { configurable: true, enumerable: true, value, writable: true });
|
|
110
|
+
};
|
|
111
|
+
const setValueAt = (document, keys, value) => {
|
|
112
|
+
let parent = document;
|
|
113
|
+
for (const key of keys.slice(0, -1)) {
|
|
114
|
+
if (!Object.hasOwn(parent, key))
|
|
115
|
+
defineOwn(parent, key, {});
|
|
116
|
+
const child = parent[key];
|
|
117
|
+
parent = child;
|
|
118
|
+
}
|
|
119
|
+
defineOwn(parent, keys.at(-1), value);
|
|
120
|
+
};
|
|
121
|
+
const deleteValueAt = (document, keys) => {
|
|
122
|
+
const parents = [];
|
|
123
|
+
let parent = document;
|
|
124
|
+
// removeSetting calls this only after locateSetting confirms that every segment is an own
|
|
125
|
+
// property and every parent is an object.
|
|
126
|
+
for (const key of keys.slice(0, -1)) {
|
|
127
|
+
parents.push({ parent, key });
|
|
128
|
+
parent = parent[key];
|
|
129
|
+
}
|
|
130
|
+
const leaf = keys.at(-1);
|
|
131
|
+
delete parent[leaf];
|
|
132
|
+
for (const item of parents.reverse()) {
|
|
133
|
+
const value = item.parent[item.key];
|
|
134
|
+
if (isSettingsDocument(value) && Object.keys(value).length === 0)
|
|
135
|
+
delete item.parent[item.key];
|
|
136
|
+
else
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const equalSetting = (left, right) => JSON.stringify(left) === JSON.stringify(right);
|
|
141
|
+
const reconcileSetting = (home, entry, previous) => {
|
|
142
|
+
const { file, keys, value } = entry.setting;
|
|
143
|
+
const path = settingLocation(home, entry);
|
|
144
|
+
let document;
|
|
145
|
+
try {
|
|
146
|
+
document = readSettingsDocument(path, file);
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
return conflict(`cannot parse ${file}: ${error instanceof Error ? error.message : String(error)}`);
|
|
150
|
+
}
|
|
151
|
+
const current = locateSetting(document, keys);
|
|
152
|
+
if (current.status === 'blocked')
|
|
153
|
+
return conflict('an unmanaged native setting blocks this nested setting');
|
|
154
|
+
const mutate = () => {
|
|
155
|
+
setValueAt(document, keys, value);
|
|
156
|
+
writeSettingsDocument(path, file, document);
|
|
157
|
+
};
|
|
158
|
+
if (current.status === 'missing')
|
|
159
|
+
return { status: 'created', mutate };
|
|
160
|
+
if (equalSetting(current.value, value))
|
|
161
|
+
return { status: 'unchanged' };
|
|
162
|
+
if (previous === undefined)
|
|
163
|
+
return conflict('an unmanaged native setting already exists here');
|
|
164
|
+
const prior = previous.target === undefined ? undefined : JSON.parse(previous.target);
|
|
165
|
+
return equalSetting(current.value, prior)
|
|
166
|
+
? { status: 'updated', mutate }
|
|
167
|
+
: conflict('the previously managed native setting was changed outside Outfitter');
|
|
168
|
+
};
|
|
169
|
+
const reconcileSymlink = (home, entry, managed) => {
|
|
170
|
+
const path = join(home, entry.path);
|
|
171
|
+
const target = entry.target;
|
|
172
|
+
const create = () => {
|
|
173
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
174
|
+
// Windows needs the link type up front; a junction to a directory needs no privilege.
|
|
175
|
+
symlinkSync(target, path, directoryTarget(target) ? (process.platform === 'win32' ? 'junction' : 'dir') : 'file');
|
|
176
|
+
};
|
|
177
|
+
if (!existsSync(path) && !isSymlink(path))
|
|
178
|
+
return { status: 'created', mutate: create };
|
|
179
|
+
if (!isSymlink(path))
|
|
180
|
+
return conflict('an unmanaged file or directory already exists here');
|
|
181
|
+
const current = resolve(dirname(path), readlinkSync(path));
|
|
182
|
+
if (current === resolve(target))
|
|
183
|
+
return { status: 'unchanged' };
|
|
184
|
+
if (!managed)
|
|
185
|
+
return conflict(`an unmanaged symlink to ${current} already exists here`);
|
|
186
|
+
return {
|
|
187
|
+
status: 'updated',
|
|
188
|
+
mutate: () => {
|
|
189
|
+
unlinkSync(path);
|
|
190
|
+
create();
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const reconcileFile = (home, entry, managed) => {
|
|
195
|
+
const path = join(home, entry.path);
|
|
196
|
+
const write = () => {
|
|
197
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
198
|
+
writeFileSync(path, entry.content);
|
|
199
|
+
};
|
|
200
|
+
if (!existsSync(path) && !isSymlink(path))
|
|
201
|
+
return { status: 'created', mutate: write };
|
|
202
|
+
if (!isRegularFile(path))
|
|
203
|
+
return conflict('an unmanaged symlink or directory already exists here');
|
|
204
|
+
if (readFileSync(path, 'utf8') === entry.content)
|
|
205
|
+
return { status: 'unchanged' };
|
|
206
|
+
if (!managed)
|
|
207
|
+
return conflict('an unmanaged file already exists here');
|
|
208
|
+
return { status: 'updated', mutate: write };
|
|
209
|
+
};
|
|
210
|
+
const reconcileMcp = (harness, entry, run) => {
|
|
211
|
+
const { id, server } = entry.mcp;
|
|
212
|
+
const add = mcpAddArgs(harness, id, server);
|
|
213
|
+
if (add.args === undefined)
|
|
214
|
+
return { status: 'skipped', detail: add.warnings.join(' ') };
|
|
215
|
+
const existing = run(harness, mcpGetArgs(id));
|
|
216
|
+
if (!existing.found)
|
|
217
|
+
return { status: 'skipped', detail: `${harness} CLI not found on PATH` };
|
|
218
|
+
if (existing.ok)
|
|
219
|
+
return { status: 'unchanged', detail: `already configured in ${harness}` };
|
|
220
|
+
const detail = add.warnings.length === 0 ? undefined : add.warnings.join(' ');
|
|
221
|
+
return {
|
|
222
|
+
status: 'created',
|
|
223
|
+
detail,
|
|
224
|
+
mutate: () => {
|
|
225
|
+
const added = run(harness, add.args);
|
|
226
|
+
// Codex may register the server and then fail a follow-up login; a registered server is a
|
|
227
|
+
// success worth owning, so the post-add state decides rather than the exit code alone.
|
|
228
|
+
if (!added.ok && !run(harness, mcpGetArgs(id)).ok)
|
|
229
|
+
throw new Error(firstLine(added.output));
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
const reconcile = (plan, home, entry, previous, run) => {
|
|
234
|
+
if (entry.kind === 'mcp')
|
|
235
|
+
return reconcileMcp(plan.harness, entry, run);
|
|
236
|
+
if (entry.kind === 'setting')
|
|
237
|
+
return reconcileSetting(home, entry, previous);
|
|
238
|
+
const ancestor = symlinkedAncestor(home, entry.path);
|
|
239
|
+
if (ancestor !== undefined) {
|
|
240
|
+
return conflict(`'${ancestor}' is an unmanaged symlink; unlink it to let outfitter manage its entries`);
|
|
241
|
+
}
|
|
242
|
+
return entry.kind === 'symlink'
|
|
243
|
+
? reconcileSymlink(home, entry, previous !== undefined)
|
|
244
|
+
: reconcileFile(home, entry, previous !== undefined);
|
|
245
|
+
};
|
|
246
|
+
const apply = (entry, reconciliation, dryRun) => {
|
|
247
|
+
if (dryRun || reconciliation.mutate === undefined) {
|
|
248
|
+
return { entry, status: reconciliation.status, detail: reconciliation.detail };
|
|
249
|
+
}
|
|
250
|
+
try {
|
|
251
|
+
reconciliation.mutate();
|
|
252
|
+
return { entry, status: reconciliation.status, detail: reconciliation.detail };
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
return { entry, status: 'skipped', detail: error instanceof Error ? error.message : String(error) };
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
const isManagedNow = (action) => action.status === 'created' || action.status === 'updated' || action.status === 'unchanged';
|
|
259
|
+
/** A managed symlink whose target vanished is pruned; anything else outside the plan is left alone. */
|
|
260
|
+
const pruneDangling = (home, stale, dryRun) => stale.flatMap((previous) => {
|
|
261
|
+
const path = join(home, previous.path);
|
|
262
|
+
if (previous.kind !== 'symlink' || !isSymlink(path) || existsSync(path))
|
|
263
|
+
return [];
|
|
264
|
+
if (!dryRun)
|
|
265
|
+
unlinkSync(path);
|
|
266
|
+
const entry = { kind: 'symlink', path: previous.path, target: previous.target, resource: previous.path };
|
|
267
|
+
return [{ entry, status: 'pruned', detail: 'target no longer exists' }];
|
|
268
|
+
});
|
|
269
|
+
/** Applies the plan idempotently, records ownership, and never rewrites anything it does not own. */
|
|
270
|
+
export const applyHarnessLinks = (plan, home, options = {}, run = spawnHarnessCommand) => {
|
|
271
|
+
const dryRun = options.dryRun === true;
|
|
272
|
+
if (!dryRun)
|
|
273
|
+
mkdirSync(home, { recursive: true });
|
|
274
|
+
const manifest = readManifest(home, plan.harness);
|
|
275
|
+
const managedEntries = new Map(manifest.entries.map((entry) => [entry.path, entry]));
|
|
276
|
+
const planned = new Set(plan.entries.map((entry) => entry.path));
|
|
277
|
+
const actions = plan.entries.map((entry) => apply(entry, reconcile(plan, home, entry, managedEntries.get(entry.path), run), dryRun));
|
|
278
|
+
const stale = manifest.entries.filter((entry) => !planned.has(entry.path));
|
|
279
|
+
const pruned = pruneDangling(home, stale, dryRun);
|
|
280
|
+
const prunedPaths = new Set(pruned.map((action) => action.entry.path));
|
|
281
|
+
if (!dryRun) {
|
|
282
|
+
const entries = [
|
|
283
|
+
...stale.filter((entry) => !prunedPaths.has(entry.path)),
|
|
284
|
+
...actions
|
|
285
|
+
.filter((action) => isManagedNow(action) && (action.status !== 'unchanged' || managedEntries.has(action.entry.path)))
|
|
286
|
+
.map(({ entry }) => ({
|
|
287
|
+
kind: entry.kind,
|
|
288
|
+
path: entry.path,
|
|
289
|
+
...(entry.target === undefined ? {} : { target: entry.target }),
|
|
290
|
+
...(entry.kind === 'setting' ? { target: JSON.stringify(entry.setting.value) } : {}),
|
|
291
|
+
})),
|
|
292
|
+
];
|
|
293
|
+
writeManifest(home, { version: 1, harness: plan.harness, entries });
|
|
294
|
+
}
|
|
295
|
+
return { actions: [...actions, ...pruned] };
|
|
296
|
+
};
|
|
297
|
+
const removeSetting = (home, previous, entry) => {
|
|
298
|
+
const [, file, encodedKeys] = previous.path.split(':');
|
|
299
|
+
const keys = encodedKeys.split('/').map(decodeURIComponent);
|
|
300
|
+
const path = join(home, file);
|
|
301
|
+
let document;
|
|
302
|
+
try {
|
|
303
|
+
document = readSettingsDocument(path, file);
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
return { entry, status: 'skipped', detail: error instanceof Error ? error.message : String(error) };
|
|
307
|
+
}
|
|
308
|
+
const expected = previous.target === undefined ? undefined : JSON.parse(previous.target);
|
|
309
|
+
const current = locateSetting(document, keys);
|
|
310
|
+
if (current.status === 'missing')
|
|
311
|
+
return { entry, status: 'removed' };
|
|
312
|
+
if (current.status === 'blocked' || !equalSetting(current.value, expected))
|
|
313
|
+
return { entry, status: 'skipped', detail: 'native setting no longer matches the managed value' };
|
|
314
|
+
deleteValueAt(document, keys);
|
|
315
|
+
writeSettingsDocument(path, file, document);
|
|
316
|
+
return { entry, status: 'removed' };
|
|
317
|
+
};
|
|
318
|
+
const removeMcp = (harness, previous, entry, run) => {
|
|
319
|
+
const result = run(harness, mcpRemoveArgs(harness, previous.path.slice('mcp:'.length)));
|
|
320
|
+
if (!result.found)
|
|
321
|
+
return { entry, status: 'skipped', detail: `${harness} CLI not found on PATH` };
|
|
322
|
+
return result.ok ? { entry, status: 'removed' } : { entry, status: 'skipped', detail: result.output };
|
|
323
|
+
};
|
|
324
|
+
const removeEntry = (harness, home, previous, run) => {
|
|
325
|
+
const entry = {
|
|
326
|
+
kind: previous.kind,
|
|
327
|
+
path: previous.path,
|
|
328
|
+
target: previous.target,
|
|
329
|
+
resource: previous.path,
|
|
330
|
+
};
|
|
331
|
+
if (previous.kind === 'mcp')
|
|
332
|
+
return removeMcp(harness, previous, entry, run);
|
|
333
|
+
if (previous.kind === 'setting')
|
|
334
|
+
return removeSetting(home, previous, entry);
|
|
335
|
+
const path = join(home, previous.path);
|
|
336
|
+
const owned = previous.kind === 'symlink' ? isSymlink(path) : isRegularFile(path);
|
|
337
|
+
if (!owned)
|
|
338
|
+
return { entry, status: 'skipped', detail: 'no longer a managed entry' };
|
|
339
|
+
unlinkSync(path);
|
|
340
|
+
return { entry, status: 'removed' };
|
|
341
|
+
};
|
|
342
|
+
/** Removes exactly what the manifest records and forgets it; unmanaged neighbors are untouched. */
|
|
343
|
+
export const removeHarnessLinks = (harness, home, run = spawnHarnessCommand) => {
|
|
344
|
+
const manifest = readManifest(home, harness);
|
|
345
|
+
const actions = manifest.entries.map((entry) => removeEntry(harness, home, entry, run));
|
|
346
|
+
const remaining = manifest.entries.filter((entry, index) => actions[index].status === 'skipped' &&
|
|
347
|
+
(entry.kind === 'setting' || actions[index].detail?.includes('CLI not found') === true));
|
|
348
|
+
writeManifest(home, { version: 1, harness, entries: remaining });
|
|
349
|
+
for (const container of ['skills', 'agents', 'commands', 'prompts']) {
|
|
350
|
+
const directory = join(home, container);
|
|
351
|
+
if (existsSync(directory) && !isSymlink(directory) && readdirSync(directory).length === 0)
|
|
352
|
+
rmdirSync(directory);
|
|
353
|
+
}
|
|
354
|
+
return { actions };
|
|
355
|
+
};
|
|
356
|
+
//# sourceMappingURL=HarnessLinkApply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HarnessLinkApply.js","sourceRoot":"","sources":["../../src/links/HarnessLinkApply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { EffectiveResourceSet, ResolvedResource } from '../resolver/Resource.js';
|
|
2
|
+
import type { AgentDefaults, HarnessDefaultSettings, Settings, SettingsValue } from '../settings/Settings.js';
|
|
3
|
+
import type { LinkHarness } from './HarnessHome.js';
|
|
4
|
+
export interface LinkSelection {
|
|
5
|
+
readonly agents: readonly string[];
|
|
6
|
+
readonly workflows: readonly string[];
|
|
7
|
+
readonly all: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface LinkScope {
|
|
10
|
+
/** Root agents to compose, sorted; every delegate they name joins the closure later. */
|
|
11
|
+
readonly agents: readonly string[];
|
|
12
|
+
readonly errors: readonly string[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* With no explicit selection the scope is everything the settings stack already opted into: every
|
|
16
|
+
* enabled workflow root plus the default agent. `--all` widens it to every resolvable agent.
|
|
17
|
+
*/
|
|
18
|
+
export declare const resolveLinkScope: (set: EffectiveResourceSet, settings: Settings, selection: LinkSelection) => LinkScope;
|
|
19
|
+
export interface LinkedAgent {
|
|
20
|
+
readonly slug: string;
|
|
21
|
+
/** Native Claude agent definition composed from the agent's full identity and loadout. */
|
|
22
|
+
readonly document: string;
|
|
23
|
+
}
|
|
24
|
+
export interface LinkedMcpServer {
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly server: Readonly<Record<string, unknown>>;
|
|
27
|
+
}
|
|
28
|
+
export interface LinkClosure {
|
|
29
|
+
readonly agents: readonly LinkedAgent[];
|
|
30
|
+
readonly skills: readonly ResolvedResource[];
|
|
31
|
+
readonly commands: readonly ResolvedResource[];
|
|
32
|
+
readonly mcpServers: readonly LinkedMcpServer[];
|
|
33
|
+
/** Winning tree-root `agents.md`, the always-on shared context, when any layer provides one. */
|
|
34
|
+
readonly sharedContextPath?: string;
|
|
35
|
+
readonly warnings: readonly string[];
|
|
36
|
+
readonly errors: readonly string[];
|
|
37
|
+
}
|
|
38
|
+
/** Composes every scoped agent and its delegates, collecting what a harness home must carry. */
|
|
39
|
+
export declare const composeLinkClosure: (set: EffectiveResourceSet, scope: readonly string[], projectDirectory: string, agentDefaults?: AgentDefaults) => LinkClosure;
|
|
40
|
+
export type LinkEntryKind = 'symlink' | 'file' | 'mcp' | 'setting';
|
|
41
|
+
export interface LinkedSetting {
|
|
42
|
+
readonly file: 'settings.json' | 'config.toml';
|
|
43
|
+
readonly keys: readonly string[];
|
|
44
|
+
readonly value: SettingsValue;
|
|
45
|
+
}
|
|
46
|
+
/** One managed item inside a harness home, addressed relative to that home. */
|
|
47
|
+
export interface LinkEntry {
|
|
48
|
+
readonly kind: LinkEntryKind;
|
|
49
|
+
/** Path relative to the harness home, POSIX-joined. */
|
|
50
|
+
readonly path: string;
|
|
51
|
+
/** Absolute symlink target. */
|
|
52
|
+
readonly target?: string;
|
|
53
|
+
/** Generated file content. */
|
|
54
|
+
readonly content?: string;
|
|
55
|
+
readonly mcp?: LinkedMcpServer;
|
|
56
|
+
readonly setting?: LinkedSetting;
|
|
57
|
+
/** `kind:slug` of the protocol resource this entry projects, for diagnostics. */
|
|
58
|
+
readonly resource: string;
|
|
59
|
+
}
|
|
60
|
+
export interface HarnessLinkPlan {
|
|
61
|
+
readonly harness: LinkHarness;
|
|
62
|
+
readonly entries: readonly LinkEntry[];
|
|
63
|
+
readonly warnings: readonly string[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Maps the closure onto one harness's native layout. Claude Code reads `skills/`, `agents/`,
|
|
67
|
+
* `commands/`, and `CLAUDE.md` from its config directory; Codex reads `skills/`, `prompts/`, and
|
|
68
|
+
* `AGENTS.md` from `CODEX_HOME`. Both take user-scope MCP servers only through their own CLIs.
|
|
69
|
+
*/
|
|
70
|
+
export declare const planHarnessLinks: (closure: LinkClosure, harness: LinkHarness, defaults?: HarnessDefaultSettings) => HarnessLinkPlan;
|