@krapht/ork 1.0.0-alpha.19 → 1.0.0-alpha.20
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/dist/{__build_info__-dPf4cEGL.mjs → __build_info__-D6mXC4cD.mjs} +2 -2
- package/dist/argument-error-CihH46Le.mjs +27 -0
- package/dist/{attach-BQl8nQz2.mjs → attach-C1OnxyMh.mjs} +7 -5
- package/dist/{attach-DhZQ87Nz.mjs → attach-CEGbRg1D.mjs} +126 -69
- package/dist/bin.mjs +556 -119
- package/dist/{brief-BQbeoPMc.mjs → brief-DH66xmj8.mjs} +11 -6
- package/dist/{builtin-files-CWL3JEo-.mjs → builtin-files-Cf-NZDqM.mjs} +1 -1
- package/dist/{command-tree-B6uvMJq1.mjs → command-tree-CEkzWNy6.mjs} +1 -1
- package/dist/{completion-DKPuD_Rw.mjs → completion-DS0gCZRm.mjs} +19 -12
- package/dist/{context-Bw6R_EYq.mjs → context-CGPh12HV.mjs} +3 -3
- package/dist/{detached-BQlbmqR0.mjs → detached-Dakw5RZj.mjs} +3 -3
- package/dist/extra-arguments-BxQMXARO.mjs +13 -0
- package/dist/{find-B30-rd-u.mjs → find-BTikxc54.mjs} +1 -1
- package/dist/{flags-ByYBx-Xb.mjs → flags-C8yCq0j5.mjs} +7 -32
- package/dist/{follow-ups-Cxca1Jgg.mjs → follow-ups-CtlhHbwe.mjs} +87 -26
- package/dist/{format-C-nEZv-P.mjs → format-BB4E-T6x.mjs} +1 -1
- package/dist/{in-a-run-CZFzoT3R.mjs → in-a-run-CbnKjO7t.mjs} +2 -2
- package/dist/{install-CsqK1avz.mjs → install-CWcpX5g4.mjs} +1 -1
- package/dist/{limits-CXh052II.mjs → limits-VQqsBoQk.mjs} +1 -1
- package/dist/{mcp-B4wME9C4.mjs → mcp-wGfkMCVF.mjs} +6 -6
- package/dist/{once-BKn3pOtg.mjs → once-BHxSdZz_.mjs} +43 -7
- package/dist/{pause-B1grR1cl.mjs → pause-C_Wxh-KM.mjs} +6 -3
- package/dist/{print-Bd8MWVJk.mjs → print-DNYzq4Rr.mjs} +1 -1
- package/dist/{project-records-BOEVs69i.mjs → project-records-XY3ku95x.mjs} +4 -1
- package/dist/{relay-CeNiq3GT.mjs → relay-BA6tsnpc.mjs} +1 -1
- package/dist/{run-D6yU2rLf.mjs → run-Bvvg-fiF.mjs} +61 -19
- package/dist/{run-C0C54UiU.mjs → run-DBUAq-Uu.mjs} +29 -20
- package/dist/{send-DqgF58hb.mjs → send-nrKtak5F.mjs} +2 -2
- package/dist/{src-Ciy7i3se.mjs → src-8cOPOgrT.mjs} +155 -32
- package/dist/{src-n-u4TGev.mjs → src-CmEvHdju.mjs} +28 -28
- package/dist/{src-D2qpd-G7.mjs → src-D4JSymhK.mjs} +11 -2
- package/dist/{src-DP02RP9O.mjs → src-I_RyKu6_.mjs} +2 -2
- package/dist/{store-2KXzMCEN.mjs → store-CDpk8Wtz.mjs} +1 -1
- package/dist/ui/assets/app--FijEXiJ.css +1 -0
- package/dist/ui/assets/{app-ICEKpy_C.js → app-BowhjEAe.js} +12 -12
- package/dist/ui/assets/{index-BGaix5wh.js → index-CrMa2oHB.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/dist/{ui-CAvygxTb.mjs → ui-DY3Dnpho.mjs} +4 -4
- package/dist/{usage-BFBco5OS.mjs → usage-1VwSg_Qt.mjs} +4 -4
- package/dist/{validate-UrmC5AG1.mjs → validate-BxayjjkV.mjs} +3 -3
- package/dist/{watch-DTxkgB8R.mjs → watch-CT0EtLPZ.mjs} +5 -5
- package/dist/{workflows-8GV-SeRm.mjs → workflows-DHHi-APg.mjs} +2 -2
- package/dist/{worktrees-CUdUvZlO.mjs → worktrees-CZvbHzbN.mjs} +4 -4
- package/package.json +1 -1
- package/dist/ui/assets/app-C5vO1M-l.css +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { in as gitOk, rn as git } from "./src-8cOPOgrT.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -10,14 +10,27 @@ import { tmpdir } from "node:os";
|
|
|
10
10
|
* written through a temporary index so the real one is untouched, with `HEAD`
|
|
11
11
|
* and the repository's common git folder, where passes are kept for every
|
|
12
12
|
* worktree. The key is the files, not the commit: a commit or a no-op rebase
|
|
13
|
-
* keeps it.
|
|
13
|
+
* keeps it. With pathspecs (`--on`), only the files they match count.
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
16
|
+
* Git rejected the pathspecs, or they match no file: a usage error, never a
|
|
17
|
+
* silent hit.
|
|
18
|
+
*/
|
|
19
|
+
var OncePathspecError = class extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "OncePathspecError";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/** The part of the key a pass is matched on: the files, else the tree. */
|
|
26
|
+
const filesOf = (key) => key.files ?? key.tree;
|
|
27
|
+
/**
|
|
16
28
|
* The key of the files in the worktree at `cwd`. Rejects outside a git
|
|
17
|
-
* repository
|
|
18
|
-
*
|
|
29
|
+
* repository, and with `OncePathspecError` when git rejects `on` or it matches
|
|
30
|
+
* no file. Starts from a copy of the real index, so git hashes only the files
|
|
31
|
+
* whose stat changed.
|
|
19
32
|
*/
|
|
20
|
-
const treeKeyOf = async (cwd) => {
|
|
33
|
+
const treeKeyOf = async (cwd, { on = [] } = {}) => {
|
|
21
34
|
const [commonDir = "", index = ""] = (await gitOk(cwd, [
|
|
22
35
|
"rev-parse",
|
|
23
36
|
"--git-common-dir",
|
|
@@ -36,11 +49,28 @@ const treeKeyOf = async (cwd) => {
|
|
|
36
49
|
"-q",
|
|
37
50
|
"HEAD"
|
|
38
51
|
]);
|
|
39
|
-
|
|
52
|
+
const key = {
|
|
40
53
|
tree,
|
|
41
54
|
head: head.code === 0 ? head.stdout.trim() : null,
|
|
42
55
|
commonDir
|
|
43
56
|
};
|
|
57
|
+
if (on.length === 0) return key;
|
|
58
|
+
const listed = await git(cwd, [
|
|
59
|
+
"ls-files",
|
|
60
|
+
"-s",
|
|
61
|
+
"-z",
|
|
62
|
+
"--full-name",
|
|
63
|
+
"--",
|
|
64
|
+
...on
|
|
65
|
+
], env);
|
|
66
|
+
if (listed.code !== 0) throw new OncePathspecError(`git rejected the pathspecs ${on.join(" ")}: ${listed.stderr.trim()}`);
|
|
67
|
+
if (listed.stdout === "") throw new OncePathspecError(`the pathspecs ${on.join(" ")} match no file: check them, or drop --on to key every file`);
|
|
68
|
+
const files = createHash("sha256").update(listed.stdout).digest("hex");
|
|
69
|
+
return {
|
|
70
|
+
...key,
|
|
71
|
+
files,
|
|
72
|
+
on: [...on]
|
|
73
|
+
};
|
|
44
74
|
} finally {
|
|
45
75
|
rmSync(scratch, {
|
|
46
76
|
recursive: true,
|
|
@@ -60,10 +90,16 @@ const treeKeyOf = async (cwd) => {
|
|
|
60
90
|
const ONCE_MAX_AGE_MS = 6048e5;
|
|
61
91
|
/** The folder of passes for a repository's common git folder. */
|
|
62
92
|
const onceDirOf = (commonDir) => path.join(commonDir, "ork-once");
|
|
63
|
-
|
|
93
|
+
/** Without pathspecs the name key is unchanged, so earlier passes still hit. */
|
|
94
|
+
const fileOf = (dir, name, key, node) => path.join(dir, `${createHash("sha256").update(JSON.stringify(key.on === void 0 || key.on.length === 0 ? [
|
|
64
95
|
name,
|
|
65
|
-
tree,
|
|
96
|
+
key.tree,
|
|
66
97
|
node
|
|
98
|
+
] : [
|
|
99
|
+
name,
|
|
100
|
+
filesOf(key),
|
|
101
|
+
node,
|
|
102
|
+
key.on
|
|
67
103
|
])).digest("hex")}.json`);
|
|
68
104
|
const read = (file) => {
|
|
69
105
|
try {
|
|
@@ -84,8 +120,8 @@ const read = (file) => {
|
|
|
84
120
|
};
|
|
85
121
|
/** The pass of `name` on these files, or `null`. */
|
|
86
122
|
const findPass = ({ key, name, withHead = false, node = process.version }) => {
|
|
87
|
-
const pass = read(fileOf(onceDirOf(key.commonDir), name, key
|
|
88
|
-
if (pass === null || pass.tree !== key
|
|
123
|
+
const pass = read(fileOf(onceDirOf(key.commonDir), name, key, node));
|
|
124
|
+
if (pass === null || pass.tree !== filesOf(key) || pass.node !== node) return null;
|
|
89
125
|
return withHead && pass.head !== key.head ? null : pass;
|
|
90
126
|
};
|
|
91
127
|
/** Records a pass under `name` and each covered name, then prunes. */
|
|
@@ -94,7 +130,7 @@ const recordPass = ({ key, name, covers = [], who, node = process.version, at =
|
|
|
94
130
|
mkdirSync(dir, { recursive: true });
|
|
95
131
|
const pass = {
|
|
96
132
|
name,
|
|
97
|
-
tree: key
|
|
133
|
+
tree: filesOf(key),
|
|
98
134
|
head: key.head,
|
|
99
135
|
node,
|
|
100
136
|
at: at.toISOString(),
|
|
@@ -106,7 +142,7 @@ const recordPass = ({ key, name, covers = [], who, node = process.version, at =
|
|
|
106
142
|
...pass,
|
|
107
143
|
name: each
|
|
108
144
|
})}\n`);
|
|
109
|
-
renameSync(temp, fileOf(dir, each,
|
|
145
|
+
renameSync(temp, fileOf(dir, each, key, node));
|
|
110
146
|
}
|
|
111
147
|
prunePasses(key.commonDir, { now: at });
|
|
112
148
|
return pass;
|
|
@@ -147,15 +183,21 @@ const prunePasses = (commonDir, { now = /* @__PURE__ */ new Date(), maxAgeMs = O
|
|
|
147
183
|
* exits 0 and the files didn't change while it ran. `force` and
|
|
148
184
|
* `ORK_ONCE=off` run it anyway; outside a git repository it always runs.
|
|
149
185
|
*/
|
|
150
|
-
/**
|
|
151
|
-
|
|
186
|
+
/**
|
|
187
|
+
* `null` outside a git repository: nothing to key the files by. Rejected
|
|
188
|
+
* pathspecs reject, so a bad `--on` is an error, never a run without a key.
|
|
189
|
+
*/
|
|
190
|
+
const keyOf = (cwd, on) => treeKeyOf(cwd, { on }).catch((error) => {
|
|
191
|
+
if (error instanceof OncePathspecError) throw error;
|
|
192
|
+
return null;
|
|
193
|
+
});
|
|
152
194
|
/** Runs `run` unless the check already passed on these files. */
|
|
153
|
-
const runOnce = async ({ cwd, name, covers = [], withHead = false, force = false, who = "you", run, env = process.env, node = process.version }) => {
|
|
195
|
+
const runOnce = async ({ cwd, name, covers = [], withHead = false, on = [], force = false, who = "you", run, env = process.env, node = process.version }) => {
|
|
154
196
|
if (env["ORK_ONCE"] === "off") return {
|
|
155
197
|
skipped: false,
|
|
156
198
|
code: await run()
|
|
157
199
|
};
|
|
158
|
-
const before = await keyOf(cwd);
|
|
200
|
+
const before = await keyOf(cwd, on);
|
|
159
201
|
const earlier = before === null || force ? null : findPass({
|
|
160
202
|
key: before,
|
|
161
203
|
name,
|
|
@@ -172,8 +214,8 @@ const runOnce = async ({ cwd, name, covers = [], withHead = false, force = false
|
|
|
172
214
|
skipped: false,
|
|
173
215
|
code
|
|
174
216
|
};
|
|
175
|
-
const after = await keyOf(cwd);
|
|
176
|
-
if (after
|
|
217
|
+
const after = await keyOf(cwd, on).catch(() => null);
|
|
218
|
+
if (after === null || filesOf(after) !== filesOf(before) || after.head !== before.head) return {
|
|
177
219
|
skipped: false,
|
|
178
220
|
code
|
|
179
221
|
};
|
|
@@ -189,4 +231,4 @@ const runOnce = async ({ cwd, name, covers = [], withHead = false, force = false
|
|
|
189
231
|
code
|
|
190
232
|
};
|
|
191
233
|
};
|
|
192
|
-
export { runOnce as t };
|
|
234
|
+
export { OncePathspecError as n, runOnce as t };
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as clearOutputFiles, a as builtinExecutors, b as runScrubber, d as maskedEnv, f as maskedNamesOfRun, i as onPath, l as clearStateFiles, m as sessionEnv, n as missingProgramMessage, r as missingPrograms, t as envProblems, v as namedMcpEntries, y as resultOf } from "./src-
|
|
3
|
-
import { n as newRunId } from "./find-
|
|
4
|
-
import { h as nodeSession, n as ORK_VERSION } from "./__build_info__-
|
|
1
|
+
import { B as appendRecorder, Dn as endLinksOf, Dt as startRun, Et as walkSummary, Fi as AGENT_DRIVERS, Ii as DRIVER_IDS, J as parseInputPairs, Jn as machineRulesOf, K as createReplay, Kn as gitRulesOf, Mi as readyDriver, Pn as liveStatus, R as openStore, Sn as deliverFollowUp, Sr as renderTemplate, Ti as retiredDriverHint, V as createRecorder, Wr as placeFiles, Xr as inside, Y as resolveInputs, Zn as findFollowUp, ct as createCalls, er as createSignals, ft as DETACHED_ENV, gn as createFollowUps, gr as createFeedback, h as resolveBase, ht as NOT_STARTED, kt as userMessageText, li as beforeOf, ln as sessionDriver, lt as adoptedCalls, mr as runGh, n as resumedOptions, nn as inspectProject, q as replayLoopAnswers, qn as loadProject, qr as runDirOf, rn as git, rt as createRelay, t as createWorkspace, tr as endOf, vn as checkFollowUpsDue, wr as startControl, xi as isClaudeNode, xr as parseTemplate, xt as planNodeSession, z as storePath, zn as templateOf } from "./src-8cOPOgrT.mjs";
|
|
2
|
+
import { _ as clearOutputFiles, a as builtinExecutors, b as runScrubber, d as maskedEnv, f as maskedNamesOfRun, i as onPath, l as clearStateFiles, m as sessionEnv, n as missingProgramMessage, r as missingPrograms, t as envProblems, v as namedMcpEntries, y as resultOf } from "./src-I_RyKu6_.mjs";
|
|
3
|
+
import { n as newRunId } from "./find-BTikxc54.mjs";
|
|
4
|
+
import { h as nodeSession, n as ORK_VERSION } from "./__build_info__-D6mXC4cD.mjs";
|
|
5
5
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
6
|
-
import {
|
|
7
|
-
import { a as refusedBuiltin, s as workflowArg, t as WORKFLOW_DIR } from "./workflows-
|
|
8
|
-
import { a as formatReport, c as checksHere, d as runReadyDriver, f as unfitLines, i as walkLoaded, l as chooseReadyDriver, o as warningLines, s as budgetWarningLines, t as loadWorkflow, u as overrideRefusal } from "./validate-
|
|
6
|
+
import { d as formatEvent, f as formatRunEvent, m as createTerminalHuman, p as callsShown, t as attachRun } from "./attach-CEGbRg1D.mjs";
|
|
7
|
+
import { a as refusedBuiltin, s as workflowArg, t as WORKFLOW_DIR } from "./workflows-DHHi-APg.mjs";
|
|
8
|
+
import { a as formatReport, c as checksHere, d as runReadyDriver, f as unfitLines, i as walkLoaded, l as chooseReadyDriver, o as warningLines, s as budgetWarningLines, t as loadWorkflow, u as overrideRefusal } from "./validate-BxayjjkV.mjs";
|
|
9
9
|
import { a as createView, o as styler } from "./verdict-CMvPCpWC.mjs";
|
|
10
|
-
import { i as runLimits, r as limitsRefusal, t as chatNotice } from "./limits-
|
|
10
|
+
import { i as runLimits, r as limitsRefusal, t as chatNotice } from "./limits-VQqsBoQk.mjs";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -25,14 +25,19 @@ const put = (rows, f, run, at) => {
|
|
|
25
25
|
return next;
|
|
26
26
|
};
|
|
27
27
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* that fails its preflight frees its
|
|
28
|
+
* Why `f` is held by the run that took it, as the end of `taken by run <id>,
|
|
29
|
+
* <note>`; `undefined` when it is free. A run the store does not know counts as
|
|
30
|
+
* live while the mark is recent, so a run that fails its preflight frees its
|
|
31
|
+
* follow-ups when the window ends.
|
|
31
32
|
*/
|
|
32
|
-
const
|
|
33
|
-
if (f.takenBy === void 0
|
|
34
|
-
|
|
33
|
+
const heldNote = (f, isLive, now) => {
|
|
34
|
+
if (f.takenBy === void 0) return void 0;
|
|
35
|
+
const live = isLive(f.takenBy);
|
|
36
|
+
if (live !== void 0) return live ? "still running" : void 0;
|
|
37
|
+
return now - Date.parse(f.updatedAt) < 12e4 ? "not started yet; free in under 2 minutes" : void 0;
|
|
35
38
|
};
|
|
39
|
+
/** Whether another run holds `f`: it is not free to take again. */
|
|
40
|
+
const heldByLive = (f, run, isLive, now) => f.takenBy !== run && heldNote(f, isLive, now) !== void 0;
|
|
36
41
|
/**
|
|
37
42
|
* The project's due `agent` follow-ups no live run has taken (`ids`), and those
|
|
38
43
|
* a live run holds (`held`), so a second `--follow-ups due` doesn't take them
|
|
@@ -54,13 +59,17 @@ const availableDue = (rows, project, isLive, run = "", now = () => (/* @__PURE__
|
|
|
54
59
|
const takeFollowUps = (rows, taking, now = () => (/* @__PURE__ */ new Date()).toISOString()) => {
|
|
55
60
|
const taken = [];
|
|
56
61
|
const refused = [];
|
|
62
|
+
const at = Date.parse(now());
|
|
57
63
|
for (const id of taking.ids) {
|
|
58
64
|
const f = rows.followUp(taking.project, id);
|
|
59
65
|
if (f === void 0) refused.push(`${id}: there is no such follow-up`);
|
|
60
66
|
else if (f.for !== "agent") refused.push(`${id}: it is for ${f.for}`);
|
|
61
67
|
else if (f.status === "done" || f.status === "dropped") refused.push(`${id}: it is ${f.status}`);
|
|
62
|
-
else
|
|
63
|
-
|
|
68
|
+
else {
|
|
69
|
+
const note = f.takenBy === taking.run ? void 0 : heldNote(f, taking.isLive, at);
|
|
70
|
+
if (note === void 0) taken.push(put(rows, f, taking.run, now()));
|
|
71
|
+
else refused.push(`${id}: taken by run ${f.takenBy}, ${note}`);
|
|
72
|
+
}
|
|
64
73
|
}
|
|
65
74
|
return {
|
|
66
75
|
taken,
|
|
@@ -1246,7 +1255,7 @@ const isDriver = (value) => AGENT_DRIVERS.some((d) => d.id === value);
|
|
|
1246
1255
|
/** Why `--driver` refuses a value: a retired id names its replacement. */
|
|
1247
1256
|
const badDriver = (value) => `--${retiredDriverHint(value) ?? `driver must be one of ${AGENT_DRIVERS.map((d) => d.id).join(", ")}, got \`${value}\``}`;
|
|
1248
1257
|
/** Loads the drivers only when a run starts, so other commands stay fast. */
|
|
1249
|
-
const loadRuntime = async (driver, runs) => (await import("./src-
|
|
1258
|
+
const loadRuntime = async (driver, runs) => (await import("./src-D4JSymhK.mjs")).createRuntime(driver, sessionEnv(process.env), runs);
|
|
1250
1259
|
/**
|
|
1251
1260
|
* Ctrl-C asks the run to stop, and so does a terminal closing or a polite kill,
|
|
1252
1261
|
* so that the run ends tidily and leaves no result unscrubbed.
|
|
@@ -1368,14 +1377,14 @@ const run = defineCommand({
|
|
|
1368
1377
|
process.exitCode = 1;
|
|
1369
1378
|
return;
|
|
1370
1379
|
}
|
|
1371
|
-
const { prepareFollowUps: prepare, followUpsFlagFine: flagFine } = await import("./brief-
|
|
1380
|
+
const { prepareFollowUps: prepare, followUpsFlagFine: flagFine } = await import("./brief-DH66xmj8.mjs");
|
|
1372
1381
|
const cwd = process.cwd();
|
|
1373
1382
|
if (refusedBuiltin([args.workflow], cwd) || !flagFine(rawArgs)) return;
|
|
1374
1383
|
const target = workflowArg(args.workflow, cwd);
|
|
1375
1384
|
const store = openStore();
|
|
1376
1385
|
if (args.detach) {
|
|
1377
1386
|
try {
|
|
1378
|
-
const { startDetached } = await import("./detached-
|
|
1387
|
+
const { startDetached } = await import("./detached-Dakw5RZj.mjs");
|
|
1379
1388
|
await startDetached(store, {
|
|
1380
1389
|
rawArgs,
|
|
1381
1390
|
cwd,
|
|
@@ -1440,4 +1449,4 @@ const run = defineCommand({
|
|
|
1440
1449
|
}
|
|
1441
1450
|
}
|
|
1442
1451
|
});
|
|
1443
|
-
export { machineSlotLedger as _, onInterrupt as a, runWorkflowFile as c, followUpsRule as d, refreshDue as f, sweepLocks as g, machineLocksDir as h, loadRuntime as i, briefOf as l, resumeChat as m, flagValues as n, run as o, runIsLive as p, isDriver as r, terminalHuman as s, badDriver as t, checkTakeable as u, availableDue as v,
|
|
1452
|
+
export { machineSlotLedger as _, onInterrupt as a, takeFollowUps as b, runWorkflowFile as c, followUpsRule as d, refreshDue as f, sweepLocks as g, machineLocksDir as h, loadRuntime as i, briefOf as l, resumeChat as m, flagValues as n, run as o, runIsLive as p, isDriver as r, terminalHuman as s, badDriver as t, checkTakeable as u, availableDue as v, heldNote as y };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { R as openStore, et as TOO_LONG, nt as sendFromScript, tt as scriptRefusal } from "./src-
|
|
2
|
-
import { u as inheritedScrubber } from "./src-
|
|
1
|
+
import { R as openStore, et as TOO_LONG, nt as sendFromScript, tt as scriptRefusal } from "./src-8cOPOgrT.mjs";
|
|
2
|
+
import { u as inheritedScrubber } from "./src-I_RyKu6_.mjs";
|
|
3
3
|
import { l as writeErr } from "./output-B1kwo0YU.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
// src/commands/send.ts
|
|
@@ -5003,7 +5003,8 @@ const feedbackActions = (item, fixRun) => {
|
|
|
5003
5003
|
accept: check,
|
|
5004
5004
|
lesson: check,
|
|
5005
5005
|
apply: check,
|
|
5006
|
-
publish: check
|
|
5006
|
+
publish: check,
|
|
5007
|
+
resolve: check
|
|
5007
5008
|
};
|
|
5008
5009
|
}
|
|
5009
5010
|
const settled = item.status === "resolved" || item.status === "published";
|
|
@@ -5018,11 +5019,13 @@ const feedbackActions = (item, fixRun) => {
|
|
|
5018
5019
|
let publish = ALLOWED;
|
|
5019
5020
|
if (!isOrk) publish = no("only feedback about Ork is shared", `${short} is about this ${item.target}, not Ork itself: only feedback about Ork is shared, and the rest stays on your machine.`);
|
|
5020
5021
|
else if (item.status === "published") publish = already(short, item.status);
|
|
5022
|
+
const resolve = settled ? already(short, item.status) : ALLOWED;
|
|
5021
5023
|
return {
|
|
5022
5024
|
accept,
|
|
5023
5025
|
lesson,
|
|
5024
5026
|
apply,
|
|
5025
|
-
publish
|
|
5027
|
+
publish,
|
|
5028
|
+
resolve
|
|
5026
5029
|
};
|
|
5027
5030
|
};
|
|
5028
5031
|
/** The running `ork:feedback-apply` run proposing a fix for `item`, if any. */
|
|
@@ -16278,7 +16281,7 @@ const answerDecision = async (store, id, choice, home, by = "decide", note) => {
|
|
|
16278
16281
|
* Calls `onEvent` for each event of `root` and of the runs it called, once
|
|
16279
16282
|
* each. A called run's stored events come right after the `call.started` that
|
|
16280
16283
|
* started it; live events as they arrive. Ends when the root ends or `signal`
|
|
16281
|
-
* aborts.
|
|
16284
|
+
* aborts; with `follow: false`, once the stored events are read.
|
|
16282
16285
|
*/
|
|
16283
16286
|
const followRunTree = async (store, root, onEvent, options = {}) => {
|
|
16284
16287
|
/** Every run followed, with its call path, in the order found. */
|
|
@@ -16286,6 +16289,7 @@ const followRunTree = async (store, root, onEvent, options = {}) => {
|
|
|
16286
16289
|
/** Each run's last event seen, for the catch-up once the root ends. */
|
|
16287
16290
|
const seqs = /* @__PURE__ */ new Map();
|
|
16288
16291
|
const followers = [];
|
|
16292
|
+
const live = options.follow ?? true;
|
|
16289
16293
|
/** Ends the called runs' following once the root's has ended. */
|
|
16290
16294
|
const halt = new AbortController();
|
|
16291
16295
|
const signal = options.signal === void 0 ? halt.signal : AbortSignal.any([options.signal, halt.signal]);
|
|
@@ -16303,7 +16307,7 @@ const followRunTree = async (store, root, onEvent, options = {}) => {
|
|
|
16303
16307
|
paths.set(run, path);
|
|
16304
16308
|
followers.push(followEvents(store, run, handle(run, path), {
|
|
16305
16309
|
...options,
|
|
16306
|
-
follow:
|
|
16310
|
+
follow: live,
|
|
16307
16311
|
after: seqs.get(run) ?? 0,
|
|
16308
16312
|
signal
|
|
16309
16313
|
}));
|
|
@@ -16314,7 +16318,7 @@ const followRunTree = async (store, root, onEvent, options = {}) => {
|
|
|
16314
16318
|
};
|
|
16315
16319
|
const end = await followEvents(store, root, handle(root, []), {
|
|
16316
16320
|
...options,
|
|
16317
|
-
follow:
|
|
16321
|
+
follow: live
|
|
16318
16322
|
});
|
|
16319
16323
|
halt.abort();
|
|
16320
16324
|
await settle();
|
|
@@ -16333,6 +16337,95 @@ const followRunTree = async (store, root, onEvent, options = {}) => {
|
|
|
16333
16337
|
})
|
|
16334
16338
|
};
|
|
16335
16339
|
};
|
|
16340
|
+
// ../core/src/remote/follow-runs.ts
|
|
16341
|
+
/**
|
|
16342
|
+
* @file Following many runs at once (`ork logs -f --all`, `ork decide
|
|
16343
|
+
* --follow`): each live top-level run through `followRunTree`, so a called
|
|
16344
|
+
* run is reached through its caller and seen once, and a run that starts
|
|
16345
|
+
* later found by polling the run list, since no socket announces a new run.
|
|
16346
|
+
*/
|
|
16347
|
+
/**
|
|
16348
|
+
* Calls `onEvent` for each event of the live runs in `scope` and of the runs
|
|
16349
|
+
* they call, once each: stored events first, then live ones. Roots are the live
|
|
16350
|
+
* runs with no `parent`, and a called run whose caller is not followed (out of
|
|
16351
|
+
* scope, or ended while it runs on). A root's end does not end the watch.
|
|
16352
|
+
*/
|
|
16353
|
+
const followRuns = async (store, scope, onEvent, options = {}) => {
|
|
16354
|
+
/** Each followed tree's runs, by its root, while it is followed. */
|
|
16355
|
+
const trees = /* @__PURE__ */ new Map();
|
|
16356
|
+
const followers = /* @__PURE__ */ new Set();
|
|
16357
|
+
/** Each run's last event passed on: a run followed again starts after it. */
|
|
16358
|
+
const seqs = /* @__PURE__ */ new Map();
|
|
16359
|
+
const workflows = /* @__PURE__ */ new Map();
|
|
16360
|
+
const failure = {};
|
|
16361
|
+
/** Ends every follower once one has failed. */
|
|
16362
|
+
const halt = new AbortController();
|
|
16363
|
+
const signal = options.signal === void 0 ? halt.signal : AbortSignal.any([options.signal, halt.signal]);
|
|
16364
|
+
const { project } = scope;
|
|
16365
|
+
const filter = project === void 0 || project === "all" ? {} : { project };
|
|
16366
|
+
/** What each tree takes: `untilIdle` is the watch's, not a tree's. */
|
|
16367
|
+
const { untilIdle, ...poll } = options;
|
|
16368
|
+
const followed = (run) => [...trees.values()].some((runs) => runs.has(run));
|
|
16369
|
+
const workflowOf = (run) => {
|
|
16370
|
+
const known = workflows.get(run);
|
|
16371
|
+
if (known !== void 0) return known;
|
|
16372
|
+
const name = store.lookup(run).find((r) => r.id === run)?.workflow ?? "";
|
|
16373
|
+
workflows.set(run, name);
|
|
16374
|
+
return name;
|
|
16375
|
+
};
|
|
16376
|
+
const inScope = (run) => (scope.run === void 0 || run.id === scope.run) && (scope.workflow === void 0 || run.workflow === scope.workflow);
|
|
16377
|
+
const adopt = (root) => {
|
|
16378
|
+
const runs = /* @__PURE__ */ new Set([root]);
|
|
16379
|
+
trees.set(root, runs);
|
|
16380
|
+
const following = followRunTree(store, root, (event) => {
|
|
16381
|
+
runs.add(event.run);
|
|
16382
|
+
if (event.stored.seq <= (seqs.get(event.run) ?? 0)) return;
|
|
16383
|
+
seqs.set(event.run, event.stored.seq);
|
|
16384
|
+
onEvent({
|
|
16385
|
+
...event,
|
|
16386
|
+
workflow: workflowOf(event.run)
|
|
16387
|
+
});
|
|
16388
|
+
}, {
|
|
16389
|
+
...poll,
|
|
16390
|
+
signal
|
|
16391
|
+
}).catch((error) => {
|
|
16392
|
+
failure.error ??= error;
|
|
16393
|
+
halt.abort();
|
|
16394
|
+
}).finally(() => {
|
|
16395
|
+
trees.delete(root);
|
|
16396
|
+
followers.delete(following);
|
|
16397
|
+
});
|
|
16398
|
+
followers.add(following);
|
|
16399
|
+
};
|
|
16400
|
+
/** Starts a tree for each live run in scope that no tree reaches. */
|
|
16401
|
+
const discover = () => {
|
|
16402
|
+
const live = store.runs(filter).filter((run) => liveStatus(run) === "running" && inScope(run));
|
|
16403
|
+
for (const run of live) workflows.set(run.id, run.workflow);
|
|
16404
|
+
const unseen = live.filter((run) => !followed(run.id));
|
|
16405
|
+
const pending = new Set(unseen.map((run) => run.id));
|
|
16406
|
+
for (const run of unseen) {
|
|
16407
|
+
const { parent } = run;
|
|
16408
|
+
const orphan = parent === void 0 || !followed(parent) && !pending.has(parent);
|
|
16409
|
+
if (scope.run !== void 0 || orphan) adopt(run.id);
|
|
16410
|
+
}
|
|
16411
|
+
};
|
|
16412
|
+
const settle = async () => {
|
|
16413
|
+
await Promise.all(followers);
|
|
16414
|
+
if ("error" in failure) throw failure.error;
|
|
16415
|
+
};
|
|
16416
|
+
for (;;) {
|
|
16417
|
+
if (signal.aborted) break;
|
|
16418
|
+
discover();
|
|
16419
|
+
if (untilIdle === true && trees.size === 0) return "idle";
|
|
16420
|
+
try {
|
|
16421
|
+
await setTimeout$1(options.intervalMs ?? 1e3, void 0, { signal });
|
|
16422
|
+
} catch {
|
|
16423
|
+
break;
|
|
16424
|
+
}
|
|
16425
|
+
}
|
|
16426
|
+
await settle();
|
|
16427
|
+
return "aborted";
|
|
16428
|
+
};
|
|
16336
16429
|
// ../core/src/remote/relay.ts
|
|
16337
16430
|
/**
|
|
16338
16431
|
* @file A run's side of the relay (RFC-003): its nodes' links, read from the
|
|
@@ -17342,7 +17435,11 @@ const feedbackQueries = (db) => {
|
|
|
17342
17435
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);
|
|
17343
17436
|
const insertItem = db.prepare(`INSERT INTO feedback_items (fingerprint, status, updated_at)
|
|
17344
17437
|
VALUES (?, 'new', ?) ON CONFLICT (fingerprint) DO NOTHING`);
|
|
17345
|
-
const shown = db.prepare(`${ITEMS} WHERE r.status
|
|
17438
|
+
const shown = db.prepare(`${ITEMS} WHERE r.status NOT IN ('dismissed', 'resolved') GROUP BY r.fingerprint ORDER BY last_seen DESC`);
|
|
17439
|
+
const reopen = db.prepare(`UPDATE feedback_items SET status = 'new', updated_at = ?
|
|
17440
|
+
WHERE fingerprint = (
|
|
17441
|
+
SELECT COALESCE(merged_into, fingerprint) FROM feedback_items WHERE fingerprint = ?
|
|
17442
|
+
) AND status = 'resolved' AND updated_at < ?`);
|
|
17346
17443
|
const every = db.prepare(`${ITEMS} GROUP BY r.fingerprint ORDER BY last_seen DESC`);
|
|
17347
17444
|
const byPrefix = db.prepare(`${ITEMS} WHERE r.fingerprint IN (
|
|
17348
17445
|
SELECT COALESCE(merged_into, fingerprint) FROM feedback_items
|
|
@@ -17367,6 +17464,7 @@ const feedbackQueries = (db) => {
|
|
|
17367
17464
|
const { origin } = feedback;
|
|
17368
17465
|
insert.run(runId, seq, at, node ?? null, feedback.source, feedback.kind, feedback.target, feedback.severity, maskSecrets(feedback.title), maskSecrets(feedback.body), JSON.stringify(feedback.evidence.map((e) => maskSecrets(e))), feedback.code ?? null, feedback.fingerprint, origin.workflow ?? null, origin.workflowHash ?? null, origin.nodeType ?? null, origin.model ?? null, origin.driver ?? null, origin.version ?? null, 1);
|
|
17369
17466
|
insertItem.run(feedback.fingerprint, at);
|
|
17467
|
+
reopen.run(at, feedback.fingerprint, at);
|
|
17370
17468
|
};
|
|
17371
17469
|
return {
|
|
17372
17470
|
insertFeedback: insertRecord,
|
|
@@ -18321,14 +18419,62 @@ const takeWatchLock = (store, pid = process.pid) => {
|
|
|
18321
18419
|
}
|
|
18322
18420
|
};
|
|
18323
18421
|
};
|
|
18422
|
+
// ../core/src/triggers/check-reads.ts
|
|
18423
|
+
/**
|
|
18424
|
+
* @file What a trigger's check runs beyond its own words, for the hash a person
|
|
18425
|
+
* accepts: the `.mcp.json` its server comes from, and the project's files its
|
|
18426
|
+
* command, interpreter or server program names (`--config=./x.json` names
|
|
18427
|
+
* `./x.json`). What those files read in turn, a program outside the project
|
|
18428
|
+
* and a path built from an env variable are not in it. Only files inside the
|
|
18429
|
+
* project are read, and what goes into the hash is the text of `.mcp.json`
|
|
18430
|
+
* and a digest of each named file's bytes, never anything else.
|
|
18431
|
+
*/
|
|
18432
|
+
/** A file's text; `undefined` only when it isn't there. Anything else throws. */
|
|
18433
|
+
const readText = (file) => {
|
|
18434
|
+
try {
|
|
18435
|
+
return readFileSync(file, "utf8");
|
|
18436
|
+
} catch (error) {
|
|
18437
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
|
|
18438
|
+
throw error;
|
|
18439
|
+
}
|
|
18440
|
+
};
|
|
18441
|
+
const isFile = (file) => statSync(file, { throwIfNoEntry: false })?.isFile() === true;
|
|
18442
|
+
/**
|
|
18443
|
+
* What a word names, if it is a file in the project: the word and a digest of
|
|
18444
|
+
* the file's bytes, not its text, so a compiled program that differs only in
|
|
18445
|
+
* bytes that aren't UTF-8 still changes the hash. A file outside the project, a
|
|
18446
|
+
* missing one and a word that is no file add nothing.
|
|
18447
|
+
*/
|
|
18448
|
+
const fileRead = (root, from, word) => {
|
|
18449
|
+
const file = path.resolve(from, word.replace(/^-{1,2}[^=\s]+=/u, ""));
|
|
18450
|
+
return word !== "" && inside(root, file) && isFile(file) ? [`${word}\0${createHash("sha256").update(readFileSync(file)).digest("hex")}`] : [];
|
|
18451
|
+
};
|
|
18452
|
+
/** The in-repo files a stdio server's program and arguments name. */
|
|
18453
|
+
const serverReads = (root, server) => {
|
|
18454
|
+
const read = serversIn(root);
|
|
18455
|
+
const entry = read.ok ? read.value[server] : void 0;
|
|
18456
|
+
if (typeof entry !== "object" || entry === null) return [];
|
|
18457
|
+
const command = Reflect.get(entry, "command");
|
|
18458
|
+
const args = Reflect.get(entry, "args");
|
|
18459
|
+
return [command, ...Array.isArray(args) ? args : []].flatMap((word) => typeof word === "string" ? fileRead(root, root, word) : []);
|
|
18460
|
+
};
|
|
18461
|
+
/** The texts a check's hash covers beyond its own words. */
|
|
18462
|
+
const checkReads = (root, check) => {
|
|
18463
|
+
if (check === void 0) return [];
|
|
18464
|
+
if (check.type === "mcp.call") return [readText(path.join(root, ".mcp.json")) ?? "", ...serverReads(root, check.server)];
|
|
18465
|
+
const from = path.resolve(root, check.cwd ?? ".");
|
|
18466
|
+
return [check.command, check.interpreter].join(" ").split(/\s+/u).flatMap((word) => fileRead(root, from, word));
|
|
18467
|
+
};
|
|
18324
18468
|
// ../core/src/triggers/trust.ts
|
|
18325
18469
|
/**
|
|
18326
18470
|
* @file What a person accepts (RFC-011): a trigger, the workflow it starts,
|
|
18327
18471
|
* what its check runs beyond its own words, and the folder it was accepted
|
|
18328
18472
|
* in. A branch can change any of them and so what runs here with nobody
|
|
18329
18473
|
* there, so a change to one turns the trigger off until someone accepts it
|
|
18330
|
-
* again.
|
|
18331
|
-
*
|
|
18474
|
+
* again. That includes the project's files a check's command or an MCP
|
|
18475
|
+
* check's server program names. It can't cover all a run reads: skills,
|
|
18476
|
+
* agents, what a script or server program itself reads, programs outside the
|
|
18477
|
+
* project and called workflows aren't in it.
|
|
18332
18478
|
*/
|
|
18333
18479
|
const sorted = (value) => {
|
|
18334
18480
|
if (Array.isArray(value)) return value.map((item) => sorted(item));
|
|
@@ -18354,29 +18500,6 @@ const triggerHash = (trigger, workflowText, root = "", reads = []) => {
|
|
|
18354
18500
|
* Read fresh each time, so a file changed by a pull turns its trigger off
|
|
18355
18501
|
* rather than running as it was.
|
|
18356
18502
|
*/
|
|
18357
|
-
/** A file's text; `undefined` only when it isn't there. Anything else throws. */
|
|
18358
|
-
const readText = (file) => {
|
|
18359
|
-
try {
|
|
18360
|
-
return readFileSync(file, "utf8");
|
|
18361
|
-
} catch (error) {
|
|
18362
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return;
|
|
18363
|
-
throw error;
|
|
18364
|
-
}
|
|
18365
|
-
};
|
|
18366
|
-
const isFile = (file) => statSync(file, { throwIfNoEntry: false })?.isFile() === true;
|
|
18367
|
-
/**
|
|
18368
|
-
* What a check runs beyond its own words, for what a person accepts: the
|
|
18369
|
-
* `.mcp.json` its server comes from, or the project's files its command names.
|
|
18370
|
-
*/
|
|
18371
|
-
const checkReads = (root, check) => {
|
|
18372
|
-
if (check === void 0) return [];
|
|
18373
|
-
if (check.type === "mcp.call") return [readText(path.join(root, ".mcp.json")) ?? ""];
|
|
18374
|
-
const from = path.resolve(root, check.cwd ?? ".");
|
|
18375
|
-
return [check.command, check.interpreter].join(" ").split(/\s+/u).flatMap((word) => {
|
|
18376
|
-
const file = path.resolve(from, word);
|
|
18377
|
-
return word !== "" && inside(root, file) && isFile(file) ? [`${word}\0${readFileSync(file, "utf8")}`] : [];
|
|
18378
|
-
});
|
|
18379
|
-
};
|
|
18380
18503
|
/** Where a project's workflow of this name is. */
|
|
18381
18504
|
const workflowFileOf = (place, name) => path.join(placeFiles(place).workflows, `${name}.ork.yaml`);
|
|
18382
18505
|
const readTriggers = (file, place, home, registered) => {
|
|
@@ -19830,4 +19953,4 @@ const createWorkspace = (options) => {
|
|
|
19830
19953
|
close
|
|
19831
19954
|
};
|
|
19832
19955
|
};
|
|
19833
|
-
export { driverQueues as $,
|
|
19956
|
+
export { driverQueues as $, isGithubIssueUrl as $n, estimateTokens as $r, planClean as $t, triggerStanding as A, PREFERRED_DRIVER as Ai, requestContinue as An, planAgentMigration as Ar, heldTimeout as At, appendRecorder as B, knownExperiments as Bi, processAlive as Bn, loadAgents as Br, lowerChild as Bt, detectInstaller as C, DriverSchema as Ci, followUpProblem as Cn, readCondition as Cr, reportSchemaFor as Ct, lateTriggers as D, INTEGRATIONS as Di, endLinksOf as Dn, MASK as Dr, startRun as Dt, parseVersion as E, timeoutMs as Ei, addressOf as En, TOOL_INPUT_KEYS as Er, walkSummary as Et, watchingPid as F, AGENT_DRIVERS as Fi, lockWaitsOf as Fn, toolsInUse as Fr, failedWith as Ft, listOrkWorktrees as G, PROJECT_FILE as Gn, placeFor as Gr, feedbackListTable as Gt, applyPrune as H, isItem as Hn, inRepoPlace as Hr, startAt as Ht, activeTree as I, DRIVER_IDS as Ii, pausedOf as In, createAgent as Ir, stoppedEnd as It, parseInputPairs as J, machineRulesOf as Jn, shownPath as Jr, usageListTable as Jt, createReplay as K, gitRulesOf as Kn, projectsHome as Kr, followUpListTable as Kt, isNodeEvent as L, firstLine as Li, runStatus as Ln, deleteAgent as Lr, declaredProblem as Lt, readProjectTriggers as M, readyDriver as Mi, requestStop as Mn, planMoveInto as Mr, calledWorkflows as Mt, workflowTextHash as N, AGENT_TOOL_LAYOUTS as Ni, tellLiveRun as Nn, linkTools as Nr, lockWaitLine as Nt, triggersReport as O, TOOL_PREFIX as Oi, linkNodes as On, maskReplacer as Or, MESSAGE_LIMIT as Ot, takeWatchLock as P, ORK_LAYOUT as Pi, liveStatus as Pn, toolLinks as Pr, endedWith as Pt, sessionRefusals as Q, followUpActions as Qn, LESSON_CAP_TOKENS as Qr, keyOf as Qt, openStore as R, EXPERIMENTS as Ri, slotWaitsOf as Rn, AGENT_SOURCES as Rr, slotClock as Rt, runningScript as S, isToolNode as Si, deliverFollowUp as Sn, renderTemplate as Sr, parseReport as St, isNewer as T, retiredDriverHint as Ti, DEFAULT_FOLLOW_UPS_RULE as Tn, socketRoom as Tr, walkChecks as Tt, planPrune as U, nestItems as Un, newProjectId as Ur, LIST_TABLES as Ut, createRecorder as V, stillTheSameProcess as Vn, hasInRepoFiles as Vr, programFound as Vt, createdWorktrees as W, countedTokens as Wn, placeFiles as Wr, decisionListTable as Wt, budgetWarnings as X, dueCause as Xn, inside as Xr, applyClean as Xt, resolveInputs as Y, changeFollowUp as Yn, workflowDirOf as Yr, worktreeListTable as Yt, driverRefusals as Z, findFollowUp as Zn, projectRootOf as Zr, cleanStep as Zt, usageReport as _, CheckReportSchema as _i, postFollowUpMessage as _n, normalizeTitle as _r, limitsReport as _t, planRemove as a, applyEdits as ai, clearGitLocalEnv as an, endFor as ar, followRunTree as at, releaseNotes as b, NodeSchema as bi, recordPublished as bn, evaluate as br, explainSession as bt, repoRoot as c, renameNodeTypes as ci, namingNoDriver as cn, recordNote as cr, createCalls as ct, mergeStateOf as d, renderJsonSchema as di, declaredOutputOf as dn, FEEDBACK_TARGETS as dr, resumable as dt, guardedBase as ei, stepActs as en, createSignals as er, TOO_LONG as et, planLine as f, parseWorkflow as fi, MCP_FILE as fn, DISCUSSIONS as fr, DETACHED_ENV as ft, USAGE_DIMENSIONS as g, WorkflowSchema as gi, createFollowUps as gn, createFeedback as gr, limitsNow as gt, resolveBase as h, EdgeInputSchema as hi, FOLLOW_UP_KINDS as hn, sendPost as hr, NOT_STARTED as ht, lostWork as i, WorkflowEditSchema as ii, gitOk as in, END_KINDS as ir, followRuns as it, declaredTriggers as j, driverChecks as ji, requestPause as jn, applySteps as jr, runScope as jt, createWatcher as k, integrationFor as ki, unlinkNodes as kn, maskSecrets as kr, userMessageText as kt, isDetached as l, beforeOf as li, sessionDriver as ln, FEEDBACK_KINDS as lr, adoptedCalls as lt, stateParts as m, markValue as mi, serversIn as mn, runGh as mr, followEvents as mt, resumedOptions as n, writePlainFile as ni, inspectProject as nn, outcomeEnd as nr, sendFromScript as nt, projectHead as o, newWorkflowText as oi, envReadsOf as on, previewPost as or, answerDecision as ot, removeRefusal as p, serializeWorkflow as pi, mcpNotText as pn, planPost as pr, detachRun as pt, replayLoopAnswers as q, loadProject as qn, runDirOf as qr, runListTable as qt, applyRemove as r, skillsIn as ri, git as rn, END_DETAIL_LIMIT as rr, createRelay as rt, readWorktrees as s, readDocument as si, modelDriver as sn, checkNote as sr, pendingDecisions as st, createWorkspace as t, plainPathInside as ti, stepPrunes as tn, endOf as tr, scriptRefusal as tt, labelOf as u, programsRunBy as ui, nodeSays as un, FEEDBACK_SEVERITIES as ur, detachResume as ut, capsHere as v, expandEdge as vi, checkFollowUpsDue as vn, feedbackActions as vr, planReason as vt, compareVersions as w, NodeIdSchema as wi, liveSessionOf as wn, startControl as wr, checkWorkflowText as wt, runningRunIds as x, isClaudeNode as xi, startFollowUpChecks as xn, parseTemplate as xr, planNodeSession as xt, planUpgrade as y, settingsOf as yi, markDue as yn, openFixRun as yr, explainWorkflowText as yt, storePath as z, experimentsOn as zi, templateOf$1 as zn, catalogAgent as zr, slotWaitLine as zt };
|