@cluesmith/codev 3.3.4 → 3.3.6

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 (290) hide show
  1. package/dashboard-dist/assets/index-BjcqV9Vv.css +32 -0
  2. package/dashboard-dist/assets/index-b7GnZV2i.js +220 -0
  3. package/dashboard-dist/assets/index-b7GnZV2i.js.map +1 -0
  4. package/dashboard-dist/index.html +2 -2
  5. package/dist/agent-farm/cli.d.ts.map +1 -1
  6. package/dist/agent-farm/cli.js +50 -17
  7. package/dist/agent-farm/cli.js.map +1 -1
  8. package/dist/agent-farm/commands/architect.d.ts.map +1 -1
  9. package/dist/agent-farm/commands/architect.js +5 -1
  10. package/dist/agent-farm/commands/architect.js.map +1 -1
  11. package/dist/agent-farm/commands/attach.d.ts +1 -1
  12. package/dist/agent-farm/commands/attach.d.ts.map +1 -1
  13. package/dist/agent-farm/commands/cleanup.d.ts +1 -1
  14. package/dist/agent-farm/commands/cleanup.d.ts.map +1 -1
  15. package/dist/agent-farm/commands/cleanup.js +2 -1
  16. package/dist/agent-farm/commands/cleanup.js.map +1 -1
  17. package/dist/agent-farm/commands/decisions.d.ts +25 -0
  18. package/dist/agent-farm/commands/decisions.d.ts.map +1 -0
  19. package/dist/agent-farm/commands/decisions.js +54 -0
  20. package/dist/agent-farm/commands/decisions.js.map +1 -0
  21. package/dist/agent-farm/commands/ide.d.ts +32 -3
  22. package/dist/agent-farm/commands/ide.d.ts.map +1 -1
  23. package/dist/agent-farm/commands/ide.js +180 -19
  24. package/dist/agent-farm/commands/ide.js.map +1 -1
  25. package/dist/agent-farm/commands/reset/context.d.ts +4 -2
  26. package/dist/agent-farm/commands/reset/context.d.ts.map +1 -1
  27. package/dist/agent-farm/commands/reset/context.js +12 -4
  28. package/dist/agent-farm/commands/reset/context.js.map +1 -1
  29. package/dist/agent-farm/commands/send.d.ts +3 -2
  30. package/dist/agent-farm/commands/send.d.ts.map +1 -1
  31. package/dist/agent-farm/commands/send.js +35 -21
  32. package/dist/agent-farm/commands/send.js.map +1 -1
  33. package/dist/agent-farm/commands/spawn-worktree.d.ts +7 -0
  34. package/dist/agent-farm/commands/spawn-worktree.d.ts.map +1 -1
  35. package/dist/agent-farm/commands/spawn-worktree.js +63 -20
  36. package/dist/agent-farm/commands/spawn-worktree.js.map +1 -1
  37. package/dist/agent-farm/commands/spawn.d.ts +17 -0
  38. package/dist/agent-farm/commands/spawn.d.ts.map +1 -1
  39. package/dist/agent-farm/commands/spawn.js +41 -19
  40. package/dist/agent-farm/commands/spawn.js.map +1 -1
  41. package/dist/agent-farm/lib/builder-lookup.d.ts +3 -2
  42. package/dist/agent-farm/lib/builder-lookup.d.ts.map +1 -1
  43. package/dist/agent-farm/lib/builder-lookup.js +24 -9
  44. package/dist/agent-farm/lib/builder-lookup.js.map +1 -1
  45. package/dist/agent-farm/lib/ide-extensions.d.ts +82 -0
  46. package/dist/agent-farm/lib/ide-extensions.d.ts.map +1 -0
  47. package/dist/agent-farm/lib/ide-extensions.js +179 -0
  48. package/dist/agent-farm/lib/ide-extensions.js.map +1 -0
  49. package/dist/agent-farm/lib/ide-record.d.ts +6 -1
  50. package/dist/agent-farm/lib/ide-record.d.ts.map +1 -1
  51. package/dist/agent-farm/lib/ide-record.js +8 -1
  52. package/dist/agent-farm/lib/ide-record.js.map +1 -1
  53. package/dist/agent-farm/lib/ide-version.d.ts +97 -0
  54. package/dist/agent-farm/lib/ide-version.d.ts.map +1 -0
  55. package/dist/agent-farm/lib/ide-version.js +224 -0
  56. package/dist/agent-farm/lib/ide-version.js.map +1 -0
  57. package/dist/agent-farm/lib/tunnel-client.d.ts.map +1 -1
  58. package/dist/agent-farm/lib/tunnel-client.js +7 -3
  59. package/dist/agent-farm/lib/tunnel-client.js.map +1 -1
  60. package/dist/agent-farm/servers/agent-state/broadcast.d.ts +19 -0
  61. package/dist/agent-farm/servers/agent-state/broadcast.d.ts.map +1 -0
  62. package/dist/agent-farm/servers/agent-state/broadcast.js +30 -0
  63. package/dist/agent-farm/servers/agent-state/broadcast.js.map +1 -0
  64. package/dist/agent-farm/servers/agent-state/identity.d.ts +50 -0
  65. package/dist/agent-farm/servers/agent-state/identity.d.ts.map +1 -0
  66. package/dist/agent-farm/servers/agent-state/identity.js +120 -0
  67. package/dist/agent-farm/servers/agent-state/identity.js.map +1 -0
  68. package/dist/agent-farm/servers/agent-state/liveness.d.ts +107 -0
  69. package/dist/agent-farm/servers/agent-state/liveness.d.ts.map +1 -0
  70. package/dist/agent-farm/servers/agent-state/liveness.js +224 -0
  71. package/dist/agent-farm/servers/agent-state/liveness.js.map +1 -0
  72. package/dist/agent-farm/servers/agent-state/route.d.ts +38 -0
  73. package/dist/agent-farm/servers/agent-state/route.d.ts.map +1 -0
  74. package/dist/agent-farm/servers/agent-state/route.js +170 -0
  75. package/dist/agent-farm/servers/agent-state/route.js.map +1 -0
  76. package/dist/agent-farm/servers/agent-state/serve.d.ts +31 -0
  77. package/dist/agent-farm/servers/agent-state/serve.d.ts.map +1 -0
  78. package/dist/agent-farm/servers/agent-state/serve.js +49 -0
  79. package/dist/agent-farm/servers/agent-state/serve.js.map +1 -0
  80. package/dist/agent-farm/servers/agent-state/store.d.ts +76 -0
  81. package/dist/agent-farm/servers/agent-state/store.d.ts.map +1 -0
  82. package/dist/agent-farm/servers/agent-state/store.js +157 -0
  83. package/dist/agent-farm/servers/agent-state/store.js.map +1 -0
  84. package/dist/agent-farm/servers/decisions/file.d.ts +50 -0
  85. package/dist/agent-farm/servers/decisions/file.d.ts.map +1 -0
  86. package/dist/agent-farm/servers/decisions/file.js +146 -0
  87. package/dist/agent-farm/servers/decisions/file.js.map +1 -0
  88. package/dist/agent-farm/servers/decisions/grammar.d.ts +36 -0
  89. package/dist/agent-farm/servers/decisions/grammar.d.ts.map +1 -0
  90. package/dist/agent-farm/servers/decisions/grammar.js +109 -0
  91. package/dist/agent-farm/servers/decisions/grammar.js.map +1 -0
  92. package/dist/agent-farm/servers/decisions/notice.d.ts +11 -0
  93. package/dist/agent-farm/servers/decisions/notice.d.ts.map +1 -0
  94. package/dist/agent-farm/servers/decisions/notice.js +18 -0
  95. package/dist/agent-farm/servers/decisions/notice.js.map +1 -0
  96. package/dist/agent-farm/servers/decisions/parse.d.ts +36 -0
  97. package/dist/agent-farm/servers/decisions/parse.d.ts.map +1 -0
  98. package/dist/agent-farm/servers/decisions/parse.js +338 -0
  99. package/dist/agent-farm/servers/decisions/parse.js.map +1 -0
  100. package/dist/agent-farm/servers/decisions/routes.d.ts +17 -0
  101. package/dist/agent-farm/servers/decisions/routes.d.ts.map +1 -0
  102. package/dist/agent-farm/servers/decisions/routes.js +160 -0
  103. package/dist/agent-farm/servers/decisions/routes.js.map +1 -0
  104. package/dist/agent-farm/servers/decisions/splice.d.ts +26 -0
  105. package/dist/agent-farm/servers/decisions/splice.d.ts.map +1 -0
  106. package/dist/agent-farm/servers/decisions/splice.js +120 -0
  107. package/dist/agent-farm/servers/decisions/splice.js.map +1 -0
  108. package/dist/agent-farm/servers/decisions/stamp.d.ts +8 -0
  109. package/dist/agent-farm/servers/decisions/stamp.d.ts.map +1 -0
  110. package/dist/agent-farm/servers/decisions/stamp.js +195 -0
  111. package/dist/agent-farm/servers/decisions/stamp.js.map +1 -0
  112. package/dist/agent-farm/servers/decisions/template.d.ts +2 -0
  113. package/dist/agent-farm/servers/decisions/template.d.ts.map +1 -0
  114. package/dist/agent-farm/servers/decisions/template.js +15 -0
  115. package/dist/agent-farm/servers/decisions/template.js.map +1 -0
  116. package/dist/agent-farm/servers/ide-server.d.ts +28 -8
  117. package/dist/agent-farm/servers/ide-server.d.ts.map +1 -1
  118. package/dist/agent-farm/servers/ide-server.js +147 -50
  119. package/dist/agent-farm/servers/ide-server.js.map +1 -1
  120. package/dist/agent-farm/servers/overview.d.ts +31 -4
  121. package/dist/agent-farm/servers/overview.d.ts.map +1 -1
  122. package/dist/agent-farm/servers/overview.js +235 -55
  123. package/dist/agent-farm/servers/overview.js.map +1 -1
  124. package/dist/agent-farm/servers/tower-instances.d.ts +14 -1
  125. package/dist/agent-farm/servers/tower-instances.d.ts.map +1 -1
  126. package/dist/agent-farm/servers/tower-instances.js +51 -9
  127. package/dist/agent-farm/servers/tower-instances.js.map +1 -1
  128. package/dist/agent-farm/servers/tower-routes.d.ts.map +1 -1
  129. package/dist/agent-farm/servers/tower-routes.js +113 -14
  130. package/dist/agent-farm/servers/tower-routes.js.map +1 -1
  131. package/dist/agent-farm/servers/tower-server.js +35 -1
  132. package/dist/agent-farm/servers/tower-server.js.map +1 -1
  133. package/dist/agent-farm/servers/tower-terminals.d.ts +25 -0
  134. package/dist/agent-farm/servers/tower-terminals.d.ts.map +1 -1
  135. package/dist/agent-farm/servers/tower-terminals.js +128 -4
  136. package/dist/agent-farm/servers/tower-terminals.js.map +1 -1
  137. package/dist/agent-farm/servers/tower-utils.d.ts.map +1 -1
  138. package/dist/agent-farm/servers/tower-utils.js +18 -5
  139. package/dist/agent-farm/servers/tower-utils.js.map +1 -1
  140. package/dist/agent-farm/utils/builder-worktree-identity.d.ts +39 -0
  141. package/dist/agent-farm/utils/builder-worktree-identity.d.ts.map +1 -0
  142. package/dist/agent-farm/utils/builder-worktree-identity.js +42 -0
  143. package/dist/agent-farm/utils/builder-worktree-identity.js.map +1 -0
  144. package/dist/agent-farm/utils/harness.d.ts +71 -0
  145. package/dist/agent-farm/utils/harness.d.ts.map +1 -1
  146. package/dist/agent-farm/utils/harness.js +153 -0
  147. package/dist/agent-farm/utils/harness.js.map +1 -1
  148. package/dist/agent-farm/utils/lifecycle-reporter.d.ts +79 -0
  149. package/dist/agent-farm/utils/lifecycle-reporter.d.ts.map +1 -0
  150. package/dist/agent-farm/utils/lifecycle-reporter.js +347 -0
  151. package/dist/agent-farm/utils/lifecycle-reporter.js.map +1 -0
  152. package/dist/agent-farm/utils/message-format.d.ts +8 -0
  153. package/dist/agent-farm/utils/message-format.d.ts.map +1 -1
  154. package/dist/agent-farm/utils/message-format.js +16 -0
  155. package/dist/agent-farm/utils/message-format.js.map +1 -1
  156. package/dist/cli.d.ts.map +1 -1
  157. package/dist/cli.js +17 -0
  158. package/dist/cli.js.map +1 -1
  159. package/dist/commands/adopt.d.ts +16 -2
  160. package/dist/commands/adopt.d.ts.map +1 -1
  161. package/dist/commands/adopt.js +67 -23
  162. package/dist/commands/adopt.js.map +1 -1
  163. package/dist/commands/bootstrap-docs.d.ts +132 -0
  164. package/dist/commands/bootstrap-docs.d.ts.map +1 -0
  165. package/dist/commands/bootstrap-docs.js +725 -0
  166. package/dist/commands/bootstrap-docs.js.map +1 -0
  167. package/dist/commands/consult/index.d.ts +20 -1
  168. package/dist/commands/consult/index.d.ts.map +1 -1
  169. package/dist/commands/consult/index.js +70 -3
  170. package/dist/commands/consult/index.js.map +1 -1
  171. package/dist/commands/consult/tree-tripwire.d.ts +2 -75
  172. package/dist/commands/consult/tree-tripwire.d.ts.map +1 -1
  173. package/dist/commands/consult/tree-tripwire.js +7 -184
  174. package/dist/commands/consult/tree-tripwire.js.map +1 -1
  175. package/dist/commands/doctor.d.ts.map +1 -1
  176. package/dist/commands/doctor.js +36 -4
  177. package/dist/commands/doctor.js.map +1 -1
  178. package/dist/commands/porch/checks.d.ts +7 -1
  179. package/dist/commands/porch/checks.d.ts.map +1 -1
  180. package/dist/commands/porch/checks.js +77 -14
  181. package/dist/commands/porch/checks.js.map +1 -1
  182. package/dist/commands/porch/index.d.ts +38 -1
  183. package/dist/commands/porch/index.d.ts.map +1 -1
  184. package/dist/commands/porch/index.js +79 -43
  185. package/dist/commands/porch/index.js.map +1 -1
  186. package/dist/commands/porch/protocol.d.ts +4 -3
  187. package/dist/commands/porch/protocol.d.ts.map +1 -1
  188. package/dist/commands/porch/protocol.js +32 -5
  189. package/dist/commands/porch/protocol.js.map +1 -1
  190. package/dist/commands/porch/state.d.ts +0 -4
  191. package/dist/commands/porch/state.d.ts.map +1 -1
  192. package/dist/commands/porch/state.js +23 -10
  193. package/dist/commands/porch/state.js.map +1 -1
  194. package/dist/commands/porch/types.d.ts +2 -0
  195. package/dist/commands/porch/types.d.ts.map +1 -1
  196. package/dist/commands/update.d.ts +5 -1
  197. package/dist/commands/update.d.ts.map +1 -1
  198. package/dist/commands/update.js +73 -18
  199. package/dist/commands/update.js.map +1 -1
  200. package/dist/lib/agent-env.d.ts +31 -1
  201. package/dist/lib/agent-env.d.ts.map +1 -1
  202. package/dist/lib/agent-env.js +38 -1
  203. package/dist/lib/agent-env.js.map +1 -1
  204. package/dist/lib/agent-process.d.ts +23 -0
  205. package/dist/lib/agent-process.d.ts.map +1 -0
  206. package/dist/lib/agent-process.js +24 -0
  207. package/dist/lib/agent-process.js.map +1 -0
  208. package/dist/lib/config.d.ts +8 -0
  209. package/dist/lib/config.d.ts.map +1 -1
  210. package/dist/lib/config.js.map +1 -1
  211. package/dist/lib/forge-contracts.d.ts +9 -3
  212. package/dist/lib/forge-contracts.d.ts.map +1 -1
  213. package/dist/lib/forge-contracts.js.map +1 -1
  214. package/dist/lib/forge.d.ts +8 -5
  215. package/dist/lib/forge.d.ts.map +1 -1
  216. package/dist/lib/forge.js +57 -1
  217. package/dist/lib/forge.js.map +1 -1
  218. package/dist/lib/github.d.ts.map +1 -1
  219. package/dist/lib/github.js +38 -0
  220. package/dist/lib/github.js.map +1 -1
  221. package/dist/lib/governance-bootstrap.d.ts +155 -0
  222. package/dist/lib/governance-bootstrap.d.ts.map +1 -0
  223. package/dist/lib/governance-bootstrap.js +469 -0
  224. package/dist/lib/governance-bootstrap.js.map +1 -0
  225. package/dist/lib/issue-id.d.ts +34 -0
  226. package/dist/lib/issue-id.d.ts.map +1 -0
  227. package/dist/lib/issue-id.js +61 -0
  228. package/dist/lib/issue-id.js.map +1 -0
  229. package/dist/lib/scaffold.d.ts +4 -0
  230. package/dist/lib/scaffold.d.ts.map +1 -1
  231. package/dist/lib/scaffold.js +29 -5
  232. package/dist/lib/scaffold.js.map +1 -1
  233. package/dist/lib/shipped-skill-hashes.d.ts +10 -0
  234. package/dist/lib/shipped-skill-hashes.d.ts.map +1 -0
  235. package/dist/lib/shipped-skill-hashes.js +197 -0
  236. package/dist/lib/shipped-skill-hashes.js.map +1 -0
  237. package/dist/lib/skill-refresh.d.ts +90 -0
  238. package/dist/lib/skill-refresh.d.ts.map +1 -0
  239. package/dist/lib/skill-refresh.js +267 -0
  240. package/dist/lib/skill-refresh.js.map +1 -0
  241. package/dist/lib/tree-snapshot.d.ts +172 -0
  242. package/dist/lib/tree-snapshot.d.ts.map +1 -0
  243. package/dist/lib/tree-snapshot.js +393 -0
  244. package/dist/lib/tree-snapshot.js.map +1 -0
  245. package/dist/terminal/pty-session.d.ts +5 -0
  246. package/dist/terminal/pty-session.d.ts.map +1 -1
  247. package/dist/terminal/pty-session.js +7 -0
  248. package/dist/terminal/pty-session.js.map +1 -1
  249. package/ide-extension/codev-vscode.vsix +0 -0
  250. package/ide-extension/manifest.json +7 -0
  251. package/package.json +8 -6
  252. package/scripts/forge/jira/_lib.sh +113 -0
  253. package/scripts/forge/jira/auth-status.sh +29 -0
  254. package/scripts/forge/jira/issue-comment.sh +23 -0
  255. package/scripts/forge/jira/issue-list.sh +32 -0
  256. package/scripts/forge/jira/issue-search.sh +40 -0
  257. package/scripts/forge/jira/issue-view.sh +41 -0
  258. package/scripts/forge/jira/recently-closed.sh +81 -0
  259. package/scripts/forge/jira/user-identity.sh +18 -0
  260. package/skeleton/.claude/skills/afx/SKILL.md +51 -0
  261. package/skeleton/.claude/skills/arch-init/SKILL.md +56 -9
  262. package/skeleton/.claude/skills/arch-save/SKILL.md +100 -9
  263. package/skeleton/.claude/skills/codev/SKILL.md +18 -2
  264. package/skeleton/.claude/skills/consult/SKILL.md +9 -0
  265. package/skeleton/.claude/skills/porch/SKILL.md +18 -0
  266. package/skeleton/.claude/skills/update-arch-docs/SKILL.md +28 -2
  267. package/skeleton/.codex/skills/afx/SKILL.md +51 -0
  268. package/skeleton/.codex/skills/arch-init/SKILL.md +56 -9
  269. package/skeleton/.codex/skills/arch-save/SKILL.md +100 -9
  270. package/skeleton/.codex/skills/codev/SKILL.md +18 -2
  271. package/skeleton/.codex/skills/consult/SKILL.md +9 -0
  272. package/skeleton/.codex/skills/porch/SKILL.md +18 -0
  273. package/skeleton/.codex/skills/update-arch-docs/SKILL.md +28 -2
  274. package/skeleton/protocol-schema.json +6 -0
  275. package/skeleton/protocols/maintain/protocol.md +5 -0
  276. package/skeleton/protocols/pir/prompts/review.md +0 -1
  277. package/skeleton/protocols/protocol-schema.json +6 -0
  278. package/skeleton/resources/commands/agent-farm.md +156 -0
  279. package/skeleton/resources/commands/codev.md +47 -0
  280. package/skeleton/resources/commands/consult.md +9 -2
  281. package/skeleton/resources/commands/overview.md +1 -0
  282. package/skeleton/resources/decision-protocol.md +215 -0
  283. package/skeleton/resources/workflow-reference.md +12 -0
  284. package/skeleton/roles/architect.md +6 -0
  285. package/skeleton/templates/bootstrap-docs-prompt.md +16 -0
  286. package/skeleton/templates/bootstrap-docs-review-prompt.md +19 -0
  287. package/skeleton/templates/cheatsheet.md +2 -1
  288. package/dashboard-dist/assets/index-DZf6pNPE.js +0 -199
  289. package/dashboard-dist/assets/index-DZf6pNPE.js.map +0 -1
  290. package/dashboard-dist/assets/index-DnYLy5C_.css +0 -32
@@ -0,0 +1,338 @@
1
+ // Decisions file parser (Spec 1819).
2
+ //
3
+ // A function from the decisions file's text, and the clock, to its read model. The
4
+ // file is the only state: this runs on every read, nothing is cached. The clock
5
+ // enters only through time-only stamps, which are read as today in their zone
6
+ // (#1836), so the same text can parse to different instants on different days:
7
+ // - `version` (the client's cache key) hashes the text alone and does not cover
8
+ // that: a client keeps the instants it has until the file changes.
9
+ // - `splice.ts`'s `verify()` re-parses at a later moment than the parse it checks
10
+ // against; it is safe only because it compares no stamps.
11
+ // Structure comes from `grammar.ts`; this module adds the format's conventions:
12
+ // - `## Open` / `## Ruled` sections; items are `###` headings inside `## Open`,
13
+ // running to the next heading of level 1–3 (or end of file).
14
+ // - item id = the heading's first token; ` · ` separates id, stamp and question. A first
15
+ // part that is not a stamp belongs to the question.
16
+ // - a `_Zone: <zone>_` line in the header (above the first `##`) is the zone of every
17
+ // stamp that names none.
18
+ // - options = backticked words on the `**Your word:**` line, first recommended; an
19
+ // option with no `= …` there takes its description from the body's `**Options:**`.
20
+ // - current ruling = everything after the `**Your word:**` line, verbatim.
21
+ // - `- **You asked (t):**` / `- **<Name>'s answer (t):**` body entries form the
22
+ // item's question-and-answer thread.
23
+ // Malformed input is reported as problems, never guessed at.
24
+ import { createHash } from 'node:crypto';
25
+ import { YOUR_WORD_LABEL, classifyLines, detectLineEnding } from './grammar.js';
26
+ import { resolveStamp } from './stamp.js';
27
+ const SEPARATOR = ' · ';
28
+ const ZONE_LINE_RE = /^ {0,3}_Zone:[ \t]*(\S+?)\.?_[ \t]*$/;
29
+ const ASKED_RE = /^ {0,3}- \*\*You asked \(([^)]*)\):\*\*[ \t]*(.*)$/;
30
+ const ANSWER_RE = /^ {0,3}- \*\*(.+?)['’]s answer \(([^)]*)\):\*\*[ \t]*(.*)$/;
31
+ const CONTINUATION_INDENT_RE = /^(?: {2}|\t)/;
32
+ const LEADING_SPAN_RE = /^`([^`\n]+)`/;
33
+ const OPTIONS_LABEL = '**Options:**';
34
+ // An entry of a body `**Options:**` list: a backticked word after an `(a)`-style marker
35
+ // (anywhere, after whitespace) or after a list marker at the start of a line.
36
+ const OPTION_ENTRY_RE = /(?:^[ \t]*[-*+][ \t]+|(?<!\S)\([A-Za-z0-9]{1,3}\)[ \t]*)`([^`\n]+)`/gm;
37
+ const OPTION_ENTRY_START_RE = /^[ \t]*(?:[-*+][ \t]+|\([A-Za-z0-9]{1,3}\)[ \t]*)`/;
38
+ function sha256(text) {
39
+ return createHash('sha256').update(text, 'utf8').digest('hex');
40
+ }
41
+ /**
42
+ * Join line contents with '\n', dropping leading and trailing blank lines. The result
43
+ * is LF-normalized whatever the file's line ending, so compare it with LF text.
44
+ */
45
+ function joinTrimmed(lines) {
46
+ let from = 0;
47
+ let to = lines.length;
48
+ while (from < to && lines[from].text.trim() === '')
49
+ from++;
50
+ while (to > from && lines[to - 1].text.trim() === '')
51
+ to--;
52
+ return lines.slice(from, to).map(l => l.text).join('\n');
53
+ }
54
+ /**
55
+ * The file's zone: the one `_Zone: <zone>_` line above the first `##` heading. None, or
56
+ * more than one, gives no file zone.
57
+ */
58
+ function fileZone(lines) {
59
+ const zones = [];
60
+ for (const line of lines) {
61
+ if (line.headingLevel >= 2)
62
+ break;
63
+ const zone = line.fenced ? null : ZONE_LINE_RE.exec(line.text);
64
+ if (zone)
65
+ zones.push(zone[1]);
66
+ }
67
+ return zones.length === 1 ? zones[0] : null;
68
+ }
69
+ /**
70
+ * Split a heading's text into id, stamp and question: the first token is the id; after a
71
+ * ` · `, the first part is the stamp and the rest (re-joined) the question. A heading
72
+ * without separators, or whose first part is not a stamp, has a question and no stamp.
73
+ */
74
+ function splitHeading(headingText, zone) {
75
+ const id = headingText.split(/\s+/)[0] ?? '';
76
+ const rest = headingText.slice(id.length);
77
+ if (!rest.startsWith(SEPARATOR))
78
+ return { id, stamp: null, question: rest.trim() };
79
+ const afterId = rest.slice(SEPARATOR.length);
80
+ const [stampText, ...questionParts] = afterId.split(SEPARATOR);
81
+ const stamp = resolveStamp(stampText.trim(), zone);
82
+ if (!stamp)
83
+ return { id, stamp: null, question: afterId.trim() };
84
+ return { id, stamp, question: questionParts.join(SEPARATOR).trim() };
85
+ }
86
+ /**
87
+ * Options from a `**Your word:**` line. An option starts at a backticked span at the
88
+ * start of the text after the label, or at a backticked span immediately preceded by
89
+ * ` / `. Its description is the text after its `=`, if any, up to the next ` / ` that
90
+ * is followed by a backtick, or end of line. Any other ` / ` is part of the
91
+ * description. Text that is not an option, or not after an `=`, is not read.
92
+ */
93
+ export function parseOptions(yourWordLineText) {
94
+ const labelAt = yourWordLineText.indexOf(YOUR_WORD_LABEL);
95
+ if (labelAt === -1)
96
+ return [];
97
+ const rest = yourWordLineText.slice(labelAt + YOUR_WORD_LABEL.length).trim();
98
+ const starts = [0];
99
+ for (let i = rest.indexOf(' / `'); i !== -1; i = rest.indexOf(' / `', i + 1)) {
100
+ starts.push(i + ' / '.length);
101
+ }
102
+ const options = [];
103
+ for (let k = 0; k < starts.length; k++) {
104
+ const segmentEnd = k + 1 < starts.length ? starts[k + 1] - ' / '.length : rest.length;
105
+ const segment = rest.slice(starts[k], segmentEnd);
106
+ const span = LEADING_SPAN_RE.exec(segment);
107
+ if (!span)
108
+ continue;
109
+ const word = span[1].trim();
110
+ if (!word)
111
+ continue;
112
+ const after = segment.slice(span[0].length).trim();
113
+ const description = after.startsWith('=') ? after.slice(1).trim() : '';
114
+ options.push({ word, description, recommended: options.length === 0 });
115
+ }
116
+ return options;
117
+ }
118
+ /**
119
+ * Descriptions from an item body's `**Options:**` entries, by word: `(a) `word` = …` or
120
+ * `(a) `word`: …` after the label, or `- `word` = …` list items under it. The entries run
121
+ * from the label to a blank line (unless an entry follows it), a heading, a fence, or a
122
+ * line that is neither indented nor an entry. An entry without `=` or `:` gives none; the
123
+ * first description for a word wins.
124
+ */
125
+ function bodyOptionDescriptions(bodyLines) {
126
+ const descriptions = new Map();
127
+ const startsEntry = (line) => !!line && !line.fenced && line.headingLevel === 0 && OPTION_ENTRY_START_RE.test(line.text);
128
+ for (let i = 0; i < bodyLines.length; i++) {
129
+ const labelAt = bodyLines[i].fenced ? -1 : bodyLines[i].text.indexOf(OPTIONS_LABEL);
130
+ if (labelAt === -1)
131
+ continue;
132
+ const block = [bodyLines[i].text.slice(labelAt + OPTIONS_LABEL.length)];
133
+ let j = i + 1;
134
+ for (; j < bodyLines.length; j++) {
135
+ const next = bodyLines[j];
136
+ if (next.fenced || next.headingLevel > 0)
137
+ break;
138
+ if (next.text.trim() === '') {
139
+ if (startsEntry(bodyLines[j + 1]))
140
+ continue;
141
+ break;
142
+ }
143
+ if (!CONTINUATION_INDENT_RE.test(next.text) && !startsEntry(next))
144
+ break;
145
+ block.push(next.text);
146
+ }
147
+ i = j - 1;
148
+ const text = block.join('\n');
149
+ const entries = [...text.matchAll(OPTION_ENTRY_RE)];
150
+ entries.forEach((entry, k) => {
151
+ const word = entry[1].trim();
152
+ const to = k + 1 < entries.length ? entries[k + 1].index : text.length;
153
+ const after = text.slice(entry.index + entry[0].length, to).trim();
154
+ if (!word || !(after.startsWith('=') || after.startsWith(':')))
155
+ return;
156
+ const description = after.slice(1).replace(/\s+/g, ' ').replace(/[;,]$/, '').trim();
157
+ if (description && !descriptions.has(word))
158
+ descriptions.set(word, description);
159
+ });
160
+ }
161
+ return descriptions;
162
+ }
163
+ /** Separate Q&A entries from the rest of an item's body lines. */
164
+ function extractQa(bodyLines) {
165
+ const qa = [];
166
+ const rest = [];
167
+ for (let i = 0; i < bodyLines.length; i++) {
168
+ const line = bodyLines[i];
169
+ const asked = line.fenced ? null : ASKED_RE.exec(line.text);
170
+ const answer = line.fenced || asked ? null : ANSWER_RE.exec(line.text);
171
+ if (!asked && !answer) {
172
+ rest.push(line);
173
+ continue;
174
+ }
175
+ // Continuation: the following indented (2+ spaces or a tab), non-blank, unfenced
176
+ // lines that are neither headings nor the start of another entry.
177
+ const parts = [asked ? asked[2] : answer[3]];
178
+ while (i + 1 < bodyLines.length) {
179
+ const next = bodyLines[i + 1];
180
+ const continues = !next.fenced &&
181
+ next.headingLevel === 0 &&
182
+ next.text.trim() !== '' &&
183
+ CONTINUATION_INDENT_RE.test(next.text) &&
184
+ !ASKED_RE.test(next.text) &&
185
+ !ANSWER_RE.test(next.text);
186
+ if (!continues)
187
+ break;
188
+ parts.push(next.text.trim());
189
+ i++;
190
+ }
191
+ const markdown = parts.join('\n').trim();
192
+ if (asked) {
193
+ qa.push({ kind: 'asked', time: asked[1].trim(), markdown, answered: false });
194
+ }
195
+ else {
196
+ qa.push({ kind: 'answer', name: answer[1].trim(), time: answer[2].trim(), markdown });
197
+ }
198
+ }
199
+ // A question is answered when an answer follows it before the next question.
200
+ for (let i = 0; i < qa.length; i++) {
201
+ const entry = qa[i];
202
+ if (entry.kind !== 'asked')
203
+ continue;
204
+ for (let j = i + 1; j < qa.length && qa[j].kind !== 'asked'; j++) {
205
+ if (qa[j].kind === 'answer') {
206
+ entry.answered = true;
207
+ break;
208
+ }
209
+ }
210
+ }
211
+ return { qa, rest };
212
+ }
213
+ /** Parse the decisions file's text into its read model. */
214
+ export function parseDecisions(text) {
215
+ const lines = classifyLines(text);
216
+ const problems = [];
217
+ // Level-2 sections: each runs to the next heading of level 1–2.
218
+ const sectionEnd = (headingLine) => {
219
+ for (let i = headingLine + 1; i < lines.length; i++) {
220
+ if (lines[i].headingLevel >= 1 && lines[i].headingLevel <= 2)
221
+ return i;
222
+ }
223
+ return lines.length;
224
+ };
225
+ const openHeadings = lines.filter(l => l.headingLevel === 2 && l.headingText === 'Open');
226
+ const ruledHeadings = lines.filter(l => l.headingLevel === 2 && l.headingText === 'Ruled');
227
+ if (openHeadings.length === 0)
228
+ problems.push('open-missing');
229
+ if (openHeadings.length > 1)
230
+ problems.push('open-multiple');
231
+ if (ruledHeadings.length > 1)
232
+ problems.push('ruled-multiple');
233
+ const offsetOf = (lineIndex) => (lineIndex < lines.length ? lines[lineIndex].start : text.length);
234
+ const zone = fileZone(lines);
235
+ const items = [];
236
+ for (const open of openHeadings) {
237
+ const openEnd = sectionEnd(open.index);
238
+ for (let i = open.index + 1; i < openEnd; i++) {
239
+ if (lines[i].headingLevel !== 3)
240
+ continue;
241
+ let endLine = openEnd;
242
+ for (let j = i + 1; j < openEnd; j++) {
243
+ if (lines[j].headingLevel >= 1 && lines[j].headingLevel <= 3) {
244
+ endLine = j;
245
+ break;
246
+ }
247
+ }
248
+ items.push(parseItem(text, lines, i, endLine, offsetOf, zone));
249
+ i = endLine - 1;
250
+ }
251
+ }
252
+ // Duplicate ids make every copy read-only.
253
+ const idCounts = new Map();
254
+ for (const item of items)
255
+ idCounts.set(item.id, (idCounts.get(item.id) ?? 0) + 1);
256
+ for (const item of items) {
257
+ if (item.id && (idCounts.get(item.id) ?? 0) > 1)
258
+ item.problems.push('duplicate-id');
259
+ item.writable = item.problems.length === 0 && item.currentRuling === '' && !problems.includes('open-multiple');
260
+ }
261
+ const ruled = ruledHeadings[0];
262
+ const ruledMarkdown = ruled ? joinTrimmed(lines.slice(ruled.index + 1, sectionEnd(ruled.index))) : '';
263
+ return { lines, eol: detectLineEnding(lines), items, ruledMarkdown, problems, version: sha256(text) };
264
+ }
265
+ function parseItem(text, lines, headingLine, endLine, offsetOf, zone) {
266
+ const heading = lines[headingLine];
267
+ const { id, stamp, question } = splitHeading(heading.headingText, zone);
268
+ const start = heading.start;
269
+ const end = offsetOf(endLine);
270
+ const itemLines = lines.slice(headingLine + 1, endLine);
271
+ // The fingerprint excludes the blank lines that separate this item from the next, so
272
+ // re-spacing between items is not an edit of this one.
273
+ let lastContent = heading;
274
+ for (const l of itemLines)
275
+ if (l.text.trim() !== '')
276
+ lastContent = l;
277
+ const yourWordLines = itemLines.filter(l => l.yourWord).map(l => l.index);
278
+ const problems = [];
279
+ if (!id)
280
+ problems.push('id-missing');
281
+ if (yourWordLines.length === 0)
282
+ problems.push('your-word-missing');
283
+ if (yourWordLines.length > 1)
284
+ problems.push('your-word-multiple');
285
+ let bodyLines = itemLines;
286
+ let options = [];
287
+ let currentRuling = '';
288
+ if (yourWordLines.length === 1) {
289
+ const yw = yourWordLines[0];
290
+ bodyLines = lines.slice(headingLine + 1, yw);
291
+ options = parseOptions(lines[yw].text);
292
+ currentRuling = joinTrimmed(lines.slice(yw + 1, endLine)).trim();
293
+ }
294
+ const { qa, rest } = extractQa(bodyLines);
295
+ if (options.some(option => !option.description)) {
296
+ const fromBody = bodyOptionDescriptions(rest);
297
+ options = options.map(option => option.description ? option : { ...option, description: fromBody.get(option.word) ?? '' });
298
+ }
299
+ return {
300
+ id,
301
+ stamp,
302
+ question,
303
+ bodyMarkdown: joinTrimmed(rest),
304
+ options,
305
+ currentRuling,
306
+ qa,
307
+ fingerprint: sha256(text.slice(start, lastContent.end)),
308
+ problems,
309
+ writable: false,
310
+ headingLine,
311
+ endLine,
312
+ start,
313
+ end,
314
+ yourWordLines,
315
+ };
316
+ }
317
+ /** Project the parse onto the wire document served to the dashboard. */
318
+ export function toDecisionsDocument(parsed, path) {
319
+ return {
320
+ path,
321
+ version: parsed.version,
322
+ items: parsed.items.map(item => ({
323
+ id: item.id,
324
+ stamp: item.stamp,
325
+ question: item.question,
326
+ bodyMarkdown: item.bodyMarkdown,
327
+ options: item.options,
328
+ currentRuling: item.currentRuling,
329
+ qa: item.qa,
330
+ fingerprint: item.fingerprint,
331
+ problems: item.problems,
332
+ writable: item.writable,
333
+ })),
334
+ ruledMarkdown: parsed.ruledMarkdown,
335
+ problems: parsed.problems,
336
+ };
337
+ }
338
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type http from 'node:http';
2
+ import type { DecisionsRefusalCode } from '@cluesmith/codev-types';
3
+ import { type DecisionsLog } from './file.js';
4
+ import { type RulingNotifier } from './notice.js';
5
+ /** Largest ruling request body accepted: a maximum-length comment, JSON-escaped, with room to spare. */
6
+ export declare const MAX_RULE_BODY_BYTES: number;
7
+ /** HTTP status per refusal: bad input 400, absent 404, the file's state 409, a structure the splice would break 422. */
8
+ export declare const DECISIONS_REFUSAL_STATUS: Record<DecisionsRefusalCode, number>;
9
+ /** GET …/api/decisions — the configured file, parsed. */
10
+ export declare function handleDecisionsGet(res: http.ServerResponse, workspacePath: string): Promise<void>;
11
+ /**
12
+ * POST …/api/decisions/rule — splice the owner's ruling into the configured file, then
13
+ * `notify` the hub architect of it. The notice is sent only after the file is replaced,
14
+ * and its failure is logged without touching the response: the file is the source of truth.
15
+ */
16
+ export declare function handleDecisionsRule(req: http.IncomingMessage, res: http.ServerResponse, workspacePath: string, log: DecisionsLog, notify: RulingNotifier): Promise<void>;
17
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/routes.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,EAAE,oBAAoB,EAAgD,MAAM,wBAAwB,CAAC;AAEjH,OAAO,EAAuF,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AACnI,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAIhE,wGAAwG;AACxG,eAAO,MAAM,mBAAmB,QAAa,CAAC;AAE9C,wHAAwH;AACxH,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,oBAAoB,EAAE,MAAM,CAqBzE,CAAC;AAiEF,yDAAyD;AACzD,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMvG;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,YAAY,EACjB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -0,0 +1,160 @@
1
+ // Tower routes for the Decisions tab (Spec 1819).
2
+ //
3
+ // GET /workspace/<enc>/api/decisions → the parsed decisions document
4
+ // POST /workspace/<enc>/api/decisions/rule → write the owner's ruling into the file
5
+ //
6
+ // Neither route reads a path from the request: the file is the configured one,
7
+ // resolved and contained by file.ts at every call. A write takes its turn on the file,
8
+ // re-reads it, splices, and replaces it atomically; success returns the document
9
+ // re-parsed from the bytes just written, then tells the hub architect (#1828).
10
+ import { promises as fsp } from 'node:fs';
11
+ import { parseJsonBody } from '../../utils/server-utils.js';
12
+ import { configuredDecisionsPath, decisionsWriteQueue, resolveDecisionsPath, writeFileAtomic } from './file.js';
13
+ import { rulingNotice } from './notice.js';
14
+ import { parseDecisions, toDecisionsDocument } from './parse.js';
15
+ import { spliceRuling } from './splice.js';
16
+ /** Largest ruling request body accepted: a maximum-length comment, JSON-escaped, with room to spare. */
17
+ export const MAX_RULE_BODY_BYTES = 256 * 1024;
18
+ /** HTTP status per refusal: bad input 400, absent 404, the file's state 409, a structure the splice would break 422. */
19
+ export const DECISIONS_REFUSAL_STATUS = {
20
+ 'invalid-request': 400,
21
+ 'empty-ruling': 400,
22
+ 'comment-too-long': 400,
23
+ 'comment-heading': 400,
24
+ 'comment-fence': 400,
25
+ 'comment-your-word': 400,
26
+ 'outside-workspace': 400,
27
+ 'not-found': 404,
28
+ 'open-multiple': 409,
29
+ 'heading-missing': 409,
30
+ 'heading-duplicate': 409,
31
+ 'your-word-missing': 409,
32
+ 'your-word-multiple': 409,
33
+ 'already-ruled': 409,
34
+ 'unknown-word': 409,
35
+ 'item-changed': 409,
36
+ 'structure-changed': 422,
37
+ 'not-utf8': 422,
38
+ 'config-error': 500,
39
+ 'write-failed': 500,
40
+ };
41
+ function refusal(code, message) {
42
+ return { ok: false, code, message };
43
+ }
44
+ function send(res, status, body) {
45
+ res.writeHead(status, { 'Content-Type': 'application/json' });
46
+ res.end(JSON.stringify(body));
47
+ }
48
+ function sendRefusal(res, refused) {
49
+ send(res, DECISIONS_REFUSAL_STATUS[refused.code], refused);
50
+ }
51
+ /** The configured decisions file, canonical and inside the workspace, or why not. */
52
+ async function locate(workspacePath) {
53
+ let configured;
54
+ try {
55
+ configured = configuredDecisionsPath(workspacePath, { fresh: true });
56
+ }
57
+ catch (err) {
58
+ return refusal('config-error', `The codev config could not be loaded: ${err.message}`);
59
+ }
60
+ const resolved = await resolveDecisionsPath(workspacePath, configured);
61
+ if (!resolved.inside) {
62
+ return refusal('outside-workspace', `The decisions file ${configured} resolves to ${resolved.canonicalPath}, outside the workspace; nothing was read or written.`);
63
+ }
64
+ if (!resolved.exists)
65
+ return refusal('not-found', `There is no decisions file at ${resolved.displayPath}.`);
66
+ return { ok: true, canonicalPath: resolved.canonicalPath, displayPath: resolved.displayPath };
67
+ }
68
+ /** The file's bytes, or `not-found` when it vanished after it was located. */
69
+ async function readBytes(canonicalPath, displayPath) {
70
+ try {
71
+ return await fsp.readFile(canonicalPath);
72
+ }
73
+ catch (err) {
74
+ if (err.code === 'ENOENT')
75
+ return refusal('not-found', `There is no decisions file at ${displayPath}.`);
76
+ throw err;
77
+ }
78
+ }
79
+ /** Validate the ruling request body's shape; the splice checks its content. */
80
+ async function readRulingRequest(req) {
81
+ let body;
82
+ try {
83
+ body = await parseJsonBody(req, MAX_RULE_BODY_BYTES);
84
+ }
85
+ catch (err) {
86
+ return refusal('invalid-request', `The request body could not be read: ${err.message}.`);
87
+ }
88
+ if (typeof body !== 'object' || body === null || Array.isArray(body)) {
89
+ return refusal('invalid-request', 'The request body must be a JSON object.');
90
+ }
91
+ const { id, fingerprint, word, comment } = body;
92
+ if (typeof id !== 'string' || id === '')
93
+ return refusal('invalid-request', '"id" must be a non-empty string.');
94
+ if (typeof fingerprint !== 'string' || fingerprint === '')
95
+ return refusal('invalid-request', '"fingerprint" must be a non-empty string.');
96
+ if (word !== undefined && typeof word !== 'string')
97
+ return refusal('invalid-request', '"word" must be a string when present.');
98
+ if (comment !== undefined && typeof comment !== 'string')
99
+ return refusal('invalid-request', '"comment" must be a string when present.');
100
+ return { ok: true, ruling: { id, fingerprint, word, comment } };
101
+ }
102
+ /** GET …/api/decisions — the configured file, parsed. */
103
+ export async function handleDecisionsGet(res, workspacePath) {
104
+ const located = await locate(workspacePath);
105
+ if (!located.ok)
106
+ return sendRefusal(res, located);
107
+ const bytes = await readBytes(located.canonicalPath, located.displayPath);
108
+ if (!Buffer.isBuffer(bytes))
109
+ return sendRefusal(res, bytes);
110
+ send(res, 200, { ok: true, document: toDecisionsDocument(parseDecisions(bytes.toString('utf8')), located.displayPath) });
111
+ }
112
+ /**
113
+ * POST …/api/decisions/rule — splice the owner's ruling into the configured file, then
114
+ * `notify` the hub architect of it. The notice is sent only after the file is replaced,
115
+ * and its failure is logged without touching the response: the file is the source of truth.
116
+ */
117
+ export async function handleDecisionsRule(req, res, workspacePath, log, notify) {
118
+ const refuse = (refused, id) => {
119
+ log('WARN', `Decisions ruling refused${id ? ` for ${id}` : ''} (${refused.code}): ${refused.message}`);
120
+ sendRefusal(res, refused);
121
+ };
122
+ const request = await readRulingRequest(req);
123
+ if (!request.ok)
124
+ return refuse(request);
125
+ const { ruling } = request;
126
+ const located = await locate(workspacePath);
127
+ if (!located.ok)
128
+ return refuse(located, ruling.id);
129
+ const { canonicalPath, displayPath } = located;
130
+ const outcome = await decisionsWriteQueue.run(canonicalPath, async () => {
131
+ const bytes = await readBytes(canonicalPath, displayPath);
132
+ if (!Buffer.isBuffer(bytes))
133
+ return bytes;
134
+ const text = bytes.toString('utf8');
135
+ if (!Buffer.from(text, 'utf8').equals(bytes)) {
136
+ return refusal('not-utf8', `${displayPath} is not valid UTF-8; writing a ruling would alter bytes the tab cannot read, so nothing was written.`);
137
+ }
138
+ const spliced = spliceRuling(text, ruling);
139
+ if (!spliced.ok)
140
+ return spliced;
141
+ try {
142
+ await writeFileAtomic(canonicalPath, spliced.text);
143
+ }
144
+ catch (err) {
145
+ return refusal('write-failed', `${displayPath} could not be written (${err.message}); the file is unchanged.`);
146
+ }
147
+ return spliced;
148
+ });
149
+ if (!outcome.ok)
150
+ return refuse(outcome, ruling.id);
151
+ log('INFO', `Decisions ruling written for ${ruling.id} into ${displayPath}`);
152
+ send(res, 200, { ok: true, document: toDecisionsDocument(parseDecisions(outcome.text), displayPath) });
153
+ try {
154
+ await notify(rulingNotice(ruling));
155
+ }
156
+ catch (err) {
157
+ log('WARN', `Decisions ruling for ${ruling.id} was written, but the hub architect was not told: ${err.message}`);
158
+ }
159
+ }
160
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { DecisionsRefusalCode } from '@cluesmith/codev-types';
2
+ /** Longest comment accepted, in characters, after trimming. */
3
+ export declare const MAX_COMMENT_LENGTH = 10000;
4
+ export interface RulingRequest {
5
+ id: string;
6
+ /** The chosen option word; absent or '' when none was chosen. */
7
+ word?: string;
8
+ /** Free text; trimmed, internal line breaks kept. */
9
+ comment?: string;
10
+ /** The item's fingerprint as the card last rendered it. */
11
+ fingerprint: string;
12
+ }
13
+ /** The refusals a splice can return; the rest belong to the route (file and config). */
14
+ export type SpliceRefusalCode = Exclude<DecisionsRefusalCode, 'not-utf8' | 'write-failed' | 'not-found' | 'outside-workspace' | 'config-error'>;
15
+ export interface SpliceRefusal {
16
+ ok: false;
17
+ code: SpliceRefusalCode;
18
+ message: string;
19
+ }
20
+ export type SpliceResult = {
21
+ ok: true;
22
+ text: string;
23
+ } | SpliceRefusal;
24
+ /** Apply the owner's ruling to the decisions file's text, or refuse with the reason. */
25
+ export declare function spliceRuling(text: string, request: RulingRequest): SpliceResult;
26
+ //# sourceMappingURL=splice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splice.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/splice.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAInE,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wFAAwF;AACxF,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,EAAE,UAAU,GAAG,cAAc,GAAG,WAAW,GAAG,mBAAmB,GAAG,cAAc,CAAC,CAAC;AAEhJ,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,iBAAiB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,aAAa,CAAC;AAmEtE,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,YAAY,CAkC/E"}