@krapht/ork 1.0.0-alpha.13 → 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 (51) hide show
  1. package/dist/__build_info__-Bsb1kjgF.mjs +340 -0
  2. package/dist/{store-CM3cERGl.mjs → attach-BHO3X3cf.mjs} +36 -91
  3. package/dist/{attach-E6NNyA3T.mjs → attach-CPespxlQ.mjs} +6 -5
  4. package/dist/bin.mjs +148 -1444
  5. package/dist/brief-za0ozN_E.mjs +58 -0
  6. package/dist/{builtin-files-n6o6oWpB.mjs → builtin-files-2bHf76x-.mjs} +1 -1
  7. package/dist/{chips-CyeB_rhR.mjs → chips-BqcT58qr.mjs} +1 -1
  8. package/dist/{completion-SNNNxnv9.mjs → completion-CQ2UYKuJ.mjs} +52 -11
  9. package/dist/context-BNqDw9z1.mjs +106 -0
  10. package/dist/{find-CjsNYAAf.mjs → find-BYLlszqj.mjs} +1 -1
  11. package/dist/follow-ups-B4GJ3Vzw.mjs +461 -0
  12. package/dist/{format-C60TFpRe.mjs → format-C8MsFj8_.mjs} +30 -16
  13. package/dist/{help-groups-CyfPWlST.mjs → help-groups-CQ98mLjF.mjs} +20 -6
  14. package/dist/{in-a-run-BYjTXaST.mjs → in-a-run-Bp0k0J09.mjs} +1 -1
  15. package/dist/{__build_info__-Da73_nBs.mjs → install-DWtXTq4y.mjs} +3 -227
  16. package/dist/{limits-C5QKZNLT.mjs → limits-B1qzS4cX.mjs} +1 -1
  17. package/dist/{mcp-bcctR-wc.mjs → mcp-BOrVkyhN.mjs} +6 -6
  18. package/dist/{once-DPQu5Q3H.mjs → once-C1fL3GVo.mjs} +4 -4
  19. package/dist/orphan-guard-BFKg8VSd.mjs +58 -0
  20. package/dist/{output-CnRzrbUM.mjs → output-B1kwo0YU.mjs} +17 -1
  21. package/dist/{pause-BPvlDIvz.mjs → pause-DOMK-R8V.mjs} +4 -4
  22. package/dist/post-BzA6Qobq.mjs +44 -0
  23. package/dist/{relay-C8W0t_zc.mjs → relay-OWuu4fib.mjs} +2 -2
  24. package/dist/run--4-1xAF2.mjs +1451 -0
  25. package/dist/{run-CQIfq918.mjs → run-CiPsW9Kf.mjs} +1 -1
  26. package/dist/send-CnNNW-ot.mjs +105 -0
  27. package/dist/{src-CqRqsb2t.mjs → src-B9zWIVqo.mjs} +226 -44
  28. package/dist/{src-CGJGL1sZ.mjs → src-DQKz2eOH.mjs} +326 -81
  29. package/dist/{src-D93tHZ5B.mjs → src-DcrhgipG.mjs} +107 -47
  30. package/dist/{src-BeR6f70A.mjs → src-Dr_fTSu-.mjs} +5858 -3746
  31. package/dist/store-oKJ-cCf3.mjs +16 -0
  32. package/dist/ui/assets/app-Bdc6OBeZ.css +1 -0
  33. package/dist/ui/assets/app-Drp8Dm9y.js +111 -0
  34. package/dist/ui/assets/{index-CWwm8HTG.js → index-BtwkftKe.js} +2 -2
  35. package/dist/ui/index.html +1 -1
  36. package/dist/{ui-D2Ydofq0.mjs → ui-CzKlsCnm.mjs} +4 -4
  37. package/dist/{usage-6WIowblz.mjs → usage-DHGNk2JL.mjs} +13 -141
  38. package/dist/{context-DHudLA5e.mjs → validate-Bs_gg22g.mjs} +17 -107
  39. package/dist/{verdict-CIy8tAyX.mjs → verdict-CMvPCpWC.mjs} +2 -2
  40. package/dist/{watch-uOU_WeBI.mjs → watch-CCCfw3n7.mjs} +24 -8
  41. package/dist/{workflows-7tQdMnrA.mjs → workflows-CW28ZU-z.mjs} +3 -3
  42. package/dist/{worktrees-ZCII298F.mjs → worktrees-CyE8aF6j.mjs} +3 -5
  43. package/package.json +2 -2
  44. package/dist/clean-Bh4KZgzc.mjs +0 -91
  45. package/dist/decide-DuIHACvH.mjs +0 -50
  46. package/dist/list-BUb5Uc3H.mjs +0 -117
  47. package/dist/remove-BkFWGVYo.mjs +0 -201
  48. package/dist/report-CEN8VoUb.mjs +0 -140
  49. package/dist/send-CaZlGG5a.mjs +0 -163
  50. package/dist/ui/assets/app-DYRC0V4p.js +0 -111
  51. package/dist/ui/assets/app-QoHVi-mb.css +0 -1
@@ -0,0 +1,58 @@
1
+ import { un as takeFollowUps } from "./src-Dr_fTSu-.mjs";
2
+ import { l as briefOf, n as flagValues, u as checkTakeable } from "./run--4-1xAF2.mjs";
3
+ import { n as newRunId } from "./find-BYLlszqj.mjs";
4
+ import { l as writeErr } from "./output-B1kwo0YU.mjs";
5
+ import { t as loadWorkflow } from "./validate-Bs_gg22g.mjs";
6
+ // src/follow-ups/brief.ts
7
+ /**
8
+ * @file `ork run --follow-ups <ids>`: the `agent` follow-ups become the run's
9
+ * `brief` input, and are marked taken by the run, which finishes them when it
10
+ * publishes (`ork follow-ups published`). Everything that could refuse them
11
+ * (an unknown id, one for someone else, a workflow with no `brief` input) is
12
+ * checked before any is marked, so a run that doesn't start leaves them be.
13
+ */
14
+ /** The ids `--follow-ups` was given, one per comma or repeat. */
15
+ const idsOf = (rawArgs) => flagValues(rawArgs, "--follow-ups").flatMap((value) => value.split(",")).map((id) => id.trim()).filter((id) => id !== "");
16
+ /**
17
+ * What stops `--follow-ups` from starting a run, one line each; none when
18
+ * nothing does.
19
+ */
20
+ const problemsOf = (loaded, inputs) => {
21
+ const name = loaded.workflow?.name ?? "";
22
+ if (loaded.workflow?.inputs?.["brief"] === void 0) return [`--follow-ups fills a workflow's \`brief\` input, and ${name} has none.`];
23
+ return inputs.some((input) => input.startsWith("brief=")) ? ["--follow-ups and --input brief=… both set the brief."] : [];
24
+ };
25
+ /**
26
+ * The inputs and run id `ork run` starts with: those it was given and, for
27
+ * `--follow-ups`, a `brief` made of the follow-ups with the id of the run that
28
+ * takes them. `undefined` after saying why it can't start.
29
+ */
30
+ const prepareFollowUps = (store, rawArgs, runId, target) => {
31
+ const inputs = flagValues(rawArgs, "--input");
32
+ const ids = idsOf(rawArgs);
33
+ const plain = {
34
+ inputs,
35
+ ...runId === void 0 ? {} : { runId }
36
+ };
37
+ if (ids.length === 0) return plain;
38
+ const loaded = loadWorkflow(target.file, process.cwd(), void 0, store.projects());
39
+ if (loaded.workflow === null) return plain;
40
+ const takeable = checkTakeable(store, loaded.place.root, ids);
41
+ const problems = [...problemsOf(loaded, inputs), ...takeable.ok ? [] : takeable.lines];
42
+ if (!takeable.ok || problems.length > 0) {
43
+ for (const line of problems) writeErr(line);
44
+ process.exitCode = 1;
45
+ return;
46
+ }
47
+ const taker = runId ?? newRunId(store);
48
+ takeFollowUps(store, {
49
+ project: loaded.place.root,
50
+ run: taker,
51
+ ids: takeable.followUps.map((f) => f.id)
52
+ });
53
+ return {
54
+ inputs: [...inputs, `brief=${briefOf(takeable.followUps)}`],
55
+ runId: taker
56
+ };
57
+ };
58
+ export { prepareFollowUps };
@@ -1,4 +1,4 @@
1
- import { $n as plainPathInside, Hn as placeFiles, Qn as guardedBase, er as writePlainFile } from "./src-BeR6f70A.mjs";
1
+ import { Er as placeFiles, Ir as guardedBase, Lr as plainPathInside, Rr as writePlainFile } from "./src-Dr_fTSu-.mjs";
2
2
  import path from "node:path";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { createHash } from "node:crypto";
@@ -1,4 +1,4 @@
1
- import { d as apply, l as CHIP, u as NODE_PALETTE } from "./output-CnRzrbUM.mjs";
1
+ import { d as CHIP, f as NODE_PALETTE, p as apply } from "./output-B1kwo0YU.mjs";
2
2
  // src/term/chips.ts
3
3
  /** The chip words the kit's commands use. */
4
4
  const CHIP_LABELS = {
@@ -1,10 +1,9 @@
1
- import { Hn as placeFiles, Nr as AGENT_DRIVERS, Sr as NodeIdSchema, T as storePath, Un as placeFor, _t as liveStatus, w as openStore } from "./src-BeR6f70A.mjs";
2
- import { a as isBuiltinArg, i as builtinWorkflowText, r as builtinWorkflowNames } from "./builtin-files-n6o6oWpB.mjs";
3
- import { n as pendingDecisions } from "./decide-DuIHACvH.mjs";
4
- import { t as findRun } from "./find-CjsNYAAf.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-CyfPWlST.mjs";
6
- import { s as writeErr } from "./output-CnRzrbUM.mjs";
7
- import { a as resolveWorkflowArg, n as WORKFLOW_SUFFIX } from "./workflows-7tQdMnrA.mjs";
1
+ import { Cn as liveStatus, Dr as placeFor, Er as placeFiles, U as openStore, W as storePath, _i as AGENT_DRIVERS, oi as NodeIdSchema, ut as pendingDecisions } from "./src-Dr_fTSu-.mjs";
2
+ import { a as isBuiltinArg, i as builtinWorkflowText, r as builtinWorkflowNames } from "./builtin-files-2bHf76x-.mjs";
3
+ import { t as findRun } from "./find-BYLlszqj.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-CQ98mLjF.mjs";
5
+ import { l as writeErr } from "./output-B1kwo0YU.mjs";
6
+ import { a as resolveWorkflowArg, n as WORKFLOW_SUFFIX } from "./workflows-CW28ZU-z.mjs";
8
7
  import path from "node:path";
9
8
  import { parse } from "yaml";
10
9
  import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
@@ -40,16 +39,45 @@ const workflowText = (arg, cwd, place) => {
40
39
  const file = path.resolve(cwd, resolveWorkflowArg(arg, cwd, placeFiles(place).workflows));
41
40
  return existsSync(file) && statSync(file).isFile() ? readFileSync(file, "utf8") : void 0;
42
41
  };
42
+ /** A mapping's entries, or none when `value` is not an object. */
43
+ const entriesOf = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? Object.entries(value) : [];
44
+ /** One top-level field of a workflow's text, read without validating it. */
45
+ const fieldOf = (text, field) => {
46
+ const parsed = text === void 0 ? void 0 : parse(text);
47
+ return Object.fromEntries(entriesOf(parsed))[field];
48
+ };
43
49
  /** The node ids of the workflow `arg` names; none when it can't be read. */
44
50
  const workflowNodes = (arg, cwd, place) => {
45
- const text = workflowText(arg, cwd, place);
46
- const parsed = text === void 0 ? void 0 : parse(text);
47
- const nodes = parsed !== null && typeof parsed === "object" && "nodes" in parsed ? parsed.nodes : void 0;
48
- return (nodes !== null && typeof nodes === "object" ? Object.keys(nodes) : []).filter((key) => NodeIdSchema.safeParse(key).success).map((value) => ({
51
+ return entriesOf(fieldOf(workflowText(arg, cwd, place), "nodes")).map(([key]) => key).filter((key) => NodeIdSchema.safeParse(key).success).map((value) => ({
49
52
  value,
50
53
  description: arg
51
54
  }));
52
55
  };
56
+ /** What a menu says of an input: its description, else its type. */
57
+ const inputDescription = (definition) => {
58
+ const fields = Object.fromEntries(entriesOf(definition));
59
+ const said = fields["description"] ?? fields["type"];
60
+ const what = typeof said === "string" ? said : "";
61
+ return fields["required"] === true && !("default" in fields) ? `${what} (required)` : what;
62
+ };
63
+ /**
64
+ * `name=` for each input a workflow's text declares, for `--input`; a name that
65
+ * isn't a valid id is left out, as a node's is.
66
+ */
67
+ const inputsOf = (text, workflow) => entriesOf(fieldOf(text, "inputs")).filter(([name]) => NodeIdSchema.safeParse(name).success).map(([name, definition]) => ({
68
+ value: `${name}=`,
69
+ description: inputDescription(definition) || workflow
70
+ }));
71
+ /** The inputs of the workflow `arg` names; none when it can't be read. */
72
+ const workflowInputs = (arg, cwd, place) => inputsOf(workflowText(arg, cwd, place), arg);
73
+ /** The inputs of the run `arg` names (else the project's newest run). */
74
+ const runInputs = (store, arg, cwd) => {
75
+ const found = findRun(store, arg, cwd);
76
+ if (!found.ok) return [];
77
+ const { file, workflow } = found.run;
78
+ const text = existsSync(file) && statSync(file).isFile() ? readFileSync(file, "utf8") : void 0;
79
+ return inputsOf(text, workflow);
80
+ };
53
81
  /**
54
82
  * Runs whose id starts with `prefix`, newest first: the project's, else any
55
83
  * project's, at most `RUN_LIMIT`.
@@ -112,6 +140,18 @@ const nodes = {
112
140
  return withStore(context, (store) => runNodes(store, context.given["run"], context.cwd));
113
141
  }
114
142
  };
143
+ /**
144
+ * `name=` for each input, for `--input`: the workflow given's when the command
145
+ * takes a workflow (none before it is), else the run given's (`ork resume`).
146
+ */
147
+ const inputs = {
148
+ group: "inputs",
149
+ values: (context) => {
150
+ const workflow = context.given["workflow"];
151
+ if (context.positionals.includes("workflow")) return workflow === void 0 ? [] : workflowInputs(workflow, context.cwd, placeOf(context.cwd, context.store()));
152
+ return withStore(context, (store) => runInputs(store, context.given["run"], context.cwd));
153
+ }
154
+ };
115
155
  const decisions = {
116
156
  group: "decisions",
117
157
  values: (context) => withStore(context, (store) => decisionCandidates(store, context.given["run"], context.cwd, placeOf(context.cwd, store)))
@@ -144,6 +184,7 @@ const VALUE_PROVIDERS = {
144
184
  files: true
145
185
  },
146
186
  node: nodes,
187
+ input: inputs,
147
188
  "decide id": decisions,
148
189
  "completion shell": shells,
149
190
  driver: drivers,
@@ -0,0 +1,106 @@
1
+ import { Pr as LESSON_CAP_TOKENS, wt as explainSession } from "./src-Dr_fTSu-.mjs";
2
+ import { c as write, s as style } from "./output-B1kwo0YU.mjs";
3
+ import { i as refusedBuiltin, o as workflowArg } from "./workflows-CW28ZU-z.mjs";
4
+ import { a as formatReport, t as loadWorkflow } from "./validate-Bs_gg22g.mjs";
5
+ import { defineCommand } from "citty";
6
+ // src/commands/context.ts
7
+ /**
8
+ * @file `ork context explain <wf> <node>`: what one node's session would load,
9
+ * layer by layer, as core's `explainSession` plans it without writing
10
+ * anything (one of Ork's own `ork:` workflows is written into the project's
11
+ * run folder first, as `ork run` does): its project instructions, every skill
12
+ * with the layer it came from and whether it is live, shadowed or switched
13
+ * off, its context files, its practices, and estimated tokens.
14
+ */
15
+ /** Loads a workflow file and plans one node's session in it, in place. */
16
+ const explainNode = (file, nodeId, cwd, home) => {
17
+ const { report, workflow, graph, place, workflowDir } = loadWorkflow(file, cwd, home);
18
+ if (workflow === null) return {
19
+ ok: false,
20
+ lines: formatReport(report)
21
+ };
22
+ const result = explainSession(workflow, graph, nodeId, {
23
+ root: place.root,
24
+ orkDir: place.dir,
25
+ workflowDir,
26
+ ...home === void 0 ? {} : { home }
27
+ });
28
+ return result.ok ? result : {
29
+ ok: false,
30
+ lines: [result.error]
31
+ };
32
+ };
33
+ const approx = (count) => style("dim", `≈${count.toLocaleString("en")} tokens`);
34
+ const formatExplanation = (e) => {
35
+ const width = Math.max(8, ...e.skills.map((s) => s.name.length));
36
+ const sourceWidth = Math.max(0, ...e.skills.map((s) => s.source.length));
37
+ const lines = [
38
+ `${style("bold", e.node)} ${style("dim", `(${e.type}) in ${e.workflow}`)}${e.template === void 0 ? "" : style("dim", `, planned as ${e.template}, the node it was spawned from`)}`,
39
+ "",
40
+ ...e.agent === void 0 ? [] : [`${style("bold", "Agent")} ${e.agent.name} ${style("dim", `(${e.agent.where})`)} ${approx(e.agent.tokens)}`],
41
+ `${style("bold", "Instructions")} ${e.instructions}`,
42
+ "",
43
+ style("bold", "Skills")
44
+ ];
45
+ if (e.skills.length === 0) lines.push(style("dim", " none"));
46
+ for (const s of e.skills) {
47
+ const mark = s.state === "live" ? style("green", "✓") : style("dim", "−");
48
+ const state = s.why === void 0 ? approx(s.tokens).replace("tokens", "tokens when used") : style("yellow", `off: ${s.why}`);
49
+ lines.push(` ${mark} ${s.name.padEnd(width)} ${s.layer.padEnd(8)} ${style("dim", s.source.padEnd(sourceWidth))} ${state}`);
50
+ }
51
+ lines.push("", style("bold", "Context files"));
52
+ if (e.files.length === 0) lines.push(style("dim", " none"));
53
+ for (const f of e.files) {
54
+ const cut = f.cutFrom === void 0 ? "" : ` ${style("yellow", `cut at the ${LESSON_CAP_TOKENS.toLocaleString("en")}-token cap; the whole file is ${approx(f.cutFrom)}`)}`;
55
+ lines.push(` ${f.layer.padEnd(8)} ${f.name} ${approx(f.tokens)}${cut}`);
56
+ }
57
+ lines.push("", style("bold", "Practices"));
58
+ for (const p of e.practices) lines.push(` ${p.name.padEnd(8)} ${approx(p.tokens)}`);
59
+ for (const name of e.skippedPractices) lines.push(` ${name.padEnd(8)} ${style("dim", "the project's own skill wins")}`);
60
+ if (e.practices.length === 0 && e.skippedPractices.length === 0) lines.push(style("dim", " off"));
61
+ lines.push("", `Appended to Claude Code's system prompt: ${approx(e.appendedTokens)}`);
62
+ return lines;
63
+ };
64
+ const explain = defineCommand({
65
+ meta: {
66
+ name: "explain",
67
+ description: "Show what one node's session loads, layer by layer"
68
+ },
69
+ args: {
70
+ workflow: {
71
+ type: "positional",
72
+ description: "A workflow file, the name of one in the project's workflows (.ork/workflows/), or one of Ork's own (ork:feedback-apply)",
73
+ required: true
74
+ },
75
+ node: {
76
+ type: "positional",
77
+ description: "Node id",
78
+ required: true
79
+ },
80
+ json: {
81
+ type: "boolean",
82
+ description: "Print JSON",
83
+ default: false
84
+ }
85
+ },
86
+ run: ({ args }) => {
87
+ const cwd = process.cwd();
88
+ if (refusedBuiltin([args.workflow], cwd)) return;
89
+ const result = explainNode(workflowArg(args.workflow, cwd).file, args.node, cwd);
90
+ if (!result.ok) {
91
+ for (const line of result.lines) process.stderr.write(`${line}\n`);
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ if (args.json) write(JSON.stringify(result.explanation, void 0, 2));
96
+ else for (const line of formatExplanation(result.explanation)) write(line);
97
+ }
98
+ });
99
+ const context = defineCommand({
100
+ meta: {
101
+ name: "context",
102
+ description: "Inspect the context Ork compiles for each node"
103
+ },
104
+ subCommands: { explain }
105
+ });
106
+ export { explainNode as n, context as t };
@@ -1,4 +1,4 @@
1
- import { Un as placeFor } from "./src-BeR6f70A.mjs";
1
+ import { Dr as placeFor } from "./src-Dr_fTSu-.mjs";
2
2
  import { randomUUID } from "node:crypto";
3
3
  // ../core/src/remote/find.ts
4
4
  /**