cloving 1.4.0 → 1.5.0

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 (167) hide show
  1. package/README.md +100 -15
  2. package/dist/src/broker/actor/authority-health.d.ts +9 -0
  3. package/dist/src/broker/actor/authority-health.js +24 -0
  4. package/dist/src/broker/actor/authority-runtime.d.ts +4 -2
  5. package/dist/src/broker/actor/authority-runtime.js +29 -20
  6. package/dist/src/broker/actor/authority-session.d.ts +6 -19
  7. package/dist/src/broker/actor/authority-session.js +66 -88
  8. package/dist/src/broker/actor/authority-settings.d.ts +2 -1
  9. package/dist/src/broker/actor/authority-settings.js +4 -1
  10. package/dist/src/broker/actor/authority-upgrades.d.ts +5 -1
  11. package/dist/src/broker/actor/authority-upgrades.js +2 -1
  12. package/dist/src/broker/actor/authority-watchdog.d.ts +6 -2
  13. package/dist/src/broker/actor/authority-watchdog.js +31 -9
  14. package/dist/src/broker/actor/authority.js +3 -1
  15. package/dist/src/broker/actor/projection-memory.d.ts +43 -0
  16. package/dist/src/broker/actor/projection-memory.js +207 -0
  17. package/dist/src/broker/actor/runtime-parts.d.ts +5 -0
  18. package/dist/src/broker/actor/runtime-parts.js +8 -3
  19. package/dist/src/broker/authority-restore.js +1 -1
  20. package/dist/src/broker/effect-upgrade.d.ts +1 -0
  21. package/dist/src/broker/effect-upgrade.js +4 -1
  22. package/dist/src/cli/arguments.js +1 -0
  23. package/dist/src/cli/client.d.ts +3 -1
  24. package/dist/src/cli/client.js +4 -4
  25. package/dist/src/cli/command-requests.d.ts +30 -1
  26. package/dist/src/cli/command-requests.js +43 -2
  27. package/dist/src/cli/commands.js +57 -48
  28. package/dist/src/cli/config-notice.js +5 -2
  29. package/dist/src/cli/doctor-retention.d.ts +2 -0
  30. package/dist/src/cli/doctor-retention.js +93 -0
  31. package/dist/src/cli/doctor.js +5 -0
  32. package/dist/src/cli/init-prompt.js +1 -1
  33. package/dist/src/cli/mcp-server.js +4 -4
  34. package/dist/src/cli/mcp-tools.d.ts +14 -14
  35. package/dist/src/cli/mcp-tools.js +212 -50
  36. package/dist/src/cli/queue-arguments.d.ts +15 -0
  37. package/dist/src/cli/queue-arguments.js +31 -0
  38. package/dist/src/cli/queue-render.d.ts +3 -0
  39. package/dist/src/cli/queue-render.js +26 -0
  40. package/dist/src/cli/reload-render.d.ts +2 -0
  41. package/dist/src/cli/reload-render.js +12 -0
  42. package/dist/src/cli/render.js +37 -8
  43. package/dist/src/cli/report-github-reader.js +1 -1
  44. package/dist/src/cli/runtime-arguments.d.ts +17 -3
  45. package/dist/src/cli/runtime-arguments.js +23 -19
  46. package/dist/src/cli/toolchain.d.ts +1 -0
  47. package/dist/src/cli/toolchain.js +1 -0
  48. package/dist/src/cli/usage.d.ts +2 -2
  49. package/dist/src/cli/usage.js +40 -5
  50. package/dist/src/cli/watch-api-document.d.ts +430 -0
  51. package/dist/src/cli/watch-api-document.js +291 -0
  52. package/dist/src/cli/watch-api-run.d.ts +56 -0
  53. package/dist/src/cli/watch-api-run.js +112 -0
  54. package/dist/src/cli/watch-api.d.ts +17 -0
  55. package/dist/src/cli/watch-api.js +230 -0
  56. package/dist/src/cli/watch-header-view.d.ts +1 -0
  57. package/dist/src/cli/watch-header-view.js +9 -1
  58. package/dist/src/cli/watch-model.d.ts +1 -0
  59. package/dist/src/cli/watch-model.js +3 -0
  60. package/dist/src/cli/watch-page.js +3 -1
  61. package/dist/src/cli/watch-reads.d.ts +1 -0
  62. package/dist/src/cli/watch-reads.js +6 -5
  63. package/dist/src/cli/watch-render.d.ts +1 -0
  64. package/dist/src/cli/watch-server.js +18 -4
  65. package/dist/src/cli.js +50 -43
  66. package/dist/src/configuration-display.js +2 -0
  67. package/dist/src/configuration-schema.d.ts +5 -0
  68. package/dist/src/daemon/claude-recovery.js +13 -9
  69. package/dist/src/daemon/claude-worker.d.ts +3 -3
  70. package/dist/src/daemon/claude-worker.js +10 -11
  71. package/dist/src/daemon/daemon-adapters.d.ts +7 -0
  72. package/dist/src/daemon/daemon-adapters.js +7 -3
  73. package/dist/src/daemon/daemon-loops.d.ts +2 -0
  74. package/dist/src/daemon/daemon-loops.js +17 -11
  75. package/dist/src/daemon/daemon.js +71 -60
  76. package/dist/src/daemon/github-attach.js +77 -4
  77. package/dist/src/daemon/github-calls.js +1 -1
  78. package/dist/src/daemon/github-methods.js +6 -2
  79. package/dist/src/daemon/issue-queue.d.ts +3 -0
  80. package/dist/src/daemon/issue-queue.js +66 -73
  81. package/dist/src/daemon/merge-turns.d.ts +10 -0
  82. package/dist/src/daemon/merge-turns.js +37 -0
  83. package/dist/src/daemon/queue-control.d.ts +13 -0
  84. package/dist/src/daemon/queue-control.js +86 -0
  85. package/dist/src/daemon/queue-journal.d.ts +20 -0
  86. package/dist/src/daemon/queue-journal.js +89 -0
  87. package/dist/src/daemon/record-archive.d.ts +19 -0
  88. package/dist/src/daemon/record-archive.js +82 -0
  89. package/dist/src/daemon/record-sweep.d.ts +24 -0
  90. package/dist/src/daemon/record-sweep.js +147 -0
  91. package/dist/src/daemon/retrying-turn.js +4 -4
  92. package/dist/src/daemon/settings-reload.d.ts +26 -0
  93. package/dist/src/daemon/settings-reload.js +82 -0
  94. package/dist/src/daemon/turn-details.d.ts +4 -0
  95. package/dist/src/daemon/turn-details.js +33 -0
  96. package/dist/src/daemon/worker-profile.d.ts +1 -0
  97. package/dist/src/daemon/worker-profile.js +4 -0
  98. package/dist/src/daemon/workflow-generations.d.ts +7 -4
  99. package/dist/src/daemon/workflow-generations.js +22 -14
  100. package/dist/src/daemon/workflow-reload.d.ts +41 -0
  101. package/dist/src/daemon/workflow-reload.js +244 -0
  102. package/dist/src/daemon/workflow-replay.d.ts +2 -1
  103. package/dist/src/daemon/workflow-replay.js +7 -3
  104. package/dist/src/doctor-report.d.ts +2 -2
  105. package/dist/src/doctor-report.js +2 -0
  106. package/dist/src/private-config.schema.json +31 -0
  107. package/dist/src/project-settings.d.ts +15 -1
  108. package/dist/src/project-settings.js +33 -1
  109. package/dist/src/queue-state.d.ts +26 -0
  110. package/dist/src/queue-state.js +34 -0
  111. package/dist/src/record-retention.d.ts +46 -0
  112. package/dist/src/record-retention.js +81 -0
  113. package/dist/src/service/active-tickets.js +5 -0
  114. package/dist/src/service/dispatcher.d.ts +4 -0
  115. package/dist/src/service/dispatcher.js +33 -0
  116. package/dist/src/service/queue-handlers.d.ts +4 -0
  117. package/dist/src/service/queue-handlers.js +32 -0
  118. package/dist/src/service/registry.d.ts +28 -2
  119. package/dist/src/service/registry.js +48 -0
  120. package/dist/src/service/replies.d.ts +16 -9
  121. package/dist/src/service/replies.js +5 -2
  122. package/dist/src/service/run-handlers.js +15 -10
  123. package/dist/src/service/service.d.ts +7 -3
  124. package/dist/src/service/service.js +16 -31
  125. package/dist/src/service/worker-totals.d.ts +4 -0
  126. package/dist/src/service/worker-totals.js +7 -0
  127. package/dist/src/service/workflow-reload.d.ts +35 -0
  128. package/dist/src/service/workflow-reload.js +52 -0
  129. package/dist/src/storage/decision-snapshots.d.ts +1 -2
  130. package/dist/src/storage/decision-snapshots.js +1 -7
  131. package/dist/src/storage/domain-changes.d.ts +1 -1
  132. package/dist/src/storage/domain-changes.js +1 -0
  133. package/dist/src/storage/domain-schema.d.ts +4 -1
  134. package/dist/src/storage/domain-schema.js +6 -2
  135. package/dist/src/storage/effect-schema.d.ts +1 -0
  136. package/dist/src/storage/effect-schema.js +4 -0
  137. package/dist/src/storage/projection-changes.d.ts +12 -0
  138. package/dist/src/storage/projection-changes.js +194 -0
  139. package/dist/src/storage/projection-lookups.d.ts +7 -0
  140. package/dist/src/storage/projection-lookups.js +30 -0
  141. package/dist/src/workflow-declaration.d.ts +1 -0
  142. package/dist/src/workflow-declaration.js +3 -0
  143. package/dist/tools/compile-workflows.js +3 -0
  144. package/dist/tools/project-configuration.d.ts +7 -2
  145. package/dist/tools/project-configuration.js +30 -1
  146. package/dist/tools/self-host-processes.js +37 -13
  147. package/dist/tools/self-host-project.d.ts +2 -0
  148. package/dist/tools/self-host-project.js +21 -3
  149. package/dist/tools/self-host.js +34 -24
  150. package/dist/tools/workflow-candidate-program.d.ts +4 -2
  151. package/dist/tools/workflow-candidate-program.js +30 -11
  152. package/dist/tools/workflow-candidate-source.d.ts +1 -0
  153. package/dist/tools/workflow-candidate-source.js +11 -3
  154. package/package.json +2 -2
  155. package/templates/develop/README.md +81 -4
  156. package/templates/develop/develop/flow-tests.ts +1 -1
  157. package/templates/develop/develop/interruption-tests.ts +157 -0
  158. package/templates/develop/develop/local.ts +1 -0
  159. package/templates/develop/develop/option-tests.ts +138 -9
  160. package/templates/develop/develop/red-green.ts +55 -0
  161. package/templates/develop/develop/report.ts +31 -11
  162. package/templates/develop/develop/round.ts +1 -0
  163. package/templates/develop/develop/scenarios.ts +27 -0
  164. package/templates/develop/develop/turn.ts +26 -6
  165. package/templates/develop/develop.declaration.json +1 -1
  166. package/templates/develop/develop.test.ts +4 -0
  167. package/templates/develop/template.json +29 -2
@@ -5,6 +5,8 @@ import { workflowRefusals } from "../workflow-refusals.js";
5
5
  import { commandText, shownCommands } from "./command-effects.js";
6
6
  import { scheduledText, statusScheduleLines, scheduleLines, } from "./schedule-render.js";
7
7
  import { show, oneLine, visible } from "./terminal-text.js";
8
+ import { queueHeadline, queueStateLines } from "./queue-render.js";
9
+ import { reloadFieldLines } from "./reload-render.js";
8
10
  export { oneLine } from "./terminal-text.js";
9
11
  export function errorText(error) {
10
12
  const { candidates } = error;
@@ -78,21 +80,33 @@ export function runOverview(result) {
78
80
  hiddenRuns: Math.max(0, finished.length - 20),
79
81
  };
80
82
  }
83
+ function refusalLines(value) {
84
+ const refusals = workflowRefusals(value);
85
+ if (refusals.length === 0)
86
+ return [];
87
+ return [
88
+ "Refused workflows:",
89
+ ...refusals.map((entry) => ` ${entry.scope} ${entry.label}: ${entry.codes.join(", ")}`),
90
+ ];
91
+ }
92
+ function reloadLines(result) {
93
+ return [
94
+ `Reload: ${show(result["status"])}`,
95
+ `Bundle digest: ${show(result["previousBundleDigest"])} -> ${show(result["bundleDigest"])}`,
96
+ `Workflows: ${visible(listing(result["workflows"]))}`,
97
+ ...reloadFieldLines(result),
98
+ ...refusalLines(result["workflowRefusals"]),
99
+ ];
100
+ }
81
101
  function runList(result) {
82
102
  const runs = result["runs"];
83
103
  const lines = Array.isArray(runs) ? runs.map(runLine) : [];
84
104
  const hiddenRuns = result["hiddenRuns"];
85
- const refusals = workflowRefusals(result["workflowRefusals"]);
86
105
  return [
87
106
  `Workflows: ${visible(listing(result["workflows"]))}`,
88
107
  ...queueLines(result["queue"]),
89
108
  ...statusScheduleLines(result["schedules"]).map(oneLine),
90
- ...(refusals.length === 0
91
- ? []
92
- : [
93
- "Refused workflows:",
94
- ...refusals.map((entry) => ` ${entry.scope} ${entry.label}: ${entry.codes.join(", ")}`),
95
- ]),
109
+ ...refusalLines(result["workflowRefusals"]),
96
110
  "Runs:",
97
111
  ...(lines.length === 0 ? [" none"] : lines),
98
112
  ...(typeof hiddenRuns === "number" && hiddenRuns > 0
@@ -108,7 +122,8 @@ export function queueLines(value) {
108
122
  return [];
109
123
  const skipped = queue["skipped"];
110
124
  return [
111
- `Queue: ${visible(queue["busy"])} of ${visible(queue["lanes"])} lanes busy`,
125
+ queueHeadline(queue),
126
+ ...queueStateLines(queue),
112
127
  ...queueSpendLines(queue["spend"]),
113
128
  ...(Array.isArray(skipped)
114
129
  ? skipped.map((item) => {
@@ -172,6 +187,16 @@ function modelLines(attempts) {
172
187
  });
173
188
  }
174
189
  export { statusJson } from "./usage-render.js";
190
+ function turnDetailsLines(value) {
191
+ const state = part(value, "state");
192
+ if (state === "deleted")
193
+ return ["Turn details were deleted by the retention rule"];
194
+ if (state !== "archived")
195
+ return [];
196
+ return [
197
+ `Turn details are archived in the journal folder of the archive: ${visible(part(value, "folder"))}`,
198
+ ];
199
+ }
175
200
  function inputText(value) {
176
201
  const text = visible(record(value) ?? null);
177
202
  const characters = Array.from(text);
@@ -204,6 +229,7 @@ export function runStatus(result) {
204
229
  `Cost${suffix}: ${priceText(part(run, "claudeCostUsd"), part(run, "estimatedCostUsd"))}`,
205
230
  `Token usage${suffix}: ${usageText(part(run, "usage"))}`,
206
231
  ...workerLines(part(run, "workerTurns")),
232
+ ...turnDetailsLines(part(run, "turnDetails")),
207
233
  ...shownCommandWaits(part(run, "commandWaits")).map((wait) => visible(commandWaitText(wait))),
208
234
  ...(record(part(run, "budget")) === undefined
209
235
  ? []
@@ -289,7 +315,10 @@ const renderers = new Map([
289
315
  ["decision-list", decisionList],
290
316
  ["decision-recorded", decisionRecorded],
291
317
  ["run-command", runCommand],
318
+ ["queue", (result) => queueLines(result["queue"])],
319
+ ["queue-command", (result) => queueLines(result["queue"])],
292
320
  ["event-page", eventPage],
321
+ ["reload", reloadLines],
293
322
  ]);
294
323
  export function rendered(result) {
295
324
  const lines = renderers.get(show(result["kind"]))?.(result) ?? [];
@@ -128,7 +128,7 @@ async function readEndpoint(input, request) {
128
128
  });
129
129
  if (output.status !== 0 || output.errorCode !== null)
130
130
  throw Object.assign(new Error("github-call-failed"), {
131
- status: Number(/\(HTTP (\d{3})\)/.exec(output.stderr)?.[1]),
131
+ status: Number(/\bHTTP (\d{3})\b/.exec(output.stderr)?.[1]),
132
132
  detail: output.stderr,
133
133
  });
134
134
  return output.stdout;
@@ -1,4 +1,5 @@
1
1
  import { type ScheduleInvocation } from "./schedule-arguments.ts";
2
+ import { type QueueInvocation } from "./queue-arguments.ts";
2
3
  export type RunSource = {
3
4
  readonly kind: "prompt";
4
5
  readonly text: string;
@@ -9,12 +10,15 @@ export type RunSource = {
9
10
  readonly kind: "input";
10
11
  readonly file: string;
11
12
  };
12
- type DecisionCommand = "answer" | "approve" | "deny";
13
- type RunCommand = "pause" | "resume" | "drop";
14
- export type RuntimeInvocation = ScheduleInvocation | {
13
+ export type DecisionCommand = "answer" | "approve" | "deny";
14
+ export type RunCommand = "pause" | "resume" | "drop";
15
+ export type RuntimeInvocation = ScheduleInvocation | QueueInvocation | {
15
16
  readonly kind: "report";
16
17
  readonly since: number;
17
18
  readonly json: boolean;
19
+ } | {
20
+ readonly kind: "reload";
21
+ readonly json: boolean;
18
22
  } | {
19
23
  readonly kind: "command-help";
20
24
  readonly command: string;
@@ -29,6 +33,7 @@ export type RuntimeInvocation = ScheduleInvocation | {
29
33
  readonly runId: string | null;
30
34
  readonly limit: number | null;
31
35
  readonly after: string | null;
36
+ readonly active: boolean;
32
37
  readonly json: boolean;
33
38
  } | {
34
39
  readonly kind: "questions";
@@ -73,6 +78,15 @@ export interface RuntimeRequest {
73
78
  readonly options: readonly GivenOption[];
74
79
  }
75
80
  type Outcome = RuntimeInvocation | string;
81
+ export declare const argumentRules: {
82
+ identifier: RegExp;
83
+ decisionReference: RegExp;
84
+ sha256Digest: RegExp;
85
+ revisions: {
86
+ minimum: number;
87
+ maximum: number;
88
+ };
89
+ };
76
90
  export declare function isRuntimeCommand(command: string): boolean;
77
91
  export declare function runtimeInvocation(request: RuntimeRequest): Outcome;
78
92
  export {};
@@ -1,5 +1,6 @@
1
1
  import { isRecordKey } from "../authority/commands.js";
2
2
  import { scheduleInvocation, } from "./schedule-arguments.js";
3
+ import { queueInvocation } from "./queue-arguments.js";
3
4
  const identifier = /^[A-Za-z0-9._:/-]{1,128}$/;
4
5
  const decisionReference = /^[A-Za-z0-9._:/-]{1,256}$/;
5
6
  const sha256Digest = /^sha256:[0-9a-f]{64}$/;
@@ -9,6 +10,12 @@ const revisions = { minimum: 1, maximum: Number.MAX_SAFE_INTEGER };
9
10
  const sequences = { minimum: 0, maximum: Number.MAX_SAFE_INTEGER };
10
11
  const bindingOptions = ["expected-revision", "generation", "subject-digest"];
11
12
  const mutationOptions = ["command-id", "json"];
13
+ export const argumentRules = {
14
+ identifier,
15
+ decisionReference,
16
+ sha256Digest,
17
+ revisions,
18
+ };
12
19
  const shapes = new Map([
13
20
  [
14
21
  "run",
@@ -52,27 +59,21 @@ const shapes = new Map([
52
59
  build: events,
53
60
  },
54
61
  ],
62
+ ["report", noSubjectShape(["since", "json"], report)],
55
63
  [
56
- "report",
57
- {
58
- subject: "none",
59
- required: [],
60
- allowed: () => ["since", "json"],
61
- build: report,
62
- },
63
- ],
64
- [
65
- "watch",
66
- {
67
- subject: "none",
68
- required: [],
69
- allowed: () => ["port"],
70
- build: watch,
71
- },
64
+ "reload",
65
+ noSubjectShape(["json"], (request) => ({
66
+ kind: "reload",
67
+ json: given(request, "json"),
68
+ })),
72
69
  ],
70
+ ["watch", noSubjectShape(["port"], watch)],
73
71
  ]);
72
+ function noSubjectShape(allowed, build) {
73
+ return { subject: "none", required: [], allowed: () => allowed, build };
74
+ }
74
75
  export function isRuntimeCommand(command) {
75
- return command === "schedule" || shapes.has(command);
76
+ return command === "schedule" || command === "queue" || shapes.has(command);
76
77
  }
77
78
  export function runtimeInvocation(request) {
78
79
  const shape = shapes.get(request.command);
@@ -85,6 +86,8 @@ export function runtimeInvocation(request) {
85
86
  return { kind: "command-help", command: request.command };
86
87
  if (request.command === "schedule")
87
88
  return scheduleInvocation(request);
89
+ if (request.command === "queue")
90
+ return queueInvocation(request);
88
91
  if (shape === undefined)
89
92
  return "unknown-command";
90
93
  return shapeFailure(shape, request) ?? shape.build(request);
@@ -123,7 +126,7 @@ function runCommandShape(command) {
123
126
  }
124
127
  function statusOptions(request) {
125
128
  return request.positionals.length === 0
126
- ? ["limit", "after", "json"]
129
+ ? ["active", "limit", "after", "json"]
127
130
  : ["json"];
128
131
  }
129
132
  function eventOptions(request) {
@@ -197,8 +200,9 @@ function status(request) {
197
200
  const after = matching(valueOf(request, "after"), identifier);
198
201
  if (runId === invalid || limit === invalid || after === invalid)
199
202
  return "invalid-option-value";
203
+ const active = given(request, "active");
200
204
  const json = given(request, "json");
201
- return { kind: "status", runId, limit, after, json };
205
+ return { kind: "status", runId, limit, after, active, json };
202
206
  }
203
207
  function watch(request) {
204
208
  const port = whole(valueOf(request, "port"), { minimum: 0, maximum: 65535 });
@@ -1,5 +1,6 @@
1
1
  import type { ToolchainIdentity } from "../workflow-admission.ts";
2
2
  export declare const supportedNodes: string;
3
+ export declare const clovingVersion: string;
3
4
  export declare function supportedNode(version: string): boolean;
4
5
  export declare function observedToolchain(start: string): Promise<ToolchainIdentity>;
5
6
  export declare function qualifiedToolchain(observed: ToolchainIdentity, start: string): Promise<ToolchainIdentity>;
@@ -4,6 +4,7 @@ import { access, readFile, realpath } from "node:fs/promises";
4
4
  import { dirname, join } from "node:path";
5
5
  import packageMetadata from "#package" with { type: "json" };
6
6
  export const supportedNodes = packageMetadata.engines.node;
7
+ export const clovingVersion = packageMetadata.version;
7
8
  export function supportedNode(version) {
8
9
  const release = /^v(\d+)\.(\d+)\.(\d+)$/.exec(version);
9
10
  if (release === null)
@@ -1,5 +1,5 @@
1
- export declare const configUsage = "Usage: cloving config list [--json]\n cloving config get <field> [--json]\n cloving config set <field> <value> [--private] [--json]\n cloving config unset <field> [--private] [--json]\n\nReads and changes settings for the current repository; --repository selects another repository.\nValues use JSON when valid, otherwise text. Every change is checked before writing.\nFields use their default project or private file; --private selects the private file.\nlist and get show the effective source and hidden file values. Unconfigured values use defaults; null means no value.\nChanges keep the previous file as .bak and replace the file atomically under a lock.\nA live lock waits at most ten seconds, then exits with settings-locked.\nPrivate files, backups and temporary files have mode 0600. Changes require a service restart.\n";
1
+ export declare const configUsage = "Usage: cloving config list [--json]\n cloving config get <field> [--json]\n cloving config set <field> <value> [--private] [--json]\n cloving config unset <field> [--private] [--json]\n\nReads and changes settings for the current repository; --repository selects another repository.\nValues use JSON when valid, otherwise text. Every change is checked before writing.\nFields use their default project or private file; --private selects the private file.\nlist and get show the effective source and hidden file values. Unconfigured values use defaults; null means no value.\nChanges keep the previous file as .bak and replace the file atomically under a lock.\nA live lock waits at most ten seconds, then exits with settings-locked.\nPrivate files, backups and temporary files have mode 0600.\ncloving reload applies changes of profiles, fallbackModels, tokenPrices and workflows.folder. Other changes require a service restart.\n";
2
2
  export declare const commandUsage: Readonly<Record<string, string>>;
3
- export declare const usage = "Usage: cloving [--help] [--version]\n cloving workflows list [--json] [--repository <directory>]\n cloving workflows test [<id>] [--repository <directory>]\n cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n cloving init [--harness <name or path>] [--repository <directory>]\n cloving init-prompt [--repository <directory>]\n cloving templates list [--json]\n cloving templates show <name> [--json]\n cloving templates copy <name> [--id <workflow-id>] [--json] [--repository <directory>]\n cloving red-green\n cloving <command> [--help]\n\nCommands:\n workflows list List project and user workflows and refusal codes.\n workflows test Run project and user workflow tests without a service.\n workflows validate Check a compiled workflow manifest, its artifacts and optional runtime input.\n templates list List the workflow templates of the package.\n templates show Show the decision points and the files of one template.\n templates copy Copy one template into .cloving/workflows of the repository.\n red-green Check assertion failure on the base and success on the head.\n init Start the setup agent\n init-prompt Print setup instructions for an agent.\n doctor Check repository requirements before starting or submitting work.\n run Submit one run of an admitted workflow.\n status List the runs or show one run.\n mcp Serve the read tools over stdio.\n schedule List, pause and resume workflow schedules.\n report Report loop facts and seven-day baselines.\n questions List the pending decisions.\n answer Answer one design question.\n approve Approve one pending approval.\n deny Deny one pending approval.\n pause Stop new dispatch for a run.\n resume Resume a paused run.\n drop Cancel a run and keep its files.\n events Print the committed events.\n watch Serve a page that shows the runs live.\n phone Show, list, remove and reset the connected phones.\n config Read and change repository settings.\n start Start the service for a repository.\n\nThe runtime commands need a Cloving service. They use the current git repository; --repository <directory> selects another repository. CLOVING_RUNTIME_DIR overrides its runtime directory.\nUse npm exec -- cloving ... for a project-local installation.\n";
3
+ export declare const usage = "Usage: cloving [--help] [--version]\n cloving workflows list [--json] [--repository <directory>]\n cloving workflows test [<id>] [--repository <directory>]\n cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n cloving init [--harness <name or path>] [--repository <directory>]\n cloving init-prompt [--repository <directory>]\n cloving templates list [--json]\n cloving templates show <name> [--json]\n cloving templates copy <name> [--id <workflow-id>] [--json] [--repository <directory>]\n cloving red-green\n cloving <command> [--help]\n\nCommands:\n workflows list List project and user workflows and refusal codes.\n workflows test Run project and user workflow tests without a service.\n workflows validate Check a compiled workflow manifest, its artifacts and optional runtime input.\n templates list List the workflow templates of the package.\n templates show Show the decision points and the files of one template.\n templates copy Copy one template into .cloving/workflows of the repository.\n red-green Check assertion failure on the base and success on the head.\n init Start the setup agent\n init-prompt Print setup instructions for an agent.\n doctor Check repository requirements before starting or submitting work.\n run Submit one run of an admitted workflow.\n status List the runs or show one run.\n mcp Serve the Cloving tools over stdio.\n schedule List, pause and resume workflow schedules.\n queue Show, resume and drain the queue.\n report Report loop facts and seven-day baselines.\n questions List the pending decisions.\n answer Answer one design question.\n approve Approve one pending approval.\n deny Deny one pending approval.\n pause Stop new dispatch for a run.\n resume Resume a paused run.\n drop Cancel a run and keep its files.\n events Print the committed events.\n watch Serve a page that shows the runs live.\n reload Check and compile the workflow files again.\n phone Show, list, remove and reset the connected phones.\n config Read and change repository settings.\n start Start the service for a repository.\n\nThe runtime commands need a Cloving service. They use the current git repository; --repository <directory> selects another repository. CLOVING_RUNTIME_DIR overrides its runtime directory.\nUse npm exec -- cloving ... for a project-local installation.\n";
4
4
  export declare const validateUsage = "Usage: cloving workflows validate <manifest-path> [--input <json-file>] [--json]\n\nChecks a Cloving workflow manifest, its compiled SDK artifacts, declared resources and toolchain, and an optional runtime input file. Relative paths resolve against the current directory.\n\nOptions:\n --input <json-file> Validate this runtime input file.\n --json Print one versioned JSON result on stdout.\n\nValidation does not admit a run, dispatch effects, import workflow code or call a model.\n\nExample:\n cloving workflows validate cloving.workflow.json --input input.json\n";
5
5
  export declare const phoneUsage = "Usage: cloving phone status [--json]\n cloving phone list [--json]\n cloving phone remove <device-id> [--json]\n cloving phone reset [--json]\n\nShows and changes the phones that answer the questions of this computer.\nstatus shows the registration with cloving.ai and the number of phones.\nlist shows each phone with its device ID, name, platform, state and pairing time.\nremove marks one phone removed on this computer, then asks cloving.ai to remove it. A failure at cloving.ai keeps the phone removed and shows a warning.\nreset removes the registration with cloving.ai, marks all phones removed and deletes phone/link.json and phone/daemon-keys.json.\nConnect a phone with the Connect a phone button of the watch page.\ncloving start runs the phone relay as a child process. With CLOVING_PHONE_RELAY=off, the relay does not start, and status says that the relay is off or not started.\n";
@@ -10,12 +10,16 @@ Fields use their default project or private file; --private selects the private
10
10
  list and get show the effective source and hidden file values. Unconfigured values use defaults; null means no value.
11
11
  Changes keep the previous file as .bak and replace the file atomically under a lock.
12
12
  A live lock waits at most ten seconds, then exits with settings-locked.
13
- Private files, backups and temporary files have mode 0600. Changes require a service restart.
13
+ Private files, backups and temporary files have mode 0600.
14
+ cloving reload applies changes of profiles, fallbackModels, tokenPrices and workflows.folder. Other changes require a service restart.
14
15
  `;
15
16
  export const commandUsage = {
16
17
  mcp: `Usage: cloving mcp [--repository <directory>]
17
18
 
18
19
  Serves cloving_status, cloving_questions and cloving_events as read tools over stdio.
20
+ Serves cloving_run, cloving_answer, cloving_approve, cloving_deny, cloving_pause,
21
+ cloving_resume and cloving_drop to submit runs and decisions. Each of these tools
22
+ needs a commandId. After a lost reply, send the same commandId again.
19
23
  The server binds to one repository at startup. It needs an existing Cloving service.
20
24
  Standard output contains only JSON-RPC messages. Diagnostics use standard error.
21
25
  `,
@@ -41,6 +45,19 @@ Prints facts, rules and setup steps for an agent. Does not change settings, call
41
45
 
42
46
  Checks repository requirements without repairs, model turns or GitHub writes.
43
47
  Required failures or skipped prerequisites exit with status 1.
48
+ `,
49
+ queue: `Usage: cloving queue [--json]
50
+ cloving queue resume [--command-id <id>] [--json]
51
+ cloving queue drain [--command-id <id>] [--json]
52
+
53
+ Shows the state of the queue: running, stopped, draining or drained, with the busy lanes.
54
+ A stopped queue shows the reason and the failed runs in a row.
55
+ resume sets the failure count to 0 and ends a stop or a drain. The next queue check can start a run.
56
+ drain starts no new queue run. The runs in work continue to their end.
57
+ When no lane is busy, the queue records the drain time, writes "Queue drained" one time and shows drained.
58
+ A drained queue is a safe point for a restart. A drain stays in place after a restart.
59
+ The queue keeps the newest 32 command IDs. A repeated kept ID does not apply the command again.
60
+ The reply shows the current state. A different command with a kept ID is refused.
44
61
  `,
45
62
  report: `Usage: cloving report [--since <hours>] [--json]
46
63
 
@@ -55,9 +72,10 @@ With --ticket, the daemon reads the ticket at admission. A declared ticket field
55
72
  With --next (the same as --ticket next), ticket workflows select a ready ticket through CLOVING_NEXT_COMMAND.
56
73
  Success means a committed receipt. It does not mean completed work.
57
74
  `,
58
- status: `Usage: cloving status [<run-id>] [--limit <n>] [--after <cursor>] [--json]
75
+ status: `Usage: cloving status [<run-id>] [--active] [--limit <n>] [--after <cursor>] [--json]
59
76
 
60
77
  Lists the runs, or shows one run with its reason, evidence and next action.
78
+ With --active, lists only the runs that are not completed, failed or cancelled.
61
79
  `,
62
80
  schedule: `Usage: cloving schedule [--json]
63
81
  cloving schedule pause <workflowId> [--json]
@@ -100,6 +118,17 @@ Cancels the run and its pending dispatch. It keeps the workspace and the evidenc
100
118
  events: `Usage: cloving events [<run-id>] [--after <sequence>] [--limit <n>] [--follow] [--json]
101
119
 
102
120
  Prints the committed events after a sequence. With --json, each line is one event.
121
+ `,
122
+ reload: `Usage: cloving reload [--json]
123
+
124
+ Checks and compiles the workflow files again while the service runs.
125
+ New runs use the new bundle. A run that started before the reload stays on the bundle of its pin.
126
+ A new refusal of a workflow file keeps the current workflows and shows the reason.
127
+ A change of the queue workflow or of a schedule needs a restart.
128
+ It also reads the settings files and the profiles file again, and applies changes of profiles, fallbackModels, tokenPrices and workflows.folder.
129
+ New turns use the new values. A turn in work keeps the values of its start.
130
+ The reply lists each other changed field as a field that needs a restart. The service keeps its old value.
131
+ An invalid settings file, an invalid profiles file or a profile harness with no worker at the start refuses the reload. Then nothing changes.
103
132
  `,
104
133
  watch: `Usage: cloving watch [--port <n>]
105
134
 
@@ -116,7 +145,8 @@ Stop it with Control-C.
116
145
 
117
146
  The queue continues after unsuccessful runs and stops after three runs in a row
118
147
  without a successful handoff. A successful handoff resets the count; ordinary restarts preserve the count.
119
- Stop the service, inspect the failures and reconcile affected issues, then start with --reset-queue and the same queue settings to clear the failure streak once. Tracked commands are preserved.
148
+ Inspect the failures and reconcile affected issues. To clear the failure streak with no restart, run cloving queue resume.
149
+ Stop the service and start with --reset-queue and the same queue settings to clear the failure streak once at a restart; --reset-queue also ends a drain. Tracked commands are preserved.
120
150
 
121
151
  The command reads these settings from the environment:
122
152
  Settings files: .cloving/config.json in the repository and <config>/cloving/projects/<name>-<id>.json for private settings. Both require version 1. Precedence: environment, private, project, defaults. <config> is an absolute XDG_CONFIG_HOME or ~/.config. The start guide shows each configured field's source. See the packaged project-config.schema.json and private-config.schema.json in dist/src.
@@ -131,9 +161,12 @@ Settings files: .cloving/config.json in the repository and <config>/cloving/proj
131
161
  CLOVING_WORKFLOW_FOLDER An absolute folder path; when set, it replaces the user workflow folder. The private setting workflows.folder sets it. The folder itself must not be a symbolic link.
132
162
  CLOVING_SCHEDULES A JSON object mapping declared workflow IDs to {everySeconds, input}; replaces declaration schedules. Intervals are whole seconds from 60 to 86400. Unset keeps declaration schedules. Scheduled runs skip overlapping slots and retain their progress across restart.
133
163
  CLOVING_SELF_UPDATE_SECONDS A whole number from 30 to 3600 seconds between checks of the own checkout; unset means no update. An update stops the daemon and restarts with new code. A change of package-lock.json needs the operator to update and install by hand.
164
+ CLOVING_RETENTION_DAYS A whole number of at least 1, or null. The default is 30. The daemon archives or deletes a journal or GitHub record folder of a completed, failed or cancelled run when the end of the run and the newest file of the folder are older than this count of days. It never touches the records of a run that is not finished. The value null keeps all records. The daemon sweeps once at start, before the watch page starts, and then each hour, with at most 200 folders in each pass.
165
+ CLOVING_RETENTION_ACTION archive or delete. The default is archive. An archive keeps the relative path of the folder in the archive folder.
166
+ CLOVING_RETENTION_ARCHIVE_FOLDER An absolute folder path, or null for <state>/archive. The folder can be on another volume. When the folder is not available, the sweep moves nothing, logs the reason and tries again in the next hour.
134
167
  CLOVING_GROK_COMMAND A JSON list of a command and its arguments for Grok. The default uses streaming-messages-json, --always-approve and -p; the turn text follows -p or --single as one argument, or is appended if neither flag is present.
135
168
  CLOVING_CLAUDE_COMMAND A JSON list of a command and its arguments for the Claude worker. The default is the claude command with a limit of 5 USD for each turn.
136
- CLOVING_PROFILES The path of a JSON file of operator-defined Claude turn profiles, read once at start. The setting has no default.
169
+ CLOVING_PROFILES The path of a JSON file of operator-defined Claude turn profiles, read at start and at each cloving reload. A relative path starts at the folder of cloving start. The setting has no default.
137
170
  CLOVING_COMMANDS A JSON object mapping names to argument arrays with an absolute executable path. Invalid values refuse startup with invalid-commands. Unset means no commands. Command execution is not available yet.
138
171
  CLOVING_COMMAND_SECONDS A whole number from 1 to 3600 seconds; the default is 60. Invalid values refuse startup with invalid-command-seconds. Reserved for command execution.
139
172
  CLOVING_TOKEN_PRICES A JSON object from model names to input, cachedInput and output USD prices per million tokens for estimates; entries override matching built-in prices.
@@ -181,8 +214,9 @@ Commands:
181
214
  doctor Check repository requirements before starting or submitting work.
182
215
  run Submit one run of an admitted workflow.
183
216
  status List the runs or show one run.
184
- mcp Serve the read tools over stdio.
217
+ mcp Serve the Cloving tools over stdio.
185
218
  schedule List, pause and resume workflow schedules.
219
+ queue Show, resume and drain the queue.
186
220
  report Report loop facts and seven-day baselines.
187
221
  questions List the pending decisions.
188
222
  answer Answer one design question.
@@ -193,6 +227,7 @@ Commands:
193
227
  drop Cancel a run and keep its files.
194
228
  events Print the committed events.
195
229
  watch Serve a page that shows the runs live.
230
+ reload Check and compile the workflow files again.
196
231
  phone Show, list, remove and reset the connected phones.
197
232
  config Read and change repository settings.
198
233
  start Start the service for a repository.