@krapht/ork 1.0.0-alpha.14 → 1.0.0-alpha.15

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 (42) hide show
  1. package/dist/__build_info__-Bsb1kjgF.mjs +340 -0
  2. package/dist/{store-CleF7KeS.mjs → attach-BHO3X3cf.mjs} +16 -19
  3. package/dist/{attach-CdtGX9se.mjs → attach-CPespxlQ.mjs} +5 -4
  4. package/dist/bin.mjs +64 -1339
  5. package/dist/brief-za0ozN_E.mjs +58 -0
  6. package/dist/{builtin-files-Bdq23IIi.mjs → builtin-files-2bHf76x-.mjs} +1 -1
  7. package/dist/{completion--ywde-56.mjs → completion-CQ2UYKuJ.mjs} +5 -5
  8. package/dist/context-BNqDw9z1.mjs +106 -0
  9. package/dist/{find-BVX-bL4u.mjs → find-BYLlszqj.mjs} +1 -1
  10. package/dist/follow-ups-B4GJ3Vzw.mjs +461 -0
  11. package/dist/{format-CvTE5CZQ.mjs → format-C8MsFj8_.mjs} +19 -5
  12. package/dist/{help-groups-CpR2UzSn.mjs → help-groups-CQ98mLjF.mjs} +4 -0
  13. package/dist/{in-a-run-cL5N9gpH.mjs → in-a-run-Bp0k0J09.mjs} +1 -1
  14. package/dist/{__build_info__-B82-dGJY.mjs → install-DWtXTq4y.mjs} +3 -227
  15. package/dist/{limits-Dhe--wmX.mjs → limits-B1qzS4cX.mjs} +1 -1
  16. package/dist/{mcp-CsmboyXv.mjs → mcp-BOrVkyhN.mjs} +6 -6
  17. package/dist/{once-CrwI-ZdN.mjs → once-C1fL3GVo.mjs} +3 -3
  18. package/dist/orphan-guard-BFKg8VSd.mjs +58 -0
  19. package/dist/{pause-DssrYcda.mjs → pause-DOMK-R8V.mjs} +3 -3
  20. package/dist/post-BzA6Qobq.mjs +44 -0
  21. package/dist/{relay-DASRgsTQ.mjs → relay-OWuu4fib.mjs} +1 -1
  22. package/dist/run--4-1xAF2.mjs +1451 -0
  23. package/dist/{run-D8divGCs.mjs → run-CiPsW9Kf.mjs} +1 -1
  24. package/dist/{send-CXv8bx0i.mjs → send-CnNNW-ot.mjs} +2 -2
  25. package/dist/{src-njdtejgZ.mjs → src-B9zWIVqo.mjs} +129 -12
  26. package/dist/{src-8Mul0695.mjs → src-DQKz2eOH.mjs} +322 -75
  27. package/dist/{src-C7z_6fhn.mjs → src-DcrhgipG.mjs} +17 -10
  28. package/dist/{src-tsuZRu0H.mjs → src-Dr_fTSu-.mjs} +4832 -4155
  29. package/dist/store-oKJ-cCf3.mjs +16 -0
  30. package/dist/ui/assets/app-Bdc6OBeZ.css +1 -0
  31. package/dist/ui/assets/app-Drp8Dm9y.js +111 -0
  32. package/dist/ui/assets/{index-D-_uPI2v.js → index-BtwkftKe.js} +2 -2
  33. package/dist/ui/index.html +1 -1
  34. package/dist/{ui-CNO1M0qT.mjs → ui-CzKlsCnm.mjs} +3 -3
  35. package/dist/{usage-BVXi0iFY.mjs → usage-DHGNk2JL.mjs} +3 -3
  36. package/dist/{context-Y_I4Mofq.mjs → validate-Bs_gg22g.mjs} +4 -104
  37. package/dist/{watch-DVNIciHp.mjs → watch-CCCfw3n7.mjs} +19 -5
  38. package/dist/{workflows-B30QkwTk.mjs → workflows-CW28ZU-z.mjs} +2 -2
  39. package/dist/{worktrees-DD4_TpkH.mjs → worktrees-CyE8aF6j.mjs} +1 -1
  40. package/package.json +1 -1
  41. package/dist/ui/assets/app-D_nAPnHM.css +0 -1
  42. package/dist/ui/assets/app-DqBAtXSZ.js +0 -111
@@ -0,0 +1,340 @@
1
+ import { A as isNewer, j as parseVersion, k as compareVersions } from "./src-Dr_fTSu-.mjs";
2
+ import path from "node:path";
3
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
4
+ import { homedir } from "node:os";
5
+ // ../core/src/follow-ups/change.ts
6
+ /** The project's follow-up whose id is, or starts with, `prefix`. */
7
+ const findFollowUp = (rows, project, prefix) => {
8
+ const exact = rows.followUp(project, prefix);
9
+ if (exact !== void 0) return {
10
+ ok: true,
11
+ followUp: exact
12
+ };
13
+ const matches = prefix === "" ? [] : rows.followUps(project).filter((f) => f.id.startsWith(prefix));
14
+ const [only, other] = matches;
15
+ if (only === void 0) return {
16
+ ok: false,
17
+ error: `No follow-up \`${prefix}\` in this project.`
18
+ };
19
+ if (other !== void 0) return {
20
+ ok: false,
21
+ error: `\`${prefix}\` matches ${matches.map((f) => f.id).join(", ")}; give more of the id.`
22
+ };
23
+ return {
24
+ ok: true,
25
+ followUp: only
26
+ };
27
+ };
28
+ /** Which statuses each action starts from, and where it goes. */
29
+ const ACTIONS = {
30
+ done: {
31
+ from: ["waiting", "due"],
32
+ to: () => "done",
33
+ note: "done"
34
+ },
35
+ drop: {
36
+ from: ["waiting", "due"],
37
+ to: () => "dropped",
38
+ note: "dropped"
39
+ },
40
+ reopen: {
41
+ from: ["done", "dropped"],
42
+ to: (f) => f.due === "now" ? "due" : "waiting",
43
+ note: "reopened"
44
+ },
45
+ due: {
46
+ from: ["waiting"],
47
+ to: () => "due",
48
+ note: "marked due"
49
+ }
50
+ };
51
+ /** Why `action` can't be done to `f` now, or `undefined`. */
52
+ const refusal = (f, action) => {
53
+ const rule = ACTIONS[action];
54
+ return rule.from.includes(f.status) ? void 0 : `${f.id} is ${f.status}, so it can't be ${rule.note}.`;
55
+ };
56
+ const check = (f, action) => {
57
+ const error = refusal(f, action);
58
+ return error === void 0 ? { ok: true } : {
59
+ ok: false,
60
+ why: `it is ${f.status}`,
61
+ error
62
+ };
63
+ };
64
+ const postCheck = (f) => {
65
+ const open = f.status === "waiting" || f.status === "due";
66
+ if (f.kind !== "message" || f.draft?.channel !== "github") return {
67
+ ok: false,
68
+ why: "not drafted for the github channel",
69
+ error: "only a message drafted for the github channel is posted; send the others yourself"
70
+ };
71
+ return open ? { ok: true } : {
72
+ ok: false,
73
+ why: `it is ${f.status}`,
74
+ error: `${f.id} is ${f.status}, so it is not posted.`
75
+ };
76
+ };
77
+ const followUpActions = (f) => ({
78
+ done: check(f, "done"),
79
+ drop: check(f, "drop"),
80
+ reopen: check(f, "reopen"),
81
+ due: check(f, "due"),
82
+ post: postCheck(f)
83
+ });
84
+ /** Applies `action` to `followUp`, and keeps it. */
85
+ const changeFollowUp = (rows, followUp, action, now = () => (/* @__PURE__ */ new Date()).toISOString()) => {
86
+ const rule = ACTIONS[action];
87
+ const refused = refusal(followUp, action);
88
+ if (refused !== void 0) return {
89
+ ok: false,
90
+ error: refused
91
+ };
92
+ const { note: _old, ...rest } = followUp;
93
+ const changed = {
94
+ ...rest,
95
+ status: rule.to(followUp),
96
+ note: rule.note,
97
+ updatedAt: now()
98
+ };
99
+ rows.putFollowUp(changed);
100
+ return {
101
+ ok: true,
102
+ followUp: changed
103
+ };
104
+ };
105
+ /**
106
+ * Why a due follow-up is due, read from the note `due.ts` left: its ref merged,
107
+ * its date came, its ref closed unmerged, or a person marked it. `undefined`
108
+ * for one that is not due, or was due from the start.
109
+ */
110
+ const dueCause = (f) => {
111
+ if (f.status !== "due" || f.note === void 0) return void 0;
112
+ if (f.note.includes("closed without merging")) return "closed-unmerged";
113
+ if (f.note.endsWith(" merged")) return "merged";
114
+ if (f.note.startsWith("due on ")) return "overdue";
115
+ return f.note === "marked due" ? "marked" : void 0;
116
+ };
117
+ // ../core/src/remote/session.ts
118
+ const chattable = (type) => type === "agent.leader" || type === "agent.worker";
119
+ /** Reads `node`'s session from a run's events, and every node's last output. */
120
+ const nodeSession = (events, node) => {
121
+ const session = {
122
+ known: false,
123
+ chattable: false,
124
+ running: false
125
+ };
126
+ const outputs = {};
127
+ for (const { event } of events) {
128
+ if (event.type === "run.started") {
129
+ const declared = event.nodes.find((n) => n.id === node);
130
+ if (declared !== void 0) {
131
+ session.known = true;
132
+ session.chattable = chattable(declared.type);
133
+ }
134
+ }
135
+ if (event.type === "node.finished") outputs[event.id] = event.output;
136
+ if (!("id" in event) || event.id !== node) continue;
137
+ if (event.type === "node.started") {
138
+ session.known = true;
139
+ session.chattable = chattable(event.nodeType);
140
+ session.running = true;
141
+ }
142
+ if (event.type === "node.finished") session.running = false;
143
+ if (event.type === "worktree" && event.action === "created") session.checkout = {
144
+ path: event.path,
145
+ ...event.branch === void 0 ? {} : { branch: event.branch },
146
+ own: true,
147
+ owner: node
148
+ };
149
+ if (event.type !== "node.event") continue;
150
+ const inner = event.event;
151
+ if (inner.fork === true) continue;
152
+ if (inner.type === "session.started") {
153
+ session.sessionId = inner.sessionId;
154
+ if (inner.cwd !== void 0) session.cwd = inner.cwd;
155
+ if (inner.driver !== void 0) session.driver = inner.driver;
156
+ if (inner.model !== "") session.model = inner.model;
157
+ }
158
+ if (inner.type === "session.finished" && inner.outcome.sessionId !== "") session.sessionId = inner.outcome.sessionId;
159
+ }
160
+ return {
161
+ session,
162
+ outputs
163
+ };
164
+ };
165
+ /** The dist-tags every install follows, toward and after 1.0.0. */
166
+ const CHANNEL_TAGS = [
167
+ "latest",
168
+ "alpha",
169
+ "beta",
170
+ "rc"
171
+ ];
172
+ /** The dist-tag of snapshots from `main`, followed only by a canary. */
173
+ const CANARY_TAG = "canary";
174
+ const updateCachePath = (home = homedir()) => path.join(home, ".ork", "update-check.json");
175
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
176
+ const text = (record, key) => {
177
+ const value = record[key];
178
+ return typeof value === "string" ? value : void 0;
179
+ };
180
+ const notifiedOf = (value) => {
181
+ if (!isRecord(value)) return void 0;
182
+ const version = text(value, "version");
183
+ const at = text(value, "at");
184
+ return version === void 0 || at === void 0 ? void 0 : {
185
+ version,
186
+ at
187
+ };
188
+ };
189
+ /** The cache, or `null` when there is none or it cannot be read. */
190
+ const readUpdateCache = (file) => {
191
+ let parsed;
192
+ try {
193
+ parsed = JSON.parse(readFileSync(file, "utf8"));
194
+ } catch {
195
+ return null;
196
+ }
197
+ if (!isRecord(parsed)) return null;
198
+ const checkedAt = text(parsed, "checkedAt");
199
+ if (checkedAt === void 0) return null;
200
+ const latest = text(parsed, "latest");
201
+ const notified = notifiedOf(parsed["notified"]);
202
+ return {
203
+ checkedAt,
204
+ ...latest === void 0 ? {} : { latest },
205
+ ...notified === void 0 ? {} : { notified }
206
+ };
207
+ };
208
+ /** Writes the cache whole (a temporary file, then a rename). */
209
+ const writeUpdateCache = (file, cache) => {
210
+ mkdirSync(path.dirname(file), { recursive: true });
211
+ const temporary = `${file}.${process.pid}.tmp`;
212
+ writeFileSync(temporary, `${JSON.stringify(cache, null, 2)}\n`);
213
+ renameSync(temporary, file);
214
+ };
215
+ const age = (iso, now) => {
216
+ const time = Date.parse(iso);
217
+ return Number.isNaN(time) ? Infinity : now.getTime() - time;
218
+ };
219
+ /** Whether it is time to ask the registry again. */
220
+ const checkDue = (cache, now) => cache === null || age(cache.checkedAt, now) >= 864e5;
221
+ /** Whether `version` is a canary snapshot: its pre-release starts `canary`. */
222
+ const isCanary = (version) => parseVersion(version)?.pre[0]?.startsWith(CANARY_TAG) === true;
223
+ /**
224
+ * The newest version, by semver precedence, among the dist-tags `current`
225
+ * follows: the channel tags, and `canary` too when `current` is a canary. A tag
226
+ * whose value doesn't parse is skipped; `null` when none does.
227
+ */
228
+ const newestTagged = (tags, current) => {
229
+ return (current !== void 0 && isCanary(current) ? [...CHANNEL_TAGS, "canary"] : CHANNEL_TAGS).flatMap((tag) => {
230
+ const value = tags[tag];
231
+ const version = typeof value === "string" ? parseVersion(value) : null;
232
+ return typeof value === "string" && version !== null ? [{
233
+ value,
234
+ version
235
+ }] : [];
236
+ }).reduce((best, candidate) => best === null || compareVersions(candidate.version, best.version) > 0 ? candidate : best, null)?.value ?? null;
237
+ };
238
+ /**
239
+ * The newest version on the registry that the running version follows ({@link
240
+ * newestTagged}), or `null` on any failure.
241
+ */
242
+ const fetchLatest = async (name, options = {}) => {
243
+ const registry = (options.registry ?? "https://registry.npmjs.org").replace(/\/+$/u, "");
244
+ const get = options.fetch ?? globalThis.fetch;
245
+ try {
246
+ const response = await get(`${registry}/-/package/${name}/dist-tags`, {
247
+ headers: { accept: "application/json" },
248
+ signal: AbortSignal.timeout(options.timeoutMs ?? 5e3)
249
+ });
250
+ if (!response.ok) return null;
251
+ const tags = await response.json();
252
+ return isRecord(tags) ? newestTagged(tags, options.current) : null;
253
+ } catch {
254
+ return null;
255
+ }
256
+ };
257
+ /**
258
+ * Asks the registry and records the answer. A failed check is recorded too, so
259
+ * an offline machine is not asked again until the interval passes; the last
260
+ * known version is kept. `options.current` is the running version.
261
+ */
262
+ const refreshUpdateCache = async (file, name, now, options = {}) => {
263
+ const before = readUpdateCache(file);
264
+ const latest = await fetchLatest(name, options) ?? before?.latest;
265
+ const cache = {
266
+ ...before,
267
+ checkedAt: now.toISOString(),
268
+ ...latest === void 0 ? {} : { latest }
269
+ };
270
+ writeUpdateCache(file, cache);
271
+ return cache;
272
+ };
273
+ /** The newer version the cache knows of, if any. */
274
+ const newerVersion = (cache, current) => cache?.latest !== void 0 && isNewer(cache.latest, current) ? cache.latest : null;
275
+ /**
276
+ * The version to tell the user about now: newer than theirs, and not already
277
+ * told today. `null` when there is nothing to say.
278
+ */
279
+ const pendingNotice = (cache, current, now) => {
280
+ const newer = newerVersion(cache, current);
281
+ if (newer === null) return null;
282
+ const told = cache?.notified;
283
+ return told?.version === newer && age(told.at, now) < 864e5 ? null : newer;
284
+ };
285
+ // ../core/src/update/switches.ts
286
+ /**
287
+ * @file The environment's say over the update check (ADR-038): the variables
288
+ * that turn it off (`ORK_NO_UPDATE_CHECK`, the common `NO_UPDATE_NOTIFIER`,
289
+ * and `CI`), and the registry to ask instead of npm's. The CLI adds its own
290
+ * rules about where a notice may go; the server behind `ork ui` uses only
291
+ * these.
292
+ */
293
+ /** Turns the automatic check and its notice off. */
294
+ const NO_UPDATE_ENV = "ORK_NO_UPDATE_CHECK";
295
+ /** A registry to ask instead of npm's, e.g. a company mirror. */
296
+ const UPDATE_REGISTRY_ENV = "ORK_UPDATE_REGISTRY";
297
+ /** The variables that turn the check off, in the order they are looked at. */
298
+ const UPDATE_SWITCHES = [
299
+ NO_UPDATE_ENV,
300
+ "NO_UPDATE_NOTIFIER",
301
+ "CI"
302
+ ];
303
+ /** Set to anything but empty, `0` or `false`. */
304
+ const isSwitchedOn = (value) => value !== void 0 && value !== "" && value !== "0" && value.toLowerCase() !== "false";
305
+ /** The variable that turns the check off in `env`, or `null` when none does. */
306
+ const updateSwitchOff = (env) => UPDATE_SWITCHES.find((name) => isSwitchedOn(env[name])) ?? null;
307
+ /** The registry `ORK_UPDATE_REGISTRY` names, if it names one. */
308
+ const registryOf = (env) => {
309
+ const registry = env[UPDATE_REGISTRY_ENV];
310
+ return registry === void 0 || registry === "" ? void 0 : registry;
311
+ };
312
+ /** The host of a registry that isn't an http(s) URL, past any `user:pass@`. */
313
+ const hostOf = (registry) => registry.replace(/^[a-z][\w+.-]*:\/\//iu, "").replace(/^[^/?#]*@/u, "").split(/[/?#]/u)[0] ?? "";
314
+ /**
315
+ * The registry as it may be shown (on a page, in a message): an http(s) URL
316
+ * without its user name and password, which a mirror's URL may carry; anything
317
+ * else only as its host.
318
+ */
319
+ const registryShown = (registry) => {
320
+ try {
321
+ const url = new URL(registry);
322
+ if (url.protocol === "http:" || url.protocol === "https:") {
323
+ if (url.username === "" && url.password === "") return registry;
324
+ url.username = "";
325
+ url.password = "";
326
+ return url.href;
327
+ }
328
+ } catch {}
329
+ return hostOf(registry);
330
+ };
331
+ // src/__build_info__.ts
332
+ /**
333
+ * @file The published package's name and version, bound to
334
+ * `packages/cli/package.json`. Do not edit by hand: `pnpm changesets:version`
335
+ * and `pnpm build` rewrite it (`tools/release/build-info.ts`), and a test
336
+ * fails when it is stale.
337
+ */
338
+ const ORK_NAME = "@krapht/ork";
339
+ const ORK_VERSION = "1.0.0-alpha.15";
340
+ export { dueCause as _, registryShown as a, fetchLatest as c, readUpdateCache as d, refreshUpdateCache as f, changeFollowUp as g, nodeSession as h, registryOf as i, newerVersion as l, writeUpdateCache as m, ORK_VERSION as n, updateSwitchOff as o, updateCachePath as p, isSwitchedOn as r, checkDue as s, ORK_NAME as t, pendingNotice as u, findFollowUp as v, followUpActions as y };
@@ -1,4 +1,4 @@
1
- import { $n as maskSecrets, An as END_KINDS, Dn as endOf, H as isNodeEvent, On as outcomeEnd, Tt as followEvents, U as openStore, cn as slotWaitLine, ct as followRunTree, lt as answerDecision, nn as lockWaitLine, ut as pendingDecisions } from "./src-tsuZRu0H.mjs";
1
+ import { Bn as outcomeEnd, H as isNodeEvent, Hn as END_KINDS, Lt as lockWaitLine, Ut as slotWaitLine, _t as followEvents, ct as followRunTree, fr as maskSecrets, lt as answerDecision, ut as pendingDecisions, zn as endOf } from "./src-Dr_fTSu-.mjs";
2
2
  import { C as termOf, D as wrap, E as widthOf, O as readKeys, _ as interrupt, a as plain, b as canKey, g as createRegion, h as paint, m as bold, n as cost, p as apply, r as costOf, s as style, u as confirmOrStop, v as readLine, w as cut, x as plainEnv, y as withdrawn } from "./output-B1kwo0YU.mjs";
3
3
  import { n as chip, r as nodeChip, t as CHIP_LABELS } from "./chips-BqcT58qr.mjs";
4
4
  import { a as createView, i as formatBusEvent, n as nodeVerdict, o as styler, r as firstLine, t as hasConflict } from "./verdict-CMvPCpWC.mjs";
@@ -769,8 +769,9 @@ const createTerminalHuman = (io) => {
769
769
  /**
770
770
  * @file How a node's end reads on the terminal (specs/runtime/session-ends.md):
771
771
  * its kind's label and Ork's own message, a note for a kind that may pass,
772
- * the setup hint for an account or provider end, and the scrubbed raw detail
773
- * only when asked for. Never the provider's own words first.
772
+ * the setup hint for an account or provider end, the last line of a failed
773
+ * tool's own stderr, and the scrubbed raw detail only when asked for. Never
774
+ * the provider's own words first.
774
775
  */
775
776
  /** What a transient kind says in place of its hint on the log line. */
776
777
  const MAY_PASS = "(may pass; ork resume retries)";
@@ -779,11 +780,17 @@ const endHeadline = (end) => {
779
780
  const { label, transient } = END_KINDS[end.kind];
780
781
  return `${label}: ${end.message}${transient ? ` ${MAY_PASS}` : ""}`;
781
782
  };
783
+ /** The longest a script's last stderr line is shown on the log line. */
784
+ const LAST_LINE_LIMIT = 200;
785
+ /** The last non-empty line of a scrubbed detail, cut; "" when there is none. */
786
+ const lastLine = (detail) => (detail ?? "").split("\n").map((line) => line.trim()).findLast((line) => line !== "")?.slice(0, LAST_LINE_LIMIT) ?? "";
782
787
  /**
783
788
  * The lines under a headline: the hint for an account or provider end (what to
784
789
  * set up) or whenever `full` (`--verbose`, one node's log), and the detail only
785
790
  * when `full`. A transient kind's hint is its retry wording, which the headline
786
- * already says, so it is not printed twice.
791
+ * already says, so it is not printed twice. A failed tool (`command_failed`)
792
+ * also shows the last line of its detail without `full`: a script's stderr is
793
+ * the workflow's own message, not the provider's.
787
794
  */
788
795
  const endLines = (end, full, term = createView().term) => {
789
796
  const style = styler(term);
@@ -792,6 +799,10 @@ const endLines = (end, full, term = createView().term) => {
792
799
  const lines = [];
793
800
  if (hint !== "" && !transient && (full || setup)) lines.push(` ${style("dim", hint)}`);
794
801
  if (full && end.detail !== void 0) lines.push(style("dim", " details:"), ...end.detail.split("\n").map((line) => style("dim", ` ${line}`)));
802
+ else if (end.kind === "command_failed") {
803
+ const last = lastLine(end.detail);
804
+ if (last !== "") lines.push(` ${style("dim", last)}`);
805
+ }
795
806
  return lines;
796
807
  };
797
808
  /**
@@ -1296,18 +1307,4 @@ const attachRun = async (store, root, out, options = {}) => {
1296
1307
  exitCode: end === "aborted" || seen.succeeded ? 0 : 1
1297
1308
  };
1298
1309
  };
1299
- // src/store.ts
1300
- /**
1301
- * @file Opening the user's store (`~/.ork/state.db`) for the length of one
1302
- * command, and closing it after, whatever happens.
1303
- */
1304
- /** Runs `body` with the user's store open, and closes it after. */
1305
- const withStore = async (body) => {
1306
- const store = openStore();
1307
- try {
1308
- await body(store);
1309
- } finally {
1310
- store.close();
1311
- }
1312
- };
1313
- export { unknownNode as a, callsShown as c, createDecisionQueue as d, followRun as i, createTerminalHuman as l, attachRun as n, formatEvent as o, askStored as r, formatRunEvent as s, withStore as t, readText as u };
1310
+ export { formatEvent as a, createTerminalHuman as c, unknownNode as i, readText as l, askStored as n, formatRunEvent as o, followRun as r, callsShown as s, attachRun as t, createDecisionQueue as u };
@@ -1,8 +1,9 @@
1
- import "./src-tsuZRu0H.mjs";
2
- import { l as createTerminalHuman, n as attachRun, t as withStore } from "./store-CleF7KeS.mjs";
3
- import { t as findRun } from "./find-BVX-bL4u.mjs";
1
+ import "./src-Dr_fTSu-.mjs";
2
+ import { c as createTerminalHuman, t as attachRun } from "./attach-BHO3X3cf.mjs";
3
+ import { t as findRun } from "./find-BYLlszqj.mjs";
4
4
  import { c as write, l as writeErr, s as style } from "./output-B1kwo0YU.mjs";
5
- import { n as attachRefusal } from "./in-a-run-cL5N9gpH.mjs";
5
+ import { n as attachRefusal } from "./in-a-run-Bp0k0J09.mjs";
6
+ import { t as withStore } from "./store-oKJ-cCf3.mjs";
6
7
  import { defineCommand } from "citty";
7
8
  // src/commands/attach.ts
8
9
  /**