@outerlayer/cli 0.18.0 → 0.19.1
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/CHANGELOG.md +33 -0
- package/README.md +21 -2
- package/dist/{agent-setup-RBTEACYU.js → agent-setup-AM42SA2D.js} +15 -16
- package/dist/{artifact-link-cmd-AVM2EKTV.js → artifact-link-cmd-OWRI5AJX.js} +2 -2
- package/dist/build-info.json +1 -1
- package/dist/{builder-DUI2ZH2H.js → builder-C4QNTYMS.js} +3 -3
- package/dist/{check-5C4YDZYV.js → check-W2JGXN3B.js} +44 -43
- package/dist/{chunk-S26M3YBJ.js → chunk-3UZTIRLF.js} +1 -1
- package/dist/{chunk-Y5MXET4M.js → chunk-3ZR7Y23Y.js} +11 -10
- package/dist/{chunk-47TTLEDX.js → chunk-5VML45HH.js} +35 -13
- package/dist/{chunk-F4XSVQJ4.js → chunk-6X4SQ5MY.js} +2 -2
- package/dist/{chunk-T4Y6SCG3.js → chunk-7UWVLZXD.js} +2 -2
- package/dist/{chunk-N3CUDFCW.js → chunk-7VUK5RFS.js} +15 -2
- package/dist/{chunk-SWCTGCSC.js → chunk-7YP7T6GV.js} +1 -1
- package/dist/{chunk-3OFZM4X6.js → chunk-B6SCN5NY.js} +151 -20
- package/dist/{chunk-KDVIU23F.js → chunk-BWSUPRDK.js} +1 -1
- package/dist/{chunk-S76AYB4M.js → chunk-CG36IONK.js} +5 -5
- package/dist/{chunk-RAZTWYZN.js → chunk-CGGPS7SI.js} +7 -8
- package/dist/chunk-CJJDJ7AT.js +56 -0
- package/dist/{chunk-W5VPCONO.js → chunk-EAEELQVQ.js} +33 -227
- package/dist/{chunk-QQM2UJ6T.js → chunk-F2KXHIFI.js} +182 -28
- package/dist/{chunk-KK4VBOH6.js → chunk-FBTGMSQF.js} +10 -11
- package/dist/{chunk-MQJSXHV7.js → chunk-G3IJ3N6F.js} +5 -3
- package/dist/{chunk-FUB7LRUE.js → chunk-GEMQLBMW.js} +5 -5
- package/dist/{chunk-Y5GE76XC.js → chunk-HOKXGFDR.js} +33 -81
- package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
- package/dist/{chunk-UYOYTKE2.js → chunk-JHGEBPLE.js} +3 -3
- package/dist/chunk-KYS3TQAG.js +296 -0
- package/dist/chunk-LLM3I5YU.js +89 -0
- package/dist/{chunk-B3UKB46N.js → chunk-LRG3ZMZD.js} +4 -5
- package/dist/{chunk-NL4XPC7W.js → chunk-LW7G5TJB.js} +1 -1
- package/dist/{chunk-MNTSH4CL.js → chunk-NNLA7LLQ.js} +1 -1
- package/dist/{chunk-GOBOJMOJ.js → chunk-PIZRPNKR.js} +4 -4
- package/dist/{chunk-ULSIJGLS.js → chunk-PSN33ERW.js} +56 -14
- package/dist/{chunk-WGAUY5LE.js → chunk-QEFKA2QD.js} +1 -1
- package/dist/{chunk-BMYGAGBJ.js → chunk-QNLX477Q.js} +155 -23
- package/dist/{chunk-JF42URPU.js → chunk-R22NZSGA.js} +33 -9
- package/dist/chunk-TUSYOL2O.js +113 -0
- package/dist/{chunk-ESC6UR76.js → chunk-TWF3RICI.js} +6 -6
- package/dist/{chunk-L2USZT6T.js → chunk-VMJPFQNE.js} +1 -1
- package/dist/{chunk-X5N6KC6V.js → chunk-WFSUUUAN.js} +2 -3
- package/dist/{chunk-6CHIYEZZ.js → chunk-XZ4H4X5F.js} +9 -83
- package/dist/{chunk-LXAY4A2G.js → chunk-YQR6E6OV.js} +34 -49
- package/dist/chunk-Z7K3L4FC.js +174 -0
- package/dist/{claude-launcher-YVXI76NX.js → claude-launcher-J5M44PFS.js} +20 -7
- package/dist/{cli-C77H54BV.js → cli-EXX2R73G.js} +206 -230
- package/dist/{command-H5CILO4S.js → command-ZQNEPDS6.js} +29 -30
- package/dist/{config-FXDG4NPJ.js → config-CLSGABD5.js} +2 -2
- package/dist/{connect-cmd-ZW5FV3ZW.js → connect-cmd-UNYKGDAL.js} +7 -7
- package/dist/context-cleanup-CHEWNYU6.js +11 -0
- package/dist/control-plane-launch-34LNRJWR.js +216 -0
- package/dist/{dist-QTX4RSCL.js → dist-WO7NOJNG.js} +2 -2
- package/dist/{docker-RC3PRX3Q.js → docker-BFU3AQGY.js} +4 -4
- package/dist/{doctor-2NQQML6P.js → doctor-DHUM5DBB.js} +32 -33
- package/dist/{emit-artifact-cmd-7MP63KXU.js → emit-artifact-cmd-XBHM647X.js} +17 -17
- package/dist/{emit-cmd-PPN4QQF2.js → emit-cmd-W55AEBCA.js} +6 -6
- package/dist/{emit-criteria-cmd-3RXPDLNK.js → emit-criteria-cmd-CRTYEF7D.js} +11 -12
- package/dist/{emit-finding-cmd-OL7JB6H3.js → emit-finding-cmd-7JHVRYOP.js} +12 -13
- package/dist/{emit-result-cmd-UZVMOCF4.js → emit-result-cmd-5NZMLCJK.js} +17 -17
- package/dist/emit-step-cmd-347XNGPQ.js +26 -0
- package/dist/{governing-source-BUU4IABS.js → governing-source-HAA4OW57.js} +21 -22
- package/dist/{hook-fast-W5MKHMJT.js → hook-fast-RL5E5OXE.js} +3 -3
- package/dist/{import-capture-cmd-ZO6KGHI2.js → import-capture-cmd-TK4XY7RD.js} +4 -4
- package/dist/{import-ruler-cmd-KJMWL5V6.js → import-ruler-cmd-T6LLO6Q7.js} +2 -2
- package/dist/index.js +4 -4
- package/dist/{init-WNXXYMO7.js → init-V6FOMD2V.js} +30 -31
- package/dist/{init-VWXIZEAN.js → init-XG47KCI4.js} +30 -31
- package/dist/{init-cmd-WS6TIRYT.js → init-cmd-Z4O4PPLZ.js} +70 -27
- package/dist/{init-update-E3J6TVIN.js → init-update-7DVAKWW3.js} +21 -22
- package/dist/{install-CBWIEF3R.js → install-4SEFIIW2.js} +3 -3
- package/dist/{login-browser-O63QZN7D.js → login-browser-DX35MARZ.js} +2 -2
- package/dist/{loop-UGI2BJOT.js → loop-TPUYUMSY.js} +44 -43
- package/dist/{machine-JOW4RNZ7.js → machine-TRHBT5NE.js} +26 -27
- package/dist/{mcp-serve-cmd-DOTY5FKY.js → mcp-serve-cmd-N3UTY6EE.js} +5 -5
- package/dist/{runner-env-4NB2GA7O.js → runner-env-FRZFFHDF.js} +4 -4
- package/dist/{runner-key-TC3NFWFV.js → runner-key-5FOWCW7J.js} +30 -31
- package/dist/{session-sender-NNVPSPY7.js → session-sender-U2BBUWNO.js} +19 -15
- package/dist/shell-function-NRD4KVUK.js +6 -0
- package/dist/{spec-cmd-OWVTBB4J.js → spec-cmd-FVLJOFGC.js} +12 -13
- package/dist/{starter-pack-OPWUDOWX.js → starter-pack-6LQVLBIA.js} +5 -5
- package/dist/{status-TKCLLKFG.js → status-BINH7MBG.js} +33 -32
- package/dist/{sync-cmd-Q6VYNPWG.js → sync-cmd-VXOUFS4I.js} +18 -14
- package/dist/{watch-ARAGADTF.js → watch-OH645CV2.js} +18 -14
- package/dist/{work-claim-cmd-34FERLYX.js → work-claim-cmd-ZRPSHMPT.js} +16 -17
- package/dist/{work-cmd-7S5B2H2P.js → work-cmd-5I3J2XQQ.js} +12 -13
- package/dist/{work-comment-cmd-SZJSPM5S.js → work-comment-cmd-UCCPWUSR.js} +12 -13
- package/dist/work-logs-cmd-7352CJPG.js +60 -0
- package/dist/{work-open-pr-cmd-RPXKCBWS.js → work-open-pr-cmd-LSH4VHJM.js} +13 -14
- package/dist/{work-pr-cmd-5LGANL32.js → work-pr-cmd-H4OQR26N.js} +12 -13
- package/package.json +2 -2
- package/skill-pack/maintained/outerlayer-cli/SKILL.md +9 -2
- package/skill-pack/maintained/outerlayer-cli/references/find-out-why-a-build-ended.md +76 -0
- package/skill-pack/shipped.json +1 -0
- package/skill-pack/template/build/references/release.md +3 -1
- package/dist/chunk-WBT5X3NH.js +0 -40
- package/dist/chunk-XCCLFVXM.js +0 -401
- package/dist/context-adopt-O5OFXMKI.js +0 -109
- package/dist/context-materialize-Y5IJ4MQT.js +0 -23
- package/dist/{chunk-NACDBXUG.js → chunk-BM63HB2M.js} +1 -1
- package/dist/{chunk-ZRL6HKBY.js → chunk-FVMYKL6L.js} +1 -1
- package/dist/{chunk-52NC2FIU.js → chunk-NTRCK4NH.js} +1 -1
- package/dist/{chunk-XGP3VYOG.js → chunk-P53VEAOF.js} +1 -1
|
@@ -1,34 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { join, dirname } from 'path';
|
|
3
|
+
import { unlinkSync, readFileSync, mkdirSync, writeFileSync, existsSync } from 'fs';
|
|
4
|
+
import { isAbsolute, join, dirname } from 'path';
|
|
6
5
|
|
|
7
6
|
createRequire(import.meta.url);
|
|
8
|
-
function pinPath(workpieceRoot) {
|
|
9
|
-
return join(workpieceRoot, CONTEXT_PIN_FILENAME);
|
|
10
|
-
}
|
|
11
|
-
function readPin(workpieceRoot) {
|
|
12
|
-
try {
|
|
13
|
-
const parsed = JSON.parse(readFileSync(pinPath(workpieceRoot), "utf8"));
|
|
14
|
-
if (typeof parsed === "object" && parsed !== null && typeof parsed.sha === "string" && typeof parsed.schemaVersion === "number") {
|
|
15
|
-
return parsed;
|
|
16
|
-
}
|
|
17
|
-
return void 0;
|
|
18
|
-
} catch {
|
|
19
|
-
return void 0;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function pinExists(workpieceRoot) {
|
|
23
|
-
return existsSync(pinPath(workpieceRoot));
|
|
24
|
-
}
|
|
25
|
-
function writePinIfChanged(workpieceRoot, sha) {
|
|
26
|
-
const existing = readPin(workpieceRoot);
|
|
27
|
-
if (existing?.sha === sha && existing.schemaVersion === CONTEXT_PIN_SCHEMA_VERSION) return false;
|
|
28
|
-
const pin = { schemaVersion: CONTEXT_PIN_SCHEMA_VERSION, sha };
|
|
29
|
-
writeFileSync(pinPath(workpieceRoot), JSON.stringify(pin) + "\n");
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
7
|
function stateDir(gitCommonDir) {
|
|
33
8
|
return join(gitCommonDir, "outerlayer");
|
|
34
9
|
}
|
|
@@ -56,19 +31,9 @@ function readContextManifest(gitCommonDir) {
|
|
|
56
31
|
function writeContextManifest(gitCommonDir, manifest) {
|
|
57
32
|
writeJson(manifestPath(gitCommonDir), manifest);
|
|
58
33
|
}
|
|
59
|
-
function
|
|
60
|
-
return manifest.files.every((f) => existsSync(join(workpieceRoot, f)));
|
|
61
|
-
}
|
|
62
|
-
function lastCheckPath(gitCommonDir) {
|
|
63
|
-
return join(stateDir(gitCommonDir), "last-check");
|
|
64
|
-
}
|
|
65
|
-
function touchLastCheck(gitCommonDir, now) {
|
|
66
|
-
const path = lastCheckPath(gitCommonDir);
|
|
67
|
-
mkdirSync(dirname(path), { recursive: true });
|
|
68
|
-
writeFileSync(path, String(now));
|
|
69
|
-
const seconds = now / 1e3;
|
|
34
|
+
function removeContextManifest(gitCommonDir) {
|
|
70
35
|
try {
|
|
71
|
-
|
|
36
|
+
unlinkSync(manifestPath(gitCommonDir));
|
|
72
37
|
} catch {
|
|
73
38
|
}
|
|
74
39
|
}
|
|
@@ -107,18 +72,38 @@ function writeSourceCache(gitCommonDir, cache) {
|
|
|
107
72
|
function isSourceCacheFresh(cache, now) {
|
|
108
73
|
return now - Date.parse(cache.checkedAt) < cache.ttlMs;
|
|
109
74
|
}
|
|
110
|
-
function
|
|
111
|
-
return join(stateDir(gitCommonDir), "
|
|
112
|
-
}
|
|
113
|
-
function
|
|
114
|
-
const parsed = readJson(
|
|
115
|
-
if (
|
|
116
|
-
return
|
|
75
|
+
function deliveryRecordPath(gitCommonDir) {
|
|
76
|
+
return join(stateDir(gitCommonDir), "delivery.json");
|
|
77
|
+
}
|
|
78
|
+
function readDeliveryRecord(gitCommonDir) {
|
|
79
|
+
const parsed = readJson(deliveryRecordPath(gitCommonDir));
|
|
80
|
+
if (typeof parsed?.dir === "string" && isAbsolute(parsed.dir) && typeof parsed.repository === "string" && typeof parsed.sha === "string") {
|
|
81
|
+
return {
|
|
82
|
+
...typeof parsed.schemaVersion === "number" ? { schemaVersion: parsed.schemaVersion } : {},
|
|
83
|
+
repository: parsed.repository,
|
|
84
|
+
...typeof parsed.ref === "string" ? { ref: parsed.ref } : {},
|
|
85
|
+
sha: parsed.sha,
|
|
86
|
+
dir: parsed.dir,
|
|
87
|
+
...parsed.launcher === true ? { launcher: true } : {}
|
|
88
|
+
};
|
|
117
89
|
}
|
|
118
90
|
return void 0;
|
|
119
91
|
}
|
|
120
|
-
function
|
|
121
|
-
|
|
92
|
+
function removeLauncherDeliveryRecord(gitCommonDir) {
|
|
93
|
+
if (readDeliveryRecord(gitCommonDir)?.launcher !== true) return;
|
|
94
|
+
try {
|
|
95
|
+
unlinkSync(deliveryRecordPath(gitCommonDir));
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function deliveryRecordExists(gitCommonDir) {
|
|
100
|
+
return existsSync(deliveryRecordPath(gitCommonDir));
|
|
101
|
+
}
|
|
102
|
+
function writeDeliveryRecord(gitCommonDir, record) {
|
|
103
|
+
writeJson(deliveryRecordPath(gitCommonDir), record);
|
|
104
|
+
}
|
|
105
|
+
function cloneIsGoverned(gitCommonDir) {
|
|
106
|
+
return readSourceCache(gitCommonDir)?.status === "governed" || deliveryRecordExists(gitCommonDir);
|
|
122
107
|
}
|
|
123
108
|
|
|
124
|
-
export { SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, clearDegraded,
|
|
109
|
+
export { SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, clearDegraded, cloneIsGoverned, isSourceCacheFresh, readContextManifest, readDegraded, readDeliveryRecord, readSourceCache, removeContextManifest, removeLauncherDeliveryRecord, writeContextManifest, writeDegraded, writeDeliveryRecord, writeSourceCache };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { readContextManifest, removeContextManifest } from './chunk-YQR6E6OV.js';
|
|
4
|
+
import { removePreCommitGuardHook } from './chunk-TUSYOL2O.js';
|
|
5
|
+
import { CONTEXT_PIN_FILENAME } from './chunk-WFSUUUAN.js';
|
|
6
|
+
import { execFileSync } from 'child_process';
|
|
7
|
+
import { existsSync, unlinkSync, lstatSync, readdirSync, rmdirSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
8
|
+
import { join, dirname, isAbsolute } from 'path';
|
|
9
|
+
|
|
10
|
+
createRequire(import.meta.url);
|
|
11
|
+
var CONTEXT_EXCLUDE_MARKER = "outerlayer context materialization";
|
|
12
|
+
var BEGIN_PREFIX = `# BEGIN ${CONTEXT_EXCLUDE_MARKER}`;
|
|
13
|
+
var END = `# END ${CONTEXT_EXCLUDE_MARKER}`;
|
|
14
|
+
function excludeFilePath(gitCommonDir) {
|
|
15
|
+
return join(gitCommonDir, "info", "exclude");
|
|
16
|
+
}
|
|
17
|
+
function readLines(path) {
|
|
18
|
+
if (!existsSync(path)) return [];
|
|
19
|
+
const content = readFileSync(path, "utf8");
|
|
20
|
+
if (content === "") return [];
|
|
21
|
+
const lines = content.split("\n");
|
|
22
|
+
if (lines[lines.length - 1] === "") lines.pop();
|
|
23
|
+
return lines;
|
|
24
|
+
}
|
|
25
|
+
function writeLines(path, lines) {
|
|
26
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
27
|
+
writeFileSync(path, lines.length ? lines.join("\n") + "\n" : "");
|
|
28
|
+
}
|
|
29
|
+
function findWellFormedBlock(lines) {
|
|
30
|
+
let i = 0;
|
|
31
|
+
while (i < lines.length) {
|
|
32
|
+
if (!lines[i].startsWith(BEGIN_PREFIX)) {
|
|
33
|
+
i++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const beginIdx = i;
|
|
37
|
+
let endIdx = -1;
|
|
38
|
+
let j = beginIdx + 1;
|
|
39
|
+
for (; j < lines.length; j++) {
|
|
40
|
+
if (lines[j] === END) {
|
|
41
|
+
endIdx = j;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
if (lines[j].startsWith(BEGIN_PREFIX)) break;
|
|
45
|
+
}
|
|
46
|
+
if (endIdx !== -1) return { beginIdx, endIdx };
|
|
47
|
+
i = j;
|
|
48
|
+
}
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
function removeContextExcludes(gitCommonDir) {
|
|
52
|
+
const path = excludeFilePath(gitCommonDir);
|
|
53
|
+
const lines = readLines(path);
|
|
54
|
+
const block = findWellFormedBlock(lines);
|
|
55
|
+
if (block === void 0) return { changed: false };
|
|
56
|
+
writeLines(path, [...lines.slice(0, block.beginIdx), ...lines.slice(block.endIdx + 1)]);
|
|
57
|
+
return { changed: true };
|
|
58
|
+
}
|
|
59
|
+
function contextExcludesPresent(gitCommonDir) {
|
|
60
|
+
return findWellFormedBlock(readLines(excludeFilePath(gitCommonDir))) !== void 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/context-cleanup.ts
|
|
64
|
+
function hasEarlierCopies(gitCommonDir) {
|
|
65
|
+
return readContextManifest(gitCommonDir) !== void 0 || contextExcludesPresent(gitCommonDir);
|
|
66
|
+
}
|
|
67
|
+
function isCopiedPath(rel) {
|
|
68
|
+
if (isAbsolute(rel) || rel.split("/").includes("..")) return false;
|
|
69
|
+
return rel === "AGENTS.md" || rel.startsWith(".claude/") || rel.startsWith(".outerlayer/");
|
|
70
|
+
}
|
|
71
|
+
function hasSymlinkComponent(root, rel) {
|
|
72
|
+
let current = root;
|
|
73
|
+
for (const segment of rel.split("/")) {
|
|
74
|
+
current = join(current, segment);
|
|
75
|
+
try {
|
|
76
|
+
if (lstatSync(current).isSymbolicLink()) return true;
|
|
77
|
+
} catch {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
function trackedPaths(repoRoot) {
|
|
84
|
+
try {
|
|
85
|
+
const out = execFileSync("git", ["ls-files", "-z", "--", "AGENTS.md", ".claude", ".outerlayer"], {
|
|
86
|
+
cwd: repoRoot,
|
|
87
|
+
encoding: "utf8",
|
|
88
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
89
|
+
timeout: 5e3
|
|
90
|
+
});
|
|
91
|
+
return new Set(out.split("\0").filter((path) => path !== ""));
|
|
92
|
+
} catch {
|
|
93
|
+
return void 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function isPin(text) {
|
|
97
|
+
try {
|
|
98
|
+
const value = JSON.parse(text);
|
|
99
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
100
|
+
const { schemaVersion, sha, ...rest } = value;
|
|
101
|
+
return Object.keys(rest).length === 0 && typeof schemaVersion === "number" && typeof sha === "string" && /^[0-9a-f]{40}$/.test(sha);
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function pinMayDiffer(repoRoot, args) {
|
|
107
|
+
try {
|
|
108
|
+
execFileSync("git", ["diff", "--quiet", ...args, "--", CONTEXT_PIN_FILENAME], { cwd: repoRoot, stdio: "ignore", timeout: 5e3 });
|
|
109
|
+
return false;
|
|
110
|
+
} catch {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function restorePin(repoRoot) {
|
|
115
|
+
try {
|
|
116
|
+
if (!isPin(readFileSync(join(repoRoot, CONTEXT_PIN_FILENAME), "utf8"))) return false;
|
|
117
|
+
if (pinMayDiffer(repoRoot, ["--cached"]) || !pinMayDiffer(repoRoot, [])) return false;
|
|
118
|
+
execFileSync("git", ["checkout", "--", CONTEXT_PIN_FILENAME], { cwd: repoRoot, stdio: "ignore", timeout: 5e3 });
|
|
119
|
+
return true;
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function pruneEmptyDirs(start, root) {
|
|
125
|
+
let current = start;
|
|
126
|
+
while (current !== root && current.startsWith(root)) {
|
|
127
|
+
try {
|
|
128
|
+
if (readdirSync(current).length > 0) return;
|
|
129
|
+
rmdirSync(current);
|
|
130
|
+
} catch {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
current = dirname(current);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function cleanupEarlierCopies(input) {
|
|
137
|
+
const { repoRoot, gitCommonDir } = input;
|
|
138
|
+
const result = { removedFiles: [], excludeRemoved: false, guardRemoved: false, pinRestored: false };
|
|
139
|
+
if (!hasEarlierCopies(gitCommonDir)) return result;
|
|
140
|
+
let complete = true;
|
|
141
|
+
try {
|
|
142
|
+
const manifest = readContextManifest(gitCommonDir);
|
|
143
|
+
if (manifest !== void 0) {
|
|
144
|
+
const tracked = trackedPaths(repoRoot);
|
|
145
|
+
if (tracked === void 0) return result;
|
|
146
|
+
const isTracked = (rel) => [...tracked].some((path) => path === rel || rel.startsWith(`${path}/`));
|
|
147
|
+
for (const rel of manifest.files) {
|
|
148
|
+
if (!isCopiedPath(rel) || isTracked(rel) || hasSymlinkComponent(repoRoot, rel)) continue;
|
|
149
|
+
const abs = join(repoRoot, rel);
|
|
150
|
+
if (!existsSync(abs)) continue;
|
|
151
|
+
try {
|
|
152
|
+
unlinkSync(abs);
|
|
153
|
+
result.removedFiles.push(rel);
|
|
154
|
+
pruneEmptyDirs(dirname(abs), repoRoot);
|
|
155
|
+
} catch {
|
|
156
|
+
complete = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
} catch {
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
if (!complete) return result;
|
|
164
|
+
result.pinRestored = restorePin(repoRoot);
|
|
165
|
+
try {
|
|
166
|
+
result.guardRemoved = removePreCommitGuardHook(repoRoot).removed;
|
|
167
|
+
result.excludeRemoved = removeContextExcludes(gitCommonDir).changed;
|
|
168
|
+
removeContextManifest(gitCommonDir);
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { cleanupEarlierCopies };
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { versionAtLeast, MINIMUM_CLAUDE_VERSION, SHIM_SCRIPT, CONTROL_PLANE_DIR_VARIABLE } from './chunk-G2YNJIGF.js';
|
|
4
4
|
export { MINIMUM_CLAUDE_VERSION } from './chunk-G2YNJIGF.js';
|
|
5
|
+
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
5
6
|
import './chunk-Z5GEFMRW.js';
|
|
6
7
|
import { spawnSync, execFileSync, spawn } from 'child_process';
|
|
7
8
|
import { existsSync, accessSync, constants, statSync, readFileSync } from 'fs';
|
|
@@ -20,7 +21,7 @@ function readDeliveryRecord(cwd) {
|
|
|
20
21
|
try {
|
|
21
22
|
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
22
23
|
if (typeof parsed.dir === "string" && isAbsolute(parsed.dir) && typeof parsed.repository === "string" && typeof parsed.sha === "string") {
|
|
23
|
-
return { kind: "found", record: { repository: parsed.repository, sha: parsed.sha, dir: parsed.dir } };
|
|
24
|
+
return { kind: "found", record: { repository: parsed.repository, sha: parsed.sha, dir: parsed.dir, launcher: parsed.launcher === true } };
|
|
24
25
|
}
|
|
25
26
|
} catch {
|
|
26
27
|
}
|
|
@@ -72,17 +73,29 @@ async function runClaudeLauncher(args, deps = {}) {
|
|
|
72
73
|
return 127;
|
|
73
74
|
}
|
|
74
75
|
const found = readDeliveryRecord(cwd);
|
|
75
|
-
|
|
76
|
-
if (found.kind === "invalid") {
|
|
76
|
+
const build = found.kind === "found" && found.record.launcher !== true ? found.record : void 0;
|
|
77
|
+
if (found.kind === "invalid" && env.OUTERLAYER_JOB_DIR !== void 0) {
|
|
77
78
|
stderr(`outerlayer claude: ${found.path} is not a readable delivery record, so the control plane cannot be attached
|
|
78
79
|
`);
|
|
79
80
|
return 1;
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
-
if (
|
|
83
|
-
|
|
82
|
+
let dir;
|
|
83
|
+
if (build !== void 0) {
|
|
84
|
+
dir = build.dir;
|
|
85
|
+
if (!existsSync(dir)) {
|
|
86
|
+
stderr(`outerlayer claude: the control plane of ${build.repository} is not at ${dir}, so it cannot be attached
|
|
84
87
|
`);
|
|
85
|
-
|
|
88
|
+
return 1;
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
const { resolveLaunchPlane } = await import('./control-plane-launch-34LNRJWR.js');
|
|
92
|
+
const plane = await resolveLaunchPlane({ cwd, env, home: homeFromEnv(env), fetchImpl: deps.fetchImpl, stderr });
|
|
93
|
+
if (plane.kind === "none") return run(claude, args, env, cwd, stderr);
|
|
94
|
+
if (plane.kind === "refused") {
|
|
95
|
+
stderr(plane.message);
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
dir = plane.dir;
|
|
86
99
|
}
|
|
87
100
|
const reported = spawnSync(claude, ["--version"], { env, encoding: "utf8", timeout: 15e3, stdio: ["ignore", "pipe", "ignore"] }).stdout ?? "";
|
|
88
101
|
if (/\d+\.\d+\.\d+/.test(reported) && !versionAtLeast(reported)) {
|