@outerlayer/cli 0.17.0 → 0.19.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/CHANGELOG.md +72 -0
- package/README.md +36 -2
- package/dist/agent-setup-TPR4BBFV.js +27 -0
- package/dist/{artifact-link-cmd-2F47LT7F.js → artifact-link-cmd-W7XF5BFB.js} +4 -3
- package/dist/{build-BG2YENGK.js → build-TQ6X5PYN.js} +5 -4
- package/dist/build-info.json +1 -1
- package/dist/{builder-2D3WSOOY.js → builder-C4QNTYMS.js} +5 -6
- package/dist/{check-5XE7XMC4.js → check-UWQAL2MN.js} +56 -52
- package/dist/{chunk-R7PF5OOU.js → chunk-3CWUOFV6.js} +21 -14
- package/dist/{chunk-4NPZVMJU.js → chunk-3UZTIRLF.js} +60 -4
- package/dist/chunk-452TM7J4.js +502 -0
- package/dist/{chunk-NNRTPG7X.js → chunk-5GHGAF6P.js} +4 -4
- package/dist/{chunk-WVUIRTWA.js → chunk-5MYFOW5V.js} +196 -37
- package/dist/{chunk-HGECYFEI.js → chunk-5TN7GLYX.js} +138 -109
- package/dist/{chunk-VQYBXPI7.js → chunk-6D7GT22T.js} +5 -5
- package/dist/{chunk-G5NPRL2K.js → chunk-6U3MV7TZ.js} +687 -76
- package/dist/{chunk-42ZI52JW.js → chunk-6X4SQ5MY.js} +4 -3
- package/dist/{chunk-MAK5LYRF.js → chunk-7KSSBQTS.js} +278 -535
- package/dist/{chunk-NWQTTSBB.js → chunk-7SJPQWBM.js} +41 -16
- package/dist/{chunk-J5M7BSJQ.js → chunk-7VUK5RFS.js} +23 -4
- package/dist/{chunk-OZGHL5Y5.js → chunk-7YP7T6GV.js} +2 -2
- package/dist/{chunk-TI7B7UEO.js → chunk-AMFWYESY.js} +1 -1
- package/dist/{chunk-YRYMNBGQ.js → chunk-ANPNT6PM.js} +2 -1
- package/dist/{chunk-4KSQKQXE.js → chunk-BM63HB2M.js} +20 -16
- package/dist/{chunk-4Q7OMKAT.js → chunk-BQXFBI7T.js} +81 -5
- package/dist/{chunk-ADJRGVZC.js → chunk-BWSUPRDK.js} +1 -1
- package/dist/{chunk-3NSNIIBE.js → chunk-CG36IONK.js} +18 -17
- package/dist/chunk-CJJDJ7AT.js +56 -0
- package/dist/chunk-CRB3POP4.js +34 -0
- package/dist/{chunk-LWSJQJC6.js → chunk-DADWEUH3.js} +7 -7
- package/dist/{chunk-KG5ECZGJ.js → chunk-DJ3ZUSC3.js} +11 -11
- package/dist/{chunk-F47JBIAW.js → chunk-DSF2FWAZ.js} +2 -1
- package/dist/{chunk-N5FOE5PS.js → chunk-ECODQ7II.js} +4 -33
- package/dist/{chunk-HHJDN6AU.js → chunk-ESVW4MJY.js} +1 -1
- package/dist/{chunk-YO4PSLVB.js → chunk-FVMYKL6L.js} +1 -1
- package/dist/chunk-G2YNJIGF.js +44 -0
- package/dist/{chunk-WUYTWNMA.js → chunk-G3IJ3N6F.js} +5 -3
- package/dist/{chunk-QKFB4K7X.js → chunk-GGOMT6KF.js} +1 -1
- package/dist/{chunk-N6LURUEF.js → chunk-GOSFARMS.js} +1 -1
- package/dist/{chunk-S3NYLI2P.js → chunk-HPJNLETG.js} +93 -38
- package/dist/{chunk-IP7BIBXJ.js → chunk-IF2OSI5T.js} +35 -1
- package/dist/{chunk-C5Y5ZJJZ.js → chunk-IXYZUUYQ.js} +5 -4
- package/dist/chunk-JBJTC3UU.js +35 -0
- package/dist/chunk-KYS3TQAG.js +296 -0
- package/dist/chunk-LLM3I5YU.js +89 -0
- package/dist/{chunk-YU3VKZ5F.js → chunk-LRG3ZMZD.js} +6 -7
- package/dist/{chunk-V7NIVOFD.js → chunk-M2ZWWTWZ.js} +1 -1
- package/dist/{chunk-ERI5GBNI.js → chunk-MLAAT4S6.js} +3 -3
- package/dist/{chunk-O765JR4W.js → chunk-MTP2QEVO.js} +1 -1
- package/dist/{chunk-ZM2IMMYN.js → chunk-N2PXGQRL.js} +9 -1
- package/dist/{chunk-BWQ66M6N.js → chunk-NFIR3GEE.js} +98 -24
- package/dist/{chunk-POJMEEJJ.js → chunk-NNLA7LLQ.js} +1 -1
- package/dist/{chunk-PLMTLGYH.js → chunk-NTRCK4NH.js} +5 -4
- package/dist/{chunk-22RMZBGW.js → chunk-P53VEAOF.js} +1 -1
- package/dist/{chunk-RLYZLUQ7.js → chunk-QEFKA2QD.js} +2 -2
- package/dist/{chunk-JXYVA45C.js → chunk-QNLX477Q.js} +1200 -322
- package/dist/{chunk-UGP76IZ5.js → chunk-S5PCA3SN.js} +1 -1
- package/dist/{chunk-RMWLBUCJ.js → chunk-SADUQSO4.js} +1 -1
- package/dist/{chunk-GQD22KKN.js → chunk-T2Q7ISPE.js} +2 -1
- package/dist/chunk-TUSYOL2O.js +113 -0
- package/dist/{chunk-NBGDBTO2.js → chunk-TWF3RICI.js} +9 -8
- package/dist/{chunk-ONKJUM6R.js → chunk-UVG35MWF.js} +1 -1
- package/dist/{chunk-KMDLFI4P.js → chunk-VMJPFQNE.js} +1 -1
- package/dist/chunk-VRRGENS4.js +144 -0
- package/dist/{chunk-PTW6W5NR.js → chunk-VYAL7PUE.js} +1 -1
- package/dist/{chunk-OHVJA253.js → chunk-WFSUUUAN.js} +47 -30
- package/dist/{chunk-RSNSZ2LJ.js → chunk-X5H2WYMB.js} +1 -1
- package/dist/{chunk-HYZRY4KZ.js → chunk-XNGMQ27R.js} +16 -6
- package/dist/chunk-XSZD4AZ6.js +490 -0
- package/dist/chunk-YQR6E6OV.js +109 -0
- package/dist/{chunk-XCK2YAY5.js → chunk-YVZJ6GKF.js} +3 -2
- package/dist/{chunk-2MNPHL23.js → chunk-ZHAUSEEN.js} +38 -15
- package/dist/claude-launcher-FPPHZPMR.js +115 -0
- package/dist/{cli-A76AXELQ.js → cli-HROW5T7X.js} +567 -285
- package/dist/{command-R2QCVX55.js → command-OEAV7BVX.js} +42 -40
- package/dist/{config-N3C6DFQA.js → config-CLSGABD5.js} +2 -3
- package/dist/{connect-cmd-JBKAQNSF.js → connect-cmd-UNYKGDAL.js} +10 -9
- package/dist/context-cleanup-HSVYDGMI.js +9 -0
- package/dist/control-plane-launch-NYVDJESK.js +216 -0
- package/dist/{dist-LKDWQWZ7.js → dist-WO7NOJNG.js} +2 -2
- package/dist/{docker-4J77Q2BF.js → docker-BFU3AQGY.js} +7 -8
- package/dist/{doctor-4TAIARIG.js → doctor-23BBJWBX.js} +48 -42
- package/dist/{emit-artifact-cmd-MPZVR56N.js → emit-artifact-cmd-O6SCM7TV.js} +27 -24
- package/dist/emit-cmd-7SP3I6UZ.js +14 -0
- package/dist/{emit-criteria-cmd-EFGYI23V.js → emit-criteria-cmd-LQNERZRV.js} +17 -16
- package/dist/{emit-finding-cmd-5GF3V4LR.js → emit-finding-cmd-AJPKHIOV.js} +18 -17
- package/dist/{emit-result-cmd-I4OADKMD.js → emit-result-cmd-RUICOKWQ.js} +22 -19
- package/dist/emit-step-cmd-347XNGPQ.js +26 -0
- package/dist/{exec-client-CQV746UF.js → exec-client-7UMESIE2.js} +3 -4
- package/dist/governing-source-V5EEGPTA.js +34 -0
- package/dist/guest-init-KPBQOFE5.js +9 -0
- package/dist/{hook-fast-R4FVSZ2H.js → hook-fast-YAZG5MDX.js} +5 -2
- package/dist/host-key-U4B5QETR.js +8 -0
- package/dist/{import-capture-cmd-EQ35EARA.js → import-capture-cmd-KKFFOGWP.js} +7 -5
- package/dist/{import-ruler-cmd-BGAZXCQM.js → import-ruler-cmd-5P6JOXQN.js} +5 -3
- package/dist/index.js +8 -4
- package/dist/{init-PWU5YVL7.js → init-LWHDMZQG.js} +40 -38
- package/dist/init-MOINY2DD.js +53 -0
- package/dist/{init-cmd-XAVO7HYZ.js → init-cmd-HSMRID6A.js} +75 -30
- package/dist/{init-update-CVCWD6VS.js → init-update-LWX5MPPR.js} +29 -29
- package/dist/{install-HDBIPHTX.js → install-4SEFIIW2.js} +4 -5
- package/dist/{install-cmd-5HYMXLEW.js → install-cmd-QDOTR4OM.js} +5 -4
- package/dist/{login-browser-QZCS3WW6.js → login-browser-DX35MARZ.js} +5 -4
- package/dist/{logout-cmd-QAUFDJ6J.js → logout-cmd-5V5MMBSY.js} +3 -2
- package/dist/{logs-H55NWW4H.js → logs-AMLKC3VP.js} +3 -1
- package/dist/loop-SYYPVFYW.js +77 -0
- package/dist/machine-6X63G2KH.js +48 -0
- package/dist/{mcp-install-cmd-FDTPQQS6.js → mcp-install-cmd-GGWB3JJ2.js} +3 -2
- package/dist/{mcp-serve-cmd-3KVYEUXG.js → mcp-serve-cmd-N3UTY6EE.js} +11 -9
- package/dist/paths-7XP63OAX.js +7 -0
- package/dist/pending-532ABZYC.js +8 -0
- package/dist/{pidfile-UZRH774M.js → pidfile-3DM4OBKO.js} +4 -2
- package/dist/{record-C43U4PKS.js → record-3WP6V2K5.js} +3 -2
- package/dist/{runner-env-EN7YE7QX.js → runner-env-FRZFFHDF.js} +5 -6
- package/dist/{runner-key-6SLBI7PP.js → runner-key-276SJU5R.js} +40 -38
- package/dist/session-sender-GGIY5OAX.js +36 -0
- package/dist/{pending-MXLSRYMO.js → shell-function-NRD4KVUK.js} +1 -2
- package/dist/spec-cmd-SIZBRN7D.js +115 -0
- package/dist/{starter-pack-KF66HGZR.js → starter-pack-6LQVLBIA.js} +7 -5
- package/dist/{status-7VNQN5PW.js → status-NAK6DYSF.js} +46 -42
- package/dist/{statusline-fast-SVTMBMD7.js → statusline-fast-KN3BX67H.js} +2 -1
- package/dist/sync-cmd-G7GF4UTW.js +35 -0
- package/dist/{watch-23HSAEI6.js → watch-EVM5GSMP.js} +22 -15
- package/dist/{work-claim-cmd-LKL3GHFQ.js → work-claim-cmd-3J3QW56U.js} +26 -29
- package/dist/work-cmd-5EPPD33Y.js +24 -0
- package/dist/{work-comment-cmd-AWHP56M2.js → work-comment-cmd-2ACOZQAE.js} +16 -15
- package/dist/{work-launch-R5HTAP6X.js → work-launch-LEQ2MPM3.js} +3 -1
- package/dist/work-logs-cmd-QDD2NMJL.js +60 -0
- package/dist/{work-open-pr-cmd-IOM4AVQQ.js → work-open-pr-cmd-XNCEI4ZM.js} +18 -17
- package/dist/work-pr-cmd-H4OQR26N.js +25 -0
- package/package.json +3 -2
- package/skill-pack/maintained/outerlayer-amend/SKILL.md +4 -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 +18 -2
- package/skill-pack/template/build/SKILL.md +23 -10
- package/skill-pack/template/build/references/agent-briefs.md +3 -1
- package/skill-pack/template/build/references/criteria-judge.md +27 -0
- package/skill-pack/template/build/references/release.md +22 -29
- package/skill-pack/template/spec/SKILL.md +35 -10
- package/skill-pack/validators/acceptance-criteria.yaml +25 -26
- package/dist/agent-setup-T624CWPD.js +0 -27
- package/dist/chunk-6Y5RUTHO.js +0 -39
- package/dist/chunk-BYT5O5RV.js +0 -61
- package/dist/chunk-WTE3MQML.js +0 -133
- package/dist/chunk-XCCLFVXM.js +0 -401
- package/dist/chunk-YZ5F4PIS.js +0 -797
- package/dist/context-adopt-NFHCLVUB.js +0 -108
- package/dist/context-materialize-IV2TUUFO.js +0 -22
- package/dist/emit-cmd-IJ3GVRFD.js +0 -12
- package/dist/guest-init-LJP5GPZF.js +0 -9
- package/dist/host-key-YMLXY6QB.js +0 -7
- package/dist/init-6XPDRDTC.js +0 -51
- package/dist/loop-FK3LPMMZ.js +0 -73
- package/dist/machine-SQXEBAM2.js +0 -46
- package/dist/paths-OYKMVYJP.js +0 -6
- package/dist/session-sender-FO3LCREV.js +0 -29
- package/dist/sync-cmd-GVPPFZ3G.js +0 -28
- package/dist/work-cmd-Z2WXLZPH.js +0 -23
- package/dist/work-pr-cmd-HNEUIEN7.js +0 -24
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { removeRetiredSkills } from './chunk-IXYZUUYQ.js';
|
|
4
|
+
import { defaultFetch } from './chunk-FVMYKL6L.js';
|
|
5
|
+
import { resolveGatewayCredentials } from './chunk-NTRCK4NH.js';
|
|
6
|
+
import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
|
|
7
|
+
import { loadMaintainedFiles, writeMaintainedFiles } from './chunk-NNLA7LLQ.js';
|
|
8
|
+
import { normalizeRepoName, parseOuterlayerConfig, classifyTree, emitTree } from './chunk-WFSUUUAN.js';
|
|
9
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
10
|
+
import { writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, writeContextManifest, SOURCE_CACHE_TTL_SUCCESS_MS, readSourceCache, isSourceCacheFresh, clearDegraded } from './chunk-YQR6E6OV.js';
|
|
11
|
+
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
12
|
+
import { withTokenHeader } from './chunk-BQXFBI7T.js';
|
|
13
|
+
import { execFileSync } from 'child_process';
|
|
14
|
+
import { existsSync, mkdirSync, writeFileSync, chmodSync, lstatSync, readFileSync, copyFileSync } from 'fs';
|
|
15
|
+
import { isAbsolute, join, dirname } from 'path';
|
|
16
|
+
|
|
17
|
+
createRequire(import.meta.url);
|
|
18
|
+
var CONFIG_PATH = ".outerlayer/config.json";
|
|
19
|
+
var CONTENT_KINDS = /* @__PURE__ */ new Set(["skill", "skill-reference"]);
|
|
20
|
+
function overlayMaintainedSkills(repoRoot, unsafe) {
|
|
21
|
+
const sources = loadMaintainedFiles().filter((file) => !unsafe(file.path));
|
|
22
|
+
writeMaintainedFiles(repoRoot, sources);
|
|
23
|
+
const paths = sources.map((file) => file.path);
|
|
24
|
+
const configAbs = join(repoRoot, CONFIG_PATH);
|
|
25
|
+
if (!existsSync(configAbs)) return paths;
|
|
26
|
+
const config = parseOuterlayerConfig(readFileSync(configAbs, "utf8"));
|
|
27
|
+
if (!config.ok || !config.config) return paths;
|
|
28
|
+
const { entries } = classifyTree(sources.map((file) => file.path));
|
|
29
|
+
const input = {
|
|
30
|
+
entries,
|
|
31
|
+
contents: new Map(entries.filter((e) => CONTENT_KINDS.has(e.kind)).map((e) => [e.path, sources.find((f) => f.path === e.path).content])),
|
|
32
|
+
assetPaths: [],
|
|
33
|
+
targets: config.config.targets
|
|
34
|
+
};
|
|
35
|
+
const compiled = emitTree(input);
|
|
36
|
+
if (compiled.errors.length > 0) return paths;
|
|
37
|
+
for (const file of compiled.files) {
|
|
38
|
+
if (unsafe(file.path)) continue;
|
|
39
|
+
const abs = join(repoRoot, file.path);
|
|
40
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
41
|
+
if (!existsSync(abs) || readFileSync(abs, "utf8") !== file.content) writeFileSync(abs, file.content);
|
|
42
|
+
paths.push(file.path);
|
|
43
|
+
}
|
|
44
|
+
for (const copy of compiled.copies) {
|
|
45
|
+
if (unsafe(copy.toPath)) continue;
|
|
46
|
+
const abs = join(repoRoot, copy.toPath);
|
|
47
|
+
mkdirSync(dirname(abs), { recursive: true });
|
|
48
|
+
copyFileSync(join(repoRoot, copy.fromSourcePath), abs);
|
|
49
|
+
paths.push(copy.toPath);
|
|
50
|
+
}
|
|
51
|
+
return paths;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/context-materialize.ts
|
|
55
|
+
var defaultGitRunner = (args, opts) => {
|
|
56
|
+
try {
|
|
57
|
+
const stdout = execFileSync("git", args, {
|
|
58
|
+
cwd: opts.cwd,
|
|
59
|
+
timeout: opts.timeoutMs,
|
|
60
|
+
input: opts.input,
|
|
61
|
+
// Control-plane trees are small config/doc surfaces (AGENTS.md,
|
|
62
|
+
// .claude/**, .outerlayer/**) — generous but bounded so a runaway
|
|
63
|
+
// cat-file stream can't exhaust memory.
|
|
64
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
65
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
66
|
+
env: (opts.env ?? ((base) => base))({
|
|
67
|
+
...process.env,
|
|
68
|
+
// classifyGitFailure greps English stderr substrings
|
|
69
|
+
// ("Authentication failed", "Permission denied", …) — a git running
|
|
70
|
+
// under a non-English locale would translate those and silently
|
|
71
|
+
// misclassify every failure as "unreachable" instead of "no-access".
|
|
72
|
+
LC_ALL: "C",
|
|
73
|
+
// A bare https:// remote with no cached credential answer otherwise
|
|
74
|
+
// blocks on an interactive username/password prompt with no
|
|
75
|
+
// terminal to read from here, hanging until OUR OWN timeout instead
|
|
76
|
+
// of failing fast with a classifiable stderr message.
|
|
77
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
78
|
+
})
|
|
79
|
+
});
|
|
80
|
+
return { ok: true, stdout: Buffer.isBuffer(stdout) ? stdout : Buffer.from(stdout), stderr: "" };
|
|
81
|
+
} catch (err) {
|
|
82
|
+
const e = err;
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
stdout: e.stdout ? Buffer.from(e.stdout) : Buffer.alloc(0),
|
|
86
|
+
stderr: e.stderr ? Buffer.from(e.stderr).toString("utf8") : e.message ?? String(err)
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
function gitText(git, cwd, args, timeoutMs) {
|
|
91
|
+
const result = git(args, { cwd, timeoutMs });
|
|
92
|
+
return result.ok ? result.stdout.toString("utf8").trim() : void 0;
|
|
93
|
+
}
|
|
94
|
+
var GATEWAY_TOO_OLD_MESSAGE = "the OuterLayer this machine talks to is too old to name the control plane \u2014 ask whoever runs it to upgrade; context written earlier is kept";
|
|
95
|
+
var CANNOT_IDENTIFY_MESSAGE = "this repository is governed, but the control plane cannot be identified \u2014 check OuterLayer connectivity/config";
|
|
96
|
+
function designationAuthRejectedMessage(credential) {
|
|
97
|
+
return credential.startsWith("olu_") ? `the OuterLayer login was rejected (401/403) \u2014 run \`${cliInvocation()} login\` to sign in again` : "the OuterLayer API key was rejected (401/403) \u2014 check apiKey in ~/.outerlayer/config.json";
|
|
98
|
+
}
|
|
99
|
+
var PARTIAL_WRITE_MESSAGE = "control-plane content could not be fully written";
|
|
100
|
+
var OVERLAY_FAILED_MESSAGE = "control-plane content was written but the maintained skills could not be refreshed";
|
|
101
|
+
function isStagingWriteFault(message) {
|
|
102
|
+
return message === PARTIAL_WRITE_MESSAGE || message === OVERLAY_FAILED_MESSAGE;
|
|
103
|
+
}
|
|
104
|
+
function hasSymlinkComponent(root, relPath) {
|
|
105
|
+
let current = root;
|
|
106
|
+
for (const segment of relPath.split("/")) {
|
|
107
|
+
current = join(current, segment);
|
|
108
|
+
let st;
|
|
109
|
+
try {
|
|
110
|
+
st = lstatSync(current);
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (st.isSymbolicLink()) return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function unreachableMessage() {
|
|
119
|
+
return "the control plane is unreachable";
|
|
120
|
+
}
|
|
121
|
+
function noAccessMessage() {
|
|
122
|
+
return "you do not have access to the control plane \u2014 check your git credentials (SSH key or token) and org/SSO access, then retry";
|
|
123
|
+
}
|
|
124
|
+
function classifyGitFailure(stderr) {
|
|
125
|
+
if (/authentication failed|permission denied \(publickey\)|\b403\b|saml sso|access denied/i.test(stderr)) {
|
|
126
|
+
return "no-access";
|
|
127
|
+
}
|
|
128
|
+
return "unreachable";
|
|
129
|
+
}
|
|
130
|
+
async function materializeContext(deps) {
|
|
131
|
+
const home = deps.home ?? homeFromEnv();
|
|
132
|
+
const now = deps.now ?? Date.now;
|
|
133
|
+
const git = deps.git ?? defaultGitRunner;
|
|
134
|
+
const fetchImpl = deps.fetchImpl ?? defaultFetch;
|
|
135
|
+
const repoRoot = gitText(git, deps.cwd, ["rev-parse", "--show-toplevel"], 2e3);
|
|
136
|
+
if (repoRoot === void 0) {
|
|
137
|
+
return { status: "not-a-repo", sha: null, verification: "none" };
|
|
138
|
+
}
|
|
139
|
+
const gitCommonDir = resolveGitCommonDir(git, repoRoot);
|
|
140
|
+
if (gitCommonDir === void 0) {
|
|
141
|
+
return { status: "not-a-repo", sha: null, verification: "none" };
|
|
142
|
+
}
|
|
143
|
+
const record = (sha2, verification, repository2, ref2) => {
|
|
144
|
+
if (deps.sessionId === void 0) return;
|
|
145
|
+
appendContextProvenance(
|
|
146
|
+
{ t: new Date(now()).toISOString(), sessionId: deps.sessionId, repoRoot, repository: repository2, ref: ref2, sha: sha2, verification },
|
|
147
|
+
home
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
const selfOutcome = () => {
|
|
151
|
+
clearDegraded(gitCommonDir);
|
|
152
|
+
return { status: "self", sha: null, verification: "none" };
|
|
153
|
+
};
|
|
154
|
+
const ownRepoName = deriveOwnRepoName(git, repoRoot);
|
|
155
|
+
if (ownRepoName === void 0) {
|
|
156
|
+
return selfOutcome();
|
|
157
|
+
}
|
|
158
|
+
const designation = deps.pinnedSource === void 0 ? await resolveDesignation({ git, fetchImpl, home, cloud: deps.cloud, now, gitCommonDir, ownRepoName, repoRoot, lookup: deps.designationLookup ?? { timeoutMs: 2e3, attempts: 1 } }) : deps.pinnedSource === null ? { status: "self" } : { status: "governed", ...deps.pinnedSource };
|
|
159
|
+
const answered = { designation: "answered" };
|
|
160
|
+
if (designation.status === "self") {
|
|
161
|
+
if (designation.unanswered !== void 0) {
|
|
162
|
+
const { authRejected, gatewayTooOld } = designation.unanswered;
|
|
163
|
+
const message = authRejected ?? (gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : void 0);
|
|
164
|
+
if (message !== void 0) {
|
|
165
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "designation-unverified", message });
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
status: "self",
|
|
169
|
+
sha: null,
|
|
170
|
+
verification: "none",
|
|
171
|
+
designation: "unknown",
|
|
172
|
+
...authRejected ? { authRejected: true } : {},
|
|
173
|
+
...message !== void 0 && !authRejected ? { message } : {}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return { ...selfOutcome(), ...answered };
|
|
177
|
+
}
|
|
178
|
+
if (designation.status === "unknown") {
|
|
179
|
+
const message = designation.authRejected ?? (designation.gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : CANNOT_IDENTIFY_MESSAGE);
|
|
180
|
+
if (designation.authRejected || designation.gatewayTooOld) {
|
|
181
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "designation-unverified", message });
|
|
182
|
+
}
|
|
183
|
+
writeSourceCache(gitCommonDir, {
|
|
184
|
+
checkedAt: new Date(now()).toISOString(),
|
|
185
|
+
status: "self",
|
|
186
|
+
ttlMs: SOURCE_CACHE_TTL_RETRY_MS,
|
|
187
|
+
unanswered: {
|
|
188
|
+
...designation.authRejected ? { authRejected: designation.authRejected } : {},
|
|
189
|
+
...designation.gatewayTooOld ? { gatewayTooOld: true } : {}
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
return {
|
|
193
|
+
status: "self",
|
|
194
|
+
sha: null,
|
|
195
|
+
verification: "none",
|
|
196
|
+
designation: "unknown",
|
|
197
|
+
...designation.authRejected ? { authRejected: true } : {},
|
|
198
|
+
...designation.gatewayTooOld ? { message } : {},
|
|
199
|
+
lookupFailure: designation.lookupFailure
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const repository = designation.repository;
|
|
203
|
+
const ref = designation.ref;
|
|
204
|
+
const unverifiedIdentity = designation.unverifiedIdentity;
|
|
205
|
+
const storedSha = designation.sha;
|
|
206
|
+
const clearOrFlagIdentity = () => {
|
|
207
|
+
if (unverifiedIdentity) {
|
|
208
|
+
writeDegraded(gitCommonDir, {
|
|
209
|
+
at: new Date(now()).toISOString(),
|
|
210
|
+
kind: "designation-unverified",
|
|
211
|
+
message: designation.gatewayTooOld ? GATEWAY_TOO_OLD_MESSAGE : CANNOT_IDENTIFY_MESSAGE,
|
|
212
|
+
repository,
|
|
213
|
+
ref
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
clearDegraded(gitCommonDir);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const remoteUrl = deps.resolveControlPlaneUrl ? deps.resolveControlPlaneUrl(repository, ref, repoRoot) : buildControlPlaneUrl(git, repoRoot, repository);
|
|
220
|
+
const cacheHost = parseRemoteHost(remoteUrl).host || "unknown-host";
|
|
221
|
+
const cacheRepoDir = ensureBareCache(git, home, repository, cacheHost);
|
|
222
|
+
const localRef = `refs/outerlayer/sha-${sanitizeRefName(storedSha)}`;
|
|
223
|
+
const wanted = `+${storedSha}:${localRef}`;
|
|
224
|
+
const access = await deps.controlPlaneAccess?.([{ repository, ref }]);
|
|
225
|
+
const token = access !== void 0 && normalizeRepoName(access.repository) === normalizeRepoName(repository) ? access.token : void 0;
|
|
226
|
+
const fetchResult = git(["fetch", "--depth", "1", remoteUrl, wanted], {
|
|
227
|
+
cwd: cacheRepoDir,
|
|
228
|
+
timeoutMs: 1e4,
|
|
229
|
+
...token === void 0 ? {} : { env: (base) => withTokenHeader(base, remoteUrl, token) }
|
|
230
|
+
});
|
|
231
|
+
const commitNote = (message) => `could not fetch commit \`${storedSha.slice(0, 7)}\` of ${repository}; ${message}`;
|
|
232
|
+
if (!fetchResult.ok) {
|
|
233
|
+
const kind = classifyGitFailure(fetchResult.stderr);
|
|
234
|
+
const doctorMessage = commitNote(kind === "no-access" ? noAccessMessage() : unreachableMessage());
|
|
235
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind, message: doctorMessage, repository, ref });
|
|
236
|
+
record(null, "none", repository, ref);
|
|
237
|
+
return { status: kind, message: doctorMessage, sha: null, verification: "none" };
|
|
238
|
+
}
|
|
239
|
+
const fetchedSha = gitText(git, cacheRepoDir, ["rev-parse", localRef], 2e3);
|
|
240
|
+
if (fetchedSha !== storedSha) {
|
|
241
|
+
const doctorMessage = commitNote(unreachableMessage());
|
|
242
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: doctorMessage, repository, ref });
|
|
243
|
+
record(null, "none", repository, ref);
|
|
244
|
+
return { status: "unreachable", message: doctorMessage, sha: null, verification: "none" };
|
|
245
|
+
}
|
|
246
|
+
const sha = fetchedSha;
|
|
247
|
+
const files = listMaterializedFiles(git, cacheRepoDir, sha);
|
|
248
|
+
const writeResult = writeFilesVerbatim(git, cacheRepoDir, files, repoRoot);
|
|
249
|
+
const partialWrite = () => {
|
|
250
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: PARTIAL_WRITE_MESSAGE, repository, ref });
|
|
251
|
+
record(null, "none", repository, ref);
|
|
252
|
+
return { status: "unreachable", message: PARTIAL_WRITE_MESSAGE, sha: null, verification: "none" };
|
|
253
|
+
};
|
|
254
|
+
if (!writeResult.ok) {
|
|
255
|
+
return partialWrite();
|
|
256
|
+
}
|
|
257
|
+
let overlayPaths = [];
|
|
258
|
+
let retiredPaths = /* @__PURE__ */ new Set();
|
|
259
|
+
let overlayFailed = false;
|
|
260
|
+
try {
|
|
261
|
+
retiredPaths = new Set(removeRetiredSkills(repoRoot, (rel) => hasSymlinkComponent(repoRoot, rel)));
|
|
262
|
+
overlayPaths = overlayMaintainedSkills(repoRoot, (rel) => hasSymlinkComponent(repoRoot, rel));
|
|
263
|
+
} catch {
|
|
264
|
+
overlayFailed = true;
|
|
265
|
+
}
|
|
266
|
+
const writtenPaths = [.../* @__PURE__ */ new Set([...writeResult.writtenPaths, ...overlayPaths])].filter((path) => !retiredPaths.has(path));
|
|
267
|
+
if (overlayFailed) {
|
|
268
|
+
writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: OVERLAY_FAILED_MESSAGE, repository, ref });
|
|
269
|
+
record(sha, "unverified", repository, ref);
|
|
270
|
+
return { status: "unreachable", message: OVERLAY_FAILED_MESSAGE, sha, verification: "unverified" };
|
|
271
|
+
}
|
|
272
|
+
writeContextManifest(gitCommonDir, { schemaVersion: 1, sha, files: writtenPaths, materializedAt: new Date(now()).toISOString() });
|
|
273
|
+
clearOrFlagIdentity();
|
|
274
|
+
writeSourceCache(gitCommonDir, {
|
|
275
|
+
checkedAt: new Date(now()).toISOString(),
|
|
276
|
+
status: "governed",
|
|
277
|
+
repository,
|
|
278
|
+
ref,
|
|
279
|
+
sha: storedSha,
|
|
280
|
+
ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
|
|
281
|
+
});
|
|
282
|
+
record(sha, "verified", repository, ref);
|
|
283
|
+
return { status: "materialized", sha, verification: "verified" };
|
|
284
|
+
}
|
|
285
|
+
async function resolveDesignation(ctx) {
|
|
286
|
+
const cache = readSourceCache(ctx.gitCommonDir);
|
|
287
|
+
if (cache && cache.status === "self" && isSourceCacheFresh(cache, ctx.now())) {
|
|
288
|
+
return { status: "self", unanswered: cache.unanswered };
|
|
289
|
+
}
|
|
290
|
+
let authRejected;
|
|
291
|
+
let lookupFailure;
|
|
292
|
+
let gatewayTooOld = false;
|
|
293
|
+
const destination = resolveGatewayCredentials({
|
|
294
|
+
home: ctx.home,
|
|
295
|
+
env: {},
|
|
296
|
+
cwd: ctx.repoRoot,
|
|
297
|
+
...ctx.cloud === void 0 ? {} : { url: ctx.cloud.url, apiKey: ctx.cloud.apiKey, appId: ctx.cloud.appId }
|
|
298
|
+
});
|
|
299
|
+
if (destination.ok) {
|
|
300
|
+
const lookup = await fetchContextSource(
|
|
301
|
+
{ url: destination.url, apiKey: destination.credential, appId: destination.appId },
|
|
302
|
+
ctx.ownRepoName,
|
|
303
|
+
ctx.fetchImpl,
|
|
304
|
+
ctx.lookup
|
|
305
|
+
);
|
|
306
|
+
if (lookup.kind === "rejected") authRejected = designationAuthRejectedMessage(destination.credential);
|
|
307
|
+
if (lookup.kind === "failed") lookupFailure = lookup.failure;
|
|
308
|
+
if (lookup.kind === "answered") {
|
|
309
|
+
if (lookup.source === null) {
|
|
310
|
+
writeSourceCache(ctx.gitCommonDir, {
|
|
311
|
+
checkedAt: new Date(ctx.now()).toISOString(),
|
|
312
|
+
status: "self",
|
|
313
|
+
ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
|
|
314
|
+
});
|
|
315
|
+
return { status: "self" };
|
|
316
|
+
}
|
|
317
|
+
if (lookup.source !== void 0) {
|
|
318
|
+
return { status: "governed", repository: lookup.source.repository, ref: lookup.source.ref, sha: lookup.source.sha };
|
|
319
|
+
}
|
|
320
|
+
gatewayTooOld = true;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (cache?.status === "self") {
|
|
324
|
+
return cache.unanswered !== void 0 || authRejected !== void 0 || gatewayTooOld ? {
|
|
325
|
+
status: "self",
|
|
326
|
+
unanswered: { ...cache.unanswered, ...authRejected ? { authRejected } : {}, ...gatewayTooOld ? { gatewayTooOld } : {} }
|
|
327
|
+
} : { status: "self" };
|
|
328
|
+
}
|
|
329
|
+
if (cache?.repository && cache.ref && cache.sha !== void 0) {
|
|
330
|
+
return { status: "governed", repository: cache.repository, ref: cache.ref, sha: cache.sha, unverifiedIdentity: true, ...gatewayTooOld ? { gatewayTooOld } : {} };
|
|
331
|
+
}
|
|
332
|
+
return { status: "unknown", authRejected, gatewayTooOld, lookupFailure };
|
|
333
|
+
}
|
|
334
|
+
async function lookupGoverningSource(config, repository, fetchImpl, lookup) {
|
|
335
|
+
return fetchContextSource(config, repository, fetchImpl, lookup);
|
|
336
|
+
}
|
|
337
|
+
async function fetchContextSource(config, ownRepoName, fetchImpl, lookup) {
|
|
338
|
+
const url = `${config.url.replace(/\/$/, "")}/v1/context/source?repo=${encodeURIComponent(ownRepoName)}`;
|
|
339
|
+
for (let attempt = 1; ; attempt++) {
|
|
340
|
+
const outcome = await askContextSource(url, config, fetchImpl, lookup.timeoutMs);
|
|
341
|
+
if (outcome.kind !== "failed" || !isRetryable(outcome.failure) || attempt >= lookup.attempts) return outcome;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function isRetryable(failure) {
|
|
345
|
+
return failure.kind !== "status" || failure.status >= 500;
|
|
346
|
+
}
|
|
347
|
+
async function askContextSource(url, config, fetchImpl, timeoutMs) {
|
|
348
|
+
const controller = new AbortController();
|
|
349
|
+
let timedOut = false;
|
|
350
|
+
const timer = setTimeout(() => {
|
|
351
|
+
timedOut = true;
|
|
352
|
+
controller.abort();
|
|
353
|
+
}, timeoutMs);
|
|
354
|
+
try {
|
|
355
|
+
const res = await fetchImpl(url, {
|
|
356
|
+
headers: { Authorization: `Bearer ${config.apiKey}`, "x-outerlayer-app-id": config.appId },
|
|
357
|
+
signal: controller.signal
|
|
358
|
+
});
|
|
359
|
+
if (res.status === 401 || res.status === 403) {
|
|
360
|
+
return { kind: "rejected" };
|
|
361
|
+
}
|
|
362
|
+
if (!res.ok) return { kind: "failed", failure: { kind: "status", status: res.status } };
|
|
363
|
+
const body = await res.json();
|
|
364
|
+
const data = body.data;
|
|
365
|
+
const source = validSource(data?.source);
|
|
366
|
+
if (typeof data !== "object" || data === null) {
|
|
367
|
+
return { kind: "failed", failure: { kind: "network", message: "the answer held no data" } };
|
|
368
|
+
}
|
|
369
|
+
return { kind: "answered", source };
|
|
370
|
+
} catch (err) {
|
|
371
|
+
return {
|
|
372
|
+
kind: "failed",
|
|
373
|
+
failure: timedOut ? { kind: "timeout", timeoutMs } : { kind: "network", message: err instanceof Error ? err.message : String(err) }
|
|
374
|
+
};
|
|
375
|
+
} finally {
|
|
376
|
+
clearTimeout(timer);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function validSource(source) {
|
|
380
|
+
if (source === null) return null;
|
|
381
|
+
const candidate = source;
|
|
382
|
+
if (typeof candidate?.repository === "string" && typeof candidate.ref === "string" && typeof candidate.sha === "string") {
|
|
383
|
+
return { repository: candidate.repository, ref: candidate.ref, sha: candidate.sha };
|
|
384
|
+
}
|
|
385
|
+
return void 0;
|
|
386
|
+
}
|
|
387
|
+
function resolveGitCommonDir(git, repoRoot) {
|
|
388
|
+
const abs = gitText(git, repoRoot, ["rev-parse", "--path-format=absolute", "--git-common-dir"], 2e3);
|
|
389
|
+
if (abs !== void 0) return abs;
|
|
390
|
+
const rel = gitText(git, repoRoot, ["rev-parse", "--git-common-dir"], 2e3);
|
|
391
|
+
if (rel === void 0) return void 0;
|
|
392
|
+
return isAbsolute(rel) ? rel : join(repoRoot, rel);
|
|
393
|
+
}
|
|
394
|
+
function deriveOwnRepoName(git, repoRoot) {
|
|
395
|
+
const url = gitText(git, repoRoot, ["config", "--get", "remote.origin.url"], 2e3);
|
|
396
|
+
if (url === void 0) return void 0;
|
|
397
|
+
return parseOwnerRepo(url);
|
|
398
|
+
}
|
|
399
|
+
function parseOwnerRepo(url) {
|
|
400
|
+
const stripped = url.replace(/\.git$/, "");
|
|
401
|
+
const scpMatch = stripped.match(/^[\w.-]+@[\w.-]+:(.+)$/);
|
|
402
|
+
if (scpMatch) return scpMatch[1];
|
|
403
|
+
try {
|
|
404
|
+
const parsed = new URL(stripped);
|
|
405
|
+
return parsed.pathname.replace(/^\//, "");
|
|
406
|
+
} catch {
|
|
407
|
+
return void 0;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function parseRemoteHost(url) {
|
|
411
|
+
const scpMatch = url.match(/^([\w.-]+)@([\w.-]+):/);
|
|
412
|
+
if (scpMatch) return { scheme: "ssh", host: scpMatch[2] };
|
|
413
|
+
try {
|
|
414
|
+
const parsed = new URL(url);
|
|
415
|
+
return { scheme: parsed.protocol === "https:" ? "https" : "ssh", host: parsed.host };
|
|
416
|
+
} catch {
|
|
417
|
+
return { scheme: "https", host: "github.com" };
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
function buildControlPlaneUrl(git, repoRoot, repository) {
|
|
421
|
+
const ownUrl = gitText(git, repoRoot, ["config", "--get", "remote.origin.url"], 2e3);
|
|
422
|
+
const { scheme, host } = ownUrl ? parseRemoteHost(ownUrl) : { scheme: "https", host: "github.com" };
|
|
423
|
+
return scheme === "ssh" ? `git@${host}:${repository}.git` : `https://${host}/${repository}.git`;
|
|
424
|
+
}
|
|
425
|
+
function cacheDirName(repository, host) {
|
|
426
|
+
const parts = repository.split("/");
|
|
427
|
+
return [host, ...parts].join("__").replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
428
|
+
}
|
|
429
|
+
function sanitizeRefName(ref) {
|
|
430
|
+
return ref.replace(/[^a-zA-Z0-9._-]/g, "-");
|
|
431
|
+
}
|
|
432
|
+
function ensureBareCache(git, home, repository, host) {
|
|
433
|
+
const dir = join(home, ".outerlayer", "control-planes", `${cacheDirName(repository, host)}.git`);
|
|
434
|
+
if (!existsSync(join(dir, "HEAD"))) {
|
|
435
|
+
mkdirSync(dirname(dir), { recursive: true });
|
|
436
|
+
git(["init", "--bare", "-q", dir], { cwd: dirname(dir), timeoutMs: 5e3 });
|
|
437
|
+
}
|
|
438
|
+
return dir;
|
|
439
|
+
}
|
|
440
|
+
var MATERIALIZED_ROOTS = ["AGENTS.md", ".claude", ".outerlayer"];
|
|
441
|
+
function listMaterializedFiles(git, cacheRepoDir, sha) {
|
|
442
|
+
const result = git(["ls-tree", "-r", "-z", sha, "--", ...MATERIALIZED_ROOTS], { cwd: cacheRepoDir, timeoutMs: 1e4 });
|
|
443
|
+
if (!result.ok) return [];
|
|
444
|
+
const entries = [];
|
|
445
|
+
for (const raw of result.stdout.toString("utf8").split("\0")) {
|
|
446
|
+
if (!raw) continue;
|
|
447
|
+
const tabIdx = raw.indexOf(" ");
|
|
448
|
+
if (tabIdx === -1) continue;
|
|
449
|
+
const meta = raw.slice(0, tabIdx).split(" ");
|
|
450
|
+
const [mode, type, objSha] = meta;
|
|
451
|
+
const path = raw.slice(tabIdx + 1);
|
|
452
|
+
if (mode === void 0 || objSha === void 0 || path === void 0) continue;
|
|
453
|
+
if (mode === "120000") continue;
|
|
454
|
+
if (type !== "blob") continue;
|
|
455
|
+
if (path.includes("..") || isAbsolute(path)) continue;
|
|
456
|
+
entries.push({ mode, type: "blob", sha: objSha, path });
|
|
457
|
+
}
|
|
458
|
+
return entries;
|
|
459
|
+
}
|
|
460
|
+
function parseBatchReply(files, stdout) {
|
|
461
|
+
const parsed = [];
|
|
462
|
+
let pos = 0;
|
|
463
|
+
for (const file of files) {
|
|
464
|
+
const headerEnd = stdout.indexOf(10, pos);
|
|
465
|
+
if (headerEnd === -1) return void 0;
|
|
466
|
+
const header = stdout.subarray(pos, headerEnd).toString("utf8");
|
|
467
|
+
const parts = header.split(" ");
|
|
468
|
+
if (parts[0] !== file.sha) return void 0;
|
|
469
|
+
if (parts[1] === "missing") return void 0;
|
|
470
|
+
const size = parts[1] === "blob" && parts[2] !== void 0 ? Number(parts[2]) : NaN;
|
|
471
|
+
if (!Number.isFinite(size) || stdout.length < headerEnd + 1 + size + 1) return void 0;
|
|
472
|
+
const contentStart = headerEnd + 1;
|
|
473
|
+
parsed.push({ path: file.path, content: stdout.subarray(contentStart, contentStart + size), mode: file.mode });
|
|
474
|
+
pos = contentStart + size + 1;
|
|
475
|
+
}
|
|
476
|
+
return parsed;
|
|
477
|
+
}
|
|
478
|
+
function writeFilesVerbatim(git, cacheRepoDir, files, workpieceRoot) {
|
|
479
|
+
if (files.length === 0) return { writtenPaths: [], ok: true };
|
|
480
|
+
const input = files.map((f) => f.sha).join("\n") + "\n";
|
|
481
|
+
const result = git(["cat-file", "--batch"], { cwd: cacheRepoDir, timeoutMs: 15e3, input });
|
|
482
|
+
if (!result.ok) return { writtenPaths: [], ok: false };
|
|
483
|
+
const parsed = parseBatchReply(files, result.stdout);
|
|
484
|
+
if (parsed === void 0) return { writtenPaths: [], ok: false };
|
|
485
|
+
const writtenPaths = [];
|
|
486
|
+
let anySkipped = false;
|
|
487
|
+
for (const file of parsed) {
|
|
488
|
+
if (hasSymlinkComponent(workpieceRoot, file.path)) {
|
|
489
|
+
anySkipped = true;
|
|
490
|
+
continue;
|
|
491
|
+
}
|
|
492
|
+
const dest = join(workpieceRoot, file.path);
|
|
493
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
494
|
+
const mode = file.mode === "100755" ? 493 : 420;
|
|
495
|
+
writeFileSync(dest, file.content, { mode });
|
|
496
|
+
chmodSync(dest, mode);
|
|
497
|
+
writtenPaths.push(file.path);
|
|
498
|
+
}
|
|
499
|
+
return { writtenPaths, ok: !anySkipped };
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export { defaultGitRunner, isStagingWriteFault, lookupGoverningSource, materializeContext, parseOwnerRepo, resolveGitCommonDir };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { LiveUploader } from './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { LiveUploader } from './chunk-7SJPQWBM.js';
|
|
4
|
+
import { spoolDir } from './chunk-NFIR3GEE.js';
|
|
5
|
+
import { CaptureDaemon } from './chunk-QNLX477Q.js';
|
|
6
|
+
import { parseWorkItemEnv } from './chunk-T2Q7ISPE.js';
|
|
7
7
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
8
8
|
import { mkdirSync, writeFileSync, rmSync } from 'fs';
|
|
9
9
|
import { join } from 'path';
|