@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.7 → 0.1.8
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/bin/adl +2 -2
- package/bin/lean-ctx-observe-strip +76 -3
- package/bin/reconcile +175 -5
- package/bin/validate-manifest +19 -1
- package/package.json +1 -1
- package/packages/agent-hooks/src/deploy/deploy.ts +98 -18
- package/packages/agent-hooks/src/deploy/doctor.ts +61 -11
- package/packages/agent-hooks/src/deploy/json-merge.ts +430 -18
- package/packages/agent-hooks/src/deploy/lock.ts +36 -2
- package/packages/agent-hooks/src/lean-ctx/env.ts +17 -0
- package/packages/agent-hooks/src/lean-ctx/mcp.ts +4 -2
- package/packages/agent-settings/assets/lean-ctx/config.toml +3 -0
- package/packages/agent-settings/assets/lean-ctx/gitignore +4 -0
- package/packages/agent-settings/assets/lean-ctx/layout.toml +2 -0
- package/packages/agent-settings/src/deploy/agents-deploy.ts +10 -5
- package/packages/agent-settings/src/deploy/doctor.ts +39 -3
- package/packages/agent-settings/src/deploy/lean-ctx-deploy.ts +104 -12
- package/packages/agent-settings/src/deploy/lean-ctx-merge.ts +580 -0
- package/packages/agent-settings/src/deploy/lock.ts +4 -1
- package/packages/agent-settings/src/deploy/mcp-deploy.ts +9 -6
- package/packages/agent-settings/src/deploy/settings.ts +6 -3
- package/packages/agent-skills/dist/deploy.d.ts +2 -0
- package/packages/agent-skills/dist/deploy.d.ts.map +1 -1
- package/packages/agent-skills/dist/deploy.js +15 -8
- package/packages/agent-skills/dist/deploy.js.map +1 -1
- package/packages/agent-skills/dist/manifest.d.ts +1 -0
- package/packages/agent-skills/dist/manifest.d.ts.map +1 -1
- package/packages/agent-skills/dist/manifest.js +6 -2
- package/packages/agent-skills/dist/manifest.js.map +1 -1
- package/packages/agent-skills/src/deploy.ts +15 -8
- package/packages/agent-skills/src/manifest.ts +5 -2
- package/packages/azdo/src/azdo-repo-doctor.ts +401 -91
- package/packages/azdo/src/lib/graph-identity.ts +190 -3
- package/packages/fleet/jobs/git-maintain/src/main.ts +305 -45
- package/packages/fleet/manifest.json +2 -0
- package/packages/fleet/manifest.schema.json +9 -0
- package/packages/repo-controls/README.md +13 -6
- package/packages/repo-controls/assets/adl-config.default.toml +1 -0
- package/packages/repo-controls/src/cli.ts +6 -1
- package/packages/repo-controls/src/install.ts +88 -6
|
@@ -22,6 +22,8 @@ export interface SettingsTargetOptions {
|
|
|
22
22
|
readonly profile?: DeployProfile;
|
|
23
23
|
readonly servers?: readonly McpServerSpec[];
|
|
24
24
|
readonly agents?: readonly AgentDef[];
|
|
25
|
+
/** deploySettings only: computes the same result without writing anything (independent review, 2026-09-29, finding 6). */
|
|
26
|
+
readonly dryRun?: boolean;
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
export interface DeploySettingsResult {
|
|
@@ -43,9 +45,10 @@ export function deploySettings(options: SettingsTargetOptions): DeploySettingsRe
|
|
|
43
45
|
const { agentsAssetsDir, leanCtxAssetsDir } = resolveDirs(options, profile);
|
|
44
46
|
const agents = options.agents ?? loadAgentSources(agentsAssetsDir);
|
|
45
47
|
|
|
46
|
-
const
|
|
47
|
-
const
|
|
48
|
-
const
|
|
48
|
+
const dryRun = options.dryRun === true;
|
|
49
|
+
const mcp = deployMcp({ targetRepo: options.targetRepo, profile, servers, dryRun });
|
|
50
|
+
const agentsResult = deployAgents({ assetsDir: agentsAssetsDir, targetRepo: options.targetRepo, profile, agents, dryRun });
|
|
51
|
+
const leanCtx = deployLeanCtx({ assetsDir: leanCtxAssetsDir, targetRepo: options.targetRepo, profile, dryRun });
|
|
49
52
|
|
|
50
53
|
const ok = mcp.conflicts.length === 0 && agentsResult.conflicts.length === 0 && leanCtx.conflicts.length === 0;
|
|
51
54
|
return { mcp, agents: agentsResult, leanCtx, ok };
|
|
@@ -4,6 +4,8 @@ export interface DeploySkillsOptions {
|
|
|
4
4
|
readonly targetRepo: string;
|
|
5
5
|
/** Defaults to loadProfile() (the package's own deploy-profile.json) — pass explicitly when the caller has already resolved real on-disk paths (see profile.ts's header). */
|
|
6
6
|
readonly profile?: DeployProfile;
|
|
7
|
+
/** Computes the exact same written/unchanged/removed/conflicts/retiredRemovals result without writing anything (independent review, 2026-09-29, finding 6). */
|
|
8
|
+
readonly dryRun?: boolean;
|
|
7
9
|
}
|
|
8
10
|
export interface SkillConflict {
|
|
9
11
|
readonly folder: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,cAAc,CAAC;AAI/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6KAA6K;IAC7K,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,cAAc,CAAC;AAI/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6KAA6K;IAC7K,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,+JAA+J;IAC/J,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C;AAeD,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAuJ7E"}
|
|
@@ -47,6 +47,7 @@ function removeEmptyParents(root, dir) {
|
|
|
47
47
|
}
|
|
48
48
|
export function deploySkills(options) {
|
|
49
49
|
const { assetsDir, targetRepo } = options;
|
|
50
|
+
const dryRun = options.dryRun === true;
|
|
50
51
|
if (!existsSync(assetsDir) || !statSync(assetsDir).isDirectory()) {
|
|
51
52
|
throw new Error(`agent-skills assets directory not found: ${assetsDir}`);
|
|
52
53
|
}
|
|
@@ -125,8 +126,10 @@ export function deploySkills(options) {
|
|
|
125
126
|
unchanged.push(targetRel);
|
|
126
127
|
continue;
|
|
127
128
|
}
|
|
128
|
-
|
|
129
|
-
|
|
129
|
+
if (!dryRun) {
|
|
130
|
+
mkdirSync(dirname(targetAbs), { recursive: true });
|
|
131
|
+
writeFileSync(targetAbs, content);
|
|
132
|
+
}
|
|
130
133
|
written.push(targetRel);
|
|
131
134
|
}
|
|
132
135
|
}
|
|
@@ -142,18 +145,21 @@ export function deploySkills(options) {
|
|
|
142
145
|
continue;
|
|
143
146
|
const absolute = join(targetRepo, relPath);
|
|
144
147
|
if (existsSync(absolute)) {
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
if (!dryRun) {
|
|
149
|
+
unlinkSync(absolute);
|
|
150
|
+
removeEmptyParents(targetRepo, dirname(absolute));
|
|
151
|
+
}
|
|
147
152
|
}
|
|
148
153
|
removed.push(relPath);
|
|
149
154
|
}
|
|
150
|
-
|
|
155
|
+
if (!dryRun)
|
|
156
|
+
writeManifest(targetRepo, [...keptPaths]);
|
|
151
157
|
// legacyLock's own record of what it wrote under a skills folder stops
|
|
152
158
|
// being meaningful the moment this deploy has assessed it — taken over,
|
|
153
159
|
// or confirmed a conflict either way — so its entries are stripped
|
|
154
160
|
// regardless of this run's outcome, deleting the lock outright once
|
|
155
161
|
// nothing (including sibling packages' own sections) is left in it.
|
|
156
|
-
if (legacyLock !== null) {
|
|
162
|
+
if (!dryRun && legacyLock !== null) {
|
|
157
163
|
const legacySkillFolders = [...profile.surfaces.map((surface) => surface.folder), ...retiredFolders(profile)];
|
|
158
164
|
stripTakenOverEntries(legacyLock, legacySkillFolders);
|
|
159
165
|
}
|
|
@@ -166,10 +172,11 @@ export function deploySkills(options) {
|
|
|
166
172
|
for (const name of directoryNames(folderAbs)) {
|
|
167
173
|
if (!availableSkillSet.has(name))
|
|
168
174
|
continue; // not ours to manage — left byte-for-byte
|
|
169
|
-
|
|
175
|
+
if (!dryRun)
|
|
176
|
+
removeDirRecursive(join(folderAbs, name));
|
|
170
177
|
retiredRemovals.push(`${folder}/${name}`);
|
|
171
178
|
}
|
|
172
|
-
if (existsSync(folderAbs) && readdirSync(folderAbs).length === 0) {
|
|
179
|
+
if (!dryRun && existsSync(folderAbs) && readdirSync(folderAbs).length === 0) {
|
|
173
180
|
rmdirSync(folderAbs);
|
|
174
181
|
retiredRemovals.push(folder);
|
|
175
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3H,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAsB,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export interface SkillManifest {
|
|
|
7
7
|
export declare function manifestPathFor(targetRepo: string): string;
|
|
8
8
|
/** `{ schema: 1, files: [] }` when no manifest exists yet — a target repo that has never been deployed into. */
|
|
9
9
|
export declare function readManifest(targetRepo: string): SkillManifest;
|
|
10
|
+
/** Skips the write entirely when the serialized content is already byte-identical (independent review, 2026-09-29, finding 8: a genuine no-op run must not touch the manifest's mtime either). */
|
|
10
11
|
export declare function writeManifest(targetRepo: string, files: readonly string[]): void;
|
|
11
12
|
/** True iff the manifest records at least one file under `folder/skill/`. */
|
|
12
13
|
export declare function manifestOwnsSkill(manifest: SkillManifest, folder: string, skill: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAGvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,gHAAgH;AAChH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAS9D;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAgBA,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAGvE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,gHAAgH;AAChH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CAS9D;AAED,kMAAkM;AAClM,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAOhF;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAGjG;AAED,6EAA6E;AAC7E,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAUnG"}
|
|
@@ -29,11 +29,15 @@ export function readManifest(targetRepo) {
|
|
|
29
29
|
}
|
|
30
30
|
return { schema: MANIFEST_SCHEMA, files: raw.files.map(String) };
|
|
31
31
|
}
|
|
32
|
+
/** Skips the write entirely when the serialized content is already byte-identical (independent review, 2026-09-29, finding 8: a genuine no-op run must not touch the manifest's mtime either). */
|
|
32
33
|
export function writeManifest(targetRepo, files) {
|
|
33
34
|
const path = manifestPathFor(targetRepo);
|
|
34
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
35
35
|
const sorted = [...new Set(files)].sort();
|
|
36
|
-
|
|
36
|
+
const next = `${JSON.stringify({ schema: MANIFEST_SCHEMA, files: sorted }, null, 2)}\n`;
|
|
37
|
+
if (existsSync(path) && readFileSync(path, "utf8") === next)
|
|
38
|
+
return;
|
|
39
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
40
|
+
writeFileSync(path, next);
|
|
37
41
|
}
|
|
38
42
|
/** True iff the manifest records at least one file under `folder/skill/`. */
|
|
39
43
|
export function manifestOwnsSkill(manifest, folder, skill) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,CAAC,MAAM,sBAAsB,GAAG,gCAAgC,CAAC;AACvE,MAAM,eAAe,GAAG,CAAC,CAAC;AAQ1B,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO,IAAI,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;AAClD,CAAC;AAED,gHAAgH;AAChH,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAErE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,eAAe,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3G,MAAM,IAAI,KAAK,CAAC,8CAA8C,IAAI,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,KAAwB;IACxE,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IACzC,
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,6 +38,8 @@ export interface DeploySkillsOptions {
|
|
|
38
38
|
readonly targetRepo: string;
|
|
39
39
|
/** Defaults to loadProfile() (the package's own deploy-profile.json) — pass explicitly when the caller has already resolved real on-disk paths (see profile.ts's header). */
|
|
40
40
|
readonly profile?: DeployProfile;
|
|
41
|
+
/** Computes the exact same written/unchanged/removed/conflicts/retiredRemovals result without writing anything (independent review, 2026-09-29, finding 6). */
|
|
42
|
+
readonly dryRun?: boolean;
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
export interface SkillConflict {
|
|
@@ -75,6 +77,7 @@ function removeEmptyParents(root: string, dir: string): void {
|
|
|
75
77
|
|
|
76
78
|
export function deploySkills(options: DeploySkillsOptions): DeploySkillsResult {
|
|
77
79
|
const { assetsDir, targetRepo } = options;
|
|
80
|
+
const dryRun = options.dryRun === true;
|
|
78
81
|
|
|
79
82
|
if (!existsSync(assetsDir) || !statSync(assetsDir).isDirectory()) {
|
|
80
83
|
throw new Error(`agent-skills assets directory not found: ${assetsDir}`);
|
|
@@ -159,8 +162,10 @@ export function deploySkills(options: DeploySkillsOptions): DeploySkillsResult {
|
|
|
159
162
|
unchanged.push(targetRel);
|
|
160
163
|
continue;
|
|
161
164
|
}
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
if (!dryRun) {
|
|
166
|
+
mkdirSync(dirname(targetAbs), { recursive: true });
|
|
167
|
+
writeFileSync(targetAbs, content);
|
|
168
|
+
}
|
|
164
169
|
written.push(targetRel);
|
|
165
170
|
}
|
|
166
171
|
}
|
|
@@ -175,20 +180,22 @@ export function deploySkills(options: DeploySkillsOptions): DeploySkillsResult {
|
|
|
175
180
|
if (!profile.surfaces.some((surface) => relPath.startsWith(`${surface.folder}/`))) continue;
|
|
176
181
|
const absolute = join(targetRepo, relPath);
|
|
177
182
|
if (existsSync(absolute)) {
|
|
178
|
-
|
|
179
|
-
|
|
183
|
+
if (!dryRun) {
|
|
184
|
+
unlinkSync(absolute);
|
|
185
|
+
removeEmptyParents(targetRepo, dirname(absolute));
|
|
186
|
+
}
|
|
180
187
|
}
|
|
181
188
|
removed.push(relPath);
|
|
182
189
|
}
|
|
183
190
|
|
|
184
|
-
writeManifest(targetRepo, [...keptPaths]);
|
|
191
|
+
if (!dryRun) writeManifest(targetRepo, [...keptPaths]);
|
|
185
192
|
|
|
186
193
|
// legacyLock's own record of what it wrote under a skills folder stops
|
|
187
194
|
// being meaningful the moment this deploy has assessed it — taken over,
|
|
188
195
|
// or confirmed a conflict either way — so its entries are stripped
|
|
189
196
|
// regardless of this run's outcome, deleting the lock outright once
|
|
190
197
|
// nothing (including sibling packages' own sections) is left in it.
|
|
191
|
-
if (legacyLock !== null) {
|
|
198
|
+
if (!dryRun && legacyLock !== null) {
|
|
192
199
|
const legacySkillFolders = [...profile.surfaces.map((surface) => surface.folder), ...retiredFolders(profile)];
|
|
193
200
|
stripTakenOverEntries(legacyLock, legacySkillFolders);
|
|
194
201
|
}
|
|
@@ -201,11 +208,11 @@ export function deploySkills(options: DeploySkillsOptions): DeploySkillsResult {
|
|
|
201
208
|
|
|
202
209
|
for (const name of directoryNames(folderAbs)) {
|
|
203
210
|
if (!availableSkillSet.has(name)) continue; // not ours to manage — left byte-for-byte
|
|
204
|
-
removeDirRecursive(join(folderAbs, name));
|
|
211
|
+
if (!dryRun) removeDirRecursive(join(folderAbs, name));
|
|
205
212
|
retiredRemovals.push(`${folder}/${name}`);
|
|
206
213
|
}
|
|
207
214
|
|
|
208
|
-
if (existsSync(folderAbs) && readdirSync(folderAbs).length === 0) {
|
|
215
|
+
if (!dryRun && existsSync(folderAbs) && readdirSync(folderAbs).length === 0) {
|
|
209
216
|
rmdirSync(folderAbs);
|
|
210
217
|
retiredRemovals.push(folder);
|
|
211
218
|
}
|
|
@@ -39,11 +39,14 @@ export function readManifest(targetRepo: string): SkillManifest {
|
|
|
39
39
|
return { schema: MANIFEST_SCHEMA, files: raw.files.map(String) };
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
/** Skips the write entirely when the serialized content is already byte-identical (independent review, 2026-09-29, finding 8: a genuine no-op run must not touch the manifest's mtime either). */
|
|
42
43
|
export function writeManifest(targetRepo: string, files: readonly string[]): void {
|
|
43
44
|
const path = manifestPathFor(targetRepo);
|
|
44
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
45
45
|
const sorted = [...new Set(files)].sort();
|
|
46
|
-
|
|
46
|
+
const next = `${JSON.stringify({ schema: MANIFEST_SCHEMA, files: sorted }, null, 2)}\n`;
|
|
47
|
+
if (existsSync(path) && readFileSync(path, "utf8") === next) return;
|
|
48
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
49
|
+
writeFileSync(path, next);
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
/** True iff the manifest records at least one file under `folder/skill/`. */
|