@outerlayer/cli 0.1.1 → 0.4.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.
Files changed (143) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/README.md +238 -77
  3. package/dist/agent-setup-IFH3FB5X.js +197 -0
  4. package/dist/build-TZUUTRGH.js +9 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/check-WQP2CZDW.js +94 -0
  7. package/dist/chunk-2E54Z3P5.js +232 -0
  8. package/dist/chunk-3TT7RQYB.js +55 -0
  9. package/dist/chunk-3YPKXE5L.js +1683 -0
  10. package/dist/{chunk-HNCCD2IX.js → chunk-5DLBAXY5.js} +209 -61
  11. package/dist/{chunk-R5KBGVII.js → chunk-5QRP3MVS.js} +30 -14
  12. package/dist/chunk-5Y3QQRUH.js +300 -0
  13. package/dist/chunk-6Y63SXFO.js +383 -0
  14. package/dist/chunk-774HEQL6.js +178 -0
  15. package/dist/chunk-7A6RVXPZ.js +2233 -0
  16. package/dist/chunk-7YIOOFVJ.js +71 -0
  17. package/dist/chunk-ABIWDUMS.js +104 -0
  18. package/dist/chunk-AUFG23AA.js +534 -0
  19. package/dist/chunk-B2G7JHHB.js +42 -0
  20. package/dist/chunk-BCJNHMZT.js +34 -0
  21. package/dist/chunk-BCLJSQCV.js +56 -0
  22. package/dist/chunk-BFESLKPP.js +61 -0
  23. package/dist/chunk-BJ3KTMDH.js +63 -0
  24. package/dist/chunk-BKO6JEZI.js +47 -0
  25. package/dist/chunk-BOLTI6LR.js +37 -0
  26. package/dist/chunk-CBPPJSAR.js +89 -0
  27. package/dist/chunk-CBZB6XY6.js +102 -0
  28. package/dist/{chunk-RCQXYLMO.js → chunk-DVDEBNQJ.js} +18 -18
  29. package/dist/{work-pr-cmd-GOYSPEN2.js → chunk-DVYHCMB2.js} +10 -25
  30. package/dist/{chunk-TFUIDMOB.js → chunk-EABW6AJQ.js} +12 -1
  31. package/dist/{chunk-KFYJV2ZG.js → chunk-EMY4I27X.js} +1 -1
  32. package/dist/{chunk-NTTPJV35.js → chunk-F47JBIAW.js} +3 -1
  33. package/dist/chunk-F6GFZXZ3.js +60 -0
  34. package/dist/{chunk-YOOSBOKS.js → chunk-F7CU5ABH.js} +1 -1
  35. package/dist/chunk-FAJSS2WN.js +1357 -0
  36. package/dist/chunk-FS2VYGZT.js +1764 -0
  37. package/dist/chunk-FV2CCGXK.js +9 -0
  38. package/dist/{chunk-BQB3U2VD.js → chunk-G7FSV7JX.js} +5113 -3729
  39. package/dist/{emit-cmd-TWSYYEZI.js → chunk-H5NCNVDA.js} +68 -17
  40. package/dist/chunk-HE2D4EY5.js +83 -0
  41. package/dist/chunk-L2DBRKRA.js +94 -0
  42. package/dist/chunk-LF6MLJCY.js +38 -0
  43. package/dist/chunk-M5POMKKW.js +1051 -0
  44. package/dist/{mcp-install-cmd-FDQH6SEN.js → chunk-MQ3IPHIZ.js} +35 -18
  45. package/dist/{chunk-D77LS3UI.js → chunk-N5FOE5PS.js} +33 -4
  46. package/dist/chunk-N6LURUEF.js +64 -0
  47. package/dist/chunk-NYC54VBD.js +1084 -0
  48. package/dist/chunk-OGFGZQA3.js +23 -0
  49. package/dist/chunk-QOZKPLVJ.js +226 -0
  50. package/dist/chunk-RA3O54FC.js +30 -0
  51. package/dist/chunk-TBT347UY.js +41 -0
  52. package/dist/{chunk-3VQ4XXQA.js → chunk-UFFXNXLQ.js} +115 -71
  53. package/dist/chunk-USO2DKBD.js +421 -0
  54. package/dist/chunk-W4SQCOZU.js +206 -0
  55. package/dist/{chunk-A3WLZX2F.js → chunk-WIOZAJ2W.js} +15 -2
  56. package/dist/chunk-WO2BXCTQ.js +83 -0
  57. package/dist/chunk-WZBHBH3J.js +20 -0
  58. package/dist/{chunk-IWIUYLDR.js → chunk-XCCLFVXM.js} +118 -189
  59. package/dist/{context-materialize-J6CRQ7O7.js → chunk-XDDW4FRS.js} +134 -26
  60. package/dist/chunk-YYYXRJUW.js +101 -0
  61. package/dist/chunk-ZM2IMMYN.js +76 -0
  62. package/dist/chunk-ZMYPLFG3.js +71 -0
  63. package/dist/chunk-ZNA27WEV.js +470 -0
  64. package/dist/{cli-EFJIG2VT.js → cli-NHUXABYH.js} +597 -965
  65. package/dist/{paths-D2VGWWFI.js → cli-build-K56DK4DS.js} +1 -1
  66. package/dist/config-XVJYZ4IQ.js +9 -0
  67. package/dist/connect-cmd-OOG4TPU7.js +16 -0
  68. package/dist/context-adopt-UMA4O5NY.js +105 -0
  69. package/dist/context-materialize-G2FUFC72.js +19 -0
  70. package/dist/dist-RW4UPPC2.js +6 -0
  71. package/dist/docker-NEGDLU6D.js +7 -0
  72. package/dist/doctor-53F2PYY7.js +43 -0
  73. package/dist/doctor-UFVL4PZY.js +426 -0
  74. package/dist/{emit-artifact-cmd-KPPD3YLO.js → emit-artifact-cmd-KTYW2TN2.js} +25 -19
  75. package/dist/emit-cmd-DCERAU27.js +9 -0
  76. package/dist/emit-criteria-cmd-VAUUSAYD.js +166 -0
  77. package/dist/{emit-finding-cmd-VR5VEGXJ.js → emit-finding-cmd-UR4ID45Z.js} +35 -30
  78. package/dist/{emit-result-cmd-YOA5BJKL.js → emit-result-cmd-FDTUKGKE.js} +35 -61
  79. package/dist/exec-client-4XGXV3XN.js +8 -0
  80. package/dist/guest-init-GENRHNP7.js +8 -0
  81. package/dist/hook-fast-EYENPK6F.js +9 -0
  82. package/dist/{hook-wrap-fast-KXYNX3AD.js → hook-wrap-fast-NPLHJXFK.js} +2 -2
  83. package/dist/host-key-KDYZ5ECC.js +7 -0
  84. package/dist/import-capture-cmd-AVZ4VIVJ.js +68 -0
  85. package/dist/{import-ruler-cmd-7LH2QOMG.js → import-ruler-cmd-GUHL6IY5.js} +1 -1
  86. package/dist/index.js +4 -4
  87. package/dist/init-DXBCOAJK.js +36 -0
  88. package/dist/init-YEXK35CF.js +221 -0
  89. package/dist/init-cmd-NHR7PRSQ.js +135 -0
  90. package/dist/install-cmd-7WXOIFDO.js +55 -0
  91. package/dist/lima-XN65D7GN.js +55 -0
  92. package/dist/login-browser-7XGSV7MA.js +10 -0
  93. package/dist/{config-POF7DEQW.js → logout-cmd-QAUFDJ6J.js} +3 -1
  94. package/dist/{logs-TRNPQM42.js → logs-7RYUH5A6.js} +1 -1
  95. package/dist/loop-VZOLL4WQ.js +43 -0
  96. package/dist/machine-WSG52J75.js +35 -0
  97. package/dist/mcp-install-cmd-RLK4SO3N.js +9 -0
  98. package/dist/{mcp-serve-cmd-57EZZOTL.js → mcp-serve-cmd-JPTP5FMS.js} +20 -9
  99. package/dist/paths-OYKMVYJP.js +6 -0
  100. package/dist/{pidfile-PTW76F56.js → pidfile-UZRH774M.js} +2 -3
  101. package/dist/real-deps-SU24ZA2K.js +21 -0
  102. package/dist/relay-L76HDX72.js +46 -0
  103. package/dist/settings-J2652U5N.js +7 -0
  104. package/dist/starter-pack-LIZYMKYQ.js +10 -0
  105. package/dist/{status-JHVSZYC5.js → status-2UZKKNB7.js} +31 -12
  106. package/dist/{statusline-fast-3C5OXHDD.js → statusline-fast-SVTMBMD7.js} +3 -2
  107. package/dist/sync-cmd-VPPYCNNM.js +28 -0
  108. package/dist/version-BWM6VLDI.js +6 -0
  109. package/dist/{watch-NRLXJUST.js → watch-5C4ZBBGO.js} +20 -7
  110. package/dist/{work-claim-cmd-HXB7K27H.js → work-claim-cmd-LSO2B2EX.js} +34 -19
  111. package/dist/work-cmd-UOQO2AD4.js +17 -0
  112. package/dist/work-comment-cmd-WF3EOLAE.js +106 -0
  113. package/dist/{work-launch-YNNCKIH3.js → work-launch-YI4CJDAP.js} +2 -1
  114. package/dist/work-open-pr-cmd-4SSQZMYG.js +156 -0
  115. package/dist/work-pr-cmd-6AN6RRQJ.js +16 -0
  116. package/package.json +13 -3
  117. package/skill-pack/maintained/amend/SKILL.md +104 -0
  118. package/skill-pack/maintained/emitting-evidence/SKILL.md +99 -0
  119. package/skill-pack/maintained/emitting-evidence/references/agents-snippet.md +20 -0
  120. package/skill-pack/maintained/outerlayer/SKILL.md +55 -0
  121. package/skill-pack/maintained/reporting-findings/SKILL.md +148 -0
  122. package/skill-pack/template/build/SKILL.md +193 -0
  123. package/skill-pack/template/build/references/agent-briefs.md +243 -0
  124. package/skill-pack/template/build/references/criteria-judge.md +91 -0
  125. package/skill-pack/template/build/references/evidence.md +42 -0
  126. package/skill-pack/template/build/references/release.md +74 -0
  127. package/skill-pack/template/build/references/review-briefs.md +275 -0
  128. package/skill-pack/template/build/references/review-loop.md +158 -0
  129. package/skill-pack/template/build/scripts/record-criteria.mjs +235 -0
  130. package/skill-pack/template/spec/SKILL.md +84 -0
  131. package/skill-pack/template/writing-specs/SKILL.md +134 -0
  132. package/dist/chunk-JJP7YLMN.js +0 -25
  133. package/dist/chunk-KKEU6FFR.js +0 -589
  134. package/dist/chunk-OZ7C3XUE.js +0 -34
  135. package/dist/chunk-WQ6VGRGZ.js +0 -150
  136. package/dist/emit-commit-credit-cmd-656BRAQ4.js +0 -121
  137. package/dist/hook-fast-I2XTHDE6.js +0 -8
  138. package/dist/import-capture-cmd-EUMBGIV3.js +0 -176
  139. package/dist/init-PTBITAUO.js +0 -103
  140. package/dist/login-cmd-IRX6LZT7.js +0 -62
  141. package/dist/loop-BWE2BS6J.js +0 -646
  142. package/dist/sync-cmd-S7Q6DWU3.js +0 -15
  143. package/dist/work-cmd-ABP6XDBP.js +0 -16
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { isPlaceholderCommand } from './chunk-CBZB6XY6.js';
4
+ import { describeCallFailure } from './chunk-7A6RVXPZ.js';
5
+ import { WorkCommandError, getJson } from './chunk-5DLBAXY5.js';
6
+ import { sanitizeTerminal } from './chunk-6Y63SXFO.js';
7
+ import { builtinKind } from './chunk-5Y3QQRUH.js';
8
+ import { claudeCredential, CLAUDE_CREDENTIAL_VARIABLES } from './chunk-AUFG23AA.js';
9
+ import { signerFor } from './chunk-M5POMKKW.js';
10
+
11
+ createRequire(import.meta.url);
12
+
13
+ // src/runner/host-setup.ts
14
+ function placeholderQueues(config) {
15
+ return config.queues.filter((queue) => {
16
+ const command = config.commands[queue];
17
+ return command !== void 0 && isPlaceholderCommand(command);
18
+ });
19
+ }
20
+ function placeholderProblem(queues) {
21
+ const keys = queues.map((queue) => `runner.commands.${queue}`).join(", ");
22
+ return `${keys} ${queues.length === 1 ? "is" : "are"} still the placeholder \`runner init\` wrote, which fails every item. Edit ${queues.length === 1 ? "it" : "them"} to start your agent on item $OUTERLAYER_WORK`;
23
+ }
24
+ function needsClaudeCredential(hooks) {
25
+ return builtinKind(hooks.provision) !== "own";
26
+ }
27
+ var CREDENTIAL_FIX = "Run `claude setup-token`, then start the runner with CLAUDE_CODE_OAUTH_TOKEN set to the token it prints (or ANTHROPIC_API_KEY set to an API key), for example with EnvironmentFile= in the runner's systemd unit";
28
+ function claudeCredentialCheck(env, options = {}) {
29
+ const name = "Claude credential";
30
+ const held = claudeCredential(env);
31
+ if (held === void 0) {
32
+ return {
33
+ name,
34
+ status: "fail",
35
+ detail: `neither ${CLAUDE_CREDENTIAL_VARIABLES.slice(0, 2).join(" nor ")} is set, so every build fails at provision as agent_credential_missing`,
36
+ fix: `${CREDENTIAL_FIX}.`
37
+ };
38
+ }
39
+ const sameVariables = options.shell === true ? "; the runner must be started with the same variable" : "";
40
+ return { name, status: "pass", detail: `${held.variable} is set${sameVariables}` };
41
+ }
42
+ function missingPermissionOf(err) {
43
+ if (!(err instanceof WorkCommandError) || err.status !== 403) return void 0;
44
+ const permission = /missing required permission '([^']+)'/i.exec(err.message)?.[1];
45
+ return permission === void 0 ? void 0 : sanitizeTerminal(permission);
46
+ }
47
+ function missingPermissionFix(permission) {
48
+ return `use a key that holds ${permission}: create one with the Runner preset on the factory's API keys page, then run \`outerlayer login\` with it`;
49
+ }
50
+ async function claimPermissionProblem(config, fetchImpl = fetch) {
51
+ const unverified = (what, err) => ({
52
+ status: "unverified",
53
+ reason: sanitizeTerminal(`${what}: ${err instanceof Error ? describeCallFailure(err) : String(err)}`)
54
+ });
55
+ let signer;
56
+ try {
57
+ signer = await signerFor(config.configPath);
58
+ } catch (err) {
59
+ return unverified("this host's key could not be read, so whether the runner key can claim work was not checked", err);
60
+ }
61
+ try {
62
+ await getJson(config.url, "/v1/runner/host-key", config.apiKey, config.appId, fetchImpl, signer);
63
+ return { status: "ok" };
64
+ } catch (err) {
65
+ const permission = missingPermissionOf(err);
66
+ if (permission === void 0) return unverified("the host-key call did not say whether the runner key can claim work", err);
67
+ return { status: "lacks", problem: `the runner key lacks ${permission}, which a runner needs to claim work: ${missingPermissionFix(permission)}` };
68
+ }
69
+ }
70
+
71
+ export { claimPermissionProblem, claudeCredentialCheck, missingPermissionFix, missingPermissionOf, needsClaudeCredential, placeholderProblem, placeholderQueues };
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from 'node:module';
3
+ import { spawn } from 'child_process';
4
+ import { existsSync } from 'fs';
5
+ import { join, dirname } from 'path';
6
+ import { createHash } from 'crypto';
7
+
8
+ createRequire(import.meta.url);
9
+ var REGISTRY_URL = "https://registry.npmjs.org";
10
+ var PACKAGE_NAME = "@outerlayer/cli";
11
+ var PACKAGE_PATH = "@outerlayer%2fcli";
12
+ var SLSA_PREDICATE = "https://slsa.dev/provenance/v1";
13
+ var REQUEST_TIMEOUT_MS = 6e4;
14
+ function get(url, fetchImpl) {
15
+ return fetchImpl(url, { signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS), headers: { accept: "application/json" } });
16
+ }
17
+ async function fetchVersionMeta(version, fetchImpl) {
18
+ const response = await get(`${REGISTRY_URL}/${PACKAGE_PATH}/${encodeURIComponent(version)}`, fetchImpl);
19
+ if (response.status === 404) return { kind: "not_published" };
20
+ if (!response.ok) throw new Error(`the registry answered HTTP ${response.status} for ${PACKAGE_NAME}@${version}`);
21
+ const body = await response.json();
22
+ const { integrity, tarball } = body.dist ?? {};
23
+ if (typeof integrity !== "string" || typeof tarball !== "string") {
24
+ throw new Error(`the registry's metadata for ${PACKAGE_NAME}@${version} has no dist.integrity or dist.tarball`);
25
+ }
26
+ const nodeRange = body.engines?.node;
27
+ return typeof nodeRange === "string" ? { kind: "found", integrity, tarball, nodeRange } : { kind: "found", integrity, tarball };
28
+ }
29
+ async function fetchTarballDigest(url, fetchImpl) {
30
+ if (!url.startsWith(`${REGISTRY_URL}/`)) throw new Error(`the tarball is not served by ${REGISTRY_URL}: ${url}`);
31
+ const response = await get(url, fetchImpl);
32
+ if (!response.ok) throw new Error(`the registry answered HTTP ${response.status} for the tarball`);
33
+ return createHash("sha512").update(Buffer.from(await response.arrayBuffer())).digest("base64");
34
+ }
35
+ async function fetchProvenance(version, fetchImpl) {
36
+ const response = await get(`${REGISTRY_URL}/-/npm/v1/attestations/${PACKAGE_PATH}@${encodeURIComponent(version)}`, fetchImpl);
37
+ if (response.status === 404) return void 0;
38
+ if (!response.ok) throw new Error(`the registry answered HTTP ${response.status} for the attestations of ${PACKAGE_NAME}@${version}`);
39
+ const body = await response.json();
40
+ const slsa = (body.attestations ?? []).find((a) => a.predicateType === SLSA_PREDICATE);
41
+ const payload = slsa?.bundle?.dsseEnvelope?.payload;
42
+ if (typeof payload !== "string") return void 0;
43
+ const statement = JSON.parse(Buffer.from(payload, "base64").toString("utf8"));
44
+ const workflow = statement.predicate?.buildDefinition?.externalParameters?.workflow;
45
+ const subjectSha512 = statement.subject?.[0]?.digest?.sha512;
46
+ if (typeof workflow?.repository !== "string" || typeof workflow.path !== "string" || typeof subjectSha512 !== "string") return void 0;
47
+ return { repository: workflow.repository, workflowPath: workflow.path, subjectSha512 };
48
+ }
49
+
50
+ // src/runner/update/npm.ts
51
+ function run(file, args, cwd) {
52
+ const COMMAND_TIMEOUT_MS = 10 * 6e4;
53
+ return new Promise((resolve) => {
54
+ const child = spawn(file, args, { cwd, stdio: ["ignore", "pipe", "pipe"], timeout: COMMAND_TIMEOUT_MS });
55
+ let stdout = "";
56
+ let stderr = "";
57
+ child.stdout.on("data", (chunk) => stdout += chunk.toString());
58
+ child.stderr.on("data", (chunk) => stderr += chunk.toString());
59
+ child.on("error", (err) => resolve({ status: 127, stdout, stderr: `${stderr}${err.message}` }));
60
+ child.on("close", (code) => resolve({ status: code ?? 1, stdout, stderr }));
61
+ });
62
+ }
63
+ function npmExecutable(nodePath) {
64
+ const beside = join(dirname(nodePath), "npm");
65
+ return existsSync(beside) ? beside : "npm";
66
+ }
67
+ function realRunNpm(nodePath) {
68
+ const npm = npmExecutable(nodePath);
69
+ return (args, cwd) => run(npm, args, cwd);
70
+ }
71
+ function realRunNode(nodePath) {
72
+ return (args, cwd) => run(nodePath, args, cwd);
73
+ }
74
+ function npmSupportsProvenance(version) {
75
+ const match = /^(\d+)\.(\d+)/.exec(version.trim());
76
+ if (match === null) return false;
77
+ const major = Number(match[1]);
78
+ return major > 9 || major === 9 && Number(match[2]) >= 5;
79
+ }
80
+ async function npmVersion(runNpm, cwd) {
81
+ const result = await runNpm(["--version"], cwd);
82
+ return result.status === 0 ? result.stdout.trim() : void 0;
83
+ }
84
+ async function installVersion(runNpm, stagingDir, version) {
85
+ return runNpm(
86
+ ["install", "--prefix", stagingDir, "--registry", REGISTRY_URL, "--ignore-scripts", "--no-audit", "--no-fund", `@outerlayer/cli@${version}`],
87
+ stagingDir
88
+ );
89
+ }
90
+ async function auditSignatures(runNpm, dir) {
91
+ const result = await runNpm(["audit", "signatures", "--json", "--registry", REGISTRY_URL], dir);
92
+ try {
93
+ const report = JSON.parse(result.stdout);
94
+ if ((report.invalid ?? []).length > 0) return { ok: false, verdict: true, reason: "npm audit signatures reported an invalid signature" };
95
+ if ((report.missing ?? []).some((entry) => entry.name === "@outerlayer/cli")) {
96
+ return { ok: false, verdict: true, reason: "npm audit signatures found no signature for @outerlayer/cli" };
97
+ }
98
+ } catch {
99
+ }
100
+ if (result.status !== 0) return { ok: false, verdict: false, reason: "npm audit signatures failed" };
101
+ return { ok: true };
102
+ }
103
+
104
+ export { auditSignatures, fetchProvenance, fetchTarballDigest, fetchVersionMeta, installVersion, npmSupportsProvenance, npmVersion, realRunNode, realRunNpm };