@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,120 @@
1
+ // Ruling splice for the decisions file (Spec 1819).
2
+ //
3
+ // A pure function that writes the owner's ruling into the file's text, or refuses
4
+ // with a specific reason and returns no text. The write route is a thin wrapper
5
+ // around it: read the file, splice, write back only on success.
6
+ //
7
+ // The ruling goes directly after the item's `**Your word:**` line: the word on the
8
+ // very next line; then the comment, after a blank line when a word was written; then
9
+ // a blank line when the line that follows is not already blank. Inserted lines use
10
+ // the file's own line ending, a missing final newline on the Your-word line is
11
+ // supplied, and every other character is preserved in order. The result is
12
+ // re-parsed and must keep the file's structure — anything the explicit checks miss
13
+ // (an option word that is itself a heading or fence, say) is `structure-changed`.
14
+ import { isFenceLine, isHeadingLine, isYourWordLine } from './grammar.js';
15
+ import { parseDecisions } from './parse.js';
16
+ /** Longest comment accepted, in characters, after trimming. */
17
+ export const MAX_COMMENT_LENGTH = 10_000;
18
+ function refuse(code, message) {
19
+ return { ok: false, code, message };
20
+ }
21
+ /** Refuse a comment line that would add structure: a heading, fence or Your-word line. */
22
+ function checkCommentLines(commentLines) {
23
+ for (const [n, line] of commentLines.entries()) {
24
+ const where = `Line ${n + 1} of the comment`;
25
+ if (isHeadingLine(line))
26
+ return refuse('comment-heading', `${where} is a markdown heading ("${line.trim()}"); headings end the item.`);
27
+ if (isFenceLine(line))
28
+ return refuse('comment-fence', `${where} is a code fence ("${line.trim()}"), which would change how the file parses.`);
29
+ if (isYourWordLine(line))
30
+ return refuse('comment-your-word', `${where} starts with **Your word:**, which would give the item a second Your-word line.`);
31
+ }
32
+ return null;
33
+ }
34
+ /** Find the request's item in `## Open` and check it can take a ruling now. */
35
+ function checkItem(parsed, request, word) {
36
+ const { id } = request;
37
+ if (parsed.problems.includes('open-multiple')) {
38
+ return refuse('open-multiple', 'The file has more than one ## Open section; the tab cannot tell where items belong, so it writes nothing.');
39
+ }
40
+ const matches = parsed.items.filter(item => item.id === id);
41
+ if (matches.length === 0)
42
+ return refuse('heading-missing', `Item ${id} is not in ## Open (it may have been ruled or removed).`);
43
+ if (matches.length > 1)
44
+ return refuse('heading-duplicate', `Item ${id} appears ${matches.length} times in ## Open; rulings for it go through main.`);
45
+ const item = matches[0];
46
+ if (item.yourWordLines.length === 0)
47
+ return refuse('your-word-missing', `Item ${id} has no **Your word:** line to rule under.`);
48
+ if (item.yourWordLines.length > 1)
49
+ return refuse('your-word-multiple', `Item ${id} has ${item.yourWordLines.length} **Your word:** lines; the tab cannot tell which one to rule under.`);
50
+ if (item.currentRuling !== '')
51
+ return refuse('already-ruled', `Item ${id} already has text under its **Your word:** line; a change goes through main or a hand edit.`);
52
+ if (word && !item.options.some(option => option.word === word)) {
53
+ return refuse('unknown-word', `"${word}" is not an option on item ${id}'s current **Your word:** line.`);
54
+ }
55
+ if (item.fingerprint !== request.fingerprint)
56
+ return refuse('item-changed', `Item ${id} changed since it was shown; review it and submit again.`);
57
+ return item;
58
+ }
59
+ /**
60
+ * Check the spliced text kept the file's structure: the same sections, the same items
61
+ * in the same order, the same options on this item, this item's current ruling equal
62
+ * to the inserted ruling, and every inserted line plain unfenced content.
63
+ */
64
+ function verify(before, after, item, ruling, insertedLines) {
65
+ const sections = (p) => p.lines.filter(l => l.headingLevel === 1 || l.headingLevel === 2).map(l => `${l.headingLevel} ${l.headingText}`).join('\n');
66
+ const changed = (what) => refuse('structure-changed', `Writing this ruling into item ${item.id} would change ${what}, so nothing was written.`);
67
+ if (sections(after) !== sections(before) || after.problems.join() !== before.problems.join())
68
+ return changed("the file's sections");
69
+ if (after.items.map(i => i.id).join('\n') !== before.items.map(i => i.id).join('\n'))
70
+ return changed('the list of open items');
71
+ const afterItem = after.items.find(i => i.headingLine === item.headingLine);
72
+ if (!afterItem || afterItem.id !== item.id)
73
+ return changed('the list of open items');
74
+ if (JSON.stringify(afterItem.options) !== JSON.stringify(item.options))
75
+ return changed("the item's options");
76
+ if (afterItem.currentRuling !== ruling)
77
+ return changed("the item's text after its **Your word:** line");
78
+ const inserted = after.lines.slice(insertedLines.from, insertedLines.from + insertedLines.count);
79
+ if (inserted.some(l => l.fenced || l.headingLevel > 0 || l.yourWord))
80
+ return changed("the file's structure (the ruling would add a heading or fence)");
81
+ return null;
82
+ }
83
+ /** Apply the owner's ruling to the decisions file's text, or refuse with the reason. */
84
+ export function spliceRuling(text, request) {
85
+ if (!request.id)
86
+ return refuse('invalid-request', 'The request names no item.');
87
+ if (!request.fingerprint)
88
+ return refuse('invalid-request', 'The request carries no item fingerprint.');
89
+ const word = request.word ?? '';
90
+ const comment = (request.comment ?? '').trim();
91
+ if (!word && !comment)
92
+ return refuse('empty-ruling', 'Choose an option or write a comment.');
93
+ if (comment.length > MAX_COMMENT_LENGTH) {
94
+ return refuse('comment-too-long', `The comment is ${comment.length} characters; the limit is ${MAX_COMMENT_LENGTH}.`);
95
+ }
96
+ const commentLines = comment ? comment.split(/\r\n|\r|\n/) : [];
97
+ const commentRefusal = checkCommentLines(commentLines);
98
+ if (commentRefusal)
99
+ return commentRefusal;
100
+ const before = parseDecisions(text);
101
+ const item = checkItem(before, request, word);
102
+ if ('ok' in item)
103
+ return item;
104
+ const rulingLines = [...(word ? [word] : []), ...(word && comment ? [''] : []), ...commentLines];
105
+ const yourWord = before.lines[item.yourWordLines[0]];
106
+ const following = before.lines[yourWord.index + 1];
107
+ const newLines = following && following.text.trim() !== '' ? [...rulingLines, ''] : rulingLines;
108
+ const at = yourWord.end + yourWord.eol.length;
109
+ const inserted = (yourWord.eol === '' ? before.eol : '') + newLines.map(line => line + before.eol).join('');
110
+ const result = text.slice(0, at) + inserted + text.slice(at);
111
+ // The parser's current ruling is LF-joined whatever the file's line ending.
112
+ const refusal = verify(before, parseDecisions(result), item, rulingLines.join('\n'), {
113
+ from: yourWord.index + 1,
114
+ count: newLines.length,
115
+ });
116
+ if (refusal)
117
+ return refusal;
118
+ return { ok: true, text: result };
119
+ }
120
+ //# sourceMappingURL=splice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"splice.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/splice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { DecisionStamp } from '@cluesmith/codev-types';
2
+ /**
3
+ * Resolve a heading stamp to an instant, using the zone written in it or else `fileZone`.
4
+ * A stamp without a date takes today's date in that zone. Returns null for text that is not
5
+ * a stamp.
6
+ */
7
+ export declare function resolveStamp(raw: string, fileZone?: string | null): DecisionStamp | null;
8
+ //# sourceMappingURL=stamp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamp.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/stamp.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAmI5D;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW,GAAG,aAAa,GAAG,IAAI,CAiD9F"}
@@ -0,0 +1,195 @@
1
+ // Decision heading timestamps (Spec 1819, Issue #1836).
2
+ //
3
+ // A stamp is `[YYYY-MM-DD] h:mm am|pm [ZONE]` or `[YYYY-MM-DD] HH:mm [ZONE]`. It is
4
+ // resolved to an absolute instant using the zone written in it or, failing that, the
5
+ // file's `_Zone: …_` line — nothing here defaults to, or special-cases, any zone. A
6
+ // stamp without a date is today in its zone. A stamp with no zone at all is returned
7
+ // unconverted with no reason, so the tab shows it as written; text in none of these
8
+ // forms is not a stamp at all (null).
9
+ //
10
+ // IANA and generic zones are resolved with the runtime's built-in `Intl` time-zone
11
+ // data by offset probing: the wall-clock time is tried against every offset the
12
+ // zone has near that date, and the candidates that round-trip are kept. One means
13
+ // success; none is a spring-forward gap; two is a fall-back fold. Gaps and folds
14
+ // are left unconverted rather than broken by a tie-break rule.
15
+ /** Generic North-American zones: DST follows the stamp's date. */
16
+ const GENERIC_ZONES = {
17
+ PT: 'America/Los_Angeles',
18
+ MT: 'America/Denver',
19
+ CT: 'America/Chicago',
20
+ ET: 'America/New_York',
21
+ AKT: 'America/Anchorage',
22
+ HT: 'Pacific/Honolulu',
23
+ };
24
+ /**
25
+ * Fixed-offset abbreviations, in minutes east of UTC. `CST` is North-American
26
+ * Central (China Standard Time is written `+08:00` or `Asia/Shanghai`). Ambiguous
27
+ * abbreviations (`IST`, `BST`, `AST`, …) are deliberately absent.
28
+ */
29
+ const FIXED_ZONES = {
30
+ UTC: 0,
31
+ GMT: 0,
32
+ Z: 0,
33
+ PST: -8 * 60,
34
+ PDT: -7 * 60,
35
+ MST: -7 * 60,
36
+ MDT: -6 * 60,
37
+ CST: -6 * 60,
38
+ CDT: -5 * 60,
39
+ EST: -5 * 60,
40
+ EDT: -4 * 60,
41
+ AKST: -9 * 60,
42
+ AKDT: -8 * 60,
43
+ HST: -10 * 60,
44
+ WET: 0,
45
+ WEST: 1 * 60,
46
+ CET: 1 * 60,
47
+ CEST: 2 * 60,
48
+ EET: 2 * 60,
49
+ EEST: 3 * 60,
50
+ MSK: 3 * 60,
51
+ SGT: 8 * 60,
52
+ HKT: 8 * 60,
53
+ JST: 9 * 60,
54
+ KST: 9 * 60,
55
+ AEST: 10 * 60,
56
+ AEDT: 11 * 60,
57
+ NZST: 12 * 60,
58
+ NZDT: 13 * 60,
59
+ };
60
+ const STAMP_RE = /^(?:(\d{4})-(\d{2})-(\d{2})\s+)?(\d{1,2}):(\d{2})(?:\s*(am|pm))?(?:\s+(\S+))?$/i;
61
+ const OFFSET_RE = /^(?:UTC|GMT)?([+-])(\d{1,2})(?::?(\d{2}))?$/;
62
+ /** Shaped like a zone (an abbreviation, an Area/Location name, an offset), known or not. */
63
+ const ZONE_LIKE_RE = /^(?:[A-Z]{2,5}|[A-Z][A-Za-z_]*(?:\/[A-Za-z0-9_+-]+)+|(?:UTC|GMT)?[+-]\d{1,2}(?::?\d{2})?)$/;
64
+ const MINUTE_MS = 60_000;
65
+ const DAY_MS = 24 * 60 * MINUTE_MS;
66
+ function isIanaZone(name) {
67
+ try {
68
+ new Intl.DateTimeFormat('en-US', { timeZone: name });
69
+ return true;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ function parseZone(zone) {
76
+ // Own keys only: `in` would let prototype names (`toString`, `__proto__`, …) through.
77
+ if (Object.hasOwn(FIXED_ZONES, zone))
78
+ return { kind: 'fixed', offsetMinutes: FIXED_ZONES[zone] };
79
+ if (Object.hasOwn(GENERIC_ZONES, zone))
80
+ return { kind: 'iana', name: GENERIC_ZONES[zone] };
81
+ const offset = OFFSET_RE.exec(zone);
82
+ if (offset) {
83
+ const hours = Number(offset[2]);
84
+ const minutes = offset[3] ? Number(offset[3]) : 0;
85
+ if (hours > 14 || minutes > 59)
86
+ return null;
87
+ const sign = offset[1] === '-' ? -1 : 1;
88
+ return { kind: 'fixed', offsetMinutes: sign * (hours * 60 + minutes) };
89
+ }
90
+ // IANA names only in Area/Location form, so legacy ids (`EST5EDT`, `IST`, …) are
91
+ // never accepted through the back door.
92
+ if (zone.includes('/') && isIanaZone(zone))
93
+ return { kind: 'iana', name: zone };
94
+ return null;
95
+ }
96
+ const formatters = new Map();
97
+ function formatterFor(zone) {
98
+ let f = formatters.get(zone);
99
+ if (!f) {
100
+ f = new Intl.DateTimeFormat('en-US', {
101
+ timeZone: zone,
102
+ hourCycle: 'h23',
103
+ year: 'numeric',
104
+ month: '2-digit',
105
+ day: '2-digit',
106
+ hour: '2-digit',
107
+ minute: '2-digit',
108
+ });
109
+ formatters.set(zone, f);
110
+ }
111
+ return f;
112
+ }
113
+ /** The zone's UTC offset, in minutes, at the given instant. */
114
+ function offsetAt(instantMs, zone) {
115
+ const parts = formatterFor(zone).formatToParts(new Date(instantMs));
116
+ const get = (type) => Number(parts.find(p => p.type === type).value);
117
+ const wallMs = Date.UTC(get('year'), get('month') - 1, get('day'), get('hour'), get('minute'));
118
+ const instantMinute = Math.floor(instantMs / MINUTE_MS) * MINUTE_MS;
119
+ return Math.round((wallMs - instantMinute) / MINUTE_MS);
120
+ }
121
+ /** All instants whose wall-clock time in `zone` is `wallMs` (as if UTC). */
122
+ function instantsForWallClock(wallMs, zone) {
123
+ const offsets = new Set([offsetAt(wallMs - DAY_MS, zone), offsetAt(wallMs, zone), offsetAt(wallMs + DAY_MS, zone)]);
124
+ const instants = new Set();
125
+ for (const offset of offsets) {
126
+ const candidate = wallMs - offset * MINUTE_MS;
127
+ if (offsetAt(candidate, zone) === offset)
128
+ instants.add(candidate);
129
+ }
130
+ return [...instants].sort((a, b) => a - b);
131
+ }
132
+ /** The wall-clock time in `zone` at the given instant, as if UTC. */
133
+ function wallClockAt(instantMs, zone) {
134
+ const offsetMinutes = zone.kind === 'fixed' ? zone.offsetMinutes : offsetAt(instantMs, zone.name);
135
+ return instantMs + offsetMinutes * MINUTE_MS;
136
+ }
137
+ /**
138
+ * Resolve a heading stamp to an instant, using the zone written in it or else `fileZone`.
139
+ * A stamp without a date takes today's date in that zone. Returns null for text that is not
140
+ * a stamp.
141
+ */
142
+ export function resolveStamp(raw, fileZone = null) {
143
+ const m = STAMP_RE.exec(raw.trim());
144
+ if (!m)
145
+ return null;
146
+ const [, y, mo, d, h, mi, meridiem, zoneText] = m;
147
+ let hour = Number(h);
148
+ const minute = Number(mi);
149
+ if (meridiem) {
150
+ if (hour < 1 || hour > 12)
151
+ return null;
152
+ const pm = meridiem.toLowerCase() === 'pm';
153
+ hour = (hour % 12) + (pm ? 12 : 0);
154
+ }
155
+ else if (hour > 23) {
156
+ return null;
157
+ }
158
+ if (minute > 59)
159
+ return null;
160
+ const timeOnly = y === undefined;
161
+ let dateMs = 0;
162
+ if (!timeOnly) {
163
+ const year = Number(y);
164
+ const month = Number(mo);
165
+ const day = Number(d);
166
+ dateMs = Date.UTC(year, month - 1, day);
167
+ const check = new Date(dateMs);
168
+ if (check.getUTCFullYear() !== year || check.getUTCMonth() !== month - 1 || check.getUTCDate() !== day)
169
+ return null;
170
+ }
171
+ const stamp = timeOnly ? { raw, instant: null, timeOnly: true } : { raw, instant: null };
172
+ const zoneName = zoneText ?? fileZone;
173
+ if (!zoneName)
174
+ return stamp;
175
+ const zone = parseZone(zoneName);
176
+ if (!zone) {
177
+ // A bare time and a word that is no zone (`10:30 standup?`) is a question, not a stamp.
178
+ if (timeOnly && zoneText !== undefined && !ZONE_LIKE_RE.test(zoneText))
179
+ return null;
180
+ return { ...stamp, unconvertedReason: 'unknown-zone' };
181
+ }
182
+ if (timeOnly)
183
+ dateMs = Math.floor(wallClockAt(Date.now(), zone) / DAY_MS) * DAY_MS;
184
+ const wallMs = dateMs + (hour * 60 + minute) * MINUTE_MS;
185
+ if (zone.kind === 'fixed') {
186
+ return { ...stamp, instant: new Date(wallMs - zone.offsetMinutes * MINUTE_MS).toISOString() };
187
+ }
188
+ const instants = instantsForWallClock(wallMs, zone.name);
189
+ if (instants.length === 0)
190
+ return { ...stamp, unconvertedReason: 'nonexistent-time' };
191
+ if (instants.length > 1)
192
+ return { ...stamp, unconvertedReason: 'ambiguous-time' };
193
+ return { ...stamp, instant: new Date(instants[0]).toISOString() };
194
+ }
195
+ //# sourceMappingURL=stamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stamp.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/stamp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const DECISIONS_FILE_TEMPLATE = "# Pending owner decisions \u2014 all architects (hub: main)\n\nRule inline: one word on the line under an item's **Your word:** line, or in the Decisions tab.\nNewest first. Only main edits this file; architects send items with `afx send architect:main 'DECISION \u2026'`.\n\n_Status: 0 open._\n_Zone: UTC_\n\n## Open\n\n## Ruled\n";
2
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/template.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,gVAWnC,CAAC"}
@@ -0,0 +1,15 @@
1
+ // The decisions file a workspace starts from (Issue #1840). `afx decisions init` writes
2
+ // it; section 4 of resources/decision-protocol.md shows it, and a test pins the two equal.
3
+ export const DECISIONS_FILE_TEMPLATE = `# Pending owner decisions — all architects (hub: main)
4
+
5
+ Rule inline: one word on the line under an item's **Your word:** line, or in the Decisions tab.
6
+ Newest first. Only main edits this file; architects send items with \`afx send architect:main 'DECISION …'\`.
7
+
8
+ _Status: 0 open._
9
+ _Zone: UTC_
10
+
11
+ ## Open
12
+
13
+ ## Ruled
14
+ `;
15
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../../../src/agent-farm/servers/decisions/template.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,2FAA2F;AAE3F,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;CAWtC,CAAC"}
@@ -7,10 +7,18 @@
7
7
  * Runtime state lives in the `~/.agent-farm/ide-server.json` record (Issue
8
8
  * #1668 §D3) — no config file, no `global.db` change. Liveness is discovered by
9
9
  * port (`getProcessesOnPort`), the same way Tower finds its own process.
10
+ *
11
+ * Every spawn runs a preflight first (Spec 1789): the server version floor and
12
+ * the embedded sidebar install into the Tower-owned extensions directory. The
13
+ * preflight throws before anything is stopped, replaced or recorded, so a
14
+ * refused start leaves a live server and its record untouched. Lifecycle
15
+ * operations are serialized by `withIdeLock`, taken only at the entry points
16
+ * (`spawnIdeServer`, `stopIdeServer`, the respawn in `ensureIdeServerLive`);
17
+ * the unlocked bodies call each other freely, so the nesting cannot deadlock.
10
18
  */
11
19
  import http from 'node:http';
12
20
  import { type IdeServerRecord } from '../lib/ide-record.js';
13
- type LogFn = (level: 'INFO' | 'ERROR' | 'WARN', message: string) => void;
21
+ import { type LogFn } from '../lib/ide-version.js';
14
22
  /**
15
23
  * The recorded IDE server port, or null if none — the forward's hot-path target
16
24
  * resolution. A plain record read, no port scan (Issue #1668): a dead server
@@ -21,18 +29,31 @@ export declare function getRecordedIdePort(): number | null;
21
29
  export interface SpawnIdeOptions {
22
30
  serverPath: string;
23
31
  port?: number;
24
- defaultFolder?: string;
32
+ }
33
+ export interface SpawnIdeResult {
34
+ record: IdeServerRecord;
35
+ /**
36
+ * True when an already-live server was adopted that is not running what
37
+ * this start asked for: the sidebar just changed, the recorded server path,
38
+ * sidebar version or extensions directory differs from the current one
39
+ * (including a legacy record with neither), or its launch arguments are
40
+ * unknown (no prior record). The live server is never killed; the user
41
+ * restarts it.
42
+ */
43
+ restartRequired: boolean;
25
44
  }
26
45
  /**
27
46
  * Spawn the IDE server detached (so it survives a Tower restart, like a
28
- * shellper) and write the runtime record. Resolves to the record once the
29
- * server is listening, or throws if the binary is missing or never binds.
47
+ * shellper) and write the runtime record. Resolves once the server is
48
+ * listening, or throws if the binary is missing, fails the preflight, or never
49
+ * binds. Serialized with every other lifecycle operation.
30
50
  */
31
- export declare function spawnIdeServer(opts: SpawnIdeOptions, log: LogFn): Promise<IdeServerRecord>;
51
+ export declare function spawnIdeServer(opts: SpawnIdeOptions, log: LogFn): Promise<SpawnIdeResult>;
32
52
  /**
33
53
  * Stop the IDE server on the recorded port: SIGTERM, wait for exit, escalate to
34
54
  * SIGKILL for survivors (mirrors `towerStop`, #1668 plan §4), then delete the
35
- * record. Cold path — `getProcessesOnPort` is fine here.
55
+ * record. Cold path — `getProcessesOnPort` is fine here. Serialized with every
56
+ * other lifecycle operation.
36
57
  */
37
58
  export declare function stopIdeServer(log: LogFn): Promise<{
38
59
  stopped: boolean;
@@ -59,10 +80,9 @@ export declare function ensureIdeServerLive(log?: LogFn): Promise<number | null>
59
80
  export declare function reconcileIdeServer(log: LogFn): Promise<void>;
60
81
  /**
61
82
  * Local-only `/api/ide` management endpoint driving the lifecycle above:
62
- * `POST` starts (body `{ serverPath, port?, defaultFolder? }`), `DELETE` stops,
83
+ * `POST` starts (body `{ serverPath, port? }`), `DELETE` stops,
63
84
  * `GET` reports status. Reached only post-`isRequestAllowed` (key required) and
64
85
  * blocked from the tunnel like `/api/tunnel/*` — it spawns/kills a process.
65
86
  */
66
87
  export declare function handleIdeApi(req: http.IncomingMessage, res: http.ServerResponse, log: LogFn): Promise<void>;
67
- export {};
68
88
  //# sourceMappingURL=ide-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ide-server.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/ide-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAM7B,OAAO,EAGL,KAAK,eAAe,EAMrB,MAAM,sBAAsB,CAAC;AAE9B,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AA4BzE;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAYD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,CA6EhG;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAkClG;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,IAAI,SAAS,CAK3C;AAKD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,GAAE,KAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsBvF;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,KAAK,GACT,OAAO,CAAC,IAAI,CAAC,CA6Cf"}
1
+ {"version":3,"file":"ide-server.d.ts","sourceRoot":"","sources":["../../../src/agent-farm/servers/ide-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,OAAO,EAGL,KAAK,eAAe,EAMrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,KAAK,KAAK,EAGX,MAAM,uBAAuB,CAAC;AA2B/B;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,GAAG,IAAI,CAElD;AAwBD,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,eAAe,CAAC;IACxB;;;;;;;OAOG;IACH,eAAe,EAAE,OAAO,CAAC;CAC1B;AA4BD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC,CAEzF;AAoID;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAE5F;AAsCD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,IAAI,SAAS,CAK3C;AAKD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,GAAE,KAAgB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUvF;AAwBD;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAQlE;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,GAAG,EAAE,KAAK,GACT,OAAO,CAAC,IAAI,CAAC,CA4Cf"}