@shivaedev/work-board 0.7.2 → 0.9.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 (277) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +110 -2
  3. package/assets/agent.js +37 -0
  4. package/assets/native.js +54 -25
  5. package/dist/board.d.ts +1 -0
  6. package/dist/board.d.ts.map +1 -1
  7. package/dist/board.js +15 -2
  8. package/dist/board.js.map +1 -1
  9. package/dist/browser/client.d.ts +19 -79
  10. package/dist/browser/client.d.ts.map +1 -1
  11. package/dist/browser/client.js +12 -1
  12. package/dist/browser/client.js.map +1 -1
  13. package/dist/browser/entry.d.ts +3 -0
  14. package/dist/browser/entry.d.ts.map +1 -0
  15. package/dist/browser/entry.js +7 -0
  16. package/dist/browser/entry.js.map +1 -0
  17. package/dist/browser/responses/Prompt.d.ts +10 -0
  18. package/dist/browser/responses/Prompt.d.ts.map +1 -0
  19. package/dist/browser/responses/Prompt.js +2 -0
  20. package/dist/browser/responses/Prompt.js.map +1 -0
  21. package/dist/browser/responses/answerBody.d.ts +4 -0
  22. package/dist/browser/responses/answerBody.d.ts.map +1 -0
  23. package/dist/browser/responses/answerBody.js +9 -0
  24. package/dist/browser/responses/answerBody.js.map +1 -0
  25. package/dist/browser/responses/draftSession.d.ts +8 -0
  26. package/dist/browser/responses/draftSession.d.ts.map +1 -0
  27. package/dist/browser/responses/draftSession.js +105 -0
  28. package/dist/browser/responses/draftSession.js.map +1 -0
  29. package/dist/browser/responses/drafts.d.ts +21 -0
  30. package/dist/browser/responses/drafts.d.ts.map +1 -0
  31. package/dist/browser/responses/drafts.js +68 -0
  32. package/dist/browser/responses/drafts.js.map +1 -0
  33. package/dist/browser/responses/preview.d.ts +4 -0
  34. package/dist/browser/responses/preview.d.ts.map +1 -0
  35. package/dist/browser/responses/preview.js +5 -0
  36. package/dist/browser/responses/preview.js.map +1 -0
  37. package/dist/browser/responses/questionnaireControls.d.ts +10 -0
  38. package/dist/browser/responses/questionnaireControls.d.ts.map +1 -0
  39. package/dist/browser/responses/questionnaireControls.js +68 -0
  40. package/dist/browser/responses/questionnaireControls.js.map +1 -0
  41. package/dist/browser/responses/schema.d.ts +168 -0
  42. package/dist/browser/responses/schema.d.ts.map +1 -0
  43. package/dist/browser/responses/schema.js +57 -0
  44. package/dist/browser/responses/schema.js.map +1 -0
  45. package/dist/browser/responses/setup.d.ts +2 -0
  46. package/dist/browser/responses/setup.d.ts.map +1 -0
  47. package/dist/browser/responses/setup.js +129 -0
  48. package/dist/browser/responses/setup.js.map +1 -0
  49. package/dist/browser/responses/submissionFields.d.ts +15 -0
  50. package/dist/browser/responses/submissionFields.d.ts.map +1 -0
  51. package/dist/browser/responses/submissionFields.js +14 -0
  52. package/dist/browser/responses/submissionFields.js.map +1 -0
  53. package/dist/browser/responses/submit.d.ts +4 -0
  54. package/dist/browser/responses/submit.d.ts.map +1 -0
  55. package/dist/browser/responses/submit.js +30 -0
  56. package/dist/browser/responses/submit.js.map +1 -0
  57. package/dist/browser/session.d.ts +1 -79
  58. package/dist/browser/session.d.ts.map +1 -1
  59. package/dist/cli.d.ts.map +1 -1
  60. package/dist/cli.js +24 -15
  61. package/dist/cli.js.map +1 -1
  62. package/dist/files/changes.d.ts +1 -0
  63. package/dist/files/changes.d.ts.map +1 -1
  64. package/dist/files/changes.js +1 -1
  65. package/dist/files/changes.js.map +1 -1
  66. package/dist/http/respond.d.ts.map +1 -1
  67. package/dist/http/respond.js +2 -0
  68. package/dist/http/respond.js.map +1 -1
  69. package/dist/metadata/backlinks.d.ts.map +1 -1
  70. package/dist/metadata/backlinks.js +5 -0
  71. package/dist/metadata/backlinks.js.map +1 -1
  72. package/dist/metadata/fields.d.ts +23 -1
  73. package/dist/metadata/fields.d.ts.map +1 -1
  74. package/dist/metadata/problems.d.ts.map +1 -1
  75. package/dist/metadata/problems.js +3 -0
  76. package/dist/metadata/problems.js.map +1 -1
  77. package/dist/metadata/schema.d.ts +23 -1
  78. package/dist/metadata/schema.d.ts.map +1 -1
  79. package/dist/metadata/schema.js +6 -2
  80. package/dist/metadata/schema.js.map +1 -1
  81. package/dist/page/attentionDetails.d.ts.map +1 -1
  82. package/dist/page/attentionDetails.js +2 -1
  83. package/dist/page/attentionDetails.js.map +1 -1
  84. package/dist/page/metadataDetails.d.ts.map +1 -1
  85. package/dist/page/metadataDetails.js +6 -0
  86. package/dist/page/metadataDetails.js.map +1 -1
  87. package/dist/page/navigationScript.js +1 -1
  88. package/dist/page/shell.d.ts +1 -1
  89. package/dist/page/shell.d.ts.map +1 -1
  90. package/dist/page/shell.js.map +1 -1
  91. package/dist/page/style.d.ts.map +1 -1
  92. package/dist/page/style.js +3 -1
  93. package/dist/page/style.js.map +1 -1
  94. package/dist/page/swap.d.ts +1 -1
  95. package/dist/page/swap.d.ts.map +1 -1
  96. package/dist/page/swap.js +3 -0
  97. package/dist/page/swap.js.map +1 -1
  98. package/dist/path/Identity.d.ts +3 -0
  99. package/dist/path/Identity.d.ts.map +1 -0
  100. package/dist/path/Identity.js +3 -0
  101. package/dist/path/Identity.js.map +1 -0
  102. package/dist/render/markdown.d.ts +1 -0
  103. package/dist/render/markdown.d.ts.map +1 -1
  104. package/dist/render/markdown.js +4 -2
  105. package/dist/render/markdown.js.map +1 -1
  106. package/dist/render/questionnaireDocuments.d.ts +3 -0
  107. package/dist/render/questionnaireDocuments.d.ts.map +1 -0
  108. package/dist/render/questionnaireDocuments.js +11 -0
  109. package/dist/render/questionnaireDocuments.js.map +1 -0
  110. package/dist/render/visualDocuments.d.ts.map +1 -1
  111. package/dist/render/visualDocuments.js +3 -0
  112. package/dist/render/visualDocuments.js.map +1 -1
  113. package/dist/responses/agent-cli.d.ts +2 -0
  114. package/dist/responses/agent-cli.d.ts.map +1 -0
  115. package/dist/responses/agent-cli.js +31 -0
  116. package/dist/responses/agent-cli.js.map +1 -0
  117. package/dist/responses/agent.d.ts +80 -0
  118. package/dist/responses/agent.d.ts.map +1 -0
  119. package/dist/responses/agent.js +49 -0
  120. package/dist/responses/agent.js.map +1 -0
  121. package/dist/responses/await.d.ts +39 -0
  122. package/dist/responses/await.d.ts.map +1 -0
  123. package/dist/responses/await.js +21 -0
  124. package/dist/responses/await.js.map +1 -0
  125. package/dist/responses/composerHtml.d.ts +27 -0
  126. package/dist/responses/composerHtml.d.ts.map +1 -0
  127. package/dist/responses/composerHtml.js +14 -0
  128. package/dist/responses/composerHtml.js.map +1 -0
  129. package/dist/responses/flags.d.ts +6 -0
  130. package/dist/responses/flags.d.ts.map +1 -0
  131. package/dist/responses/flags.js +23 -0
  132. package/dist/responses/flags.js.map +1 -0
  133. package/dist/responses/history.d.ts +20 -0
  134. package/dist/responses/history.d.ts.map +1 -0
  135. package/dist/responses/history.js +16 -0
  136. package/dist/responses/history.js.map +1 -0
  137. package/dist/responses/locate.d.ts +13 -0
  138. package/dist/responses/locate.d.ts.map +1 -0
  139. package/dist/responses/locate.js +55 -0
  140. package/dist/responses/locate.js.map +1 -0
  141. package/dist/responses/make.d.ts +3 -0
  142. package/dist/responses/make.d.ts.map +1 -0
  143. package/dist/responses/make.js +16 -0
  144. package/dist/responses/make.js.map +1 -0
  145. package/dist/responses/outcome.d.ts +71 -0
  146. package/dist/responses/outcome.d.ts.map +1 -0
  147. package/dist/responses/outcome.js +14 -0
  148. package/dist/responses/outcome.js.map +1 -0
  149. package/dist/responses/page.d.ts +6 -0
  150. package/dist/responses/page.d.ts.map +1 -0
  151. package/dist/responses/page.js +22 -0
  152. package/dist/responses/page.js.map +1 -0
  153. package/dist/responses/publish.d.ts +4 -0
  154. package/dist/responses/publish.d.ts.map +1 -0
  155. package/dist/responses/publish.js +56 -0
  156. package/dist/responses/publish.js.map +1 -0
  157. package/dist/responses/publishIn.d.ts +3 -0
  158. package/dist/responses/publishIn.d.ts.map +1 -0
  159. package/dist/responses/publishIn.js +69 -0
  160. package/dist/responses/publishIn.js.map +1 -0
  161. package/dist/responses/read.d.ts +36 -0
  162. package/dist/responses/read.d.ts.map +1 -0
  163. package/dist/responses/read.js +43 -0
  164. package/dist/responses/read.js.map +1 -0
  165. package/dist/responses/records.d.ts +12 -0
  166. package/dist/responses/records.d.ts.map +1 -0
  167. package/dist/responses/records.js +49 -0
  168. package/dist/responses/records.js.map +1 -0
  169. package/dist/responses/retry.d.ts +34 -0
  170. package/dist/responses/retry.d.ts.map +1 -0
  171. package/dist/responses/retry.js +14 -0
  172. package/dist/responses/retry.js.map +1 -0
  173. package/dist/responses/service.d.ts +142 -0
  174. package/dist/responses/service.d.ts.map +1 -0
  175. package/dist/responses/service.js +95 -0
  176. package/dist/responses/service.js.map +1 -0
  177. package/dist/responses/template.d.ts +7 -0
  178. package/dist/responses/template.d.ts.map +1 -0
  179. package/dist/responses/template.js +58 -0
  180. package/dist/responses/template.js.map +1 -0
  181. package/dist/responses/templateHtml.d.ts +7 -0
  182. package/dist/responses/templateHtml.d.ts.map +1 -0
  183. package/dist/responses/templateHtml.js +18 -0
  184. package/dist/responses/templateHtml.js.map +1 -0
  185. package/dist/responses/templateLinks.d.ts +3 -0
  186. package/dist/responses/templateLinks.d.ts.map +1 -0
  187. package/dist/responses/templateLinks.js +45 -0
  188. package/dist/responses/templateLinks.js.map +1 -0
  189. package/dist/responses/templateNodes.d.ts +17 -0
  190. package/dist/responses/templateNodes.d.ts.map +1 -0
  191. package/dist/responses/templateNodes.js +47 -0
  192. package/dist/responses/templateNodes.js.map +1 -0
  193. package/dist/responses/validateSupersedes.d.ts +5 -0
  194. package/dist/responses/validateSupersedes.d.ts.map +1 -0
  195. package/dist/responses/validateSupersedes.js +21 -0
  196. package/dist/responses/validateSupersedes.js.map +1 -0
  197. package/dist/responses/validatedInput.d.ts +3 -0
  198. package/dist/responses/validatedInput.d.ts.map +1 -0
  199. package/dist/responses/validatedInput.js +43 -0
  200. package/dist/responses/validatedInput.js.map +1 -0
  201. package/dist/responses/waitFor.d.ts +37 -0
  202. package/dist/responses/waitFor.d.ts.map +1 -0
  203. package/dist/responses/waitFor.js +47 -0
  204. package/dist/responses/waitFor.js.map +1 -0
  205. package/dist/rpc/contract.d.ts +125 -2
  206. package/dist/rpc/contract.d.ts.map +1 -1
  207. package/dist/rpc/contract.js +3 -2
  208. package/dist/rpc/contract.js.map +1 -1
  209. package/dist/rpc/responseContract.d.ts +260 -0
  210. package/dist/rpc/responseContract.d.ts.map +1 -0
  211. package/dist/rpc/responseContract.js +37 -0
  212. package/dist/rpc/responseContract.js.map +1 -0
  213. package/dist/rpc/server.d.ts +3 -1
  214. package/dist/rpc/server.d.ts.map +1 -1
  215. package/dist/rpc/server.js +6 -1
  216. package/dist/rpc/server.js.map +1 -1
  217. package/dist/serve-cli.d.ts +3 -0
  218. package/dist/serve-cli.d.ts.map +1 -0
  219. package/dist/serve-cli.js +20 -0
  220. package/dist/serve-cli.js.map +1 -0
  221. package/package.json +3 -3
  222. package/src/board.ts +16 -2
  223. package/src/browser/client.ts +30 -4
  224. package/src/browser/entry.ts +9 -0
  225. package/src/browser/responses/Prompt.ts +6 -0
  226. package/src/browser/responses/answerBody.ts +11 -0
  227. package/src/browser/responses/draftSession.ts +101 -0
  228. package/src/browser/responses/drafts.ts +82 -0
  229. package/src/browser/responses/preview.ts +7 -0
  230. package/src/browser/responses/questionnaireControls.ts +74 -0
  231. package/src/browser/responses/schema.ts +63 -0
  232. package/src/browser/responses/setup.ts +132 -0
  233. package/src/browser/responses/submissionFields.ts +15 -0
  234. package/src/browser/responses/submit.ts +33 -0
  235. package/src/cli.ts +14 -22
  236. package/src/files/changes.ts +2 -1
  237. package/src/http/respond.ts +2 -0
  238. package/src/metadata/backlinks.ts +5 -0
  239. package/src/metadata/problems.ts +3 -0
  240. package/src/metadata/schema.ts +6 -2
  241. package/src/page/attentionDetails.ts +2 -1
  242. package/src/page/metadataDetails.ts +6 -0
  243. package/src/page/navigationScript.ts +1 -1
  244. package/src/page/shell.ts +1 -1
  245. package/src/page/style.ts +3 -1
  246. package/src/page/swap.ts +3 -0
  247. package/src/path/Identity.ts +3 -0
  248. package/src/render/markdown.ts +5 -2
  249. package/src/render/questionnaireDocuments.ts +12 -0
  250. package/src/render/visualDocuments.ts +3 -0
  251. package/src/responses/agent-cli.ts +35 -0
  252. package/src/responses/agent.ts +59 -0
  253. package/src/responses/await.ts +21 -0
  254. package/src/responses/composerHtml.ts +28 -0
  255. package/src/responses/flags.ts +22 -0
  256. package/src/responses/history.ts +18 -0
  257. package/src/responses/locate.ts +60 -0
  258. package/src/responses/make.ts +17 -0
  259. package/src/responses/outcome.ts +15 -0
  260. package/src/responses/page.ts +30 -0
  261. package/src/responses/publish.ts +53 -0
  262. package/src/responses/publishIn.ts +64 -0
  263. package/src/responses/read.ts +45 -0
  264. package/src/responses/records.ts +55 -0
  265. package/src/responses/retry.ts +23 -0
  266. package/src/responses/service.ts +117 -0
  267. package/src/responses/template.ts +72 -0
  268. package/src/responses/templateHtml.ts +26 -0
  269. package/src/responses/templateLinks.ts +43 -0
  270. package/src/responses/templateNodes.ts +55 -0
  271. package/src/responses/validateSupersedes.ts +24 -0
  272. package/src/responses/validatedInput.ts +45 -0
  273. package/src/responses/waitFor.ts +58 -0
  274. package/src/rpc/contract.ts +3 -2
  275. package/src/rpc/responseContract.ts +46 -0
  276. package/src/rpc/server.ts +8 -1
  277. package/src/serve-cli.ts +37 -0
@@ -0,0 +1,142 @@
1
+ import { Effect, FileSystem } from "effect";
2
+ import { type DraftInput, ResponseFailed } from "#browser/responses/schema.ts";
3
+ import type { Changes } from "#files/changes.ts";
4
+ import type { Snapshot } from "#search/snapshot.ts";
5
+ import { responseHistory } from "./history.ts";
6
+ export interface ResponseOptions {
7
+ readonly changes: Changes;
8
+ readonly enabled: boolean;
9
+ readonly index: Effect.Effect<Snapshot, unknown>;
10
+ readonly root: string;
11
+ }
12
+ export declare const responseService: (options: ResponseOptions) => Effect.Effect<{
13
+ awaitResponse: (input: {
14
+ readonly question: string;
15
+ readonly after?: string | undefined;
16
+ }) => Effect.Effect<{
17
+ expired: boolean;
18
+ question: {
19
+ readonly context: string;
20
+ readonly id: string;
21
+ readonly question: {
22
+ readonly deadline: number;
23
+ readonly item: string;
24
+ readonly reason: string;
25
+ readonly registeredAt: number;
26
+ readonly request: string;
27
+ readonly reviewedRevision: string;
28
+ readonly source: string;
29
+ };
30
+ };
31
+ response: {
32
+ readonly body: string;
33
+ readonly id: string;
34
+ readonly response: {
35
+ readonly answers?: readonly {
36
+ readonly prompt: string;
37
+ readonly selected: readonly string[];
38
+ readonly text: string;
39
+ }[] | undefined;
40
+ readonly author: string;
41
+ readonly question: string;
42
+ readonly recordedAt: number;
43
+ readonly reviewedRevision: string;
44
+ readonly supersedes?: string | undefined;
45
+ readonly type: "answer" | "clarify" | "not_now";
46
+ };
47
+ } | undefined;
48
+ }, ResponseFailed, never>;
49
+ history: (preview: Parameters<typeof responseHistory>[1]) => Effect.Effect<{
50
+ readonly body: string;
51
+ readonly id: string;
52
+ readonly response: {
53
+ readonly answers?: readonly {
54
+ readonly prompt: string;
55
+ readonly selected: readonly string[];
56
+ readonly text: string;
57
+ }[] | undefined;
58
+ readonly author: string;
59
+ readonly question: string;
60
+ readonly recordedAt: number;
61
+ readonly reviewedRevision: string;
62
+ readonly supersedes?: string | undefined;
63
+ readonly type: "answer" | "clarify" | "not_now";
64
+ };
65
+ }[], ResponseFailed, never>;
66
+ locate: (item: string, request: string) => Effect.Effect<{
67
+ readonly context: string;
68
+ readonly id: string;
69
+ readonly item: string;
70
+ readonly reason: string;
71
+ readonly request: string;
72
+ readonly reviewedRevision: string;
73
+ readonly source: string;
74
+ }, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
75
+ read: (id: string) => Effect.Effect<{
76
+ readonly question: {
77
+ readonly context: string;
78
+ readonly id: string;
79
+ readonly question: {
80
+ readonly deadline: number;
81
+ readonly item: string;
82
+ readonly reason: string;
83
+ readonly registeredAt: number;
84
+ readonly request: string;
85
+ readonly reviewedRevision: string;
86
+ readonly source: string;
87
+ };
88
+ };
89
+ readonly responses: readonly {
90
+ readonly body: string;
91
+ readonly id: string;
92
+ readonly response: {
93
+ readonly answers?: readonly {
94
+ readonly prompt: string;
95
+ readonly selected: readonly string[];
96
+ readonly text: string;
97
+ }[] | undefined;
98
+ readonly author: string;
99
+ readonly question: string;
100
+ readonly recordedAt: number;
101
+ readonly reviewedRevision: string;
102
+ readonly supersedes?: string | undefined;
103
+ readonly type: "answer" | "clarify" | "not_now";
104
+ };
105
+ }[];
106
+ }, ResponseFailed, never>;
107
+ record: (draft: DraftInput) => Effect.Effect<{
108
+ readonly body: string;
109
+ readonly id: string;
110
+ readonly response: {
111
+ readonly answers?: readonly {
112
+ readonly prompt: string;
113
+ readonly selected: readonly string[];
114
+ readonly text: string;
115
+ }[] | undefined;
116
+ readonly author: string;
117
+ readonly question: string;
118
+ readonly recordedAt: number;
119
+ readonly reviewedRevision: string;
120
+ readonly supersedes?: string | undefined;
121
+ readonly type: "answer" | "clarify" | "not_now";
122
+ };
123
+ }, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
124
+ register: (input: {
125
+ readonly item: string;
126
+ readonly request: string;
127
+ readonly revision: string;
128
+ }) => Effect.Effect<{
129
+ readonly context: string;
130
+ readonly id: string;
131
+ readonly question: {
132
+ readonly deadline: number;
133
+ readonly item: string;
134
+ readonly reason: string;
135
+ readonly registeredAt: number;
136
+ readonly request: string;
137
+ readonly reviewedRevision: string;
138
+ readonly source: string;
139
+ };
140
+ }, ResponseFailed, FileSystem.FileSystem | import("effect/Path").Path>;
141
+ }, never, FileSystem.FileSystem>;
142
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/responses/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,UAAU,EAAa,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,KAAK,UAAU,EAAiB,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAU/C,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAKD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAkFD,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBApCxC,UAAU;;;;;;;;;;;;;;;;;sBAvCR;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;gCAoFtG,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { Clock, Effect, FileSystem, Semaphore } from "effect";
2
+ import { ResponseFailed } from "#browser/responses/schema.ts";
3
+ import { awaitResponse } from "./await.js";
4
+ import { responseHistory } from "./history.js";
5
+ import { locate as locateQuestion } from "./locate.js";
6
+ import { makeResponse } from "./make.js";
7
+ import { publish } from "./publish.js";
8
+ import { readResponses } from "./read.js";
9
+ import { questionMarkdown, responseMarkdown } from "./records.js";
10
+ import { retryResponse } from "./retry.js";
11
+ import { validatedInput } from "./validatedInput.js";
12
+ import { validateSupersedes } from "./validateSupersedes.js";
13
+ function reject(code, message) {
14
+ return Effect.fail(new ResponseFailed({ code, message }));
15
+ }
16
+ const HOURS_48 = 48 * 60 * 60 * 1000;
17
+ export const responseService = Effect.fn("WorkBoard.responseService")(function* (options) {
18
+ const fs = yield* FileSystem.FileSystem;
19
+ const lock = yield* Semaphore.make(1);
20
+ const snapshot = options.index.pipe(Effect.catch(() => reject("Unavailable", "The workspace could not be indexed.")));
21
+ const enabled = options.enabled ? Effect.void : reject("Disabled", "Start with --responses to explicitly enable local question/response writes.");
22
+ const locate = locateQuestion(options.root, options.changes.realRoot, snapshot, fs);
23
+ const read = readResponses(snapshot);
24
+ function register(input) {
25
+ return lock.withPermit(Effect.gen(function* () {
26
+ yield* enabled;
27
+ const preview = yield* locate(input.item, input.request);
28
+ if (preview.reviewedRevision !== input.revision) {
29
+ return yield* reject("Stale", "Source changed since review. Read it again before registering this question.");
30
+ }
31
+ const data = yield* snapshot;
32
+ const matches = data.model.ids.get(preview.id);
33
+ if (matches?.length) {
34
+ if (matches.length !== 1 || matches[0]?.file !== `responses/${preview.id}.md`) {
35
+ return yield* reject("Conflict", "The registered identity moved or is duplicated. Read the existing record instead of retrying a write.");
36
+ }
37
+ const saved = (yield* read(preview.id)).question;
38
+ yield* publish(options.root, options.changes.realRoot, saved.id, questionMarkdown(saved));
39
+ return saved;
40
+ }
41
+ const now = yield* Clock.currentTimeMillis;
42
+ const question = {
43
+ context: preview.context,
44
+ id: preview.id,
45
+ question: {
46
+ deadline: now + HOURS_48,
47
+ item: preview.item,
48
+ reason: preview.reason,
49
+ registeredAt: now,
50
+ request: preview.request,
51
+ reviewedRevision: preview.reviewedRevision,
52
+ source: preview.source,
53
+ },
54
+ };
55
+ yield* publish(options.root, options.changes.realRoot, question.id, questionMarkdown(question)).pipe(Effect.ensuring(options.changes.refresh ?? Effect.void));
56
+ return question;
57
+ }));
58
+ }
59
+ function record(draft) {
60
+ return lock.withPermit(Effect.gen(function* () {
61
+ yield* enabled;
62
+ const result = yield* read(draft.question);
63
+ const input = yield* Effect.try({
64
+ catch: (cause) => new ResponseFailed({ code: "Conflict", message: String(cause) }),
65
+ try: () => validatedInput(draft, result.question.context, result.question.question.request, result.question.question.source),
66
+ });
67
+ const existing = result.responses.find((candidate) => candidate.id === input.id);
68
+ if (existing) {
69
+ yield* retryResponse(existing, input, snapshot, options);
70
+ return existing;
71
+ }
72
+ const { question } = result;
73
+ const current = yield* locate(question.question.item, question.question.request);
74
+ if (current.reviewedRevision !== question.question.reviewedRevision || current.source !== question.question.source) {
75
+ return yield* reject("Stale", "Source changed or moved. Keep the draft and review the new revision before responding.");
76
+ }
77
+ const data = yield* snapshot;
78
+ yield* validateSupersedes(input, question, data);
79
+ if (data.model.ids.has(input.id)) {
80
+ return yield* reject("Conflict", "This response identity is already used.");
81
+ }
82
+ const response = makeResponse(input, question, result.responses.reduce((time, saved) => Math.max(time, saved.response.recordedAt + 1), yield* Clock.currentTimeMillis));
83
+ yield* publish(options.root, options.changes.realRoot, response.id, responseMarkdown(response)).pipe(Effect.ensuring(options.changes.refresh ?? Effect.void));
84
+ return response;
85
+ }));
86
+ }
87
+ function history(preview) {
88
+ return Effect.flatMap(snapshot, (data) => Effect.try({
89
+ catch: (cause) => new ResponseFailed({ code: "Unavailable", message: String(cause) }),
90
+ try: () => responseHistory(data, preview),
91
+ }));
92
+ }
93
+ return { awaitResponse: awaitResponse(read), history, locate, read, record, register };
94
+ });
95
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/responses/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Prompt } from "#browser/responses/Prompt.ts";
2
+ export interface Template {
3
+ readonly context: string;
4
+ readonly prompts: readonly Prompt[];
5
+ }
6
+ export declare function questionTemplate(context: string, request: string, file?: string): Template;
7
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/responses/template.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAK3D,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAuBD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,CAmC1F"}
@@ -0,0 +1,58 @@
1
+ import remarkDirective from "remark-directive";
2
+ import remarkParse from "remark-parse";
3
+ import { unified } from "unified";
4
+ import { metadataParse } from "#metadata/parse.ts";
5
+ import { templateLinks } from "./templateLinks.js";
6
+ import { isContainer, promptFrom, sliceNode } from "./templateNodes.js";
7
+ function nestedControl(node) {
8
+ return (((node.type === "leafDirective" || node.type === "textDirective" || node.type === "containerDirective")
9
+ && ["question", "option"].includes(node.name))
10
+ || ("children" in node && node.children.some(nestedControl)));
11
+ }
12
+ function scopedPrompt(node, source, requests, request) {
13
+ const result = promptFrom(node, source);
14
+ if (result.request !== undefined && !requests.some((entry) => entry.id === result.request)) {
15
+ throw new Error("A question's request= must name an attention request in this document.");
16
+ }
17
+ if (result.request === undefined && requests.filter((entry) => entry.state === "open").length > 1) {
18
+ throw new Error("Use request= on question directives when a document has several open attention requests.");
19
+ }
20
+ return result.request === undefined || result.request === request ? result.prompt : undefined;
21
+ }
22
+ export function questionTemplate(context, request, file) {
23
+ const parsed = metadataParse(context);
24
+ const parser = unified().use(remarkParse).use(remarkDirective);
25
+ const body = parsed.body.replace(/\r\n?/gu, "\n");
26
+ const original = parser.parse(body);
27
+ const source = file === undefined ? body : templateLinks(body, original.children, file);
28
+ const tree = parser.parse(source);
29
+ const definitions = tree.children
30
+ .filter((node) => node.type === "definition")
31
+ .map((node) => sliceNode(source, node))
32
+ .join("\n\n");
33
+ const prompts = [];
34
+ const plain = [];
35
+ for (const node of tree.children) {
36
+ if (isContainer(node) && node.name === "question") {
37
+ const prompt = scopedPrompt(node, source, parsed.fields.attention ?? [], request);
38
+ if (prompt) {
39
+ prompts.push({
40
+ ...prompt,
41
+ options: prompt.options.map((option) => ({ ...option, source: `${option.source}\n\n${definitions}`.trim() })),
42
+ source: `${prompt.source}\n\n${definitions}`.trim(),
43
+ });
44
+ }
45
+ }
46
+ else {
47
+ if (nestedControl(node)) {
48
+ throw new Error("Use top-level question containers with direct option children.");
49
+ }
50
+ plain.push(sliceNode(source, node));
51
+ }
52
+ }
53
+ if (prompts.length > 32 || new Set(prompts.map((prompt) => prompt.id)).size !== prompts.length) {
54
+ throw new Error("Use at most 32 questions with unique IDs per attention request.");
55
+ }
56
+ return { context: plain.join("\n\n"), prompts };
57
+ }
58
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/responses/template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Effect } from "effect";
2
+ export declare const templateHtml: (context: string, request: string, file: string) => Effect.Effect<{
3
+ background: string;
4
+ controls: string;
5
+ hasPrompts: boolean;
6
+ }, import("../render/failed.ts").RenderFailed, import("../render/highlighter.ts").Highlighter>;
7
+ //# sourceMappingURL=templateHtml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateHtml.d.ts","sourceRoot":"","sources":["../../src/responses/templateHtml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAKhC,eAAO,MAAM,YAAY;;;;8FAoBvB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Effect } from "effect";
2
+ import { escapeHtml } from "#page/escape.ts";
3
+ import { renderMarkdown } from "#render/markdown.ts";
4
+ import { questionTemplate } from "./template.js";
5
+ export const templateHtml = Effect.fn("WorkBoard.templateHtml")(function* (context, request, file) {
6
+ const template = questionTemplate(context, request, file);
7
+ function render(source) {
8
+ return renderMarkdown(source, { file, safe: true });
9
+ }
10
+ const background = yield* render(template.context);
11
+ const controls = yield* Effect.forEach(template.prompts, (prompt, index) => Effect.gen(function* () {
12
+ const description = yield* render(prompt.source);
13
+ const options = yield* Effect.forEach(prompt.options, (option, choice) => Effect.map(render(option.source), (html) => `<div class="question-option"><input id="question-${index}-${choice}" type="${prompt.mode === "one" ? "radio" : "checkbox"}" name="choice-${escapeHtml(prompt.id)}" value="${escapeHtml(option.id)}" data-option-source="${escapeHtml(option.source)}"><div><label for="question-${index}-${choice}">Option ${escapeHtml(option.id)}</label>${html}</div></div>`));
14
+ return `<fieldset data-prompt="${escapeHtml(prompt.id)}" data-mode="${prompt.mode}" data-source="${escapeHtml(prompt.source)}"><legend>Question ${index + 1} · ${escapeHtml(prompt.id)}</legend>${description}<p>${prompt.mode === "text" ? "Answer in your own words" : `${prompt.mode === "one" ? "Choose one option" : "Choose any combination"}, or answer in your own words`}. Nothing is selected for you.</p>${options.join("")}${prompt.mode === "text" ? "" : '<button type="button" data-clear-choices>Clear selections</button>'}<label>Additional text / another answer<textarea data-answer-text maxlength="8192" rows="3"></textarea></label></fieldset>`;
15
+ }));
16
+ return { background, controls: controls.join(""), hasPrompts: template.prompts.length > 0 };
17
+ });
18
+ //# sourceMappingURL=templateHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateHtml.js","sourceRoot":"","sources":["../../src/responses/templateHtml.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAe,EAAE,OAAe,EAAE,IAAY;IACxH,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC1D,SAAS,MAAM,CAAC,MAAc;QAC7B,OAAO,cAAc,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAC1E,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CACxE,MAAM,CAAC,GAAG,CACT,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EACrB,CAAC,IAAI,EAAE,EAAE,CACR,oDAAoD,KAAK,IAAI,MAAM,WAAW,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,kBAAkB,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,yBAAyB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,+BAA+B,KAAK,IAAI,MAAM,YAAY,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,IAAI,cAAc,CACjW,CACD,CAAC;QACF,OAAO,0BAA0B,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,gBAAgB,MAAM,CAAC,IAAI,kBAAkB,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,sBAAsB,KAAK,GAAG,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,YAAY,WAAW,MAAM,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,wBAAwB,+BAA+B,qCAAqC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,oEAAoE,4HAA4H,CAAC;IACzoB,CAAC,CAAC,CACF,CAAC;IACF,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;AAC7F,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { RootContent } from "mdast";
2
+ export declare function templateLinks(source: string, nodes: readonly RootContent[], file: string): string;
3
+ //# sourceMappingURL=templateLinks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateLinks.d.ts","sourceRoot":"","sources":["../../src/responses/templateLinks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAazC,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,UA6BxF"}
@@ -0,0 +1,45 @@
1
+ import { fileUrl } from "#files/url.ts";
2
+ function destination(url, file) {
3
+ if (url.startsWith("//") || url.search(/^[a-z][a-z\d+.-]*:/iu) === 0) {
4
+ return url;
5
+ }
6
+ const resolved = new URL(url, `http://work-board.local${fileUrl(file)}`);
7
+ return resolved.pathname + resolved.search + resolved.hash;
8
+ }
9
+ function titleSuffix(title) {
10
+ return title ? ` "${title.replaceAll("\\", "\\\\").replaceAll('"', '\\"')}"` : "";
11
+ }
12
+ export function templateLinks(source, nodes, file) {
13
+ const edits = [];
14
+ function visit(node) {
15
+ const start = node.position?.start.offset;
16
+ const end = node.position?.end.offset;
17
+ if (start === undefined || end === undefined) {
18
+ return;
19
+ }
20
+ if (node.type === "link") {
21
+ const label = source.slice(node.children.at(0)?.position?.start.offset, node.children.at(-1)?.position?.end.offset);
22
+ edits.push({ end, start, text: `[${label}](<${destination(node.url, file)}>${titleSuffix(node.title)})` });
23
+ }
24
+ else if (node.type === "image") {
25
+ edits.push({
26
+ end,
27
+ start,
28
+ text: `![${(node.alt ?? "").replaceAll("[", "\\[").replaceAll("]", "\\]")}](<${destination(node.url, file)}>${titleSuffix(node.title)})`,
29
+ });
30
+ }
31
+ else if (node.type === "definition") {
32
+ edits.push({ end, start, text: `[${node.label ?? node.identifier}]: <${destination(node.url, file)}>${titleSuffix(node.title)}` });
33
+ }
34
+ else if ("children" in node) {
35
+ node.children.forEach(visit);
36
+ }
37
+ }
38
+ nodes.forEach(visit);
39
+ let result = source;
40
+ for (const edit of edits.sort((a, b) => b.start - a.start)) {
41
+ result = result.slice(0, edit.start) + edit.text + result.slice(edit.end);
42
+ }
43
+ return result;
44
+ }
45
+ //# sourceMappingURL=templateLinks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateLinks.js","sourceRoot":"","sources":["../../src/responses/templateLinks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { RootContent } from "mdast";
2
+ import type { ContainerDirective } from "mdast-util-directive";
3
+ export declare function sliceNode(source: string, node: RootContent): string;
4
+ export declare function isContainer(node: RootContent): node is ContainerDirective;
5
+ export declare function promptFrom(node: ContainerDirective, source: string): {
6
+ prompt: {
7
+ id: string;
8
+ mode: "many" | "one" | "text";
9
+ options: {
10
+ id: string;
11
+ source: string;
12
+ }[];
13
+ source: string;
14
+ };
15
+ request: string | undefined;
16
+ };
17
+ //# sourceMappingURL=templateNodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateNodes.d.ts","sourceRoot":"","sources":["../../src/responses/templateNodes.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAQ/D,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,UAE1D;AACD,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,IAAI,kBAAkB,CAEzE;AAQD,wBAAgB,UAAU,CAAC,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;EA+BlE"}
@@ -0,0 +1,47 @@
1
+ import { Schema } from "effect";
2
+ import { Identity } from "#path/Identity.ts";
3
+ const Id = Identity.check(Schema.isMaxLength(128));
4
+ const PromptFields = Schema.Struct({ id: Id, request: Schema.optional(Identity), select: Schema.optional(Schema.Literals(["one", "many", "text"])) });
5
+ const OptionFields = Schema.Struct({ id: Id });
6
+ export function sliceNode(source, node) {
7
+ return source.slice(node.position?.start.offset, node.position?.end.offset);
8
+ }
9
+ export function isContainer(node) {
10
+ return node.type === "containerDirective";
11
+ }
12
+ function hasControl(node) {
13
+ return (((node.type === "containerDirective" || node.type === "leafDirective" || node.type === "textDirective")
14
+ && ["question", "option"].includes(node.name))
15
+ || ("children" in node && node.children.some(hasControl)));
16
+ }
17
+ export function promptFrom(node, source) {
18
+ const attrs = Schema.decodeUnknownSync(PromptFields, { onExcessProperty: "error" })(node.attributes ?? {});
19
+ const options = node.children.filter((child) => isContainer(child) && child.name === "option");
20
+ const description = node.children.filter((child) => !(isContainer(child) && child.name === "option"));
21
+ if (description.some(hasControl)
22
+ || description.length === 0
23
+ || options.length > 32
24
+ || (attrs.select === "text" ? options.length > 0 : options.length === 0)) {
25
+ throw new Error("A question needs Markdown context and 1–32 direct options (or select=text without options), without nested questions.");
26
+ }
27
+ const choices = options.map((option) => {
28
+ if (!isContainer(option) || option.children.some(hasControl) || option.children.length === 0) {
29
+ throw new Error("Options need Markdown descriptions and cannot nest response controls.");
30
+ }
31
+ const fields = Schema.decodeUnknownSync(OptionFields, { onExcessProperty: "error" })(option.attributes ?? {});
32
+ return { id: fields.id, source: option.children.map((child) => sliceNode(source, child)).join("\n\n") };
33
+ });
34
+ if (new Set(choices.map((option) => option.id)).size !== choices.length) {
35
+ throw new Error("Option IDs must be unique within each question.");
36
+ }
37
+ return {
38
+ prompt: {
39
+ id: attrs.id,
40
+ mode: attrs.select ?? "one",
41
+ options: choices,
42
+ source: description.map((child) => sliceNode(source, child)).join("\n\n"),
43
+ },
44
+ request: attrs.request,
45
+ };
46
+ }
47
+ //# sourceMappingURL=templateNodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templateNodes.js","sourceRoot":"","sources":["../../src/responses/templateNodes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Effect } from "effect";
2
+ import { type DraftInput, type Question, ResponseFailed } from "#browser/responses/schema.ts";
3
+ import type { Snapshot } from "#search/snapshot.ts";
4
+ export declare function validateSupersedes(input: DraftInput, question: Question, data: Snapshot): Effect.Effect<void, never, never> | Effect.Effect<never, ResponseFailed, never>;
5
+ //# sourceMappingURL=validateSupersedes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateSupersedes.d.ts","sourceRoot":"","sources":["../../src/responses/validateSupersedes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,mFAkBvF"}
@@ -0,0 +1,21 @@
1
+ import { Effect } from "effect";
2
+ import { ResponseFailed } from "#browser/responses/schema.ts";
3
+ import { questionFrom, responseFrom } from "./records.js";
4
+ export function validateSupersedes(input, question, data) {
5
+ if (input.supersedes === undefined) {
6
+ return Effect.void;
7
+ }
8
+ const matches = data.model.ids.get(input.supersedes);
9
+ const previous = matches?.length === 1 && matches[0] ? responseFrom(matches[0]) : undefined;
10
+ const context = previous && data.model.ids.get(previous.response.question);
11
+ const old = context?.length === 1 && context[0] ? questionFrom(context[0]) : undefined;
12
+ return old
13
+ && previous
14
+ && previous.response.reviewedRevision === old.question.reviewedRevision
15
+ && old.question.item === question.question.item
16
+ && old.question.request === question.question.request
17
+ && input.supersedes !== input.id
18
+ ? Effect.void
19
+ : Effect.fail(new ResponseFailed({ code: "Conflict", message: "Supersedes must identify one recorded response to this item's attention request." }));
20
+ }
21
+ //# sourceMappingURL=validateSupersedes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateSupersedes.js","sourceRoot":"","sources":["../../src/responses/validateSupersedes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAkC,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9F,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,UAAU,kBAAkB,CAAC,KAAiB,EAAE,QAAkB,EAAE,IAAc;IACvF,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,OAAO,MAAM,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5F,MAAM,OAAO,GAAG,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,OAAO,EAAE,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,OAAO,GAAG;WACN,QAAQ;WACR,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,KAAK,GAAG,CAAC,QAAQ,CAAC,gBAAgB;WACpE,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,QAAQ,CAAC,IAAI;WAC5C,GAAG,CAAC,QAAQ,CAAC,OAAO,KAAK,QAAQ,CAAC,QAAQ,CAAC,OAAO;WAClD,KAAK,CAAC,UAAU,KAAK,KAAK,CAAC,EAAE;QAChC,CAAC,CAAC,MAAM,CAAC,IAAI;QACb,CAAC,CAAC,MAAM,CAAC,IAAI,CACX,IAAI,cAAc,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,kFAAkF,EAAE,CAAC,CACrI,CAAC;AACL,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { DraftInput } from "#browser/responses/schema.ts";
2
+ export declare function validatedInput(input: DraftInput, context: string, request: string, file?: string): DraftInput;
3
+ //# sourceMappingURL=validatedInput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validatedInput.d.ts","sourceRoot":"","sources":["../../src/responses/validatedInput.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,8BAA8B,CAAC;AAiB7E,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,CAyB7G"}
@@ -0,0 +1,43 @@
1
+ import { answerBody } from "#browser/responses/answerBody.ts";
2
+ import { questionTemplate } from "./template.js";
3
+ function answerFor(prompt, answer, required) {
4
+ if (!answer || answer.prompt !== prompt.id) {
5
+ throw new Error("Submit one answer per question, in template order.");
6
+ }
7
+ if (new Set(answer.selected).size !== answer.selected.length || (prompt.mode === "one" && answer.selected.length > 1)) {
8
+ throw new Error("The selected options do not match the question's selection mode.");
9
+ }
10
+ if (answer.selected.some((id) => !prompt.options.some((option) => option.id === id))) {
11
+ throw new Error("A selected option is not in the reviewed template.");
12
+ }
13
+ if (required && answer.selected.length === 0 && !answer.text.trim()) {
14
+ throw new Error("Answer every question with a selection or additional text, or use Clarify / Not now.");
15
+ }
16
+ }
17
+ export function validatedInput(input, context, request, file) {
18
+ const template = questionTemplate(context, request, file);
19
+ if (input.answers === undefined) {
20
+ if (template.prompts.length > 0 && input.type === "answer") {
21
+ throw new Error("This question packet requires answers for all prompts.");
22
+ }
23
+ if (!input.body.trim()) {
24
+ throw new Error("A response needs text or answers to the question packet.");
25
+ }
26
+ return input;
27
+ }
28
+ if (input.answers.length !== template.prompts.length || template.prompts.length === 0) {
29
+ throw new Error("The answer packet does not match the reviewed questions.");
30
+ }
31
+ template.prompts.forEach((prompt, index) => {
32
+ answerFor(prompt, input.answers?.[index], input.type === "answer");
33
+ });
34
+ if (input.type !== "answer" && !input.body.trim() && !input.answers.some((answer) => answer.text.trim())) {
35
+ throw new Error("Clarify / Not now needs explanatory text.");
36
+ }
37
+ const body = answerBody(template.prompts, input.answers, input.body);
38
+ if (body.length > 32_768) {
39
+ throw new Error("The complete recorded response exceeds 32768 characters. Shorten the response or split the source request.");
40
+ }
41
+ return { ...input, body };
42
+ }
43
+ //# sourceMappingURL=validatedInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validatedInput.js","sourceRoot":"","sources":["../../src/responses/validatedInput.ts"],"names":[],"mappings":"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"}