@krapht/ork 1.0.0-alpha.11 → 1.0.0-alpha.12

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 (36) hide show
  1. package/dist/{__build_info__-CIchF6nr.mjs → __build_info__-BJbE3Zvp.mjs} +3 -2
  2. package/dist/attach-BmV5ckb9.mjs +89 -0
  3. package/dist/bin.mjs +132 -1208
  4. package/dist/{decide-B6PnKeqo.mjs → builtin-files-w0YULJ4c.mjs} +2 -50
  5. package/dist/{chips-BA7SrrH5.mjs → chips-CyeB_rhR.mjs} +1 -1
  6. package/dist/{clean-Di-KT7Mf.mjs → clean-D8GI_2K-.mjs} +1 -1
  7. package/dist/{completion-C5D0sEs5.mjs → completion-CzElB8nS.mjs} +7 -6
  8. package/dist/{context-BaNshWr9.mjs → context-BAwgVSX5.mjs} +5 -5
  9. package/dist/decide-DlbyctOE.mjs +50 -0
  10. package/dist/{find-BicBbGMg.mjs → find-p05wlbmu.mjs} +1 -1
  11. package/dist/{format-lWhN-jYR.mjs → format-Dni98cbh.mjs} +5 -85
  12. package/dist/{help-groups-BwYoAWsh.mjs → help-groups-DYP_zMRP.mjs} +4 -0
  13. package/dist/{in-a-run-CgkVouyG.mjs → in-a-run-BI-hLIl_.mjs} +4 -2
  14. package/dist/{limits-jZQp9ZJC.mjs → limits-CElmhowV.mjs} +1 -1
  15. package/dist/{list-CEaJ07jd.mjs → list-zW2xKuGr.mjs} +1 -1
  16. package/dist/{mcp-DYgVA9f5.mjs → mcp-CM3b65AZ.mjs} +6 -6
  17. package/dist/{output-CM95njYt.mjs → output-CnRzrbUM.mjs} +3 -1
  18. package/dist/{pause-D6PuSlNl.mjs → pause-BuS83WAI.mjs} +4 -4
  19. package/dist/{relay-DNx7be9k.mjs → relay-DAsJA8wF.mjs} +2 -2
  20. package/dist/{remove-CpMb4NDl.mjs → remove-Dh7D_hVn.mjs} +3 -3
  21. package/dist/{send-CLs_fyg7.mjs → send-MFEQZH31.mjs} +3 -3
  22. package/dist/{src-9iGkjnsy.mjs → src-BfxkJOYm.mjs} +1 -1
  23. package/dist/{src-D6_xjm-x.mjs → src-CdDTQLdQ.mjs} +173 -24
  24. package/dist/{src-BnZgZGrf.mjs → src-D1QedD5y.mjs} +1 -1
  25. package/dist/{src-B6KvTm7B.mjs → src-S9yK2OHU.mjs} +7 -6
  26. package/dist/store-B2OaE4ID.mjs +1356 -0
  27. package/dist/ui/assets/{app-CxURph7a.js → app-CAoZtku5.js} +1 -1
  28. package/dist/ui/assets/{index-By_8KKG6.js → index-BL7Ad0OA.js} +2 -2
  29. package/dist/ui/index.html +1 -1
  30. package/dist/{ui-CIci4UBW.mjs → ui-C4Ys26oO.mjs} +4 -4
  31. package/dist/{usage-GceBGMjU.mjs → usage-C2zx-X6q.mjs} +6 -6
  32. package/dist/verdict-CIy8tAyX.mjs +84 -0
  33. package/dist/{watch-BmoybMQg.mjs → watch-DzCeqM05.mjs} +7 -7
  34. package/dist/{workflows-DZvW3i1e.mjs → workflows-Rr5w90A0.mjs} +3 -3
  35. package/dist/{worktrees-Be51E2rB.mjs → worktrees-f6SAbum5.mjs} +5 -5
  36. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { Bn as placeFiles, Cn as wakeRun, Qn as writePlainFile, Xn as guardedBase, Zn as plainPathInside, xn as socketPath, xt as liveStatus } from "./src-D6_xjm-x.mjs";
1
+ import { Bn as placeFiles, Qn as writePlainFile, Xn as guardedBase, Zn as plainPathInside } from "./src-CdDTQLdQ.mjs";
2
2
  import path from "node:path";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { createHash } from "node:crypto";
@@ -62,52 +62,4 @@ const builtinWorkflowFile = (place, arg) => {
62
62
  if (existsSync(file) && readFileSync(file, "utf8") === text) return file;
63
63
  return writePlainFile(base, file, text).ok ? file : void 0;
64
64
  };
65
- // ../core/src/remote/decide.ts
66
- /**
67
- * @file The open decisions of live runs, and answering one from another process
68
- * (`ork decide`, the local server), with the person's note if they gave one.
69
- * An answer goes to the store (the first one wins), then the run is woken on
70
- * its socket so it picks the answer up at once (specs/messaging.md).
71
- */
72
- /** Open decisions whose run is still live, oldest first, ANDing the filter. */
73
- const pendingDecisions = (store, filter) => {
74
- const live = /* @__PURE__ */ new Map();
75
- return store.decisions({
76
- ...filter,
77
- status: "open"
78
- }).filter((decision) => {
79
- if (!live.has(decision.runId)) {
80
- const [run] = store.lookup(decision.runId);
81
- live.set(decision.runId, run !== void 0 && liveStatus(run) === "running" && (filter.workflow === void 0 || run.workflow === filter.workflow));
82
- }
83
- return live.get(decision.runId) === true;
84
- });
85
- };
86
- /**
87
- * Answers an open decision with one of its options, and wakes its run. `home`
88
- * is `~`, where the sockets are (tests pass a folder); `by` says who answered;
89
- * `note` is what they said with it, if anything (blank is nothing).
90
- */
91
- const answerDecision = async (store, id, choice, home, by = "decide", note) => {
92
- const decision = store.decision(id);
93
- if (decision === void 0) return {
94
- ok: false,
95
- error: `No decision \`${id}\`.`
96
- };
97
- if (!decision.options.some((o) => o.id === choice)) return {
98
- ok: false,
99
- error: `\`${choice}\` is not an option of \`${id}\`: \`${decision.options.map((o) => o.id).join("`, `")}\``
100
- };
101
- if (!store.answerDecision(id, choice, by, note)) {
102
- const now = store.decision(id);
103
- return {
104
- ok: false,
105
- error: now?.status === "answered" ? `${id} was already answered: ${now.answer ?? ""} (${now.answeredBy ?? ""})` : `${id} was withdrawn`
106
- };
107
- }
108
- return {
109
- ok: true,
110
- woke: await wakeRun(socketPath(decision.runId, home))
111
- };
112
- };
113
- export { builtinWorkflowNames as a, builtinWorkflowFile as i, pendingDecisions as n, builtinWorkflowText as o, builtinProblem as r, isBuiltinArg as s, answerDecision as t };
65
+ export { isBuiltinArg as a, builtinWorkflowText as i, builtinWorkflowFile as n, builtinWorkflowNames as r, builtinProblem as t };
@@ -1,4 +1,4 @@
1
- import { c as CHIP, l as NODE_PALETTE, u as apply } from "./output-CM95njYt.mjs";
1
+ import { d as apply, l as CHIP, u as NODE_PALETTE } from "./output-CnRzrbUM.mjs";
2
2
  // src/term/chips.ts
3
3
  /** The chip words the kit's commands use. */
4
4
  const CHIP_LABELS = {
@@ -1,4 +1,4 @@
1
- import { D as removeWorktree, k as gitOk } from "./src-D6_xjm-x.mjs";
1
+ import { D as removeWorktree, k as gitOk } from "./src-CdDTQLdQ.mjs";
2
2
  // ../core/src/worktree/clean.ts
3
3
  /**
4
4
  * @file What `ork worktrees clean` and `ork worktrees remove` do with what
@@ -1,9 +1,10 @@
1
- import { Ar as AGENT_DRIVERS, Bn as placeFiles, C as openStore, Vn as placeFor, w as storePath, xt as liveStatus, yr as NodeIdSchema } from "./src-D6_xjm-x.mjs";
2
- import { a as builtinWorkflowNames, n as pendingDecisions, o as builtinWorkflowText, s as isBuiltinArg } from "./decide-B6PnKeqo.mjs";
3
- import { t as findRun } from "./find-BicBbGMg.mjs";
4
- import { a as findEntry, c as subcommandsOf, d as SHELL_SCRIPTS, l as COMPLETE_COMMAND, n as groupedEntries, r as argInfoOf, t as groupOf, u as SHELLS } from "./help-groups-BwYoAWsh.mjs";
5
- import { o as writeErr } from "./output-CM95njYt.mjs";
6
- import { a as resolveWorkflowArg, n as WORKFLOW_SUFFIX } from "./workflows-DZvW3i1e.mjs";
1
+ import { Ar as AGENT_DRIVERS, Bn as placeFiles, C as openStore, Vn as placeFor, w as storePath, xt as liveStatus, yr as NodeIdSchema } from "./src-CdDTQLdQ.mjs";
2
+ import { a as isBuiltinArg, i as builtinWorkflowText, r as builtinWorkflowNames } from "./builtin-files-w0YULJ4c.mjs";
3
+ import { n as pendingDecisions } from "./decide-DlbyctOE.mjs";
4
+ import { t as findRun } from "./find-p05wlbmu.mjs";
5
+ import { a as findEntry, c as subcommandsOf, d as SHELL_SCRIPTS, l as COMPLETE_COMMAND, n as groupedEntries, r as argInfoOf, t as groupOf, u as SHELLS } from "./help-groups-DYP_zMRP.mjs";
6
+ import { s as writeErr } from "./output-CnRzrbUM.mjs";
7
+ import { a as resolveWorkflowArg, n as WORKFLOW_SUFFIX } from "./workflows-Rr5w90A0.mjs";
7
8
  import path from "node:path";
8
9
  import { parse } from "yaml";
9
10
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
@@ -1,8 +1,8 @@
1
- import { Ar as AGENT_DRIVERS, Bn as placeFiles, C as openStore, Dr as readyDriver, Er as driverChecks, F as driverQueues, Fr as knownExperiments, Gn as workflowDirOf, Jn as LESSON_CAP_TOKENS, Mr as firstLine, Nr as EXPERIMENTS, P as driverRefusals, Pr as experimentsOn, Sn as socketRoom, Sr as INTEGRATIONS, Vn as placeFor, _ as readProjectTriggers, br as retiredDriverHint, ct as explainSession, f as lateTriggers, gt as walkSummary, ht as walkChecks, jr as DRIVER_IDS, mt as checkWorkflowText, p as triggersReport, qt as loadProject, ut as namingNoDriver, v as workflowTextHash, vr as DriverSchema, w as storePath } from "./src-D6_xjm-x.mjs";
2
- import { c as checkDue, d as pendingNotice, f as readUpdateCache, h as writeUpdateCache, i as registryOf, m as updateCachePath, n as ORK_VERSION, o as updateSwitchOff, p as refreshUpdateCache, r as isSwitchedOn, t as ORK_NAME, u as newerVersion } from "./__build_info__-CIchF6nr.mjs";
3
- import { C as widthOf, a as write, b as termOf, f as paint, i as style, o as writeErr, r as plain, v as plainEnv, w as wrap, x as cut } from "./output-CM95njYt.mjs";
4
- import { n as chip, t as CHIP_LABELS } from "./chips-BA7SrrH5.mjs";
5
- import { c as registeredProjects, i as refusedBuiltin, o as workflowArg, r as findWorkflowFiles, s as projectAt } from "./workflows-DZvW3i1e.mjs";
1
+ import { Ar as AGENT_DRIVERS, Bn as placeFiles, C as openStore, Dr as readyDriver, Er as driverChecks, F as driverQueues, Fr as knownExperiments, Gn as workflowDirOf, Jn as LESSON_CAP_TOKENS, Mr as firstLine, Nr as EXPERIMENTS, P as driverRefusals, Pr as experimentsOn, Sn as socketRoom, Sr as INTEGRATIONS, Vn as placeFor, _ as readProjectTriggers, br as retiredDriverHint, ct as explainSession, f as lateTriggers, gt as walkSummary, ht as walkChecks, jr as DRIVER_IDS, mt as checkWorkflowText, p as triggersReport, qt as loadProject, ut as namingNoDriver, v as workflowTextHash, vr as DriverSchema, w as storePath } from "./src-CdDTQLdQ.mjs";
2
+ import { c as checkDue, d as pendingNotice, f as readUpdateCache, h as writeUpdateCache, i as registryOf, m as updateCachePath, n as ORK_VERSION, o as updateSwitchOff, p as refreshUpdateCache, r as isSwitchedOn, t as ORK_NAME, u as newerVersion } from "./__build_info__-BJbE3Zvp.mjs";
3
+ import { S as cut, T as wrap, a as style, i as plain, o as write, p as paint, s as writeErr, w as widthOf, x as termOf, y as plainEnv } from "./output-CnRzrbUM.mjs";
4
+ import { n as chip, t as CHIP_LABELS } from "./chips-CyeB_rhR.mjs";
5
+ import { c as registeredProjects, i as refusedBuiltin, o as workflowArg, r as findWorkflowFiles, s as projectAt } from "./workflows-Rr5w90A0.mjs";
6
6
  import path from "node:path";
7
7
  import { readFileSync } from "node:fs";
8
8
  import { execFile, spawn } from "node:child_process";
@@ -0,0 +1,50 @@
1
+ import { Cn as wakeRun, xn as socketPath, xt as liveStatus } from "./src-CdDTQLdQ.mjs";
2
+ // ../core/src/remote/decide.ts
3
+ /**
4
+ * @file The open decisions of live runs, and answering one from another process
5
+ * (`ork decide`, the local server), with the person's note if they gave one.
6
+ * An answer goes to the store (the first one wins), then the run is woken on
7
+ * its socket so it picks the answer up at once (specs/messaging.md).
8
+ */
9
+ /** Open decisions whose run is still live, oldest first, ANDing the filter. */
10
+ const pendingDecisions = (store, filter) => {
11
+ const live = /* @__PURE__ */ new Map();
12
+ return store.decisions({
13
+ ...filter,
14
+ status: "open"
15
+ }).filter((decision) => {
16
+ if (!live.has(decision.runId)) {
17
+ const [run] = store.lookup(decision.runId);
18
+ live.set(decision.runId, run !== void 0 && liveStatus(run) === "running" && (filter.workflow === void 0 || run.workflow === filter.workflow));
19
+ }
20
+ return live.get(decision.runId) === true;
21
+ });
22
+ };
23
+ /**
24
+ * Answers an open decision with one of its options, and wakes its run. `home`
25
+ * is `~`, where the sockets are (tests pass a folder); `by` says who answered;
26
+ * `note` is what they said with it, if anything (blank is nothing).
27
+ */
28
+ const answerDecision = async (store, id, choice, home, by = "decide", note) => {
29
+ const decision = store.decision(id);
30
+ if (decision === void 0) return {
31
+ ok: false,
32
+ error: `No decision \`${id}\`.`
33
+ };
34
+ if (!decision.options.some((o) => o.id === choice)) return {
35
+ ok: false,
36
+ error: `\`${choice}\` is not an option of \`${id}\`: \`${decision.options.map((o) => o.id).join("`, `")}\``
37
+ };
38
+ if (!store.answerDecision(id, choice, by, note)) {
39
+ const now = store.decision(id);
40
+ return {
41
+ ok: false,
42
+ error: now?.status === "answered" ? `${id} was already answered: ${now.answer ?? ""} (${now.answeredBy ?? ""})` : `${id} was withdrawn`
43
+ };
44
+ }
45
+ return {
46
+ ok: true,
47
+ woke: await wakeRun(socketPath(decision.runId, home))
48
+ };
49
+ };
50
+ export { pendingDecisions as n, answerDecision as t };
@@ -1,4 +1,4 @@
1
- import { Vn as placeFor } from "./src-D6_xjm-x.mjs";
1
+ import { Vn as placeFor } from "./src-CdDTQLdQ.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  // ../core/src/remote/find.ts
4
4
  /**
@@ -1,87 +1,7 @@
1
- import { Ct as runStatus, Tt as slotWaitsOf, kt as isItem, xt as liveStatus } from "./src-D6_xjm-x.mjs";
2
- import { C as widthOf, b as termOf, i as style, n as cost, u as apply, x as cut } from "./output-CM95njYt.mjs";
3
- import { i as statusChip, n as chip, t as CHIP_LABELS } from "./chips-BA7SrrH5.mjs";
4
- // src/run/view.ts
5
- /**
6
- * @file How a run's lines are drawn: the terminal kit's {@link Term} for the
7
- * stream they go to, and what a transcript has to remember between events (a
8
- * node's worktree, to show its paths relative to it). Plain, a view draws
9
- * today's line-based transcript; rich, it draws chips and cuts to the width.
10
- */
11
- /** A view for `stream` (stdout when not given), as `env` sets it. */
12
- const createView = (stream = process.stdout, env = process.env) => ({
13
- term: termOf(stream, env),
14
- roots: /* @__PURE__ */ new Map()
15
- });
16
- /** Styles text for `term`: no escape codes when it is plain. */
17
- const styler = (term) => (format, text) => apply(term, format, text);
18
- // src/run/format-bus.ts
19
- /** The first line of a message body, cut to fit one terminal line. */
20
- const firstLine = (body) => {
21
- const [line = ""] = body.trim().split("\n");
22
- return line.length > 100 ? `${line.slice(0, 99)}…` : line;
23
- };
24
- /** Messages, owner questions and claims, without the node prefix. */
25
- const formatBusEvent = (event, term = createView().term) => {
26
- const style = styler(term);
27
- if (event.type === "claim.taken") return [style("dim", `⚑ claimed ${event.resource}`)];
28
- if (event.type === "claim.refused") {
29
- const held = event.held === event.resource ? "" : ` (it holds ${event.held})`;
30
- return [style("yellow", `⚑ ${event.resource} is ${event.holder}'s${held}`)];
31
- }
32
- if (event.type === "claim.released") return [style("dim", `⚑ released ${event.resource}`)];
33
- if (event.type === "message.sent") {
34
- const how = event.via === void 0 ? "" : ` (${event.via})`;
35
- return [style("dim", `✉ to ${event.to}${how}: ${firstLine(event.body)}`)];
36
- }
37
- if (event.type === "message.received") {
38
- const how = event.via === void 0 ? "" : ` (${event.via})`;
39
- return [style("dim", `✉ from ${event.from}${how}: ${firstLine(event.body)}`)];
40
- }
41
- if (event.type === "call.started") return [style("dim", `↳ started ${event.workflow} as run ${event.run}`)];
42
- if (event.type === "link.notice") return [style("dim", `↔ ${event.text}`)];
43
- if (event.type === "message.read") return [];
44
- if (event.type === "owner.asked") return [`${term.rich ? chip(term, CHIP_LABELS.ask, "accent") : style(["yellow", "bold"], "?")} asked as the owner of ${event.about}: ${event.text} ${style("dim", `(${event.question})`)}`];
45
- if (event.type === "owner.answered") return [style("dim", `→ ${event.answer} (owner)`)];
46
- return [style("dim", "→ its session ended first; asking you")];
47
- };
48
- // src/run/items-ran.ts
49
- /**
50
- * @file How a fan-out's finished line counts its items: only the ones that
51
- * started.
52
- */
53
- /** How many of a fan-out's items started; a skipped one never did. */
54
- const itemsRan = (count, statuses) => {
55
- const ran = Array.isArray(statuses) ? statuses.filter((status) => status !== "skipped").length : count;
56
- return ran === count ? `${String(count)} ran` : `${String(ran)} of ${String(count)} ran`;
57
- };
58
- // src/run/verdict.ts
59
- /**
60
- * @file The one-line verdict of a finished node: its report's status, unless
61
- * the node failed or its work did not merge.
62
- */
63
- /** Whether a finished node's work did not merge into its owner. */
64
- const hasConflict = (output) => {
65
- const { merge } = output;
66
- return typeof merge === "object" && merge !== null && "ok" in merge && merge.ok === false;
67
- };
68
- /**
69
- * A one-line verdict for a finished node, by what its type outputs. A node that
70
- * failed reads `fail` even when its report said `pass` (a hook refused its
71
- * commit); a child that did not merge says so.
72
- */
73
- const nodeVerdict = (output, ok = true, error) => {
74
- const { status, summary, exitCode, choice, answeredBy, count } = output;
75
- if (typeof status === "string") {
76
- if (!ok && (status === "pass" || status === "done")) return error === void 0 ? "fail" : `fail: ${firstLine(error)}`;
77
- const label = hasConflict(output) ? `${status}, merge conflict` : status;
78
- return typeof summary === "string" && summary !== "" ? `${label}: ${summary}` : label;
79
- }
80
- if (typeof exitCode === "number") return `exit ${String(exitCode)}`;
81
- if (typeof choice === "string") return `${choice} (${String(answeredBy)})`;
82
- if (typeof count === "number") return itemsRan(count, output["statuses"]);
83
- return "done";
84
- };
1
+ import { Ct as runStatus, Tt as slotWaitsOf, kt as isItem, xt as liveStatus } from "./src-CdDTQLdQ.mjs";
2
+ import { S as cut, a as style, n as cost, w as widthOf, x as termOf } from "./output-CnRzrbUM.mjs";
3
+ import { i as statusChip, n as chip } from "./chips-CyeB_rhR.mjs";
4
+ import { n as nodeVerdict } from "./verdict-CIy8tAyX.mjs";
85
5
  // src/term/table.ts
86
6
  /**
87
7
  * @file Aligned columns for the listing commands: each column as wide as its
@@ -283,4 +203,4 @@ const formatTree = (roots, now = Date.now()) => {
283
203
  return `${text.padEnd(label)} ${style("dim", node.type.padEnd(type))} ${state}${spent}${usage}`;
284
204
  });
285
205
  };
286
- export { header as a, nodeVerdict as c, createView as d, styler as f, listedStatus as i, firstLine as l, formatRuns as n, table as o, formatTree as r, hasConflict as s, ago as t, formatBusEvent as u };
206
+ export { header as a, listedStatus as i, formatRuns as n, table as o, formatTree as r, ago as t };
@@ -220,6 +220,10 @@ const HELP_GROUPS = [
220
220
  name: "logs",
221
221
  short: "Print a run's transcript"
222
222
  },
223
+ {
224
+ name: "attach",
225
+ short: "Follow a run here and answer its questions"
226
+ },
223
227
  {
224
228
  name: "tree",
225
229
  short: "Show a run's tree, tokens and cost"
@@ -1,4 +1,4 @@
1
- import { p as runMarkerIn } from "./src-9iGkjnsy.mjs";
1
+ import { p as runMarkerIn } from "./src-BfxkJOYm.mjs";
2
2
  // src/commands/in-a-run.ts
3
3
  /**
4
4
  * @file The commands that act as the user refuse a program or an agent in a run
@@ -19,4 +19,6 @@ const decideRefusal = (env = process.env) => refusal("`ork decide` answers as yo
19
19
  const continueRefusal = (env = process.env) => refusal("`ork continue` undoes a pause you set, so a program or an agent in a run cannot use it.", env);
20
20
  /** Whether `ork ui` may print its sign-in link, which acts as the user. */
21
21
  const mayShowSignIn = (env = process.env) => runMarkerIn(env) === null;
22
- export { mayShowSignIn as a, decideRefusal as i, chatRefusal as n, continueRefusal as r, acceptRefusal as t };
22
+ /** Why `ork attach` will not answer here, or `null` when it may. */
23
+ const attachRefusal = (env = process.env) => refusal("`ork attach` answers as you, so a program or an agent in a run cannot use it; `ork logs` still shows the run.", env);
24
+ export { decideRefusal as a, continueRefusal as i, attachRefusal as n, mayShowSignIn as o, chatRefusal as r, acceptRefusal as t };
@@ -1,4 +1,4 @@
1
- import { it as limitsReport, nt as NOT_STARTED, r as capsHere, rt as limitsNow } from "./src-D6_xjm-x.mjs";
1
+ import { it as limitsReport, nt as NOT_STARTED, r as capsHere, rt as limitsNow } from "./src-CdDTQLdQ.mjs";
2
2
  // src/run/limits.ts
3
3
  /**
4
4
  * @file The limits across runs that apply here (RFC-007): the user's settings
@@ -1,4 +1,4 @@
1
- import { A as lines, O as git, k as gitOk } from "./src-D6_xjm-x.mjs";
1
+ import { A as lines, O as git, k as gitOk } from "./src-CdDTQLdQ.mjs";
2
2
  import { existsSync } from "node:fs";
3
3
  // ../core/src/worktree/list.ts
4
4
  /**
@@ -1,8 +1,8 @@
1
- import { u as isNewer } from "./src-D6_xjm-x.mjs";
2
- import { n as ORK_VERSION } from "./__build_info__-CIchF6nr.mjs";
3
- import { p as runMarkerIn } from "./src-9iGkjnsy.mjs";
4
- import { n as explainNode } from "./context-BaNshWr9.mjs";
5
- import { a as openMcp, c as refused, o as tool, s as answer } from "./src-B6KvTm7B.mjs";
1
+ import { u as isNewer } from "./src-CdDTQLdQ.mjs";
2
+ import { n as ORK_VERSION } from "./__build_info__-BJbE3Zvp.mjs";
3
+ import { p as runMarkerIn } from "./src-BfxkJOYm.mjs";
4
+ import { n as explainNode } from "./context-BAwgVSX5.mjs";
5
+ import { a as openMcp, c as refused, o as tool, s as answer } from "./src-S9yK2OHU.mjs";
6
6
  import { z } from "zod";
7
7
  import { defineCommand } from "citty";
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -43,7 +43,7 @@ const orkMcpServer = (options = {}) => {
43
43
  ...options.script === void 0 ? {} : { script: options.script }
44
44
  });
45
45
  const all = [...opened.tools, explainTool(opened, options.home)];
46
- const tools = options.expects !== void 0 && isNewer(options.expects, "1.0.0-alpha.11") ? tooOld(all, options.expects) : all;
46
+ const tools = options.expects !== void 0 && isNewer(options.expects, "1.0.0-alpha.12") ? tooOld(all, options.expects) : all;
47
47
  const server = new McpServer({
48
48
  name: "ork",
49
49
  version: ORK_VERSION
@@ -407,6 +407,8 @@ const writeErr = (text) => {
407
407
  if (process.stderr.isTTY && printAbove(text)) return;
408
408
  process.stderr.write(`${text}\n`);
409
409
  };
410
+ /** What to run to follow, steer or stop the detached run `id` (ADR-081). */
411
+ const detachHint = (id) => `ork attach ${id} · ork logs ${id} -f · ork tree ${id} · ork decide · ork stop ${id}`;
410
412
  /** What a run spent: `$0.0312`, or `$0.00` for nothing. */
411
413
  const cost = (usd) => usd === 0 ? "$0.00" : `$${usd.toFixed(4)}`;
412
414
  /**
@@ -418,4 +420,4 @@ const confirm = (question) => confirm$1({
418
420
  input: process.stdin,
419
421
  output: process.stderr
420
422
  }, { question: question.replace(/\s*\[y\/N\]\s*$/u, "") });
421
- export { widthOf as C, hang as S, readKeys as T, canKey as _, write as a, termOf as b, CHIP as c, bold as d, paint as f, withdrawn as g, readLine as h, style as i, NODE_PALETTE as l, interrupt as m, cost as n, writeErr as o, createRegion as p, plain as r, confirmOrStop as s, confirm as t, apply as u, plainEnv as v, wrap as w, cut as x, takePlainFlag as y };
423
+ export { hang as C, readKeys as E, cut as S, wrap as T, withdrawn as _, style as a, takePlainFlag as b, confirmOrStop as c, apply as d, bold as f, readLine as g, interrupt as h, plain as i, CHIP as l, createRegion as m, cost as n, write as o, paint as p, detachHint as r, writeErr as s, confirm as t, NODE_PALETTE as u, canKey as v, widthOf as w, termOf as x, plainEnv as y };
@@ -1,7 +1,7 @@
1
- import { C as openStore, G as requestContinue, K as requestPause } from "./src-D6_xjm-x.mjs";
2
- import { t as findRun } from "./find-BicBbGMg.mjs";
3
- import { a as write, i as style, o as writeErr } from "./output-CM95njYt.mjs";
4
- import { r as continueRefusal } from "./in-a-run-CgkVouyG.mjs";
1
+ import { C as openStore, G as requestContinue, K as requestPause } from "./src-CdDTQLdQ.mjs";
2
+ import { t as findRun } from "./find-p05wlbmu.mjs";
3
+ import { a as style, o as write, s as writeErr } from "./output-CnRzrbUM.mjs";
4
+ import { i as continueRefusal } from "./in-a-run-BI-hLIl_.mjs";
5
5
  import { defineCommand } from "citty";
6
6
  // src/commands/pause.ts
7
7
  /**
@@ -1,5 +1,5 @@
1
- import { B as linkNodes, C as openStore, L as addressOf, U as unlinkNodes } from "./src-D6_xjm-x.mjs";
2
- import { a as write, i as style, o as writeErr } from "./output-CM95njYt.mjs";
1
+ import { B as linkNodes, C as openStore, L as addressOf, U as unlinkNodes } from "./src-CdDTQLdQ.mjs";
2
+ import { a as style, o as write, s as writeErr } from "./output-CnRzrbUM.mjs";
3
3
  import { defineCommand } from "citty";
4
4
  // src/commands/relay.ts
5
5
  /**
@@ -1,6 +1,6 @@
1
- import { A as lines, O as git, xt as liveStatus } from "./src-D6_xjm-x.mjs";
2
- import { n as listOrkWorktrees, t as createdWorktrees } from "./list-CEaJ07jd.mjs";
3
- import { i as keyOf, n as applyStep, r as cleanStep, s as stepPrunes } from "./clean-Di-KT7Mf.mjs";
1
+ import { A as lines, O as git, xt as liveStatus } from "./src-CdDTQLdQ.mjs";
2
+ import { n as listOrkWorktrees, t as createdWorktrees } from "./list-zW2xKuGr.mjs";
3
+ import { i as keyOf, n as applyStep, r as cleanStep, s as stepPrunes } from "./clean-D8GI_2K-.mjs";
4
4
  // ../core/src/worktree/words.ts
5
5
  /**
6
6
  * @file The plain words for what `ork worktrees` shows, in one place, so the
@@ -1,6 +1,6 @@
1
- import { C as openStore, Cn as wakeRun, jt as scriptContactsOf, xn as socketPath, xt as liveStatus } from "./src-D6_xjm-x.mjs";
2
- import { o as writeErr } from "./output-CM95njYt.mjs";
3
- import { u as inheritedScrubber } from "./src-9iGkjnsy.mjs";
1
+ import { C as openStore, Cn as wakeRun, jt as scriptContactsOf, xn as socketPath, xt as liveStatus } from "./src-CdDTQLdQ.mjs";
2
+ import { s as writeErr } from "./output-CnRzrbUM.mjs";
3
+ import { u as inheritedScrubber } from "./src-BfxkJOYm.mjs";
4
4
  import { defineCommand } from "citty";
5
5
  // ../core/src/remote/send.ts
6
6
  /**
@@ -1,4 +1,4 @@
1
- import { $t as endOf, Bt as lowerChild, Cr as TOOL_PREFIX, Ft as failedWith, Ht as envReadsOf, It as stoppedEnd, Lt as calledWorkflows, Mt as runScope, Nt as declaredProblem, Pt as endedWith, Rt as slotClock, Sr as INTEGRATIONS, Vt as startAt, Wt as declaredOutputOf, Xt as mcpNotText, Yt as MCP_FILE, Zt as serversIn, _n as parseTemplate, _r as isToolNode, ar as programsRunBy, at as planReason, bt as heldTimeout, dt as sessionDriver, en as outcomeEnd, gn as evaluate, gr as isClaudeNode, ir as beforeOf, lr as markValue, lt as planNodeSession, pt as reportSchemaFor, rn as endFor, tn as END_DETAIL_LIMIT, vn as renderTemplate, wr as integrationFor, xr as timeoutMs } from "./src-D6_xjm-x.mjs";
1
+ import { $t as endOf, Bt as lowerChild, Cr as TOOL_PREFIX, Ft as failedWith, Ht as envReadsOf, It as stoppedEnd, Lt as calledWorkflows, Mt as runScope, Nt as declaredProblem, Pt as endedWith, Rt as slotClock, Sr as INTEGRATIONS, Vt as startAt, Wt as declaredOutputOf, Xt as mcpNotText, Yt as MCP_FILE, Zt as serversIn, _n as parseTemplate, _r as isToolNode, ar as programsRunBy, at as planReason, bt as heldTimeout, dt as sessionDriver, en as outcomeEnd, gn as evaluate, gr as isClaudeNode, ir as beforeOf, lr as markValue, lt as planNodeSession, pt as reportSchemaFor, rn as endFor, tn as END_DETAIL_LIMIT, vn as renderTemplate, wr as integrationFor, xr as timeoutMs } from "./src-CdDTQLdQ.mjs";
2
2
  import path from "node:path";
3
3
  import { accessSync, constants, lstatSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { spawn } from "node:child_process";