@krapht/ork 1.0.0-alpha.16 → 1.0.0-alpha.18
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__-DcRdK0Du.mjs → __build_info__-B8TNbFtN.mjs} +2 -2
- package/dist/{attach-7lB5_jpr.mjs → attach-CU4Pk42S.mjs} +5 -5
- package/dist/{attach-B-FeE1dJ.mjs → attach-qvfyaQXC.mjs} +1 -1
- package/dist/bin.mjs +35 -35
- package/dist/brief-Bh1FnAHv.mjs +100 -0
- package/dist/{builtin-files-BRSOObAv.mjs → builtin-files-dnTP2GaX.mjs} +1 -1
- package/dist/{completion-Cgb2qPPh.mjs → completion-CzXUGSVn.mjs} +46 -4
- package/dist/{context-BN9A2Nnu.mjs → context-b4_gPlv3.mjs} +3 -3
- package/dist/{find-mLYsR0uC.mjs → find-P-VV4B47.mjs} +1 -1
- package/dist/{flags-CdgIH1L6.mjs → flags-CqjJ44uW.mjs} +3 -108
- package/dist/{follow-ups-DxCsOby1.mjs → follow-ups-B_c1DSpA.mjs} +8 -8
- package/dist/{format-hiDvtNGM.mjs → format-BS1qzpkf.mjs} +1 -1
- package/dist/in-a-run-DKoMGTNE.mjs +27 -0
- package/dist/{install-23g_1ngs.mjs → install-B743Bwzz.mjs} +1 -1
- package/dist/{limits-C_Xz_t3C.mjs → limits-DrsKCqaN.mjs} +1 -1
- package/dist/{mcp-CWng9I9n.mjs → mcp-BMwekw38.mjs} +6 -6
- package/dist/{once-lvwcWfVf.mjs → once-6L8gciJV.mjs} +3 -3
- package/dist/parse-BzWpMN-a.mjs +107 -0
- package/dist/{pause-Cy11KrXK.mjs → pause-8gnVgICR.mjs} +3 -3
- package/dist/{post-C9soCx7i.mjs → post-y1qL1Fnj.mjs} +2 -2
- package/dist/{print-BaWiWf4v.mjs → print-DLe4MHn-.mjs} +1 -1
- package/dist/{project-records-BRiyQzUo.mjs → project-records-CsILxwfI.mjs} +1 -1
- package/dist/{relay-C0M1TWMB.mjs → relay-Bvm9JEoN.mjs} +1 -1
- package/dist/{run-B-j3Qxqc.mjs → run-D4yuTmmJ.mjs} +17 -17
- package/dist/{run-D_u9V_Ve.mjs → run-y8jI7bAI.mjs} +1 -1
- package/dist/{send-qBxj0JbJ.mjs → send-BV9eIxQ7.mjs} +2 -2
- package/dist/{src-DHDQ0itC.mjs → src-CVeA4tAw.mjs} +73 -18
- package/dist/{src-nXLIwDrt.mjs → src-DWAcd3Sy.mjs} +235 -73
- package/dist/{src-DN-RPsil.mjs → src-Frwpx3WF.mjs} +49 -6
- package/dist/{src-CXBmaGwS.mjs → src-ygFMh2eP.mjs} +391 -233
- package/dist/{store-Dyr1mP8K.mjs → store-B0nGqnPq.mjs} +1 -1
- package/dist/ui/assets/app-9Q-62Ywz.css +1 -0
- package/dist/ui/assets/app-C4yxmYQR.js +111 -0
- package/dist/ui/assets/{index-CVzwYlz3.js → index-CcbJWo5C.js} +2 -2
- package/dist/ui/index.html +1 -1
- package/dist/{ui-DLrSt5ny.mjs → ui-BZ9BhFw8.mjs} +3 -3
- package/dist/{usage-CxmpYYO4.mjs → usage-BIs4j5Rw.mjs} +5 -4
- package/dist/{validate-BVrT43GO.mjs → validate-Xn2ZbJQC.mjs} +3 -3
- package/dist/{watch-mkLm4t9D.mjs → watch-9VM3DFTp.mjs} +5 -5
- package/dist/{workflows-Bvl2Fquu.mjs → workflows-CBYtycIy.mjs} +2 -2
- package/dist/{worktrees-DOOCoS2w.mjs → worktrees-C7vfh7y5.mjs} +4 -4
- package/package.json +1 -1
- package/dist/brief-BvMtIFio.mjs +0 -58
- package/dist/in-a-run-a447hxq8.mjs +0 -24
- package/dist/ui/assets/app-BPSCxb_l.css +0 -1
- package/dist/ui/assets/app-CnNRowFn.js +0 -111
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// ../core/src/list-filters/time.ts
|
|
2
|
+
/**
|
|
3
|
+
* @file The times every list's `--since` and `--until` take (specs/usage.md,
|
|
4
|
+
* RFC-017), and `ork prune --older-than`'s age: an age (`24h`, `30d`, `12w`)
|
|
5
|
+
* or a day (`2026-11-01`, in the machine's time zone).
|
|
6
|
+
*/
|
|
7
|
+
const UNITS = {
|
|
8
|
+
h: 36e5,
|
|
9
|
+
d: 864e5,
|
|
10
|
+
w: 6048e5
|
|
11
|
+
};
|
|
12
|
+
/** `30d`, `12w`, `24h` before `now`, as an ISO time; `null` when it is not one. */
|
|
13
|
+
const agoTime = (text, now) => {
|
|
14
|
+
const match = /^(\d+)([hdw])$/u.exec(text);
|
|
15
|
+
if (match === null) return null;
|
|
16
|
+
const [, amount = "0", unit = "d"] = match;
|
|
17
|
+
if (Number(amount) === 0) return null;
|
|
18
|
+
const date = new Date(now - Number(amount) * (UNITS[unit] ?? 0));
|
|
19
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
20
|
+
};
|
|
21
|
+
/** A `YYYY-MM-DD` day's start in the machine's time zone, `after` days on. */
|
|
22
|
+
const dayTime = (text, after) => {
|
|
23
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/u.exec(text);
|
|
24
|
+
if (match === null) return null;
|
|
25
|
+
const [, year = "", month = "", day = ""] = match;
|
|
26
|
+
const start = new Date(Number(year), Number(month) - 1, Number(day));
|
|
27
|
+
if (start.getMonth() !== Number(month) - 1) return null;
|
|
28
|
+
if (start.getDate() !== Number(day)) return null;
|
|
29
|
+
start.setDate(start.getDate() + after);
|
|
30
|
+
return start.toISOString();
|
|
31
|
+
};
|
|
32
|
+
/** The start of the day `days` whole days ago, counting today as one. */
|
|
33
|
+
const wholeDays = (days, now) => {
|
|
34
|
+
const today = new Date(now);
|
|
35
|
+
return new Date(today.getFullYear(), today.getMonth(), today.getDate() - (days - 1)).toISOString();
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* `--since`: an age or the day it starts from. Days and weeks are whole days,
|
|
39
|
+
* today among them, as the Usage panel counts them; hours are exact.
|
|
40
|
+
*/
|
|
41
|
+
const sinceTime = (text, now) => {
|
|
42
|
+
const ago = agoTime(text, now);
|
|
43
|
+
if (ago === null) return dayTime(text, 0);
|
|
44
|
+
if (text.endsWith("h")) return ago;
|
|
45
|
+
const amount = Number(text.slice(0, -1));
|
|
46
|
+
return wholeDays(text.endsWith("w") ? amount * 7 : amount, now);
|
|
47
|
+
};
|
|
48
|
+
/** `--until`: the last day it includes. */
|
|
49
|
+
const untilTime = (text) => dayTime(text, 1);
|
|
50
|
+
// ../core/src/list-filters/parse.ts
|
|
51
|
+
/**
|
|
52
|
+
* @file Reads a list's filter flags against its field table (RFC-017): each
|
|
53
|
+
* value checked, times turned into ISO times, and `--limit`.
|
|
54
|
+
*/
|
|
55
|
+
const FOR = /^(agent|me|(project|person):\S+)$/u;
|
|
56
|
+
/** The field's value, checked; `null` when the field does not take it. */
|
|
57
|
+
const valueOf = (field, text, now) => {
|
|
58
|
+
if (text === "all" && field.all === true) return "all";
|
|
59
|
+
return {
|
|
60
|
+
enum: () => field.values?.includes(text) === true ? text : null,
|
|
61
|
+
text: () => text === "" ? null : text,
|
|
62
|
+
for: () => FOR.test(text) ? text : null,
|
|
63
|
+
since: () => sinceTime(text, now),
|
|
64
|
+
until: () => untilTime(text)
|
|
65
|
+
}[field.type]();
|
|
66
|
+
};
|
|
67
|
+
/** What the field takes, for the error that refuses a value. */
|
|
68
|
+
const takes = (field) => {
|
|
69
|
+
const all = field.all === true ? ["all"] : [];
|
|
70
|
+
const or = all.length === 0 ? "" : " or all";
|
|
71
|
+
return {
|
|
72
|
+
enum: `one of ${[...field.values ?? [], ...all].join(", ")}`,
|
|
73
|
+
text: `a value${or}`,
|
|
74
|
+
for: "agent, me, project:<name> or person:<name>",
|
|
75
|
+
since: `an age (30d), a day (2026-11-01)${or}`,
|
|
76
|
+
until: "a day (2026-11-01)"
|
|
77
|
+
}[field.type];
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* The filter `given` (a command's parsed flags, by field name) asks for, each
|
|
81
|
+
* value checked against `table`; `now` dates an age. The first value a field
|
|
82
|
+
* does not take is refused, naming the flag and what it takes.
|
|
83
|
+
*/
|
|
84
|
+
const parseFilters = (table, given, now) => {
|
|
85
|
+
const filter = {};
|
|
86
|
+
for (const field of table.fields) {
|
|
87
|
+
const text = given[field.name];
|
|
88
|
+
if (typeof text !== "string") continue;
|
|
89
|
+
const value = valueOf(field, text, now);
|
|
90
|
+
if (value === null) return {
|
|
91
|
+
ok: false,
|
|
92
|
+
error: `--${field.name} takes ${takes(field)}, not \`${text}\`.`
|
|
93
|
+
};
|
|
94
|
+
filter[field.name] = value;
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
ok: true,
|
|
98
|
+
filter
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
/** `--limit`: a positive whole number, else `null` (`0`, `-1`, `abc`, `2.5`). */
|
|
102
|
+
const parseLimit = (text) => {
|
|
103
|
+
if (!/^[1-9]\d*$/u.test(text)) return null;
|
|
104
|
+
const limit = Number(text);
|
|
105
|
+
return Number.isSafeInteger(limit) ? limit : null;
|
|
106
|
+
};
|
|
107
|
+
export { parseLimit as n, agoTime as r, parseFilters as t };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as findRun } from "./find-
|
|
1
|
+
import { Dn as requestPause, En as requestContinue, L as openStore } from "./src-Frwpx3WF.mjs";
|
|
2
|
+
import { t as findRun } from "./find-P-VV4B47.mjs";
|
|
3
3
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
4
|
-
import { i as continueRefusal } from "./in-a-run-
|
|
4
|
+
import { i as continueRefusal } from "./in-a-run-DKoMGTNE.mjs";
|
|
5
5
|
import { defineCommand } from "citty";
|
|
6
6
|
// src/commands/pause.ts
|
|
7
7
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { b as githubDraftRefusal } from "./__build_info__-
|
|
1
|
+
import { ar as redact } from "./src-Frwpx3WF.mjs";
|
|
2
|
+
import { b as githubDraftRefusal } from "./__build_info__-B8TNbFtN.mjs";
|
|
3
3
|
// ../core/src/follow-ups/post.ts
|
|
4
4
|
/** Posts `f`'s draft as a GitHub comment once `confirmed`, and marks it done. */
|
|
5
5
|
const postFollowUpMessage = async (f, options) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as refuseIdsWithJson } from "./flags-CdgIH1L6.mjs";
|
|
2
1
|
import { c as write } from "./output-B1kwo0YU.mjs";
|
|
2
|
+
import { a as refuseIdsWithJson } from "./flags-CqjJ44uW.mjs";
|
|
3
3
|
// src/list/print.ts
|
|
4
4
|
/**
|
|
5
5
|
* Prints `rows`: `--ids` their ids (`table.id`) comma-separated; `--json` the
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ir as projectsHome, L as openStore, Mr as inRepoPlace, Nr as newProjectId, Pr as placeFiles, Rr as shownPath, Vr as projectRootOf, jr as hasInRepoFiles } from "./src-Frwpx3WF.mjs";
|
|
2
2
|
import { C as termOf, c as write, l as writeErr, s as style, w as cut } from "./output-B1kwo0YU.mjs";
|
|
3
3
|
import { n as chip } from "./chips-BqcT58qr.mjs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { L as openStore, Sn as addressOf, Tn as unlinkNodes, wn as linkNodes } from "./src-Frwpx3WF.mjs";
|
|
2
2
|
import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
3
3
|
import { defineCommand } from "citty";
|
|
4
4
|
// src/commands/relay.ts
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Ct as startRun, G as parseInputPairs, Gn as
|
|
2
|
-
import { c as callsShown, d as createDecisionQueue, l as createTerminalHuman, o as formatEvent, s as formatRunEvent, t as attachRun } from "./attach-
|
|
3
|
-
import { h as nodeSession, n as ORK_VERSION, v as findFollowUp } from "./__build_info__-
|
|
4
|
-
import { n as newRunId } from "./find-
|
|
1
|
+
import { $r as beforeOf, $t as git, An as liveStatus, Br as inside, Cn as endLinksOf, Ct as startRun, Ei as DRIVER_IDS, Fn as templateOf, G as parseInputPairs, Gn as createSignals, Hn as gitRulesOf, K as resolveInputs, Kn as endOf, L as openStore, Lr as runDirOf, Pr as placeFiles, Qt as inspectProject, R as storePath, Si as readyDriver, St as walkSummary, Ti as AGENT_DRIVERS, Tt as userMessageText, U as createReplay, Un as loadProject, W as replayLoopAnswers, Wn as machineRulesOf, _n as takeFollowUps, _t as planNodeSession, an as sessionDriver, at as adoptedCalls, ct as DETACHED_ENV, di as isClaudeNode, dr as parseTemplate, dt as NOT_STARTED, et as createRelay, fn as createFollowUps, fr as renderTemplate, hi as retiredDriverHint, hr as socketPath, it as createCalls, lt as detachRun, m as resolveBase, mr as serveRun, n as resumedOptions, nr as runGh, or as createFeedback, pn as checkFollowUpsDue, t as createWorkspace, vn as deliverFollowUp, vr as maskReplacer } from "./src-Frwpx3WF.mjs";
|
|
2
|
+
import { c as callsShown, d as createDecisionQueue, l as createTerminalHuman, o as formatEvent, s as formatRunEvent, t as attachRun } from "./attach-qvfyaQXC.mjs";
|
|
3
|
+
import { h as nodeSession, n as ORK_VERSION, v as findFollowUp } from "./__build_info__-B8TNbFtN.mjs";
|
|
4
|
+
import { n as newRunId } from "./find-P-VV4B47.mjs";
|
|
5
5
|
import { c as write, i as detachHint, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
|
|
6
|
-
import { _ as
|
|
7
|
-
import { i as refusedBuiltin, o as workflowArg } 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 { _ as clearOutputFiles, a as builtinExecutors, d as maskedEnv, f as maskedNamesOfRun, i as onPath, l as clearStateFiles, m as sessionEnv, n as missingProgramMessage, p as runScrubber, r as missingPrograms, t as envProblems, v as namedMcpEntries, y as resultOf } from "./src-CVeA4tAw.mjs";
|
|
7
|
+
import { i as refusedBuiltin, o as workflowArg } from "./workflows-CBYtycIy.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-Xn2ZbJQC.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-DrsKCqaN.mjs";
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import { appendFileSync, existsSync, linkSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -1162,7 +1162,8 @@ const runWorkflowFile = async (options) => {
|
|
|
1162
1162
|
const executorOptions = {
|
|
1163
1163
|
runtimeFor: (driver) => options.runtime(driver, placeFiles(place).runs),
|
|
1164
1164
|
inPlace: options.inPlace,
|
|
1165
|
-
maskedNames
|
|
1165
|
+
maskedNames,
|
|
1166
|
+
store: storePath(options.home)
|
|
1166
1167
|
};
|
|
1167
1168
|
if (options.driver !== void 0) executorOptions.driver = options.driver;
|
|
1168
1169
|
if (ready.readyDriver !== void 0) executorOptions.readyDriver = ready.readyDriver;
|
|
@@ -1251,7 +1252,7 @@ const isDriver = (value) => AGENT_DRIVERS.some((d) => d.id === value);
|
|
|
1251
1252
|
/** Why `--driver` refuses a value: a retired id names its replacement. */
|
|
1252
1253
|
const badDriver = (value) => `--${retiredDriverHint(value) ?? `driver must be one of ${AGENT_DRIVERS.map((d) => d.id).join(", ")}, got \`${value}\``}`;
|
|
1253
1254
|
/** Loads the drivers only when a run starts, so other commands stay fast. */
|
|
1254
|
-
const loadRuntime = async (driver, runs) => (await import("./src-
|
|
1255
|
+
const loadRuntime = async (driver, runs) => (await import("./src-ygFMh2eP.mjs")).createRuntime(driver, sessionEnv(process.env), runs);
|
|
1255
1256
|
/**
|
|
1256
1257
|
* Ctrl-C asks the run to stop, and so does a terminal closing or a polite kill,
|
|
1257
1258
|
* so that the run ends tidily and leaves no result unscrubbed.
|
|
@@ -1302,7 +1303,7 @@ const run = defineCommand({
|
|
|
1302
1303
|
},
|
|
1303
1304
|
"follow-ups": {
|
|
1304
1305
|
type: "string",
|
|
1305
|
-
description: "Follow-up ids an agent does (repeatable or comma-separated): they become the run's brief, done when it publishes"
|
|
1306
|
+
description: "Follow-up ids an agent does, or `due` for every due one (repeatable or comma-separated): they become the run's brief, done when it publishes"
|
|
1306
1307
|
},
|
|
1307
1308
|
driver: {
|
|
1308
1309
|
type: "string",
|
|
@@ -1373,8 +1374,9 @@ const run = defineCommand({
|
|
|
1373
1374
|
process.exitCode = 1;
|
|
1374
1375
|
return;
|
|
1375
1376
|
}
|
|
1377
|
+
const { prepareFollowUps: prepare, followUpsFlagFine: flagFine } = await import("./brief-Bh1FnAHv.mjs");
|
|
1376
1378
|
const cwd = process.cwd();
|
|
1377
|
-
if (refusedBuiltin([args.workflow], cwd)) return;
|
|
1379
|
+
if (refusedBuiltin([args.workflow], cwd) || !flagFine(rawArgs)) return;
|
|
1378
1380
|
const target = workflowArg(args.workflow, cwd);
|
|
1379
1381
|
const store = openStore();
|
|
1380
1382
|
if (args.detach) {
|
|
@@ -1406,9 +1408,8 @@ const run = defineCommand({
|
|
|
1406
1408
|
}
|
|
1407
1409
|
return;
|
|
1408
1410
|
}
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
if (taking === void 0) {
|
|
1411
|
+
const taken = await prepare(store, rawArgs, args["run-id"], target);
|
|
1412
|
+
if (taken === void 0) {
|
|
1412
1413
|
store.close();
|
|
1413
1414
|
return;
|
|
1414
1415
|
}
|
|
@@ -1416,7 +1417,7 @@ const run = defineCommand({
|
|
|
1416
1417
|
const common = {
|
|
1417
1418
|
file: target.file,
|
|
1418
1419
|
cwd,
|
|
1419
|
-
|
|
1420
|
+
...taken,
|
|
1420
1421
|
inPlace: args["in-place"],
|
|
1421
1422
|
...args["machine-claude"] ? { machineClaude: true } : {},
|
|
1422
1423
|
json: args.json,
|
|
@@ -1424,7 +1425,6 @@ const run = defineCommand({
|
|
|
1424
1425
|
runtime: loadRuntime,
|
|
1425
1426
|
store,
|
|
1426
1427
|
...human === void 0 ? {} : { human },
|
|
1427
|
-
...taking.runId === void 0 ? {} : { runId: taking.runId },
|
|
1428
1428
|
out: write,
|
|
1429
1429
|
err: writeErr,
|
|
1430
1430
|
...args.driver === void 0 ? {} : { driver: args.driver }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $t as
|
|
1
|
+
import { $t as git, en as gitOk } from "./src-Frwpx3WF.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";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as sendFromScript, L as openStore, Q as scriptRefusal, Z as TOO_LONG } from "./src-
|
|
1
|
+
import { $ as sendFromScript, L as openStore, Q as scriptRefusal, Z as TOO_LONG } from "./src-Frwpx3WF.mjs";
|
|
2
2
|
import { l as writeErr } from "./output-B1kwo0YU.mjs";
|
|
3
|
-
import { u as inheritedScrubber } from "./src-
|
|
3
|
+
import { u as inheritedScrubber } from "./src-CVeA4tAw.mjs";
|
|
4
4
|
import { defineCommand } from "citty";
|
|
5
5
|
// src/commands/send.ts
|
|
6
6
|
/**
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $r as
|
|
2
|
-
import { t as runOnce } from "./run-
|
|
1
|
+
import { $r as beforeOf, At as endedWith, Bn as countedTokens, Dt as runScope, Et as heldTimeout, It as lowerChild, Jn as END_DETAIL_LIMIT, Kn as endOf, Mt as stoppedEnd, Nt as declaredProblem, Ot as calledWorkflows, Pt as slotClock, R as storePath, Rt as startAt, Ti as AGENT_DRIVERS, Xn as endFor, Y as sessionRefusals, _i as INTEGRATIONS, _t as planNodeSession, an as sessionDriver, cn as MCP_FILE, di as isClaudeNode, dr as parseTemplate, ei as programsRunBy, fi as isToolNode, fr as renderTemplate, gi as timeoutMs, ii as markValue, jt as failedWith, ln as mcpNotText, mt as planReason, nn as envReadsOf, qn as outcomeEnd, sn as declaredOutputOf, un as serversIn, ur as evaluate, vi as TOOL_PREFIX, yi as integrationFor, yt as reportSchemaFor } from "./src-Frwpx3WF.mjs";
|
|
2
|
+
import { t as runOnce } from "./run-y8jI7bAI.mjs";
|
|
3
3
|
import { n as holdGuard, r as orphanGuard, t as KILL_AFTER_MS } from "./orphan-guard-BFKg8VSd.mjs";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { accessSync, constants, lstatSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { accessSync, constants, lstatSync, mkdirSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import { Readable } from "node:stream";
|
|
8
8
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
@@ -1100,6 +1100,62 @@ const skippedCheck = (outputFile) => {
|
|
|
1100
1100
|
}
|
|
1101
1101
|
}, endFor("done"));
|
|
1102
1102
|
};
|
|
1103
|
+
// ../nodes/src/run-marker.ts
|
|
1104
|
+
/**
|
|
1105
|
+
* @file The marker a run leaves on its sessions and programs (ADR-047), and the
|
|
1106
|
+
* stores it guards: the commands that act as the user refuse in the stores of
|
|
1107
|
+
* the runs that started a process, and everywhere under a marker that lists
|
|
1108
|
+
* none, which an older `ork` sets.
|
|
1109
|
+
*/
|
|
1110
|
+
/** Set for a program in a run. */
|
|
1111
|
+
const RUN_ENV = "ORK_RUN";
|
|
1112
|
+
/** Set for a Claude session. It says no more than that: no run, no node. */
|
|
1113
|
+
const SESSION_ENV = "ORK_SESSION";
|
|
1114
|
+
/**
|
|
1115
|
+
* The stores whose runs started a session or program, as a JSON array of real
|
|
1116
|
+
* paths: the commands that act as the user refuse only in these.
|
|
1117
|
+
*/
|
|
1118
|
+
const GUARDED_STORES_ENV = "ORK_GUARDED_STORES";
|
|
1119
|
+
/**
|
|
1120
|
+
* The variable that says a program in a run or a session started this process,
|
|
1121
|
+
* or `null` when none does.
|
|
1122
|
+
*/
|
|
1123
|
+
const runMarkerIn = (env) => ["ORK_RUN", "ORK_SESSION"].find((name) => env[name] !== void 0) ?? null;
|
|
1124
|
+
/** The stores `env` lists, or `undefined` when it lists none or garbles it. */
|
|
1125
|
+
const listIn = (env) => {
|
|
1126
|
+
const text = env[GUARDED_STORES_ENV];
|
|
1127
|
+
if (text === void 0) return void 0;
|
|
1128
|
+
try {
|
|
1129
|
+
const value = JSON.parse(text);
|
|
1130
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string") ? value : void 0;
|
|
1131
|
+
} catch {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
/** A store file's real path, so a symlinked `~/.ork` is the same store. */
|
|
1136
|
+
const realStore = (store) => {
|
|
1137
|
+
try {
|
|
1138
|
+
return realpathSync(store);
|
|
1139
|
+
} catch {
|
|
1140
|
+
return path.resolve(store);
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
/**
|
|
1144
|
+
* The stores a run that started this process is in: `null` when no run did, and
|
|
1145
|
+
* `"all"` when one did but listed none (an older `ork`), which fails closed.
|
|
1146
|
+
*/
|
|
1147
|
+
const guardedStoresIn = (env) => runMarkerIn(env) === null ? null : listIn(env) ?? "all";
|
|
1148
|
+
/** Whether a run in `store` (a store file) started this process. */
|
|
1149
|
+
const storeGuarded = (env, store) => {
|
|
1150
|
+
const guarded = guardedStoresIn(env);
|
|
1151
|
+
return guarded === "all" || guarded !== null && guarded.includes(realStore(store));
|
|
1152
|
+
};
|
|
1153
|
+
/**
|
|
1154
|
+
* What a run in `store` (default: the user's) tells its sessions and programs:
|
|
1155
|
+
* the stores it inherited, and its own. Nothing when it inherited "all", so
|
|
1156
|
+
* that holds.
|
|
1157
|
+
*/
|
|
1158
|
+
const guardOf = (env, store = storePath()) => guardedStoresIn(env) === "all" ? {} : { [GUARDED_STORES_ENV]: JSON.stringify([.../* @__PURE__ */ new Set([...listIn(env) ?? [], realStore(store)])]) };
|
|
1103
1159
|
// ../nodes/src/tool-scrub.ts
|
|
1104
1160
|
/**
|
|
1105
1161
|
* @file Masking a secret in what a program prints. A plain search, so a value
|
|
@@ -1263,16 +1319,13 @@ const scrubberOf = (values) => {
|
|
|
1263
1319
|
const OUTPUT_ENV = "ORK_OUTPUT";
|
|
1264
1320
|
/** A file a `watch:` node's program keeps between looks (RFC-011). */
|
|
1265
1321
|
const STATE_ENV = "ORK_STATE";
|
|
1266
|
-
/** Set for a program in a run. */
|
|
1267
|
-
const RUN_ENV = "ORK_RUN";
|
|
1268
|
-
/** Set for a Claude session. It says no more than that: no run, no node. */
|
|
1269
|
-
const SESSION_ENV = "ORK_SESSION";
|
|
1270
1322
|
/** The variables a caller's run reads, for a run it calls to mask too. */
|
|
1271
1323
|
const MASKED_ENV = "ORK_MASKED";
|
|
1272
1324
|
/** Every variable Ork sets itself; a workflow's `env:` cannot set them. */
|
|
1273
1325
|
const IDENTITY_KEYS = /* @__PURE__ */ new Set([
|
|
1274
1326
|
RUN_ENV,
|
|
1275
1327
|
SESSION_ENV,
|
|
1328
|
+
GUARDED_STORES_ENV,
|
|
1276
1329
|
MASKED_ENV,
|
|
1277
1330
|
"ORK_NODE",
|
|
1278
1331
|
"ORK_ROUND",
|
|
@@ -1291,20 +1344,21 @@ const IDENTITY_KEYS = /* @__PURE__ */ new Set([
|
|
|
1291
1344
|
*/
|
|
1292
1345
|
const withoutIdentity = (env) => Object.fromEntries(Object.entries(env).flatMap(([key, value]) => value === void 0 || IDENTITY_KEYS.has(key) ? [] : [[key, value]]));
|
|
1293
1346
|
/**
|
|
1294
|
-
* What a Claude session
|
|
1295
|
-
* Bash from speaking as the user
|
|
1347
|
+
* What a Claude session of a run in `store` (default: the user's) runs with: no
|
|
1348
|
+
* identity, only the marker that stops its Bash from speaking as the user
|
|
1349
|
+
* through `ork chat`, and the stores it must not do that in.
|
|
1296
1350
|
*/
|
|
1297
|
-
const sessionEnv = (env) => ({
|
|
1351
|
+
const sessionEnv = (env, store) => ({
|
|
1298
1352
|
...withoutIdentity(env),
|
|
1299
|
-
[SESSION_ENV]: "1"
|
|
1353
|
+
[SESSION_ENV]: "1",
|
|
1354
|
+
...guardOf(env, store)
|
|
1300
1355
|
});
|
|
1301
1356
|
/**
|
|
1302
|
-
*
|
|
1303
|
-
*
|
|
1357
|
+
* Who a node's program is, and the stores its run guards (none listed without
|
|
1358
|
+
* `store`, which guards every one). It is attribution, not a boundary.
|
|
1304
1359
|
*/
|
|
1305
|
-
const
|
|
1306
|
-
|
|
1307
|
-
const identityOf = (context, orkBin) => ({
|
|
1360
|
+
const identityOf = (context, orkBin, environ = {}, store) => ({
|
|
1361
|
+
...store === void 0 ? {} : guardOf(environ, store),
|
|
1308
1362
|
[RUN_ENV]: context.runId,
|
|
1309
1363
|
ORK_NODE: context.id,
|
|
1310
1364
|
ORK_ROUND: String(context.round),
|
|
@@ -1526,7 +1580,7 @@ const toolExecutor = (given, options = {}) => async (context) => {
|
|
|
1526
1580
|
const outputFile = node.output?.format === "json" ? prepareOutputFile(context.runDir, context.id, context.round) : void 0;
|
|
1527
1581
|
const env = {
|
|
1528
1582
|
...nodeEnv.values,
|
|
1529
|
-
...identityOf(context, options.orkBin),
|
|
1583
|
+
...identityOf(context, options.orkBin, environ, options.store),
|
|
1530
1584
|
...maskedEnv(namesToMask(context.workflow, environ, options.maskedNames)),
|
|
1531
1585
|
...outputFile === void 0 ? {} : { [OUTPUT_ENV]: outputFile },
|
|
1532
1586
|
...node.watch === void 0 ? {} : { [STATE_ENV]: prepareStateFile(context.runDir, context.id) }
|
|
@@ -2320,6 +2374,7 @@ const spawnTool = (program, args, { cwd, signal, env, priority }) => {
|
|
|
2320
2374
|
const builtinExecutors = (options) => {
|
|
2321
2375
|
const tool = toolExecutor(options.tools ?? spawnTool, {
|
|
2322
2376
|
...options.orkBin === void 0 ? {} : { orkBin: options.orkBin },
|
|
2377
|
+
...options.store === void 0 ? {} : { store: options.store },
|
|
2323
2378
|
...options.maskedNames === void 0 ? {} : { maskedNames: options.maskedNames }
|
|
2324
2379
|
});
|
|
2325
2380
|
const claude = claudeExecutor({
|
|
@@ -2460,4 +2515,4 @@ const missingPrograms = (workflow, installed = (program) => onPath(program)) =>
|
|
|
2460
2515
|
}
|
|
2461
2516
|
return [...missing.values()];
|
|
2462
2517
|
};
|
|
2463
|
-
export {
|
|
2518
|
+
export { clearOutputFiles as _, builtinExecutors as a, toolExecutor as c, maskedEnv as d, maskedNamesOfRun as f, storeGuarded as g, runMarkerIn as h, onPath as i, clearStateFiles as l, sessionEnv as m, missingProgramMessage as n, spawnTool as o, runScrubber as p, missingPrograms as r, mcpCallExecutor as s, envProblems as t, inheritedScrubber as u, namedMcpEntries as v, resultOf as y };
|