@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,34 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
4
|
+
import { join, sep } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
createRequire(import.meta.url);
|
|
8
|
+
var CLI_PACKAGE = "@outerlayer/cli";
|
|
9
|
+
function packageRunnerOf(bin) {
|
|
10
|
+
for (const part of bin.replace(/\\/g, "/").split("/")) {
|
|
11
|
+
if (part === "_npx") return "npx";
|
|
12
|
+
if (part === "dlx") return "pnpm dlx";
|
|
13
|
+
if (part.startsWith("dlx-")) return "yarn dlx";
|
|
14
|
+
if (part.startsWith("bunx-")) return "bunx";
|
|
15
|
+
}
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
18
|
+
function runningModule() {
|
|
19
|
+
try {
|
|
20
|
+
return fileURLToPath(import.meta.url);
|
|
21
|
+
} catch {
|
|
22
|
+
return "";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function cliInvocation(opts = {}) {
|
|
26
|
+
const bin = opts.bin ?? runningModule();
|
|
27
|
+
const runner = packageRunnerOf(bin);
|
|
28
|
+
if (runner !== void 0) return `${runner} ${CLI_PACKAGE}`;
|
|
29
|
+
const installedCopy = join(opts.home ?? homeFromEnv(), ".outerlayer", "cli") + sep;
|
|
30
|
+
if (bin.startsWith(installedCopy)) return `npx ${CLI_PACKAGE}`;
|
|
31
|
+
return "outerlayer";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { cliInvocation, packageRunnerOf };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { isPlaceholderCommand } from './chunk-
|
|
4
|
-
import { describeCallFailure } from './chunk-
|
|
5
|
-
import { WorkCommandError, getJson } from './chunk-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import { isPlaceholderCommand } from './chunk-6D7GT22T.js';
|
|
4
|
+
import { describeCallFailure } from './chunk-XSZD4AZ6.js';
|
|
5
|
+
import { WorkCommandError, getJson } from './chunk-HPJNLETG.js';
|
|
6
|
+
import { sanitizeTerminal } from './chunk-G3IJ3N6F.js';
|
|
7
|
+
import { builtinKind } from './chunk-P53VEAOF.js';
|
|
8
|
+
import { signerFor } from './chunk-M2ZWWTWZ.js';
|
|
9
|
+
import { CLAUDE_CREDENTIAL_VARIABLES, claudeCredential } from './chunk-BQXFBI7T.js';
|
|
10
10
|
|
|
11
11
|
createRequire(import.meta.url);
|
|
12
12
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { runEmit } from './chunk-
|
|
4
|
-
import { addStdioMcpEntryIfAbsent, addDocsMcpEntryIfAbsent, DOCS_MCP_SERVER_NAME } from './chunk-
|
|
5
|
-
import { installStarterPack } from './chunk-
|
|
6
|
-
import { C } from './chunk-
|
|
7
|
-
import { resolveGitCommonDir, defaultGitRunner } from './chunk-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
3
|
+
import { runEmit } from './chunk-ZHAUSEEN.js';
|
|
4
|
+
import { addStdioMcpEntryIfAbsent, addDocsMcpEntryIfAbsent, DOCS_MCP_SERVER_NAME } from './chunk-YVZJ6GKF.js';
|
|
5
|
+
import { installStarterPack } from './chunk-6X4SQ5MY.js';
|
|
6
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
7
|
+
import { resolveGitCommonDir, defaultGitRunner } from './chunk-452TM7J4.js';
|
|
8
|
+
import { loadTemplateFiles, loadMaintainedFiles, skillDir } from './chunk-NNLA7LLQ.js';
|
|
9
|
+
import { generatedHeaderSource } from './chunk-WFSUUUAN.js';
|
|
10
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
11
|
+
import { cloneIsGoverned } from './chunk-YQR6E6OV.js';
|
|
11
12
|
import { execFileSync } from 'child_process';
|
|
12
13
|
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
13
14
|
import { join, dirname } from 'path';
|
|
@@ -39,10 +40,9 @@ function gitTopLevel(cwd) {
|
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
function contextComesFromControlPlane(repoRoot) {
|
|
42
|
-
if (pinExists(repoRoot)) return true;
|
|
43
43
|
const gitCommonDir = resolveGitCommonDir(defaultGitRunner, repoRoot);
|
|
44
44
|
if (gitCommonDir === void 0) throw new GitLookupError("git could not report this repository's git directory");
|
|
45
|
-
return
|
|
45
|
+
return cloneIsGoverned(gitCommonDir);
|
|
46
46
|
}
|
|
47
47
|
function mcpReplacementLosesNothing(existing, content) {
|
|
48
48
|
try {
|
|
@@ -176,7 +176,7 @@ function renderPaths(paths, kept) {
|
|
|
176
176
|
`;
|
|
177
177
|
}
|
|
178
178
|
function renderDone(paths, kept, mcpKept) {
|
|
179
|
-
const mcpNote = mcpKept ? ` ${C.yellow}!${C.reset} The outerlayer and ${DOCS_MCP_SERVER_NAME} entries were not added to .mcp.json, so their MCP servers are not set up. Add them to .mcp.json by hand, or move the servers you wrote into .outerlayer/mcp.json and run
|
|
179
|
+
const mcpNote = mcpKept ? ` ${C.yellow}!${C.reset} The outerlayer and ${DOCS_MCP_SERVER_NAME} entries were not added to .mcp.json, so their MCP servers are not set up. Add them to .mcp.json by hand, or move the servers you wrote into .outerlayer/mcp.json and run \`${cliInvocation()} context emit\`.
|
|
180
180
|
` : "";
|
|
181
181
|
const what = mcpKept ? "the OuterLayer skills" : "the OuterLayer skills and MCP servers";
|
|
182
182
|
if (paths.length === 0) {
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { recordReportedCost } from './chunk-BKO6JEZI.js';
|
|
4
4
|
import { decodeWrappedCommand } from './chunk-5QRP3MVS.js';
|
|
5
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
5
6
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
7
|
import { readFileSync } from 'fs';
|
|
7
8
|
import { spawn } from 'child_process';
|
|
@@ -69,7 +70,7 @@ function renderStatusline(stdin, state, now) {
|
|
|
69
70
|
segments.push(`${state.unsynced} unsynced`);
|
|
70
71
|
}
|
|
71
72
|
if (!fresh) {
|
|
72
|
-
segments.push(dim(
|
|
73
|
+
segments.push(dim(`${cliInvocation()} doctor`));
|
|
73
74
|
}
|
|
74
75
|
const prefix = "\u2B22 OL";
|
|
75
76
|
return segments.length === 0 ? prefix : `${prefix} ${segments.join(dim(" \xB7 "))}`;
|
|
@@ -1,40 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { isSameProcess } from './chunk-JBJTC3UU.js';
|
|
4
|
+
import { RUNNER_DIR_MODE, RUNNER_FILE_MODE } from './chunk-N2PXGQRL.js';
|
|
5
|
+
import { existsSync, readFileSync, rmSync, mkdirSync, writeFileSync } from 'fs';
|
|
5
6
|
import { dirname } from 'path';
|
|
6
|
-
import { execFileSync } from 'child_process';
|
|
7
7
|
|
|
8
8
|
createRequire(import.meta.url);
|
|
9
|
-
function startTimeOf(pid) {
|
|
10
|
-
if (process.platform === "linux") return startTimeOfLinux(pid);
|
|
11
|
-
return startTimeOfPs(pid);
|
|
12
|
-
}
|
|
13
|
-
function startTimeOfLinux(pid) {
|
|
14
|
-
try {
|
|
15
|
-
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
16
|
-
const afterComm = stat.slice(stat.lastIndexOf(")") + 1).trim();
|
|
17
|
-
const fields = afterComm.split(/\s+/);
|
|
18
|
-
if (fields[0] === "Z" || fields[0] === "X") return null;
|
|
19
|
-
const starttime = fields[19];
|
|
20
|
-
return starttime ?? null;
|
|
21
|
-
} catch {
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function startTimeOfPs(pid) {
|
|
26
|
-
try {
|
|
27
|
-
const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], { encoding: "utf8" }).trim();
|
|
28
|
-
return out.length > 0 ? out : null;
|
|
29
|
-
} catch {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function isSameProcess(pid, start) {
|
|
34
|
-
return startTimeOf(pid) === start;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// src/runner/pidfile.ts
|
|
38
9
|
function readPidFile(path) {
|
|
39
10
|
if (!existsSync(path)) return null;
|
|
40
11
|
try {
|
|
@@ -68,4 +39,4 @@ function claimPidFile(path, self, isSameProcessFn = isSameProcess) {
|
|
|
68
39
|
writePidFile(path, self);
|
|
69
40
|
}
|
|
70
41
|
|
|
71
|
-
export { RunnerAlreadyRunningError, claimPidFile,
|
|
42
|
+
export { RunnerAlreadyRunningError, claimPidFile, readPidFile, releasePidFile };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { readCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
|
|
4
|
-
import { signRunnerRequest, signerFor } from './chunk-V7NIVOFD.js';
|
|
5
4
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
5
|
+
import { signRunnerRequest, signerFor } from './chunk-M2ZWWTWZ.js';
|
|
6
6
|
|
|
7
7
|
createRequire(import.meta.url);
|
|
8
8
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
|
|
4
|
+
createRequire(import.meta.url);
|
|
5
|
+
|
|
6
|
+
// src/control-plane-paths.ts
|
|
7
|
+
var CONTROL_PLANE_DIR_VARIABLE = "OUTERLAYER_CONTROL_PLANE_DIR";
|
|
8
|
+
var PROJECT_DIR_SPELLINGS = [
|
|
9
|
+
/"\$\{?CLAUDE_PROJECT_DIR\}?"\/\.claude(?![\w.-])/g,
|
|
10
|
+
/\$\{CLAUDE_PROJECT_DIR\}\/\.claude(?![\w.-])/g,
|
|
11
|
+
/\$CLAUDE_PROJECT_DIR\/\.claude(?![\w.-])/g
|
|
12
|
+
];
|
|
13
|
+
var CONTROL_PLANE_VARIABLE_FORMS = [
|
|
14
|
+
new RegExp(`\\$\\{${CONTROL_PLANE_DIR_VARIABLE}:-[^}]*\\}/\\.claude(?![\\w.-])`, "g"),
|
|
15
|
+
new RegExp(`\\$\\{${CONTROL_PLANE_DIR_VARIABLE}\\}/\\.claude(?![\\w.-])`, "g"),
|
|
16
|
+
new RegExp(`\\$${CONTROL_PLANE_DIR_VARIABLE}/\\.claude(?![\\w.-])`, "g")
|
|
17
|
+
];
|
|
18
|
+
function rewriteHookCommand(command, dir) {
|
|
19
|
+
return PROJECT_DIR_SPELLINGS.reduce((text, pattern) => text.replace(pattern, () => `${dir}/.claude`), command);
|
|
20
|
+
}
|
|
21
|
+
function rewriteControlPlanePaths(text, dir) {
|
|
22
|
+
return text.replace(/(?<![\w./~$}:-])(\.outerlayer|\.claude)\//g, (_match, root) => `${dir}/${root}/`);
|
|
23
|
+
}
|
|
24
|
+
function hookCommandEscapesControlPlane(command) {
|
|
25
|
+
const remaining = [...PROJECT_DIR_SPELLINGS, ...CONTROL_PLANE_VARIABLE_FORMS].reduce((text, pattern) => text.replace(pattern, " "), command);
|
|
26
|
+
return /\.claude(?:\/|["'\s;|&)]|$)/.test(remaining) || /\$\{?CLAUDE_PROJECT_DIR\}?"?\/\.claude/.test(remaining);
|
|
27
|
+
}
|
|
28
|
+
var MINIMUM_CLAUDE_VERSION = "2.1.284";
|
|
29
|
+
function versionParts(text) {
|
|
30
|
+
const found = /(\d+)\.(\d+)\.(\d+)/.exec(text);
|
|
31
|
+
return found === null ? void 0 : [Number(found[1]), Number(found[2]), Number(found[3])];
|
|
32
|
+
}
|
|
33
|
+
function versionAtLeast(text, minimum = MINIMUM_CLAUDE_VERSION) {
|
|
34
|
+
const have = versionParts(text);
|
|
35
|
+
const need = versionParts(minimum);
|
|
36
|
+
if (have === void 0 || need === void 0) return false;
|
|
37
|
+
const difference = have.map((part, i) => part - need[i]).find((delta) => delta !== 0);
|
|
38
|
+
return (difference ?? 0) >= 0;
|
|
39
|
+
}
|
|
40
|
+
var SHIM_SCRIPT = `#!/bin/sh
|
|
41
|
+
exec outerlayer claude "$@"
|
|
42
|
+
`;
|
|
43
|
+
|
|
44
|
+
export { CONTROL_PLANE_DIR_VARIABLE, MINIMUM_CLAUDE_VERSION, SHIM_SCRIPT, hookCommandEscapesControlPlane, rewriteControlPlanePaths, rewriteHookCommand, versionAtLeast };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-
|
|
3
|
+
import { ArtifactTombstoneRecordSchema, ArtifactSpoolRecordSchema } from './chunk-7VUK5RFS.js';
|
|
4
4
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
5
5
|
import { mkdirSync, appendFileSync, writeFileSync, renameSync, unlinkSync, existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
6
6
|
import { join, dirname } from 'path';
|
|
@@ -273,7 +273,9 @@ function artifactLockIsStale(path, nowMs, isAlive) {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
async function acquireArtifactSpoolLock(home = homeFromEnv(), opts = {}) {
|
|
276
|
-
|
|
276
|
+
return acquireSpoolLockAt(artifactsLockPath(home), opts);
|
|
277
|
+
}
|
|
278
|
+
async function acquireSpoolLockAt(path, opts = {}) {
|
|
277
279
|
const waitMs = opts.waitMs ?? ARTIFACT_LOCK_WAIT_MS;
|
|
278
280
|
const sleep = opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
279
281
|
const isAlive = opts.isAlive ?? processIsAlive;
|
|
@@ -460,4 +462,4 @@ function resolveArtifactTurnIndex(turns, filename) {
|
|
|
460
462
|
return found;
|
|
461
463
|
}
|
|
462
464
|
|
|
463
|
-
export { ARTIFACT_RETRY_MAX_AGE_MS, acquireArtifactSpoolLock, appendArtifactRecord, appendArtifactTombstone, artifactBlobsDir, artifactsSpoolPath, artifactsStatePath, findPendingArtifactRecord, isArtifactTombstoned, localArtifactIds, migrateLegacyArtifactSidecars, neededArtifactShas, planArtifactUpload, readEffectiveArtifactSpoolState, reclaimUnneededArtifactBlobs, resolveArtifactTurnIndex, sanitizeTerminal, writeArtifactSpoolState };
|
|
465
|
+
export { ARTIFACT_RETRY_MAX_AGE_MS, acquireArtifactSpoolLock, acquireSpoolLockAt, appendArtifactRecord, appendArtifactTombstone, artifactBlobsDir, artifactsSpoolPath, artifactsStatePath, findPendingArtifactRecord, isArtifactTombstoned, localArtifactIds, migrateLegacyArtifactSidecars, neededArtifactShas, planArtifactUpload, readEffectiveArtifactSpoolState, reclaimUnneededArtifactBlobs, resolveArtifactTurnIndex, sanitizeTerminal, writeArtifactSpoolState };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { C } from './chunk-
|
|
3
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
4
4
|
import { readCloudConfig, removeCloudConfigKeys } from './chunk-EABW6AJQ.js';
|
|
5
5
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
6
6
|
|
|
@@ -1,20 +1,69 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { autoConnect } from './chunk-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { C } from './chunk-YRYMNBGQ.js';
|
|
3
|
+
import { detectActiveSession, autoConnect } from './chunk-IF2OSI5T.js';
|
|
4
|
+
import { workPageUrl } from './chunk-CG36IONK.js';
|
|
5
|
+
import { sanitizeTerminal } from './chunk-G3IJ3N6F.js';
|
|
6
|
+
import { resolveRepoIdentity } from './chunk-QNLX477Q.js';
|
|
7
|
+
import { C } from './chunk-ANPNT6PM.js';
|
|
9
8
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
10
|
-
import { defaultFetch } from './chunk-
|
|
11
|
-
import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-
|
|
12
|
-
import { signRunnerRequest } from './chunk-V7NIVOFD.js';
|
|
9
|
+
import { defaultFetch } from './chunk-FVMYKL6L.js';
|
|
10
|
+
import { resolveGatewayCredentials, unauthorizedMessage } from './chunk-NTRCK4NH.js';
|
|
13
11
|
import { readRepoConnection } from './chunk-BJ3KTMDH.js';
|
|
14
12
|
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
13
|
+
import { signRunnerRequest } from './chunk-M2ZWWTWZ.js';
|
|
15
14
|
|
|
16
15
|
createRequire(import.meta.url);
|
|
17
16
|
|
|
17
|
+
// ../trackers/src/descriptor.ts
|
|
18
|
+
var TRACKERS = {
|
|
19
|
+
github: {
|
|
20
|
+
label: "GitHub",
|
|
21
|
+
hasStoredConnection: false,
|
|
22
|
+
verifiedKeys: false,
|
|
23
|
+
issueRef: "number",
|
|
24
|
+
scopeNoun: "repository",
|
|
25
|
+
connect: { kind: "builtin" }
|
|
26
|
+
},
|
|
27
|
+
linear: {
|
|
28
|
+
label: "Linear",
|
|
29
|
+
hasStoredConnection: true,
|
|
30
|
+
verifiedKeys: true,
|
|
31
|
+
issueRef: "key",
|
|
32
|
+
scopeNoun: "team",
|
|
33
|
+
connect: {
|
|
34
|
+
kind: "oauth",
|
|
35
|
+
summary: "Read the teams you pick in a workspace, and file specs as issues. One authorization; Linear registers its own webhook."
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
jira: {
|
|
39
|
+
label: "Jira",
|
|
40
|
+
hasStoredConnection: true,
|
|
41
|
+
verifiedKeys: true,
|
|
42
|
+
issueRef: "key",
|
|
43
|
+
scopeNoun: "project",
|
|
44
|
+
connect: {
|
|
45
|
+
kind: "form",
|
|
46
|
+
summary: "Read the projects you pick on a site, and file specs as issues, with a service account. One webhook is created in Jira by an admin.",
|
|
47
|
+
intro: "Uses a service account's OAuth client credential. Create one under Atlassian administration, then paste it here. Give it read:jira-work, and write:jira-work to file specs. A credential's scopes are fixed when it is created.",
|
|
48
|
+
notice: "After connecting, you get a webhook URL and secret to put on one webhook in Jira. That is the only manual step, and the only time the secret is shown.",
|
|
49
|
+
fields: [
|
|
50
|
+
{ name: "siteUrl", label: "Site URL", placeholder: "https://your-team.atlassian.net" },
|
|
51
|
+
{ name: "clientId", label: "Client ID" },
|
|
52
|
+
{ name: "clientSecret", label: "Client secret", secret: true },
|
|
53
|
+
{
|
|
54
|
+
name: "projectKeys",
|
|
55
|
+
label: "Projects to read",
|
|
56
|
+
placeholder: "ENG, OPS",
|
|
57
|
+
helperText: "Project keys, comma separated. Only issues in these projects are listed."
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
function verifiedTrackerNames(descriptors) {
|
|
64
|
+
return Object.keys(descriptors).filter((name) => descriptors[name].verifiedKeys);
|
|
65
|
+
}
|
|
66
|
+
|
|
18
67
|
// src/runner/signature-refusals.ts
|
|
19
68
|
var MESSAGES = /* @__PURE__ */ new Map([
|
|
20
69
|
[
|
|
@@ -101,14 +150,8 @@ function parseRetries(raw) {
|
|
|
101
150
|
const n = parseTrackerNumber(raw);
|
|
102
151
|
return n === void 0 ? 0 : Math.min(n, WORK_LINK_RETRY_DELAYS_MS.length);
|
|
103
152
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (issue === void 0) {
|
|
107
|
-
throw new WorkCommandError("pass --issue");
|
|
108
|
-
}
|
|
109
|
-
return { issue };
|
|
110
|
-
}
|
|
111
|
-
var TRACKER_FLAG_HELP = 'expected "linear" or "jira" \u2014 GitHub issues are named by number, with no --tracker';
|
|
153
|
+
var VERIFIED_TRACKERS = verifiedTrackerNames(TRACKERS);
|
|
154
|
+
var TRACKER_FLAG_HELP = `expected ${VERIFIED_TRACKERS.map((name) => `"${name}"`).join(" or ")} \u2014 GitHub issues are named by number, with no --tracker`;
|
|
112
155
|
function resolveWorkSubject(opts) {
|
|
113
156
|
if (opts.issue === void 0) {
|
|
114
157
|
throw new WorkCommandError("pass --issue");
|
|
@@ -120,32 +163,36 @@ function resolveWorkSubject(opts) {
|
|
|
120
163
|
}
|
|
121
164
|
return { repository: resolveRepository(opts.repo, opts.cwd), issue: asNumber };
|
|
122
165
|
}
|
|
123
|
-
|
|
166
|
+
const tracker = opts.tracker === void 0 ? void 0 : VERIFIED_TRACKERS.find((name) => name === opts.tracker);
|
|
167
|
+
if (opts.tracker !== void 0 && tracker === void 0) {
|
|
124
168
|
throw new WorkCommandError(`invalid --tracker "${opts.tracker}": ${TRACKER_FLAG_HELP}`);
|
|
125
169
|
}
|
|
126
|
-
return { key: String(opts.issue), tracker
|
|
170
|
+
return { key: String(opts.issue), tracker, repository: opts.repo };
|
|
127
171
|
}
|
|
128
172
|
async function postJson(url, path, apiKey, appId, body, fetchImpl, timeoutMs, signer) {
|
|
129
173
|
const deadline = timeoutMs === void 0 ? void 0 : startDeadline(timeoutMs);
|
|
130
174
|
try {
|
|
131
|
-
return await
|
|
175
|
+
return await sendJsonBefore("POST", url, path, apiKey, appId, body, fetchImpl, deadline, signer);
|
|
132
176
|
} finally {
|
|
133
177
|
deadline?.clear();
|
|
134
178
|
}
|
|
135
179
|
}
|
|
180
|
+
function patchJson(url, path, apiKey, appId, body, fetchImpl) {
|
|
181
|
+
return sendJsonBefore("PATCH", url, path, apiKey, appId, body, fetchImpl, void 0, void 0);
|
|
182
|
+
}
|
|
136
183
|
function startDeadline(ms) {
|
|
137
184
|
const controller = new AbortController();
|
|
138
185
|
const timer = setTimeout(() => controller.abort(), ms);
|
|
139
186
|
return { signal: controller.signal, ms, clear: () => clearTimeout(timer) };
|
|
140
187
|
}
|
|
141
|
-
async function
|
|
188
|
+
async function sendJsonBefore(method, url, path, apiKey, appId, body, fetchImpl, deadline, signer) {
|
|
142
189
|
let response;
|
|
143
190
|
const endpoint = new URL(path, url).toString();
|
|
144
191
|
const payload = JSON.stringify(body);
|
|
145
|
-
const signature = await signatureHeaders(
|
|
192
|
+
const signature = await signatureHeaders(method, endpoint, payload ?? "", signer);
|
|
146
193
|
try {
|
|
147
194
|
response = await fetchImpl(endpoint, {
|
|
148
|
-
method
|
|
195
|
+
method,
|
|
149
196
|
headers: {
|
|
150
197
|
"content-type": "application/json",
|
|
151
198
|
authorization: `Bearer ${apiKey}`,
|
|
@@ -264,6 +311,22 @@ async function findLiveItem(creds, repository, subject, fetchImpl) {
|
|
|
264
311
|
const items = page.data ?? [];
|
|
265
312
|
return items[0] ?? null;
|
|
266
313
|
}
|
|
314
|
+
async function findLiveItemForIssue(creds, opts, fetchImpl) {
|
|
315
|
+
const subject = resolveWorkSubject(opts);
|
|
316
|
+
if ("issue" in subject) {
|
|
317
|
+
const item = await findLiveItem(creds, subject.repository, { issue: subject.issue }, fetchImpl);
|
|
318
|
+
return { item, label: `${subject.repository}#${subject.issue}` };
|
|
319
|
+
}
|
|
320
|
+
const query = new URLSearchParams({ key: subject.key });
|
|
321
|
+
if (subject.tracker !== void 0) query.set("tracker", subject.tracker);
|
|
322
|
+
const page = await getJson(creds.url, `/v1/work-items?${query.toString()}`, creds.apiKey, creds.appId, fetchImpl);
|
|
323
|
+
const items = page.data ?? [];
|
|
324
|
+
if (items.length > 1) {
|
|
325
|
+
const trackers = items.map((i) => i.tracker ?? "unknown").join(" and ");
|
|
326
|
+
throw new WorkCommandError(`${subject.key} names an item in ${trackers}. Pass --tracker to say which.`);
|
|
327
|
+
}
|
|
328
|
+
return { item: items[0] ?? null, label: subject.key };
|
|
329
|
+
}
|
|
267
330
|
function environmentFacts(opts) {
|
|
268
331
|
const identity = resolveRepoIdentity(opts.cwd);
|
|
269
332
|
const sessionId = opts.sessionIdOverride ?? detectActiveSession({
|
|
@@ -336,9 +399,7 @@ async function runWorkBuild(opts) {
|
|
|
336
399
|
const { data: data2 } = await postJsonWithRetry(url, "/v1/work-items", apiKey, appId, body2, fetchImpl, retries, sleep);
|
|
337
400
|
const label = data2.number != null ? `#${data2.number}` : String(data2.workItemId);
|
|
338
401
|
const launch = data2.number != null ? `OUTERLAYER_WORK=${data2.number} claude` : null;
|
|
339
|
-
const
|
|
340
|
-
const output2 = opts.json ? JSON.stringify({ ...data2, ...launch !== null ? { launchCommand: launch } : {} }) : `${C.green}\u2713${C.reset} on Work for you to build ${C.dim}\xB7${C.reset} ${label} ${C.dim}\xB7${C.reset} no host will take it` + (branch !== null ? `
|
|
341
|
-
branch: ${branch}` : "") + (launch !== null ? `
|
|
402
|
+
const output2 = opts.json ? JSON.stringify({ ...data2, ...launch !== null ? { launchCommand: launch } : {} }) : `${C.green}\u2713${C.reset} on Work for you to build ${C.dim}\xB7${C.reset} ${label} ${C.dim}\xB7${C.reset} no host will take it` + (launch !== null ? `
|
|
342
403
|
start your session with: ${launch}` : "");
|
|
343
404
|
if (!opts.quiet) process.stdout.write(output2 + "\n");
|
|
344
405
|
return { data: data2, output: output2 };
|
|
@@ -360,7 +421,7 @@ async function runWorkLinkSession(opts) {
|
|
|
360
421
|
return await linkSession(opts);
|
|
361
422
|
} catch (err) {
|
|
362
423
|
if (opts.logFailures) {
|
|
363
|
-
const { logHookError } = await import('./hook-fast-
|
|
424
|
+
const { logHookError } = await import('./hook-fast-YAZG5MDX.js');
|
|
364
425
|
const reason = err instanceof Error ? err.message : String(err);
|
|
365
426
|
logHookError(opts.home ?? homeFromEnv(opts.env ?? process.env), new Error(`work link-session #${opts.number} failed: ${reason}`));
|
|
366
427
|
}
|
|
@@ -428,13 +489,10 @@ async function runWorkRemove(opts) {
|
|
|
428
489
|
if (!opts.quiet) process.stdout.write(output2 + "\n");
|
|
429
490
|
return { data: data2, output: output2 };
|
|
430
491
|
}
|
|
431
|
-
const
|
|
432
|
-
const repository = resolveRepository(opts.repo, cwd);
|
|
433
|
-
const number = subject.issue;
|
|
434
|
-
const item = await findLiveItem(creds, repository, subject, fetchImpl);
|
|
492
|
+
const { item, label } = await findLiveItemForIssue(creds, { ...opts, cwd }, fetchImpl);
|
|
435
493
|
if (!item) {
|
|
436
494
|
const data2 = { workItemId: null, removed: true, itemWithdrawn: false, noLiveAddition: true };
|
|
437
|
-
const output2 = opts.json ? JSON.stringify(data2) : `${C.green}\u2713${C.reset} nothing to remove ${C.dim}\xB7${C.reset} no live addition on ${
|
|
495
|
+
const output2 = opts.json ? JSON.stringify(data2) : `${C.green}\u2713${C.reset} nothing to remove ${C.dim}\xB7${C.reset} no live addition on ${label}`;
|
|
438
496
|
if (!opts.quiet) process.stdout.write(output2 + "\n");
|
|
439
497
|
return { data: data2, output: output2 };
|
|
440
498
|
}
|
|
@@ -485,13 +543,10 @@ async function runWorkStatus(opts) {
|
|
|
485
543
|
if (!opts.quiet) process.stdout.write(body + "\n");
|
|
486
544
|
return { data: data2, output: body };
|
|
487
545
|
}
|
|
488
|
-
const subject = resolveSubject(opts);
|
|
489
|
-
const repository = resolveRepository(opts.repo, cwd);
|
|
490
546
|
const fetchImpl = opts.fetchImpl ?? defaultFetch;
|
|
491
|
-
const
|
|
492
|
-
const item = await findLiveItem(creds, repository, subject, fetchImpl);
|
|
547
|
+
const { item, label } = await findLiveItemForIssue(creds, { ...opts, cwd }, fetchImpl);
|
|
493
548
|
if (!item) {
|
|
494
|
-
throw new WorkCommandError(`no live item for ${
|
|
549
|
+
throw new WorkCommandError(`no live item for ${label}`);
|
|
495
550
|
}
|
|
496
551
|
const { data } = await getJson(creds.url, `/v1/work-items/${item.id}`, creds.apiKey, creds.appId, fetchImpl);
|
|
497
552
|
const output = statusOutput(data, opts.json === true);
|
|
@@ -536,4 +591,4 @@ async function runWorkList(opts) {
|
|
|
536
591
|
return { data, output };
|
|
537
592
|
}
|
|
538
593
|
|
|
539
|
-
export { WorkCommandError, environmentFacts,
|
|
594
|
+
export { TRACKERS, WorkCommandError, environmentFacts, findLiveItemForIssue, getJson, isSignatureRefusal, parsePositiveInt, patchJson, postJson, resolveCredentials, runWorkBuild, runWorkLinkSession, runWorkList, runWorkRemove, runWorkStatus, signatureRefusalMessage, verifiedTrackerNames };
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
+
import { fetchFactories, selectFactory, saveFactoryConnection, autoConnectedLine } from './chunk-CG36IONK.js';
|
|
4
|
+
import { resolveRepoIdentity } from './chunk-QNLX477Q.js';
|
|
5
|
+
import { resolveGatewayCredentials } from './chunk-NTRCK4NH.js';
|
|
6
|
+
import { findGitDirs, readRepoConnection } from './chunk-BJ3KTMDH.js';
|
|
7
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
8
|
+
import { homeFromEnv } from './chunk-VNVZDWO3.js';
|
|
3
9
|
import { openSync, fstatSync, readSync, closeSync } from 'fs';
|
|
4
10
|
import { join } from 'path';
|
|
5
11
|
|
|
@@ -76,4 +82,32 @@ function transcriptPathForSession(sessionId, home, readTailImpl = readTail) {
|
|
|
76
82
|
return found;
|
|
77
83
|
}
|
|
78
84
|
|
|
79
|
-
|
|
85
|
+
// src/auto-connect.ts
|
|
86
|
+
async function autoConnect(opts) {
|
|
87
|
+
const env = opts.env ?? process.env;
|
|
88
|
+
const home = opts.home ?? homeFromEnv(env);
|
|
89
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
90
|
+
const resolved = resolveGatewayCredentials({ url: opts.url, apiKey: opts.apiKey, appId: opts.appId, home, env, cwd });
|
|
91
|
+
if (resolved.ok || resolved.kind !== "login" || !resolved.credential || !resolved.url) return void 0;
|
|
92
|
+
const dirs = findGitDirs(cwd);
|
|
93
|
+
const repository = opts.repository ?? resolveRepoIdentity(cwd).gitRepo;
|
|
94
|
+
if (dirs === void 0 || repository === void 0) return void 0;
|
|
95
|
+
const listed = await fetchFactories(opts.fetchImpl ?? fetch, resolved.url, resolved.credential, repository);
|
|
96
|
+
if (!listed.ok || listed.factories.length === 0) return void 0;
|
|
97
|
+
const chosen = selectFactory(listed.factories, readRepoConnection(cwd), repository);
|
|
98
|
+
if (chosen.factory === void 0) {
|
|
99
|
+
return `you are logged in, but no factory is chosen for this repository, and more than one fits. Run \`${cliInvocation()} connect --factory <org>/<factory>\` with one of:
|
|
100
|
+
${chosen.text}
|
|
101
|
+
Or pass --app-id / set OUTERLAYER_APP_ID.`;
|
|
102
|
+
}
|
|
103
|
+
try {
|
|
104
|
+
saveFactoryConnection(dirs.gitCommonDir, void 0, chosen.factory, /* @__PURE__ */ new Date());
|
|
105
|
+
} catch {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
process.stderr.write(`${autoConnectedLine(repository, chosen.factory, chosen.reason)}
|
|
109
|
+
`);
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export { autoConnect, detectActiveSession, transcriptPathForSession };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { skillDir, FORMER_MAINTAINED_NAMES, isMaintainedCopy } from './chunk-
|
|
4
|
-
import { emitTree, ALL_TARGET_IDS, classifyTree } from './chunk-
|
|
3
|
+
import { skillDir, FORMER_MAINTAINED_NAMES, isMaintainedCopy } from './chunk-NNLA7LLQ.js';
|
|
4
|
+
import { emitTree, ALL_TARGET_IDS, classifyTree } from './chunk-WFSUUUAN.js';
|
|
5
|
+
import { cliInvocation } from './chunk-CRB3POP4.js';
|
|
5
6
|
import { readFileSync, existsSync, unlinkSync, rmdirSync, readdirSync } from 'fs';
|
|
6
7
|
import { join, dirname, relative, sep } from 'path';
|
|
7
8
|
|
|
@@ -70,7 +71,7 @@ function checkFormerSkillNames(repoRoot) {
|
|
|
70
71
|
name: "Renamed skills",
|
|
71
72
|
status: "warn",
|
|
72
73
|
detail: `copies under earlier names: ${retired.map(skillDir).join(", ")}`,
|
|
73
|
-
fix:
|
|
74
|
+
fix: `Run \`${cliInvocation()} context emit\` to replace them with the current names, then commit.`
|
|
74
75
|
});
|
|
75
76
|
}
|
|
76
77
|
const hits = filesNamingFormerSkills(repoRoot);
|
|
@@ -79,7 +80,7 @@ function checkFormerSkillNames(repoRoot) {
|
|
|
79
80
|
name: "Skill names",
|
|
80
81
|
status: "warn",
|
|
81
82
|
detail: `${hits.map((h) => `${h.path} (${h.formers.join(", ")})`).join("; ")} still ${hits.length === 1 ? "names" : "name"} a skill by an earlier name`,
|
|
82
|
-
fix: `Replace each earlier name with the current one: ${Object.entries(FORMER_MAINTAINED_NAMES).map(([former, current]) => `${former} \u2192 ${current}`).join(", ")}.
|
|
83
|
+
fix: `Replace each earlier name with the current one: ${Object.entries(FORMER_MAINTAINED_NAMES).map(([former, current]) => `${former} \u2192 ${current}`).join(", ")}. \`${cliInvocation()} init --update\` does this for a file you have not edited.`
|
|
83
84
|
});
|
|
84
85
|
}
|
|
85
86
|
return checks;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { readFileSync } from 'fs';
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
5
|
+
|
|
6
|
+
createRequire(import.meta.url);
|
|
7
|
+
function startTimeOf(pid) {
|
|
8
|
+
if (process.platform === "linux") return startTimeOfLinux(pid);
|
|
9
|
+
return startTimeOfPs(pid);
|
|
10
|
+
}
|
|
11
|
+
function startTimeOfLinux(pid) {
|
|
12
|
+
try {
|
|
13
|
+
const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
|
|
14
|
+
const afterComm = stat.slice(stat.lastIndexOf(")") + 1).trim();
|
|
15
|
+
const fields = afterComm.split(/\s+/);
|
|
16
|
+
if (fields[0] === "Z" || fields[0] === "X") return null;
|
|
17
|
+
const starttime = fields[19];
|
|
18
|
+
return starttime ?? null;
|
|
19
|
+
} catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function startTimeOfPs(pid) {
|
|
24
|
+
try {
|
|
25
|
+
const out = execFileSync("ps", ["-o", "lstart=", "-p", String(pid)], { encoding: "utf8" }).trim();
|
|
26
|
+
return out.length > 0 ? out : null;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function isSameProcess(pid, start) {
|
|
32
|
+
return startTimeOf(pid) === start;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { isSameProcess, startTimeOf };
|