@outerlayer/cli 0.22.1 → 0.22.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +4 -1
  3. package/dist/{agent-setup-LTSLXPS3.js → agent-setup-KXPDPTAJ.js} +3 -4
  4. package/dist/bridge-QFN3KJP6.js +8 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/{check-UYKEMQNR.js → check-N6WLZCER.js} +21 -21
  7. package/dist/{chunk-7FEY33MY.js → chunk-2CPOAPU4.js} +8 -8
  8. package/dist/{chunk-BOMRFYTZ.js → chunk-4542B3RR.js} +2 -2
  9. package/dist/{chunk-O6RJ3QMU.js → chunk-4OYKJJ2V.js} +1 -1
  10. package/dist/{chunk-QOALB6ZD.js → chunk-B42BIYC6.js} +2 -2
  11. package/dist/{chunk-3V5C64Y5.js → chunk-BVR6MQLS.js} +2 -3
  12. package/dist/{chunk-IZSVXRDR.js → chunk-DXDF43YG.js} +1 -1
  13. package/dist/{chunk-F7CU5ABH.js → chunk-DYEFPYME.js} +1 -1
  14. package/dist/{chunk-JRCSET55.js → chunk-EMUNEAQK.js} +3 -3
  15. package/dist/{chunk-BET347JZ.js → chunk-FQE5RDHI.js} +4 -5
  16. package/dist/{chunk-FRNYCJ4W.js → chunk-FVDVC2GF.js} +1 -1
  17. package/dist/{chunk-5QRP3MVS.js → chunk-GNPTU4BM.js} +9 -4
  18. package/dist/{chunk-QC72I5GQ.js → chunk-HWZCE745.js} +2 -2
  19. package/dist/{chunk-CUFFDEF3.js → chunk-IMCVQF5F.js} +3 -3
  20. package/dist/{chunk-ENTHEUKT.js → chunk-IPS2JCHK.js} +3 -3
  21. package/dist/{chunk-56X5TOJY.js → chunk-JD6GWYY7.js} +2 -3
  22. package/dist/{chunk-FOCML5FI.js → chunk-KOIMUHIS.js} +8 -7
  23. package/dist/chunk-QS43O4DR.js +113 -0
  24. package/dist/{chunk-ORNJJ7XN.js → chunk-QZX6DAAW.js} +7 -8
  25. package/dist/{chunk-JZGFDTNC.js → chunk-SFHR45FA.js} +19 -2
  26. package/dist/{chunk-6YBLN4TR.js → chunk-SNVXHNU7.js} +1 -2
  27. package/dist/{chunk-URAKVDSI.js → chunk-U6RKHNC7.js} +5 -6
  28. package/dist/{chunk-5NJIWKD4.js → chunk-WKSBSEWT.js} +2 -2
  29. package/dist/chunk-WXJXHZVB.js +73 -0
  30. package/dist/{chunk-ZPSLJFGL.js → chunk-ZCXP35T3.js} +2 -2
  31. package/dist/{claude-launcher-TBWV3YL3.js → claude-launcher-QD3C427Y.js} +1 -1
  32. package/dist/{cli-U253V422.js → cli-A2Y67WAB.js} +69 -62
  33. package/dist/{command-IQTPFSXY.js → command-Q5Q2EIO4.js} +8 -9
  34. package/dist/{connect-cmd-ZFOK6HEL.js → connect-cmd-TNGEIWCA.js} +7 -2
  35. package/dist/{control-plane-launch-OWSNH6YA.js → control-plane-launch-HE6OSWKO.js} +2 -3
  36. package/dist/{doctor-FZTS57ZO.js → doctor-BRN4BGMA.js} +10 -11
  37. package/dist/{emit-artifact-cmd-YLZ5WLSF.js → emit-artifact-cmd-GPAJCCUC.js} +9 -9
  38. package/dist/{emit-criteria-cmd-MF6TVE7C.js → emit-criteria-cmd-R3FKHSQG.js} +4 -4
  39. package/dist/{emit-finding-cmd-S3YMFTZT.js → emit-finding-cmd-IK7RAVP5.js} +4 -4
  40. package/dist/{emit-result-cmd-JHEUFTPX.js → emit-result-cmd-5FJTF7YD.js} +9 -9
  41. package/dist/{emit-step-cmd-TUI2T3DS.js → emit-step-cmd-VRTD5YPP.js} +5 -5
  42. package/dist/{governing-source-XSEIRSBE.js → governing-source-WM736XR4.js} +6 -7
  43. package/dist/{guest-init-DF7V5D2R.js → guest-init-2OZ4YC7R.js} +2 -1
  44. package/dist/{hook-fast-O3UUN6SO.js → hook-fast-QUGEI2IT.js} +1 -1
  45. package/dist/{hook-wrap-fast-NPLHJXFK.js → hook-wrap-fast-NOOGDNSW.js} +2 -2
  46. package/dist/index.js +6 -6
  47. package/dist/{init-VZE72CR4.js → init-U3I43XCP.js} +9 -10
  48. package/dist/{init-ZZZPYGUH.js → init-X7FCQDFX.js} +9 -10
  49. package/dist/{init-cmd-W5VV62ZN.js → init-cmd-VCKH2DUQ.js} +10 -11
  50. package/dist/{init-update-YFPIQS5G.js → init-update-TCMH7M3Q.js} +4 -5
  51. package/dist/{loop-6WENRS5S.js → loop-P3QDQOE5.js} +21 -21
  52. package/dist/{machine-M4MQBV5A.js → machine-EEFOW32K.js} +8 -9
  53. package/dist/{mcp-serve-cmd-SBW7HYKD.js → mcp-serve-cmd-TQSPFRC7.js} +2 -2
  54. package/dist/{runner-key-QT7GKGEE.js → runner-key-O42EUXQU.js} +9 -10
  55. package/dist/{session-sender-BK6TGNVO.js → session-sender-HF6DXFA2.js} +10 -10
  56. package/dist/{settings-J2652U5N.js → settings-AKYEOCC2.js} +1 -1
  57. package/dist/{spec-cmd-ZNJ3GXWC.js → spec-cmd-ADPH236D.js} +5 -5
  58. package/dist/{status-JOO7MGIC.js → status-LXFIVGP3.js} +16 -16
  59. package/dist/{statusline-fast-2OK3DVAA.js → statusline-fast-GVRSBHAF.js} +2 -2
  60. package/dist/{sync-cmd-W2FPY3T5.js → sync-cmd-5XS3CUV5.js} +9 -9
  61. package/dist/{watch-WLH5ZUZU.js → watch-FBZHZV56.js} +9 -9
  62. package/dist/{work-claim-cmd-4PLDTEZR.js → work-claim-cmd-LIIINECF.js} +7 -7
  63. package/dist/{work-cmd-KWHAYUYB.js → work-cmd-SM6DY2WK.js} +5 -5
  64. package/dist/{work-comment-cmd-4CUI7ZDE.js → work-comment-cmd-VYVXGT4W.js} +5 -5
  65. package/dist/{work-logs-cmd-AF253WLM.js → work-logs-cmd-XZSCWWMW.js} +5 -5
  66. package/dist/{work-open-pr-cmd-JETE6HRL.js → work-open-pr-cmd-YZNC3P3R.js} +6 -6
  67. package/dist/{work-pr-cmd-V5G4CPMG.js → work-pr-cmd-AMN23KFJ.js} +5 -5
  68. package/dist/{work-stop-cmd-FIEKUDGE.js → work-stop-cmd-HSR2GOJJ.js} +5 -5
  69. package/package.json +1 -1
  70. package/skill-pack/maintained/outerlayer-amend/SKILL.md +83 -82
  71. package/skill-pack/maintained/outerlayer-build/SKILL.md +4 -2
  72. package/skill-pack/maintained/outerlayer-build/references/agent-briefs.md +10 -3
  73. package/skill-pack/maintained/outerlayer-build/references/release.md +7 -4
  74. package/skill-pack/maintained/outerlayer-build/references/review-briefs.md +6 -3
  75. package/skill-pack/maintained/outerlayer-cli/SKILL.md +8 -1
  76. package/skill-pack/maintained/outerlayer-cli/references/merge-base-branch.md +54 -0
  77. package/dist/chunk-NTRCK4NH.js +0 -38
  78. package/dist/chunk-QF7WZUU6.js +0 -56
@@ -89,7 +89,9 @@ Given a request instead of a work item, stop and say:
89
89
  Optional flag: `--unattended` means no person is present and nothing wakes
90
90
  the session after a turn ends. Spawn every agent in the foreground and wait
91
91
  for it in the same turn. Run the gate in the foreground with the maximum
92
- timeout. End the turn only at the final report.
92
+ timeout. A command that outlives that timeout continues in the background:
93
+ wait for it in the foreground before you use its result. End the turn only at
94
+ the final report.
93
95
 
94
96
  ## State rules
95
97
 
@@ -305,7 +307,7 @@ Run them in order.
305
307
 
306
308
  5. **Pull request.** Run `outerlayer emit step "Pull request" --item "$OUTERLAYER_WORK"`,
307
309
  then apply the team's changes for this phase. Read [references/release.md](references/release.md)
308
- on entry and run it. A release agent rebases, gates and pushes. Open the
310
+ on entry and run it. A release agent merges the base branch in, gates and pushes. Open the
309
311
  pull request as release.md says: a runner build with `outerlayer work open-pr`,
310
312
  which links it, and a local session with `gh pr create` and then
311
313
  `outerlayer work pr <number>`. When the build recorded criteria, from the issue or drafted, a fresh agent judges them with
@@ -45,6 +45,13 @@ Run every long command, such as the full gate, the mutation tool or the
45
45
  integration suite, in the foreground with the maximum timeout. Never
46
46
  background one, and never end a turn waiting on a notification.
47
47
 
48
+ A command that runs past the maximum timeout moves to the background and
49
+ continues. It has not finished. Wait for it in the foreground before you use
50
+ or report its result. For a command named `run-checks`, wait with
51
+ `while pgrep -f '[r]un-checks' >/dev/null; do sleep 15; done`. Keep the
52
+ brackets around the first letter of the name. Without them, `pgrep` on Linux
53
+ finds the waiting shell, and the loop does not stop.
54
+
48
55
  Every agent in a run shares one memory cap. Run only the test files for the
49
56
  code you change or check, one at a time. Run a whole package's suite, a
50
57
  coverage run, a repository-wide typecheck or the full gate only where this
@@ -181,9 +188,9 @@ The shared rules apply. Your inputs are the state file path, the branch and
181
188
  the instructions-file pointer. You run no write command against the tracker
182
189
  or the git host beyond the push.
183
190
 
184
- Fetch the base branch, then rebase the branch onto it. Merge instead once the
185
- branch is pushed and someone else may hold it. Resolve every conflict on the
186
- branch, never in a web editor.
191
+ Bring the base branch into the branch as
192
+ `.outerlayer/skills/outerlayer-cli/references/merge-base-branch.md` says.
193
+ Resolve every conflict on the branch, never in a web editor.
187
194
 
188
195
  A migration this branch adds whose version is at or below the newest one on
189
196
  the base branch is renamed to the current UTC time, with every reference to
@@ -9,10 +9,13 @@ file, not from the transcript.
9
9
 
10
10
  The orchestrator does not sync, run the gate, push or watch CI itself. Spawn
11
11
  one release agent in a fresh context on the "sync and push" brief, with the
12
- state file path, the branch and the instructions-file pointer. A check that
13
- fails there has the standing of a red gate and returns to the review phase's
14
- remaining budget. If its report names files the sync moved that the review had
15
- already cleared, run one check round on the rebased diff before going on.
12
+ state file path, the branch and the instructions-file pointer. The agent
13
+ brings the base branch in as
14
+ `.outerlayer/skills/outerlayer-cli/references/merge-base-branch.md` says. A
15
+ check that fails there has the standing of a red gate and returns to the
16
+ review phase's remaining budget. If its report names files the sync moved that
17
+ the review had already cleared, run one check round on the merged diff before
18
+ going on.
16
19
 
17
20
  ## Open the pull request
18
21
 
@@ -259,9 +259,12 @@ shared tree while you run, so no mutation may touch it.
259
259
 
260
260
  1. Run the repository's changed-lines mutation tool once over the whole diff.
261
261
  Every survivor it reports is a finding. Never rerun it per file, never
262
- lower its budget, and never run a whole suite or a coverage run. A run
263
- that ends over budget is reported as over budget with the mutants it
264
- scored. One rerun is allowed, and only when the tool reports no result
262
+ lower its budget, and never run a whole suite or a coverage run. The
263
+ tool can run longer than your shell's maximum timeout. Then your shell
264
+ moves it to the background. Wait for it to exit before you write your
265
+ report. Only the tool's own output can say that a run went over budget.
266
+ A run that ends over budget is reported as over budget with the mutants
267
+ it scored. One rerun is allowed, and only when the tool reports no result
265
268
  because a workspace dependency could not be resolved: build the
266
269
  dependencies, then run once more.
267
270
  2. Read the tool's report. For each criterion whose production lines were
@@ -38,7 +38,7 @@ from the output of `outerlayer work build`.
38
38
  4. `outerlayer emit artifact <file> --caption "<what it shows>"` attaches a
39
39
  screenshot, recording, report or log as evidence. The `outerlayer-evidence`
40
40
  skill says what to capture.
41
- 5. `/outerlayer-amend` answers the review threads a person handed to an agent.
41
+ 5. `/outerlayer-amend` answers the review threads a person handed to an agent. It also resolves a merge conflict on a pull request a host built.
42
42
 
43
43
  ## Several repositories
44
44
 
@@ -76,6 +76,13 @@ ended, which session ran in it, and what the runner did around the agent. The
76
76
  steps, and what each outcome and reason means, are in
77
77
  [references/find-out-why-a-build-ended.md](references/find-out-why-a-build-ended.md).
78
78
 
79
+ ## Merging the base branch
80
+
81
+ A build merges the base branch into its branch before the pull request opens.
82
+ A run that resolves a merge conflict does the same on an open pull request.
83
+ Both follow one procedure in
84
+ [references/merge-base-branch.md](references/merge-base-branch.md).
85
+
79
86
  ## Reading work items
80
87
 
81
88
  When the OuterLayer MCP server is configured in this repository, its
@@ -0,0 +1,54 @@
1
+ # Merge the base branch into a branch
2
+
3
+ Use this procedure when a branch must take in its base branch: a build's
4
+ last sync before the pull request opens, and a run that resolves a merge
5
+ conflict on a pull request already open. It is the one written procedure
6
+ for both.
7
+
8
+ Merge the base branch. Never rebase, and never force-push. A merge keeps the
9
+ commits a reviewer already read and keeps review comments on their lines.
10
+
11
+ 1. Fetch the base branch. Use the pull request's base, which the item's
12
+ `outerlayer work status --item "$OUTERLAYER_WORK" --json` names in
13
+ `pullRequests[].conflict.baseBranch`, or the repository's default branch
14
+ when the pull request has no conflict record.
15
+
16
+ git fetch origin <base>
17
+
18
+ 2. Record the base commit you merge. Read it after the fetch.
19
+
20
+ git rev-parse origin/<base>
21
+
22
+ 3. Merge it into the checked-out branch, and stop before git commits.
23
+
24
+ git merge origin/<base> --no-commit --no-ff
25
+
26
+ If git reports `Already up to date`, the branch holds the base already.
27
+ Stop: there is nothing to push. If the merge has no conflict, go to step 5.
28
+
29
+ 4. Resolve each conflict so that the result keeps the intent of both sides.
30
+ List the conflicting files with `git diff --name-only --diff-filter=U`.
31
+ For each file, read the base commits that changed it
32
+ (`git log --oneline HEAD..origin/<base> -- <file>`) and the work item's
33
+ spec. Do not pick one side to make the conflict go away. Mark a file
34
+ resolved with `git add <file>` only when its code and its tests agree
35
+ with both sides.
36
+
37
+ 5. Run the repository's pre-push gate in the foreground, with the maximum
38
+ timeout. It names its own command in the repository's instructions file.
39
+ Wait for it to end. If the gate fails, fix the cause and run it again once.
40
+ A second failure is a hand-off, not a third try.
41
+
42
+ 6. Commit the merge. Name the base sha from step 2 in the message, so a reader
43
+ can find the exact base commit.
44
+
45
+ git commit -m "Merge <base> at <base sha> into <branch>"
46
+
47
+ 7. Push the branch. The hooks run, and you never bypass them. A push goes to
48
+ the pull request's own branch only.
49
+
50
+ ## When you cannot resolve it
51
+
52
+ Abort the merge with `git merge --abort`. The branch returns to the state it
53
+ had before step 3. Push nothing. Hand the item to a person in the way the
54
+ calling skill says.
@@ -1,38 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- import { readRepoConnection, findGitDirs } from './chunk-BJ3KTMDH.js';
4
- import { readCloudConfig } from './chunk-EABW6AJQ.js';
5
- import { cliInvocation } from './chunk-CRB3POP4.js';
6
- import { homeFromEnv } from './chunk-VNVZDWO3.js';
7
-
8
- createRequire(import.meta.url);
9
-
10
- // src/credentials.ts
11
- var MISSING_HELP = `Run \`${cliInvocation()} login\` to sign in, or set OUTERLAYER_URL / OUTERLAYER_API_KEY / OUTERLAYER_APP_ID. Mint a key in the dashboard: Settings \u2192 API keys.`;
12
- var NO_FACTORY_MESSAGE = `you are logged in, but no factory is chosen for this repository. Run \`${cliInvocation()} connect\` to choose one, or pass --app-id / set OUTERLAYER_APP_ID.`;
13
- var NO_FACTORY_OUTSIDE_REPOSITORY_MESSAGE = "you are logged in, but this directory is not in a git repository, so no factory is chosen. Pass --app-id / set OUTERLAYER_APP_ID, or run this from inside a connected repository.";
14
- var LOGIN_TOKEN_PREFIX = "olu_";
15
- function unauthorizedMessage(credential) {
16
- return credential.startsWith(LOGIN_TOKEN_PREFIX) ? `not authorized \u2014 the login is expired or was revoked. Run \`${cliInvocation()} login\` to sign in again.` : "not authorized \u2014 the API key is unknown, expired, or bound to a different factory. Mint a fresh key: dashboard \u2192 Settings \u2192 API keys.";
17
- }
18
- function resolveGatewayCredentials(sources = {}) {
19
- const env = sources.env ?? process.env;
20
- const config = readCloudConfig(sources.home ?? homeFromEnv(env));
21
- const url = sources.url ?? env.OUTERLAYER_URL ?? config.url;
22
- const key = sources.apiKey ?? (env.OUTERLAYER_API_KEY || void 0) ?? config.apiKey;
23
- const kind = key ? "key" : "login";
24
- const credential = key ?? config.accountToken;
25
- const cwd = sources.cwd ?? process.cwd();
26
- const appId = sources.appId ?? (env.OUTERLAYER_APP_ID || void 0) ?? (kind === "key" ? config.appId : readRepoConnection(cwd)?.appId);
27
- if (credential && url && !appId && kind === "login") {
28
- const message = findGitDirs(cwd) === void 0 ? NO_FACTORY_OUTSIDE_REPOSITORY_MESSAGE : NO_FACTORY_MESSAGE;
29
- return { ok: false, message, url, credential, appId, kind };
30
- }
31
- if (!url || !credential || !appId) {
32
- const missing = [!url && "--url", !credential && "a login or OUTERLAYER_API_KEY", !appId && "--app-id"].filter(Boolean).join(", ");
33
- return { ok: false, message: `missing ${missing}. ${MISSING_HELP}`, url, credential, appId, kind };
34
- }
35
- return { ok: true, url, credential, appId, kind };
36
- }
37
-
38
- export { resolveGatewayCredentials, unauthorizedMessage };
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- import { readCloudConfig, cloudConfigPath } from './chunk-EABW6AJQ.js';
4
- import { homeFromEnv } from './chunk-VNVZDWO3.js';
5
- import { signRunnerRequest, signerFor } from './chunk-OW52QLK3.js';
6
-
7
- createRequire(import.meta.url);
8
-
9
- // src/signing-fetch.ts
10
- function bodyBytes(body) {
11
- if (body === void 0 || body === null) return new Uint8Array(0);
12
- if (typeof body === "string") return new TextEncoder().encode(body);
13
- if (body instanceof Uint8Array) return body;
14
- if (body instanceof ArrayBuffer) return new Uint8Array(body);
15
- return void 0;
16
- }
17
- async function savedKeySigner(headers, home) {
18
- const authorization = headers.get("authorization");
19
- if (authorization === null || !authorization.startsWith("Bearer ")) return void 0;
20
- if (headers.has("signature")) return void 0;
21
- if (readCloudConfig(home).apiKey !== authorization.slice("Bearer ".length)) return void 0;
22
- try {
23
- return await signerFor(cloudConfigPath(home));
24
- } catch {
25
- return void 0;
26
- }
27
- }
28
- function signedBy(base, signerOf) {
29
- return (async (input, init) => {
30
- if (input instanceof Request) return base(input, init);
31
- const headers = new Headers(init?.headers);
32
- const signer = await signerOf(headers);
33
- const body = bodyBytes(init?.body);
34
- if (signer === void 0 || body === void 0) return base(input, init);
35
- const signature = await signRunnerRequest({ method: init?.method ?? "GET", url: input.toString(), body, signer });
36
- for (const [name, value] of Object.entries(signature)) headers.set(name, value);
37
- return base(input, { ...init, headers });
38
- });
39
- }
40
- function signingFetch(base, home = () => homeFromEnv()) {
41
- return signedBy(base, (headers) => savedKeySigner(headers, home()));
42
- }
43
- function signingFetchFor(base, configPath, apiKey) {
44
- return signedBy(base, async (headers) => {
45
- const authorization = headers.get("authorization");
46
- if (authorization !== `Bearer ${apiKey}` || headers.has("signature")) return void 0;
47
- try {
48
- return await signerFor(configPath);
49
- } catch {
50
- return void 0;
51
- }
52
- });
53
- }
54
- var defaultFetch = signingFetch((input, init) => globalThis.fetch(input, init));
55
-
56
- export { defaultFetch, signingFetchFor };