@outerlayer/cli 0.4.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +4 -2
- package/dist/build-info.json +1 -1
- package/dist/{check-WQP2CZDW.js → check-7MFH6HNC.js} +11 -11
- package/dist/{chunk-L2DBRKRA.js → chunk-3TFPDVTI.js} +1 -1
- package/dist/{chunk-G7FSV7JX.js → chunk-4C4THABW.js} +2116 -5
- package/dist/{chunk-DVYHCMB2.js → chunk-7WERLFVR.js} +1 -1
- package/dist/{chunk-FAJSS2WN.js → chunk-DM3VFDS3.js} +138 -34
- package/dist/{chunk-7A6RVXPZ.js → chunk-HZRNMGLF.js} +1 -1
- package/dist/{chunk-3YPKXE5L.js → chunk-LT5TZHYH.js} +8 -5
- package/dist/{chunk-HE2D4EY5.js → chunk-LYCDNMOH.js} +1 -1
- package/dist/{chunk-FV2CCGXK.js → chunk-QDQEUVUF.js} +1 -1
- package/dist/{chunk-FS2VYGZT.js → chunk-QY22NZUW.js} +6 -6
- package/dist/{chunk-7YIOOFVJ.js → chunk-RFUPN6KX.js} +4 -4
- package/dist/{chunk-3TT7RQYB.js → chunk-SY4GK4SP.js} +1 -1
- package/dist/{chunk-NYC54VBD.js → chunk-TWNWNS2Q.js} +5 -5
- package/dist/{chunk-5DLBAXY5.js → chunk-W5FVUZXV.js} +2 -2
- package/dist/{chunk-6Y63SXFO.js → chunk-WFJ65NUD.js} +1 -1
- package/dist/{chunk-2E54Z3P5.js → chunk-Y7KJLXYN.js} +3 -3
- package/dist/{chunk-CBZB6XY6.js → chunk-YFHIIH4B.js} +2 -2
- package/dist/{cli-NHUXABYH.js → cli-W62AFRSW.js} +71 -47
- package/dist/{connect-cmd-OOG4TPU7.js → connect-cmd-ZTJONP37.js} +4 -4
- package/dist/{dist-RW4UPPC2.js → dist-44CQVWGT.js} +1 -1
- package/dist/{doctor-UFVL4PZY.js → doctor-ZLGZYMDK.js} +7 -7
- package/dist/{emit-artifact-cmd-KTYW2TN2.js → emit-artifact-cmd-AKZP7TMF.js} +67 -7
- package/dist/{emit-criteria-cmd-VAUUSAYD.js → emit-criteria-cmd-7MXQVCKD.js} +1 -1
- package/dist/{emit-finding-cmd-UR4ID45Z.js → emit-finding-cmd-N2FTGCVC.js} +1 -1
- package/dist/{emit-result-cmd-FDTUKGKE.js → emit-result-cmd-4CPDBMN2.js} +4 -4
- package/dist/index.js +1 -1
- package/dist/{init-DXBCOAJK.js → init-55Y4LHWF.js} +6 -6
- package/dist/{init-YEXK35CF.js → init-XXEKWZQP.js} +6 -6
- package/dist/{init-cmd-NHR7PRSQ.js → init-cmd-WLST2F7G.js} +6 -6
- package/dist/{loop-VZOLL4WQ.js → loop-JFIBP4B7.js} +8 -8
- package/dist/{machine-WSG52J75.js → machine-ZBPT2J3R.js} +5 -5
- package/dist/{mcp-serve-cmd-JPTP5FMS.js → mcp-serve-cmd-N6UD2KBX.js} +1 -1
- package/dist/{status-2UZKKNB7.js → status-UJXWZRN5.js} +6 -6
- package/dist/{sync-cmd-VPPYCNNM.js → sync-cmd-4G4A7EVN.js} +4 -4
- package/dist/{watch-5C4ZBBGO.js → watch-7SKJKGAA.js} +4 -4
- package/dist/{work-claim-cmd-LSO2B2EX.js → work-claim-cmd-5F7VZ42N.js} +6 -6
- package/dist/{work-cmd-UOQO2AD4.js → work-cmd-QAUZ7MTD.js} +3 -3
- package/dist/{work-comment-cmd-WF3EOLAE.js → work-comment-cmd-BNCSBTLH.js} +3 -3
- package/dist/{work-open-pr-cmd-4SSQZMYG.js → work-open-pr-cmd-VFYZHIIW.js} +4 -4
- package/dist/{work-pr-cmd-6AN6RRQJ.js → work-pr-cmd-PV32ZLSI.js} +2 -2
- package/package.json +1 -1
- package/skill-pack/maintained/emitting-evidence/SKILL.md +10 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-
|
|
4
|
-
import './chunk-
|
|
3
|
+
import { gatherDoctorChecks, doctorExitCode, summarizeChecks, renderDoctorText, recordWrapped, recordUnwrapped, recordRemoval, readManifest, recordInstall, recordStatusline } from './chunk-TWNWNS2Q.js';
|
|
4
|
+
import './chunk-SY4GK4SP.js';
|
|
5
5
|
import './chunk-F47JBIAW.js';
|
|
6
6
|
import './chunk-BKO6JEZI.js';
|
|
7
|
-
import './chunk-
|
|
7
|
+
import './chunk-W5FVUZXV.js';
|
|
8
8
|
import './chunk-BFESLKPP.js';
|
|
9
|
-
import './chunk-
|
|
10
|
-
import './chunk-
|
|
9
|
+
import './chunk-WFJ65NUD.js';
|
|
10
|
+
import './chunk-4C4THABW.js';
|
|
11
11
|
import './chunk-USO2DKBD.js';
|
|
12
12
|
import './chunk-N6LURUEF.js';
|
|
13
13
|
import { C, NO_COLOR_FLAG, warnDeprecated, stripNoColor, API_KEY_FLAG_DEPRECATION } from './chunk-YRYMNBGQ.js';
|
|
@@ -3792,8 +3792,8 @@ ${starter.output}`),
|
|
|
3792
3792
|
}
|
|
3793
3793
|
}
|
|
3794
3794
|
async function realConnectDepsForCwd() {
|
|
3795
|
-
const { realConnectDeps } = await import('./connect-cmd-
|
|
3796
|
-
const { resolveRepoIdentity } = await import('./dist-
|
|
3795
|
+
const { realConnectDeps } = await import('./connect-cmd-ZTJONP37.js');
|
|
3796
|
+
const { resolveRepoIdentity } = await import('./dist-44CQVWGT.js');
|
|
3797
3797
|
return {
|
|
3798
3798
|
...realConnectDeps(),
|
|
3799
3799
|
home: homeFromEnv(),
|
|
@@ -3846,7 +3846,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3846
3846
|
else process.stdout.write(outcome.text);
|
|
3847
3847
|
return;
|
|
3848
3848
|
}
|
|
3849
|
-
const { runInitCommand } = await import('./init-cmd-
|
|
3849
|
+
const { runInitCommand } = await import('./init-cmd-WLST2F7G.js');
|
|
3850
3850
|
const code = await runInitCommand(
|
|
3851
3851
|
{ json: opts.json, factory: opts.factory },
|
|
3852
3852
|
{
|
|
@@ -3870,7 +3870,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3870
3870
|
"after",
|
|
3871
3871
|
"\nRun it in a repository, after `outerlayer login`. With a login, connect lists\nthe factories you can use and takes the first rule that leaves one answer:\n 1. --factory <org>/<factory>, or a factory id\n 2. the factory this repository is already connected to\n 3. the one factory this repository is linked to\n 4. the one factory you can use\n 5. on a terminal, ask; with no terminal, exit 1 and list each --factory value\n\nIt says what it chose and why. The choice is saved in this repository's git\ndirectory (outerlayer/connection.json), shared by every worktree of the\nclone and never committed. A factory key already belongs to one factory, so\nconnect changes nothing for it. Connect never links a repository.\n\nAfter it saves the choice, connect checks that this repository is linked to\nthe factory. If it is not, connect says so, prints the factory's Work page\nlink where you link it, and exits 2. The choice is saved either way. Run\nconnect again once the repository is linked. With --json, the document has\nlinked (true, false, or null when it could not be checked) and, when false,\nlinkUrl.\n"
|
|
3872
3872
|
).action(async (opts) => {
|
|
3873
|
-
const { runConnectCommand } = await import('./connect-cmd-
|
|
3873
|
+
const { runConnectCommand } = await import('./connect-cmd-ZTJONP37.js');
|
|
3874
3874
|
const code = await runConnectCommand({ factory: opts.factory, json: opts.json }, await realConnectDepsForCwd(), {
|
|
3875
3875
|
stdout: process.stdout,
|
|
3876
3876
|
stderr: process.stderr
|
|
@@ -3918,7 +3918,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3918
3918
|
"\nIncremental: only sessions newer than the last checkpoint ship. The tier\nis applied on this machine before anything leaves it; `--dry-run` prints\nexactly what would. The hook-triggered background sync runs `--quiet`.\nExit 2 means the server rejected at least one session.\n"
|
|
3919
3919
|
).action(async (opts) => {
|
|
3920
3920
|
warnIfApiKeyFlag(opts);
|
|
3921
|
-
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-
|
|
3921
|
+
const { runSync, SyncConfigError, SyncTransportError } = await import('./sync-cmd-4G4A7EVN.js');
|
|
3922
3922
|
try {
|
|
3923
3923
|
const result = await runSync({
|
|
3924
3924
|
url: opts.url,
|
|
@@ -3947,7 +3947,7 @@ function buildProgram(argv = process.argv) {
|
|
|
3947
3947
|
if (invokedCommandToken(argv) === "watch") {
|
|
3948
3948
|
warnDeprecated("`outerlayer watch` is now `outerlayer daemon`; the old name will be removed in a future release.");
|
|
3949
3949
|
}
|
|
3950
|
-
const { runWatch } = await import('./watch-
|
|
3950
|
+
const { runWatch } = await import('./watch-7SKJKGAA.js');
|
|
3951
3951
|
await runWatch({ once: opts.once });
|
|
3952
3952
|
});
|
|
3953
3953
|
program2.command("hook <event>", { hidden: true }).description("capture-hook fast path, installed by `init`").action(() => {
|
|
@@ -4051,7 +4051,7 @@ function registerEmitCommands(program2) {
|
|
|
4051
4051
|
return;
|
|
4052
4052
|
}
|
|
4053
4053
|
warnIfApiKeyFlag(opts);
|
|
4054
|
-
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-
|
|
4054
|
+
const { runEmitResult, EmitResultError } = await import('./emit-result-cmd-4CPDBMN2.js');
|
|
4055
4055
|
try {
|
|
4056
4056
|
const result = await runEmitResult({
|
|
4057
4057
|
name,
|
|
@@ -4074,12 +4074,35 @@ function registerEmitCommands(program2) {
|
|
|
4074
4074
|
throw err;
|
|
4075
4075
|
}
|
|
4076
4076
|
});
|
|
4077
|
-
emitCmd.command("artifact <file>").description("Emit a proof artifact: screenshot, recording, report, or log").requiredOption("--caption <text>", "what this artifact shows or proves").option("--for <criterion-id>", "id of the criterion this artifact proves (e.g. LOGIN-01)").option(
|
|
4077
|
+
emitCmd.command("artifact <file>").description("Emit a proof artifact: screenshot, recording, report, or log").requiredOption("--caption <text>", "what this artifact shows or proves").option("--for <criterion-id>", "id of the criterion this artifact proves (e.g. LOGIN-01)").option(
|
|
4078
|
+
"--test <name[=path:line]>",
|
|
4079
|
+
"bind only this test of JUnit results; repeatable; =path:line sets its location",
|
|
4080
|
+
(value, previous = []) => [...previous, value]
|
|
4081
|
+
).option("--replaces <ids>", "artifact id(s) this one corrects; comma-separate 2-20 to retire them all").option("--pr <number>", "pull request number to anchor to").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").addHelpText(
|
|
4078
4082
|
"after",
|
|
4079
|
-
|
|
4083
|
+
`
|
|
4084
|
+
outerlayer emit artifact shot.png --caption "the dot row, current dot marked" --for LOGIN-01
|
|
4085
|
+
|
|
4086
|
+
Inside a recorded Claude Code session the artifact spools locally and ships,
|
|
4087
|
+
bound to that session, on the next \`outerlayer sync\` \u2014 but only if that
|
|
4088
|
+
session was launched with OUTERLAYER_WORK; without it nothing the session
|
|
4089
|
+
produces may leave the machine, and the command refuses rather than queue an
|
|
4090
|
+
artifact that can never ship. Otherwise it uploads immediately, anchored to a
|
|
4091
|
+
pull request (--pr, or CI's PR context) or to the current git checkout. With
|
|
4092
|
+
nothing to attach it to, the command refuses.
|
|
4093
|
+
|
|
4094
|
+
A JUnit XML file (.xml, root <testsuites> or <testsuite>) bound with --for proves a
|
|
4095
|
+
criterion that declares test proof once every bound test passed. Without --test every
|
|
4096
|
+
test in the file is bound; each --test binds only that one. Give a test's location with
|
|
4097
|
+
--test "name=src/a.test.ts:42" when the runner's file does not carry it.
|
|
4098
|
+
|
|
4099
|
+
--replaces: an already-uploaded target is marked superseded and hidden
|
|
4100
|
+
everywhere, bytes and deep link untouched; a still-queued one is cancelled
|
|
4101
|
+
locally so it never uploads. One correction can retire several duplicates.
|
|
4102
|
+
`
|
|
4080
4103
|
).action(async (file, opts) => {
|
|
4081
4104
|
warnIfApiKeyFlag(opts);
|
|
4082
|
-
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-
|
|
4105
|
+
const { runEmitArtifact, EmitArtifactError } = await import('./emit-artifact-cmd-AKZP7TMF.js');
|
|
4083
4106
|
let pr;
|
|
4084
4107
|
if (opts.pr !== void 0) {
|
|
4085
4108
|
pr = parseTrackerNumber(opts.pr);
|
|
@@ -4094,6 +4117,7 @@ function registerEmitCommands(program2) {
|
|
|
4094
4117
|
caption: opts.caption,
|
|
4095
4118
|
criterionId: opts.for,
|
|
4096
4119
|
replaces: opts.replaces,
|
|
4120
|
+
tests: opts.test,
|
|
4097
4121
|
pr,
|
|
4098
4122
|
json: opts.json,
|
|
4099
4123
|
url: opts.url,
|
|
@@ -4113,7 +4137,7 @@ function registerEmitCommands(program2) {
|
|
|
4113
4137
|
'\n outerlayer emit finding --id gate-skip --category tooling \\\n --title "The pre-push gate prints green when a step was skipped" \\\n --file scripts/git/pre-push-checks.mjs --where "build session"\n\nRecords one problem you hit in the factory: an instruction that is wrong or\nmissing (context), a flaky test, a misbehaving script (tooling), a local\nsetup trap (environment), a bug outside your own change (defect), or\nanything else. A problem in your own change is fixed, not recorded.\nA context finding needs --rule-path and --rule-relation, and --rule-quote\nunless the relation is missing.\n--item names the work item; without it, inside a recorded session, the\nitem that session was launched for is used automatically.\n'
|
|
4114
4138
|
).action(async (opts) => {
|
|
4115
4139
|
warnIfApiKeyFlag(opts);
|
|
4116
|
-
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4140
|
+
const { runEmitFinding, refuseRemovedFindingFlags, EmitFindingError } = await import('./emit-finding-cmd-N2FTGCVC.js');
|
|
4117
4141
|
try {
|
|
4118
4142
|
refuseRemovedFindingFlags(opts);
|
|
4119
4143
|
const result = await runEmitFinding({
|
|
@@ -4152,7 +4176,7 @@ function registerEmitCommands(program2) {
|
|
|
4152
4176
|
"\n outerlayer emit findings review.json --item 412\n\nRecords a whole batch at once \u2014 a FindingBatch JSON file (schemaVersion,\noptional headSha / contextSourceSha, and 1-500 findings), validated against\nthe same contract `emit finding` uses before anything is sent. Re-emitting\nan id already on the item replaces that row rather than adding a second one.\n--item names the work item; without it, inside a recorded session, the item\nthat session was launched for is used automatically.\n"
|
|
4153
4177
|
).action(async (file, opts) => {
|
|
4154
4178
|
warnIfApiKeyFlag(opts);
|
|
4155
|
-
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-
|
|
4179
|
+
const { runEmitFindings, EmitFindingError } = await import('./emit-finding-cmd-N2FTGCVC.js');
|
|
4156
4180
|
try {
|
|
4157
4181
|
const result = await runEmitFindings({
|
|
4158
4182
|
file,
|
|
@@ -4173,10 +4197,10 @@ function registerEmitCommands(program2) {
|
|
|
4173
4197
|
});
|
|
4174
4198
|
emitCmd.command("criteria <file>").description("Record a work item's acceptance criteria from a JSON file (- for stdin)").option("--item <number>", "work item to record on directly, by its number in this factory").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").addHelpText(
|
|
4175
4199
|
"after",
|
|
4176
|
-
'\n outerlayer emit criteria criteria.json --item 412\n\nRecords the item\'s acceptance criteria as one list. The file is JSON:\n { "criteria": [ { "id": "AC-1", "text": "Given ...", "proof": null },\n { "id": "login.redirect", "text": "...", "proof": "screenshot" } ] }\nAn id is 1-64 characters of A-Z a-z 0-9 . _ : - and is the id evidence is bound to with\n`emit artifact --for`. proof is video, screenshot, report, log, file or null (any bound\nartifact proves it). The list holds 1 to 200 criteria, each text at most 2,000\ncharacters, and no id twice. The list is validated before anything is sent.\nOnce an item has a list, only a person can replace it: run the command outside an\nagent session, with your own login. A key bound to no member cannot replace it either.\n--item names the work item; without it, inside a recorded session, the item that\nsession was launched for is used automatically.\n'
|
|
4200
|
+
'\n outerlayer emit criteria criteria.json --item 412\n\nRecords the item\'s acceptance criteria as one list. The file is JSON:\n { "criteria": [ { "id": "AC-1", "text": "Given ...", "proof": null },\n { "id": "login.redirect", "text": "...", "proof": "screenshot" } ] }\nAn id is 1-64 characters of A-Z a-z 0-9 . _ : - and is the id evidence is bound to with\n`emit artifact --for`. proof is video, screenshot, report, log, test, file or null (any bound\nartifact proves it). The list holds 1 to 200 criteria, each text at most 2,000\ncharacters, and no id twice. The list is validated before anything is sent.\nOnce an item has a list, only a person can replace it: run the command outside an\nagent session, with your own login. A key bound to no member cannot replace it either.\n--item names the work item; without it, inside a recorded session, the item that\nsession was launched for is used automatically.\n'
|
|
4177
4201
|
).action(async (file, opts) => {
|
|
4178
4202
|
warnIfApiKeyFlag(opts);
|
|
4179
|
-
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-
|
|
4203
|
+
const { runEmitCriteria, EmitCriteriaError } = await import('./emit-criteria-cmd-7MXQVCKD.js');
|
|
4180
4204
|
try {
|
|
4181
4205
|
const result = await runEmitCriteria({
|
|
4182
4206
|
file,
|
|
@@ -4203,7 +4227,7 @@ function registerWorkCommands(program2) {
|
|
|
4203
4227
|
"\n outerlayer work build --issue 42 # a host builds it\n outerlayer work build --item 7 # retry an item already on Work\n outerlayer work build --issue 42 --local # you build it\n outerlayer work build --issue ENG-123 --tracker linear # a Linear issue\n\nWithout --local, records a build request: a host takes the item when it\nhas a free slot. It never links the calling session and never takes a\nlease, even run from inside one.\n\nWith --local, puts the item on Work with no build request, so no host\ntakes it, and prints the line that starts your session on it. That\nsession links itself and holds the item's lease while it works.\n"
|
|
4204
4228
|
).action(async (opts) => {
|
|
4205
4229
|
warnIfApiKeyFlag(opts);
|
|
4206
|
-
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-
|
|
4230
|
+
const { runWorkBuild, WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4207
4231
|
try {
|
|
4208
4232
|
await runWorkBuild(opts);
|
|
4209
4233
|
} catch (err) {
|
|
@@ -4219,7 +4243,7 @@ function registerWorkCommands(program2) {
|
|
|
4219
4243
|
"\n outerlayer work link-session 42\n\nNames an item that already exists on the calling session \u2014 it never\ncreates one. Create one with `outerlayer work build --local`. Linking\nthe same session to the same item twice is a no-op. Also takes or\nrenews that session's own 20-minute lease, unless --no-lease or\n--ended is given, or another worker already holds a live one.\n"
|
|
4220
4244
|
).action(async (number, opts) => {
|
|
4221
4245
|
warnIfApiKeyFlag(opts);
|
|
4222
|
-
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-
|
|
4246
|
+
const { runWorkLinkSession, WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4223
4247
|
try {
|
|
4224
4248
|
await runWorkLinkSession({ ...opts, number, noLease: opts.lease === false });
|
|
4225
4249
|
} catch (err) {
|
|
@@ -4244,8 +4268,8 @@ most one action flag may be given.
|
|
|
4244
4268
|
`
|
|
4245
4269
|
).action(async (opts) => {
|
|
4246
4270
|
warnIfApiKeyFlag(opts);
|
|
4247
|
-
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4248
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4271
|
+
const { runWorkComment, WorkCommentCommandError } = await import('./work-comment-cmd-BNCSBTLH.js');
|
|
4272
|
+
const { WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4249
4273
|
try {
|
|
4250
4274
|
await runWorkComment(opts);
|
|
4251
4275
|
} catch (err) {
|
|
@@ -4261,8 +4285,8 @@ most one action flag may be given.
|
|
|
4261
4285
|
"\n outerlayer work threads --item 7\n\nPrints the item's general thread, then one thread per acceptance\ncriterion that carries proof or a comment, each with who is waiting\non whom next.\n"
|
|
4262
4286
|
).action(async (opts) => {
|
|
4263
4287
|
warnIfApiKeyFlag(opts);
|
|
4264
|
-
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-
|
|
4265
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4288
|
+
const { runWorkThreads, WorkCommentCommandError } = await import('./work-comment-cmd-BNCSBTLH.js');
|
|
4289
|
+
const { WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4266
4290
|
try {
|
|
4267
4291
|
await runWorkThreads(opts);
|
|
4268
4292
|
} catch (err) {
|
|
@@ -4284,7 +4308,7 @@ live addition remains on it.
|
|
|
4284
4308
|
`
|
|
4285
4309
|
).action(async (opts) => {
|
|
4286
4310
|
warnIfApiKeyFlag(opts);
|
|
4287
|
-
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-
|
|
4311
|
+
const { runWorkRemove, WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4288
4312
|
try {
|
|
4289
4313
|
await runWorkRemove(opts);
|
|
4290
4314
|
} catch (err) {
|
|
@@ -4297,7 +4321,7 @@ live addition remains on it.
|
|
|
4297
4321
|
});
|
|
4298
4322
|
workCmd.command("status").description("Show one item's stage, gate ledger, and additions").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
|
|
4299
4323
|
warnIfApiKeyFlag(opts);
|
|
4300
|
-
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-
|
|
4324
|
+
const { runWorkStatus, WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4301
4325
|
try {
|
|
4302
4326
|
await runWorkStatus(opts);
|
|
4303
4327
|
} catch (err) {
|
|
@@ -4310,7 +4334,7 @@ live addition remains on it.
|
|
|
4310
4334
|
});
|
|
4311
4335
|
workCmd.command("list").description("List live work items for this factory").option("--stage <spec|build|review>", "filter by stage").option("--section <attention|waiting|flowing>", "filter by Queue section").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--unclaimed", "only items with no live lease").option("--claimed", "only items with a live lease, held by a host or a local session").option("--startable", "only items with an unused build request and no live lease").option("--needs <amend>", "only items with a thread waiting on an agent").option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").action(async (opts) => {
|
|
4312
4336
|
warnIfApiKeyFlag(opts);
|
|
4313
|
-
const { runWorkList, WorkCommandError } = await import('./work-cmd-
|
|
4337
|
+
const { runWorkList, WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4314
4338
|
try {
|
|
4315
4339
|
await runWorkList(opts);
|
|
4316
4340
|
} catch (err) {
|
|
@@ -4326,7 +4350,7 @@ live addition remains on it.
|
|
|
4326
4350
|
"\n outerlayer work claim --item 42 --kind implement\n\nRecords a lease for this host. A live lease already held by a\ndifferent host is refused; claiming again under the same host extends\nit.\n"
|
|
4327
4351
|
).action(async (opts) => {
|
|
4328
4352
|
warnIfApiKeyFlag(opts);
|
|
4329
|
-
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-
|
|
4353
|
+
const { runWorkClaim, WorkCommandError } = await import('./work-claim-cmd-5F7VZ42N.js');
|
|
4330
4354
|
try {
|
|
4331
4355
|
await runWorkClaim(opts);
|
|
4332
4356
|
} catch (err) {
|
|
@@ -4342,7 +4366,7 @@ live addition remains on it.
|
|
|
4342
4366
|
"\n outerlayer work renew --item 42\n\nExtends this host's own live lease. Refused with a 410 if the lease\nhas expired, or a 403 if a different host holds it.\n"
|
|
4343
4367
|
).action(async (opts) => {
|
|
4344
4368
|
warnIfApiKeyFlag(opts);
|
|
4345
|
-
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-
|
|
4369
|
+
const { runWorkRenew, WorkCommandError } = await import('./work-claim-cmd-5F7VZ42N.js');
|
|
4346
4370
|
try {
|
|
4347
4371
|
await runWorkRenew(opts);
|
|
4348
4372
|
} catch (err) {
|
|
@@ -4354,14 +4378,14 @@ live addition remains on it.
|
|
|
4354
4378
|
}
|
|
4355
4379
|
});
|
|
4356
4380
|
workCmd.command("release").description("Release this host's lease on a work item").option("--item <number>", "the item's number inside this factory").option("--issue <number>", "issue number (default: named by --item instead)").option("--repo <owner/name>", "repository (default: the current checkout's remote)").option("--host <name>", "the claiming host (default: this machine's hostname)").option(
|
|
4357
|
-
"--outcome <ok|failed|timed_out|idle|lease_lost|interrupted|stopped>",
|
|
4381
|
+
"--outcome <ok|incomplete|failed|timed_out|idle|lease_lost|interrupted|stopped>",
|
|
4358
4382
|
"how the attempt ended (default: none)"
|
|
4359
4383
|
).option("--json", "machine-readable JSON output").option("--url <url>", "cloud base URL (or OUTERLAYER_URL / config)").addOption(apiKeyOption()).option("--app-id <id>", "factory id the key is bound to (or OUTERLAYER_APP_ID / config)").addHelpText(
|
|
4360
4384
|
"after",
|
|
4361
4385
|
"\n outerlayer work release --item 42 --outcome ok\n\nMarks this host's lease released, optionally with an outcome.\nReleasing an already-released lease is a no-op that returns the\nrecorded release time and outcome.\n"
|
|
4362
4386
|
).action(async (opts) => {
|
|
4363
4387
|
warnIfApiKeyFlag(opts);
|
|
4364
|
-
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-
|
|
4388
|
+
const { runWorkRelease, WorkCommandError } = await import('./work-claim-cmd-5F7VZ42N.js');
|
|
4365
4389
|
try {
|
|
4366
4390
|
await runWorkRelease(opts);
|
|
4367
4391
|
} catch (err) {
|
|
@@ -4377,7 +4401,7 @@ live addition remains on it.
|
|
|
4377
4401
|
"\n outerlayer work pr 481\n\nRun inside a session already on a work item. Records that pull\nrequest 481 in the checkout's repository belongs to that item \u2014 the\nsame fact a `pr-link` in the session's own transcript records on\nsync. Idempotent: declaring the same pull request twice is a no-op.\n"
|
|
4378
4402
|
).action(async (number, opts) => {
|
|
4379
4403
|
warnIfApiKeyFlag(opts);
|
|
4380
|
-
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-
|
|
4404
|
+
const { runWorkPr, WorkPrCommandError } = await import('./work-pr-cmd-PV32ZLSI.js');
|
|
4381
4405
|
try {
|
|
4382
4406
|
await runWorkPr({ ...opts, number });
|
|
4383
4407
|
} catch (err) {
|
|
@@ -4393,8 +4417,8 @@ live addition remains on it.
|
|
|
4393
4417
|
'\n outerlayer work open-pr --title "Add the thing" --body-file pr.md\n\nIn a host build, which holds an item key, the gateway opens the pull\nrequest as the factory\'s GitHub App, from the branch the claim named,\nor edits the one already open on that branch. No gh command runs.\nIn your own session it runs `gh pr create` (or `gh pr edit`) under your\nlogin, then declares the pull request on the item, as `work pr` does.\nRun it again after a change to the title or description.\n'
|
|
4394
4418
|
).action(async (opts) => {
|
|
4395
4419
|
warnIfApiKeyFlag(opts);
|
|
4396
|
-
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-
|
|
4397
|
-
const { WorkCommandError } = await import('./work-cmd-
|
|
4420
|
+
const { runWorkOpenPr, WorkOpenPrCommandError } = await import('./work-open-pr-cmd-VFYZHIIW.js');
|
|
4421
|
+
const { WorkCommandError } = await import('./work-cmd-QAUZ7MTD.js');
|
|
4398
4422
|
try {
|
|
4399
4423
|
await runWorkOpenPr(opts);
|
|
4400
4424
|
} catch (err) {
|
|
@@ -4411,7 +4435,7 @@ function registerRunnerCommands(program2) {
|
|
|
4411
4435
|
const configOption = "the cloud config file to run against (default: ~/.outerlayer/config.json)";
|
|
4412
4436
|
runnerCmd.command("start").description("Run the loop: claim work, run it, report, clean up, repeat").option("--config <path>", configOption).action(async (opts) => {
|
|
4413
4437
|
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-XVJYZ4IQ.js');
|
|
4414
|
-
const { start, RunnerStartError } = await import('./loop-
|
|
4438
|
+
const { start, RunnerStartError } = await import('./loop-JFIBP4B7.js');
|
|
4415
4439
|
const { RunnerAlreadyRunningError } = await import('./pidfile-UZRH774M.js');
|
|
4416
4440
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4417
4441
|
try {
|
|
@@ -4427,7 +4451,7 @@ function registerRunnerCommands(program2) {
|
|
|
4427
4451
|
});
|
|
4428
4452
|
runnerCmd.command("check").description("Validate the config, the hooks and the key, and print the effective settings").option("--config <path>", configOption).action(async (opts) => {
|
|
4429
4453
|
const { defaultRunnerConfigPath } = await import('./config-XVJYZ4IQ.js');
|
|
4430
|
-
const { runRunnerCheck } = await import('./check-
|
|
4454
|
+
const { runRunnerCheck } = await import('./check-7MFH6HNC.js');
|
|
4431
4455
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4432
4456
|
const result = await runRunnerCheck(configPath);
|
|
4433
4457
|
if (!result.ok) {
|
|
@@ -4466,9 +4490,9 @@ Start the runner from the install layout by putting this line in the service uni
|
|
|
4466
4490
|
});
|
|
4467
4491
|
runnerCmd.command("init").description("Write a runner block that fits this machine; on macOS, offers a Linux VM").option("--config <path>", configOption).option("--vm", "on macOS, run the runner in a Linux VM (Lima), with container builds").option("--no-vm", "on macOS, skip the VM and run builds as unisolated processes").option("--allow-process-builds", "where builds cannot be isolated, run them as processes anyway").addOption(new Option("--config-stdin", "the VM-side hand-off: read the whole config as JSON on stdin").hideHelp()).addOption(new Option("--vm-cli-package <path>", "install this packed CLI tarball in the VM instead of the published version").hideHelp()).action(async (opts) => {
|
|
4468
4492
|
const { defaultRunnerConfigPath, RunnerConfigError } = await import('./config-XVJYZ4IQ.js');
|
|
4469
|
-
const { runRunnerInit, RunnerInitError } = await import('./init-
|
|
4470
|
-
const { detectMachine } = await import('./machine-
|
|
4471
|
-
const { chooseVm, runVmInit, VmInitError } = await import('./init-
|
|
4493
|
+
const { runRunnerInit, RunnerInitError } = await import('./init-55Y4LHWF.js');
|
|
4494
|
+
const { detectMachine } = await import('./machine-ZBPT2J3R.js');
|
|
4495
|
+
const { chooseVm, runVmInit, VmInitError } = await import('./init-XXEKWZQP.js');
|
|
4472
4496
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4473
4497
|
try {
|
|
4474
4498
|
const machine = detectMachine();
|
|
@@ -4625,15 +4649,15 @@ Next:
|
|
|
4625
4649
|
});
|
|
4626
4650
|
runnerCmd.command("stop").description("Take no more work; wait for running jobs to finish, then exit").option("--config <path>", "the cloud config file naming the runner to stop").option("--now", "end running jobs immediately, with outcome stopped").action(async (opts) => {
|
|
4627
4651
|
const { defaultRunnerConfigPath } = await import('./config-XVJYZ4IQ.js');
|
|
4628
|
-
const { requestStop } = await import('./loop-
|
|
4652
|
+
const { requestStop } = await import('./loop-JFIBP4B7.js');
|
|
4629
4653
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4630
4654
|
await requestStop(configPath, Boolean(opts.now));
|
|
4631
4655
|
});
|
|
4632
4656
|
runnerCmd.command("status").description("List running jobs; with --recent, finished ones too").option("--config <path>", "the cloud config file naming the runner to inspect").option("--recent", "also list finished jobs, newest first, capped at 20").option("--json", "machine-readable JSON output").action(async (opts) => {
|
|
4633
4657
|
const { defaultRunnerConfigPath, loadRunnerConfig } = await import('./config-XVJYZ4IQ.js');
|
|
4634
4658
|
const { jobsDir } = await import('./paths-OYKMVYJP.js');
|
|
4635
|
-
const { listJobFiles, runnerProcessState } = await import('./loop-
|
|
4636
|
-
const { renderStatus } = await import('./status-
|
|
4659
|
+
const { listJobFiles, runnerProcessState } = await import('./loop-JFIBP4B7.js');
|
|
4660
|
+
const { renderStatus } = await import('./status-UJXWZRN5.js');
|
|
4637
4661
|
const path2 = await import('path');
|
|
4638
4662
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4639
4663
|
const all = listJobFiles(configPath);
|
|
@@ -4671,7 +4695,7 @@ Next:
|
|
|
4671
4695
|
});
|
|
4672
4696
|
runnerCmd.command("logs").argument("<item>", "the work item's number in the factory").description("Print the newest attempt's log for one item").option("--config <path>", "the cloud config file naming the runner to inspect").option("-f, --follow", "keep printing as the log grows").action(async (itemArg, opts) => {
|
|
4673
4697
|
const { defaultRunnerConfigPath } = await import('./config-XVJYZ4IQ.js');
|
|
4674
|
-
const { listJobFiles } = await import('./loop-
|
|
4698
|
+
const { listJobFiles } = await import('./loop-JFIBP4B7.js');
|
|
4675
4699
|
const { newestAttempt, logPathFor, tail, RunnerLogsError } = await import('./logs-7RYUH5A6.js');
|
|
4676
4700
|
const configPath = opts.config ?? defaultRunnerConfigPath();
|
|
4677
4701
|
const item = parseTrackerNumber(itemArg);
|
|
@@ -4917,7 +4941,7 @@ function registerMcpCommands(program2) {
|
|
|
4917
4941
|
"after",
|
|
4918
4942
|
"\nWhat the stdio .mcp.json entry spawns. Reads newline-delimited JSON-RPC 2.0 on\nstdin and writes responses on stdout. The API key comes from OUTERLAYER_API_KEY\nor ~/.outerlayer/config.json at start-up; with neither the command exits 1 and\nprints why, which the MCP client shows as the connect error.\n"
|
|
4919
4943
|
).action(async (opts) => {
|
|
4920
|
-
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-
|
|
4944
|
+
const { runMcpServe, handleMcpServeError } = await import('./mcp-serve-cmd-N6UD2KBX.js');
|
|
4921
4945
|
try {
|
|
4922
4946
|
await runMcpServe({ url: opts.url, appId: opts.appId });
|
|
4923
4947
|
} catch (err) {
|
|
@@ -4942,7 +4966,7 @@ function registerImportCommands(program2) {
|
|
|
4942
4966
|
});
|
|
4943
4967
|
importCmd.command("capture").description("Install the maintained skills into .outerlayer/").option("--dir <path>", "repo root to write into (default: cwd)").option("--json", "machine-readable JSON output").addHelpText(
|
|
4944
4968
|
"after",
|
|
4945
|
-
"\nInstalls the
|
|
4969
|
+
"\nInstalls the four maintained skills (emitting-evidence, amend,\nreporting-findings, outerlayer) and an AGENTS.md snippet teaching agents to run\n`emit artifact`. A skill that differs from this CLI's bundle is rewritten to it, and the output says so.\n"
|
|
4946
4970
|
).action(async (opts) => {
|
|
4947
4971
|
const { runImportCapture, ImportCaptureError } = await import('./import-capture-cmd-AVZ4VIVJ.js');
|
|
4948
4972
|
try {
|
|
@@ -4982,7 +5006,7 @@ function registerContextCommands(program2) {
|
|
|
4982
5006
|
const contextCmd = program2.command("context").description("Compile and materialize agent context");
|
|
4983
5007
|
contextCmd.command("emit").description("Compile .outerlayer/ into each configured target tool's native files").option("--check", "compare against disk, write nothing, exit 1 on drift (CI mode)").option("--dir <path>", "repo root to read from (default: cwd)").option("--json", "machine-readable JSON output").addHelpText(
|
|
4984
5008
|
"after",
|
|
4985
|
-
'\nTargets come from .outerlayer/config.json only; there is no --target flag.\nMissing or empty config: {"targets": [...]}, e.g. {"targets": ["claude-code"]}.\nKnown targets: claude-code, cursor, codex, copilot, factory.\n\nThe maintained skills (emitting-evidence, amend, reporting-findings)\nfollow this CLI: emit rewrites one that differs from its bundle, and --check reports it as\ndrift. Templates (spec, writing-specs, build) are never rewritten or reported.\n\nOrphan detection (--check) only covers header-carrying outputs: every markdown\ntarget file gets a generated-by comment, but .mcp.json and .cursor/mcp.json are\nJSON with no comment syntax, so they can never be flagged as orphaned; missing\nand content drift still apply to them.\n'
|
|
5009
|
+
'\nTargets come from .outerlayer/config.json only; there is no --target flag.\nMissing or empty config: {"targets": [...]}, e.g. {"targets": ["claude-code"]}.\nKnown targets: claude-code, cursor, codex, copilot, factory.\n\nThe maintained skills (emitting-evidence, amend, reporting-findings, outerlayer)\nfollow this CLI: emit rewrites one that differs from its bundle, and --check reports it as\ndrift. Templates (spec, writing-specs, build) are never rewritten or reported.\n\nOrphan detection (--check) only covers header-carrying outputs: every markdown\ntarget file gets a generated-by comment, but .mcp.json and .cursor/mcp.json are\nJSON with no comment syntax, so they can never be flagged as orphaned; missing\nand content drift still apply to them.\n'
|
|
4986
5010
|
).action(async (opts) => {
|
|
4987
5011
|
await compileContext({ dir: opts.dir, check: opts.check, json: opts.json });
|
|
4988
5012
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
export { promptOnTerminal, realConnectDeps, runConnect, runConnectCommand } from './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
6
|
-
import './chunk-
|
|
3
|
+
export { promptOnTerminal, realConnectDeps, runConnect, runConnectCommand } from './chunk-Y7KJLXYN.js';
|
|
4
|
+
import './chunk-SY4GK4SP.js';
|
|
5
|
+
import './chunk-WFJ65NUD.js';
|
|
6
|
+
import './chunk-4C4THABW.js';
|
|
7
7
|
import './chunk-USO2DKBD.js';
|
|
8
8
|
import './chunk-N6LURUEF.js';
|
|
9
9
|
import './chunk-YRYMNBGQ.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
export { CaptureDaemon, PRICE_TABLE_SOURCE, SECRET_PATTERNS, SOURCE_ADAPTERS, SUPPORTED_VERSIONS, StatuslineAggregator, WARNING_CODES, claudeCodeAdapter, codexAdapter, codexSessionIdFromPath, compareVersions, completePrefix, computeStatuslineState, costOfUsage, cursorAdapter, cursorChatIdFromPath, defaultCodexSessionsDir, defaultCursorChatsDir, defaultCursorProjectsDir, defaultProjectsDir, defaultRawDir, enrichSessionRepo, findCodexRollouts, findCursorChats, findTranscripts, isNewerThanSupported, isPriceKnown, normalizeErrorSignature, normalizeRemote, parseCodexRollout, parseCursorChat, parseTranscript, readStatuslineState, readSyncWatermarkMs, remoteLookupFailed, resolvePrice, resolveRepoIdentity, rootChildIds, scanAll, scrubDeep, scrubText, sessionIdFromPath, setCustomScrubbers, setLocalIdentity, setRepoRoot, statuslineStatePath, tailTranscript, workspacesByHash, writeStatuslineState } from './chunk-
|
|
3
|
+
export { CaptureDaemon, PRICE_TABLE_SOURCE, SECRET_PATTERNS, SOURCE_ADAPTERS, SUPPORTED_VERSIONS, StatuslineAggregator, WARNING_CODES, claudeCodeAdapter, codexAdapter, codexSessionIdFromPath, compareVersions, completePrefix, computeStatuslineState, costOfUsage, cursorAdapter, cursorChatIdFromPath, defaultCodexSessionsDir, defaultCursorChatsDir, defaultCursorProjectsDir, defaultProjectsDir, defaultRawDir, enrichSessionRepo, findCodexRollouts, findCursorChats, findTranscripts, isNewerThanSupported, isPriceKnown, normalizeErrorSignature, normalizeRemote, parseCodexRollout, parseCursorChat, parseTranscript, readStatuslineState, readSyncWatermarkMs, remoteLookupFailed, resolvePrice, resolveRepoIdentity, rootChildIds, scanAll, scrubDeep, scrubText, sessionIdFromPath, setCustomScrubbers, setLocalIdentity, setRepoRoot, statuslineStatePath, tailTranscript, workspacesByHash, writeStatuslineState } from './chunk-4C4THABW.js';
|
|
4
4
|
import './chunk-Z5GEFMRW.js';
|
|
5
5
|
|
|
6
6
|
createRequire(import.meta.url);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-
|
|
3
|
+
import { needsClaudeCredential, claudeCredentialCheck, missingPermissionOf, missingPermissionFix } from './chunk-RFUPN6KX.js';
|
|
4
4
|
import { RepoFilter } from './chunk-TBT347UY.js';
|
|
5
|
-
import './chunk-
|
|
6
|
-
import { detectMachine, supportsContainerBuilds, describeMachineDocker, reachDockerStep, supportsMicroVmBuilds, microVmArchSupported, microVmAssetsPinned } from './chunk-
|
|
7
|
-
import { MIN_ENGINE_MAJOR } from './chunk-
|
|
5
|
+
import './chunk-YFHIIH4B.js';
|
|
6
|
+
import { detectMachine, supportsContainerBuilds, describeMachineDocker, reachDockerStep, supportsMicroVmBuilds, microVmArchSupported, microVmAssetsPinned } from './chunk-3TFPDVTI.js';
|
|
7
|
+
import { MIN_ENGINE_MAJOR } from './chunk-HZRNMGLF.js';
|
|
8
8
|
import { CLAUDE_CODE_VERSION } from './chunk-ZNA27WEV.js';
|
|
9
9
|
import './chunk-N5FOE5PS.js';
|
|
10
10
|
import './chunk-OGFGZQA3.js';
|
|
@@ -12,10 +12,10 @@ import { resolveDevcontainerCli } from './chunk-774HEQL6.js';
|
|
|
12
12
|
import { locateRecipe, assertBuildable, readRecipe, RecipeError } from './chunk-QOZKPLVJ.js';
|
|
13
13
|
import './chunk-W4SQCOZU.js';
|
|
14
14
|
import './chunk-B2G7JHHB.js';
|
|
15
|
-
import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-
|
|
15
|
+
import { getJson, WorkCommandError, signatureRefusalMessage } from './chunk-W5FVUZXV.js';
|
|
16
16
|
import './chunk-BFESLKPP.js';
|
|
17
|
-
import './chunk-
|
|
18
|
-
import { compareVersions } from './chunk-
|
|
17
|
+
import './chunk-WFJ65NUD.js';
|
|
18
|
+
import { compareVersions } from './chunk-4C4THABW.js';
|
|
19
19
|
import { builtinKind } from './chunk-5Y3QQRUH.js';
|
|
20
20
|
import { parseSize } from './chunk-F6GFZXZ3.js';
|
|
21
21
|
import './chunk-AUFG23AA.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import { staleBuildRefusal, staleBuildWarning } from './chunk-
|
|
4
|
-
import { detectCi } from './chunk-
|
|
3
|
+
import { staleBuildRefusal, staleBuildWarning } from './chunk-LT5TZHYH.js';
|
|
4
|
+
import { detectCi } from './chunk-LYCDNMOH.js';
|
|
5
5
|
import { launchRefusalForSession } from './chunk-BCJNHMZT.js';
|
|
6
6
|
import './chunk-TBT347UY.js';
|
|
7
7
|
import './chunk-F7CU5ABH.js';
|
|
8
8
|
import './chunk-BKO6JEZI.js';
|
|
9
9
|
import { detectActiveSession } from './chunk-BFESLKPP.js';
|
|
10
|
-
import { readEffectiveArtifactSpoolState, localArtifactIds, isArtifactTombstoned, artifactBlobsDir, appendArtifactRecord, artifactsSpoolPath, findPendingArtifactRecord, appendArtifactTombstone } from './chunk-
|
|
11
|
-
import { ARTIFACT_MAX_CAPTION_LENGTH, ArtifactCriterionIdSchema, ARTIFACT_MAX_FILENAME_LENGTH, mediaTypeForArtifactPath, inferArtifactKind, resolveRepoIdentity, ARTIFACT_MAX_REPLACES_TARGETS } from './chunk-
|
|
10
|
+
import { readEffectiveArtifactSpoolState, localArtifactIds, isArtifactTombstoned, artifactBlobsDir, appendArtifactRecord, artifactsSpoolPath, findPendingArtifactRecord, appendArtifactTombstone } from './chunk-WFJ65NUD.js';
|
|
11
|
+
import { ARTIFACT_MAX_CAPTION_LENGTH, ArtifactCriterionIdSchema, ARTIFACT_MAX_FILENAME_LENGTH, mediaTypeForArtifactPath, inferArtifactKind, resolveRepoIdentity, ARTIFACT_MAX_REPLACES_TARGETS, parseTestSelector, parseJunit, bindTests } from './chunk-4C4THABW.js';
|
|
12
12
|
import './chunk-YRYMNBGQ.js';
|
|
13
13
|
import './chunk-DVDEBNQJ.js';
|
|
14
14
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
@@ -88,6 +88,52 @@ function prNumberFromCiEnv(env) {
|
|
|
88
88
|
}
|
|
89
89
|
return void 0;
|
|
90
90
|
}
|
|
91
|
+
function prHeadShaFromCiEnv(env) {
|
|
92
|
+
if (!env.GITHUB_EVENT_PATH) return void 0;
|
|
93
|
+
try {
|
|
94
|
+
const event = JSON.parse(readFileSync(env.GITHUB_EVENT_PATH, "utf8"));
|
|
95
|
+
const sha = event.pull_request?.head?.sha;
|
|
96
|
+
return typeof sha === "string" && /^[0-9a-f]{40,64}$/i.test(sha) ? sha.toLowerCase() : void 0;
|
|
97
|
+
} catch {
|
|
98
|
+
return void 0;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function checkTestResults(params) {
|
|
102
|
+
const { file, bytes, mediaType, criterionId, rawTests, warn } = params;
|
|
103
|
+
const selection = [];
|
|
104
|
+
for (const raw of rawTests) {
|
|
105
|
+
const parsedSelector = parseTestSelector(raw);
|
|
106
|
+
if (!parsedSelector.ok) throw new EmitArtifactError(`invalid --test "${raw}" \u2014 ${parsedSelector.message}`);
|
|
107
|
+
if (selection.some((entry) => entry.name === parsedSelector.test.name)) {
|
|
108
|
+
throw new EmitArtifactError(`invalid --test \u2014 "${parsedSelector.test.name}" is named more than once`);
|
|
109
|
+
}
|
|
110
|
+
selection.push(parsedSelector.test);
|
|
111
|
+
}
|
|
112
|
+
if (selection.length > 0 && criterionId === void 0) {
|
|
113
|
+
throw new EmitArtifactError("--test names tests that prove a criterion \u2014 add --for <criterion-id>");
|
|
114
|
+
}
|
|
115
|
+
if (mediaType !== "application/xml") {
|
|
116
|
+
if (selection.length > 0) {
|
|
117
|
+
throw new EmitArtifactError(`--test needs a JUnit XML file, but ${file} is not an .xml file`);
|
|
118
|
+
}
|
|
119
|
+
return void 0;
|
|
120
|
+
}
|
|
121
|
+
if (criterionId === void 0) return void 0;
|
|
122
|
+
const parsed = parseJunit(bytes);
|
|
123
|
+
if (parsed.kind === "refused") throw new EmitArtifactError(`${file} cannot be read as test results \u2014 ${parsed.message}`);
|
|
124
|
+
if (parsed.kind === "other") {
|
|
125
|
+
if (selection.length > 0) {
|
|
126
|
+
throw new EmitArtifactError(`--test needs JUnit XML, but ${file} has no <testsuites> or <testsuite> root`);
|
|
127
|
+
}
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
const bound = bindTests(parsed, selection);
|
|
131
|
+
if (!bound.ok) throw new EmitArtifactError(`${file} has no test named "${bound.missing}"`);
|
|
132
|
+
for (const name of bound.duplicates) {
|
|
133
|
+
warn(`${file} has more than one test named "${name}"; all of them are bound, so each must pass`);
|
|
134
|
+
}
|
|
135
|
+
return selection.length > 0 ? selection : void 0;
|
|
136
|
+
}
|
|
91
137
|
async function runEmitArtifact(opts) {
|
|
92
138
|
const env = opts.env ?? process.env;
|
|
93
139
|
const refusal = staleBuildRefusal(env);
|
|
@@ -188,6 +234,17 @@ async function runEmitArtifact(opts) {
|
|
|
188
234
|
}
|
|
189
235
|
const mediaType = mediaTypeForArtifactPath(filePath);
|
|
190
236
|
const kind = inferArtifactKind(mediaType);
|
|
237
|
+
const tests = checkTestResults({
|
|
238
|
+
file: opts.file,
|
|
239
|
+
bytes,
|
|
240
|
+
mediaType,
|
|
241
|
+
criterionId,
|
|
242
|
+
rawTests: opts.tests ?? [],
|
|
243
|
+
warn: (message) => {
|
|
244
|
+
if (!opts.quiet) process.stderr.write(`${YELLOW}!${RESET} ${message}
|
|
245
|
+
`);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
191
248
|
const sha256 = createHash("sha256").update(bytes).digest("hex");
|
|
192
249
|
const identity = resolveRepoIdentity(cwd);
|
|
193
250
|
const sessionId = detectActiveSession({
|
|
@@ -224,7 +281,8 @@ async function runEmitArtifact(opts) {
|
|
|
224
281
|
caption,
|
|
225
282
|
...criterionId !== void 0 ? { criterionId } : {},
|
|
226
283
|
...replacesTargets !== void 0 ? { replaces: replacesTargets[0] } : {},
|
|
227
|
-
...replacesTargets !== void 0 && replacesTargets.length > 1 ? { replacesTargets } : {}
|
|
284
|
+
...replacesTargets !== void 0 && replacesTargets.length > 1 ? { replacesTargets } : {},
|
|
285
|
+
...tests !== void 0 ? { tests } : {}
|
|
228
286
|
};
|
|
229
287
|
try {
|
|
230
288
|
appendArtifactRecord(record, home);
|
|
@@ -266,6 +324,7 @@ async function runEmitArtifact(opts) {
|
|
|
266
324
|
if (!resolved.ok) throw new EmitArtifactError(resolved.message);
|
|
267
325
|
const { url, credential: apiKey, appId } = resolved;
|
|
268
326
|
const clientArtifactId = randomUUID();
|
|
327
|
+
const commitSha = prHeadShaFromCiEnv(env) ?? identity.commitSha;
|
|
269
328
|
const singleTarget = replacesTargets !== void 0 && replacesTargets.length === 1 ? replacesTargets[0] : void 0;
|
|
270
329
|
const targetPendingLocally = singleTarget !== void 0 && findPendingArtifactRecord(singleTarget, home) !== void 0;
|
|
271
330
|
const directTargets = targetPendingLocally ? void 0 : replacesTargets;
|
|
@@ -285,9 +344,10 @@ async function runEmitArtifact(opts) {
|
|
|
285
344
|
...repository !== void 0 ? { repository } : {},
|
|
286
345
|
...identity.gitRepo !== void 0 ? { gitRepo: identity.gitRepo } : {},
|
|
287
346
|
...identity.gitBranch !== void 0 ? { gitBranch: identity.gitBranch } : {},
|
|
288
|
-
...
|
|
347
|
+
...commitSha !== void 0 ? { commitSha } : {},
|
|
289
348
|
...directTargets !== void 0 && directTargets.length > 0 ? { replaces: directTargets[0] } : {},
|
|
290
|
-
...directTargets !== void 0 && directTargets.length > 1 ? { replacesTargets: directTargets } : {}
|
|
349
|
+
...directTargets !== void 0 && directTargets.length > 1 ? { replacesTargets: directTargets } : {},
|
|
350
|
+
...tests !== void 0 ? { tests } : {}
|
|
291
351
|
},
|
|
292
352
|
blob: { data: bytes.toString("base64") }
|
|
293
353
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { launchRefusalForSession } from './chunk-BCJNHMZT.js';
|
|
4
4
|
import { detectActiveSession } from './chunk-BFESLKPP.js';
|
|
5
|
-
import { resolveRepoIdentity, CriteriaListSchema } from './chunk-
|
|
5
|
+
import { resolveRepoIdentity, CriteriaListSchema } from './chunk-4C4THABW.js';
|
|
6
6
|
import { launchedItemForSession } from './chunk-DVDEBNQJ.js';
|
|
7
7
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
8
8
|
import { defaultFetch } from './chunk-BCLJSQCV.js';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { launchRefusalForSession } from './chunk-BCJNHMZT.js';
|
|
4
4
|
import { detectActiveSession } from './chunk-BFESLKPP.js';
|
|
5
|
-
import { FindingBatchSchema, resolveRepoIdentity } from './chunk-
|
|
5
|
+
import { FindingBatchSchema, resolveRepoIdentity } from './chunk-4C4THABW.js';
|
|
6
6
|
import { launchedItemForSession } from './chunk-DVDEBNQJ.js';
|
|
7
7
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
|
8
8
|
import { readLatestProvenanceForSession } from './chunk-ZJSNLVCE.js';
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
import './chunk-
|
|
4
|
-
import { detectCi } from './chunk-
|
|
3
|
+
import './chunk-LT5TZHYH.js';
|
|
4
|
+
import { detectCi } from './chunk-LYCDNMOH.js';
|
|
5
5
|
import { launchRefusalForSession } from './chunk-BCJNHMZT.js';
|
|
6
6
|
import './chunk-TBT347UY.js';
|
|
7
7
|
import './chunk-F7CU5ABH.js';
|
|
8
8
|
import './chunk-BKO6JEZI.js';
|
|
9
9
|
import { detectActiveSession } from './chunk-BFESLKPP.js';
|
|
10
|
-
import './chunk-
|
|
11
|
-
import { EmittedNameSchema, EMITTED_RESULT_MAX_LINK_LENGTH, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, resolveRepoIdentity } from './chunk-
|
|
10
|
+
import './chunk-WFJ65NUD.js';
|
|
11
|
+
import { EmittedNameSchema, EMITTED_RESULT_MAX_LINK_LENGTH, EMITTED_RESULTS, EMITTED_RESULT_MAX_BODY_LENGTH, resolveRepoIdentity } from './chunk-4C4THABW.js';
|
|
12
12
|
import './chunk-YRYMNBGQ.js';
|
|
13
13
|
import './chunk-DVDEBNQJ.js';
|
|
14
14
|
import { parseTrackerNumber, trackerNumberError } from './chunk-WZBHBH3J.js';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
|
-
export { PLACEHOLDER_MARKER, RunnerInitError, isPlaceholderCommand, readConfigObject, runRunnerInit } from './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import './chunk-
|
|
3
|
+
export { PLACEHOLDER_MARKER, RunnerInitError, isPlaceholderCommand, readConfigObject, runRunnerInit } from './chunk-YFHIIH4B.js';
|
|
4
|
+
import './chunk-3TFPDVTI.js';
|
|
5
|
+
import './chunk-HZRNMGLF.js';
|
|
6
6
|
import './chunk-ZNA27WEV.js';
|
|
7
7
|
import './chunk-N5FOE5PS.js';
|
|
8
8
|
import './chunk-OGFGZQA3.js';
|
|
@@ -10,10 +10,10 @@ import './chunk-774HEQL6.js';
|
|
|
10
10
|
import './chunk-QOZKPLVJ.js';
|
|
11
11
|
import './chunk-W4SQCOZU.js';
|
|
12
12
|
import './chunk-B2G7JHHB.js';
|
|
13
|
-
import './chunk-
|
|
13
|
+
import './chunk-W5FVUZXV.js';
|
|
14
14
|
import './chunk-BFESLKPP.js';
|
|
15
|
-
import './chunk-
|
|
16
|
-
import './chunk-
|
|
15
|
+
import './chunk-WFJ65NUD.js';
|
|
16
|
+
import './chunk-4C4THABW.js';
|
|
17
17
|
import './chunk-F6GFZXZ3.js';
|
|
18
18
|
import './chunk-AUFG23AA.js';
|
|
19
19
|
import './chunk-WZBHBH3J.js';
|