@rse/ase 1.0.6 → 2.0.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 (279) hide show
  1. package/dst/ase-agent-definition-api.d.ts +184 -0
  2. package/dst/ase-agent-definition-api.js +6 -0
  3. package/dst/ase-agent-definition-builtin/condenser.js +42 -0
  4. package/dst/ase-agent-definition-builtin/editor.js +45 -0
  5. package/dst/ase-agent-definition-builtin/estimator.js +98 -0
  6. package/dst/ase-agent-definition-builtin/implementer.js +121 -0
  7. package/dst/ase-agent-definition-builtin/integrator.js +56 -0
  8. package/dst/ase-agent-definition-builtin/qualifier.js +61 -0
  9. package/dst/ase-agent-definition-builtin/rebooter.js +41 -0
  10. package/dst/ase-agent-definition-builtin/researcher.js +77 -0
  11. package/dst/ase-agent-definition-core.js +827 -0
  12. package/dst/ase-agent-fleet.js +772 -0
  13. package/dst/ase-agent-process.js +232 -0
  14. package/dst/ase-agent-relay-client.js +509 -0
  15. package/dst/ase-agent-relay-core.js +213 -0
  16. package/dst/ase-agent-relay-server-bind.js +242 -0
  17. package/dst/ase-agent-relay-server-cli.js +50 -0
  18. package/dst/ase-agent-runtime-claim.js +189 -0
  19. package/dst/ase-agent-runtime-engine.js +1100 -0
  20. package/dst/ase-agent-runtime-exec.js +275 -0
  21. package/dst/ase-agent-runtime-phase.js +581 -0
  22. package/dst/ase-agent-runtime-request.js +272 -0
  23. package/dst/ase-agent-runtime-tool.js +207 -0
  24. package/dst/ase-agent-runtime.js +1316 -0
  25. package/dst/ase-agent.js +65 -0
  26. package/dst/ase-artifact.js +6 -5
  27. package/dst/ase-config-core.js +465 -0
  28. package/dst/ase-config-schema.js +351 -0
  29. package/dst/ase-config-scope.js +172 -0
  30. package/dst/ase-config.js +25 -585
  31. package/dst/ase-hook.js +230 -116
  32. package/dst/ase-lib-daemon-cli.js +130 -0
  33. package/dst/ase-lib-hash.js +20 -0
  34. package/dst/{ase-log.js → ase-lib-log.js} +40 -7
  35. package/dst/ase-lib-server-bind.js +115 -0
  36. package/dst/ase-lib-server-cli.js +474 -0
  37. package/dst/{ase-table.js → ase-lib-table.js} +1 -1
  38. package/dst/{ase-version.js → ase-lib-version.js} +3 -0
  39. package/dst/ase-man.js +96 -0
  40. package/dst/ase-mcp.js +166 -13
  41. package/dst/{ase-getopt.js → ase-service-getopt.js} +82 -80
  42. package/dst/{ase-markdown.js → ase-service-markdown.js} +18 -11
  43. package/dst/ase-service-otel.js +1246 -0
  44. package/dst/{ase-skills.js → ase-service-skills.js} +29 -64
  45. package/dst/ase-service-state.js +101 -0
  46. package/dst/ase-service.js +251 -76
  47. package/dst/ase-setup-common.js +141 -0
  48. package/dst/ase-setup-mcp.js +359 -0
  49. package/dst/ase-setup-settings.js +837 -0
  50. package/dst/ase-setup.js +113 -869
  51. package/dst/ase-spec.js +31 -19
  52. package/dst/ase-statusline.js +108 -43
  53. package/dst/ase-task-board-core.js +739 -0
  54. package/dst/ase-task-board-filter.js +127 -0
  55. package/dst/ase-task-board-flow.js +237 -0
  56. package/dst/ase-task-board-graph.js +497 -0
  57. package/dst/ase-task-board-stats.js +263 -0
  58. package/dst/ase-task-board-tui-control.js +775 -0
  59. package/dst/ase-task-board-tui-model.js +1008 -0
  60. package/dst/ase-task-board-tui-popup.js +626 -0
  61. package/dst/ase-task-board-tui-style.js +106 -0
  62. package/dst/ase-task-board-tui-view.js +847 -0
  63. package/dst/ase-task-board-tui.js +189 -0
  64. package/dst/ase-task-board-web-client.css +1 -0
  65. package/dst/ase-task-board-web-client.html +20 -0
  66. package/dst/ase-task-board-web-client.js +81 -0
  67. package/dst/ase-task-board-web-server.js +823 -0
  68. package/dst/ase-task-board.js +134 -0
  69. package/dst/ase-task-format.js +757 -0
  70. package/dst/ase-task-request.js +208 -0
  71. package/dst/ase-task-store-client.js +495 -0
  72. package/dst/ase-task-store-core.js +804 -0
  73. package/dst/ase-task-store-issues.js +237 -0
  74. package/dst/ase-task-store-plugin-api.js +6 -0
  75. package/dst/ase-task-store-plugin-ase.js +484 -0
  76. package/dst/ase-task-store-plugin-delegate.js +137 -0
  77. package/dst/ase-task-store-plugin-gitea.js +666 -0
  78. package/dst/ase-task-store-plugin-github.js +696 -0
  79. package/dst/ase-task-store-plugin-gitlab.js +668 -0
  80. package/dst/ase-task-store-server-bind.js +538 -0
  81. package/dst/ase-task-store-server-cli.js +154 -0
  82. package/dst/ase-task.js +1335 -357
  83. package/dst/{ase-compat.js → ase-util-compat.js} +2 -2
  84. package/dst/{ase-diagram.js → ase-util-diagram.js} +107 -32
  85. package/dst/{ase-meta.js → ase-util-meta.js} +2 -2
  86. package/dst/{ase-metric.js → ase-util-metric.js} +2 -2
  87. package/dst/{ase-mint.js → ase-util-mint.js} +19 -12
  88. package/dst/{ase-worktree.js → ase-util-worktree.js} +30 -19
  89. package/dst/ase-util.js +20 -0
  90. package/dst/ase.js +108 -32
  91. package/dst/man/ase-agent-adhoc.1 +515 -0
  92. package/dst/man/ase-agent-condenser.1 +193 -0
  93. package/dst/man/ase-agent-editor.1 +212 -0
  94. package/dst/man/ase-agent-estimator.1 +214 -0
  95. package/dst/man/ase-agent-fleet.1 +185 -0
  96. package/dst/man/ase-agent-implementer.1 +233 -0
  97. package/dst/man/ase-agent-integrator.1 +213 -0
  98. package/dst/man/ase-agent-qualifier.1 +214 -0
  99. package/dst/man/ase-agent-rebooter.1 +193 -0
  100. package/dst/man/ase-agent-relay.1 +128 -0
  101. package/dst/man/ase-agent-researcher.1 +217 -0
  102. package/dst/man/ase-agent.1 +264 -0
  103. package/dst/man/ase-artifact-list.1 +38 -0
  104. package/dst/man/ase-artifact-name.1 +39 -0
  105. package/dst/man/ase-artifact.1 +56 -0
  106. package/dst/man/ase-config-delete.1 +45 -0
  107. package/dst/man/ase-config-edit.1 +48 -0
  108. package/dst/man/ase-config-get.1 +46 -0
  109. package/dst/man/ase-config-init.1 +60 -0
  110. package/dst/man/ase-config-list.1 +42 -0
  111. package/dst/man/ase-config-set.1 +52 -0
  112. package/dst/man/ase-config.1 +225 -0
  113. package/dst/man/ase-hook-permission-request.1 +36 -0
  114. package/dst/man/ase-hook-pre-tool-use.1 +59 -0
  115. package/dst/man/ase-hook-session-end.1 +47 -0
  116. package/dst/man/ase-hook-session-persona.1 +37 -0
  117. package/dst/man/ase-hook-session-start.1 +81 -0
  118. package/dst/man/ase-hook-stop.1 +34 -0
  119. package/dst/man/ase-hook-user-prompt-submit.1 +34 -0
  120. package/dst/man/ase-hook.1 +51 -0
  121. package/dst/man/ase-man.1 +67 -0
  122. package/dst/man/ase-mcp.1 +61 -0
  123. package/dst/man/ase-service-log.1 +43 -0
  124. package/dst/man/ase-service-send.1 +47 -0
  125. package/dst/man/ase-service-start.1 +54 -0
  126. package/dst/man/ase-service-status.1 +46 -0
  127. package/dst/man/ase-service-stop.1 +37 -0
  128. package/dst/man/ase-service.1 +85 -0
  129. package/dst/man/ase-setup-disable.1 +44 -0
  130. package/dst/man/ase-setup-enable.1 +45 -0
  131. package/dst/man/ase-setup-install.1 +73 -0
  132. package/dst/man/ase-setup-mcp.1 +124 -0
  133. package/dst/man/ase-setup-status.1 +60 -0
  134. package/dst/man/ase-setup-statusline.1 +92 -0
  135. package/dst/man/ase-setup-telemetry.1 +92 -0
  136. package/dst/man/ase-setup-uninstall.1 +59 -0
  137. package/dst/man/ase-setup-update.1 +64 -0
  138. package/dst/man/ase-setup.1 +93 -0
  139. package/dst/man/ase-spec-export.1 +62 -0
  140. package/dst/man/ase-spec-lint.1 +40 -0
  141. package/dst/man/ase-spec-preview.1 +40 -0
  142. package/dst/man/ase-spec.1 +46 -0
  143. package/dst/man/ase-statusline.1 +189 -0
  144. package/dst/man/ase-task-assign.1 +71 -0
  145. package/dst/man/ase-task-board.1 +384 -0
  146. package/dst/man/ase-task-delete.1 +35 -0
  147. package/dst/man/ase-task-edit.1 +46 -0
  148. package/dst/man/ase-task-idscheme.1 +65 -0
  149. package/dst/man/ase-task-lifecycle.1 +57 -0
  150. package/dst/man/ase-task-list.1 +47 -0
  151. package/dst/man/ase-task-load.1 +36 -0
  152. package/dst/man/ase-task-newid.1 +61 -0
  153. package/dst/man/ase-task-purge.1 +37 -0
  154. package/dst/man/ase-task-rename.1 +44 -0
  155. package/dst/man/ase-task-request.1 +61 -0
  156. package/dst/man/ase-task-save.1 +48 -0
  157. package/dst/man/ase-task-status.1 +55 -0
  158. package/dst/man/ase-task-store.1 +194 -0
  159. package/dst/man/ase-task-view.1 +40 -0
  160. package/dst/man/ase-task.1 +160 -0
  161. package/dst/man/ase-util-compat.1 +25 -0
  162. package/dst/man/ase-util-diagram.1 +76 -0
  163. package/dst/man/ase-util-meta.1 +45 -0
  164. package/dst/man/ase-util-metric.1 +54 -0
  165. package/dst/man/ase-util-mint.1 +59 -0
  166. package/dst/man/ase-util-worktree.1 +72 -0
  167. package/dst/man/ase-util.1 +50 -0
  168. package/dst/man/ase.1 +124 -0
  169. package/package.json +79 -21
  170. package/plugin/.claude-plugin/plugin.json +1 -1
  171. package/plugin/.codex-plugin/plugin.json +1 -1
  172. package/plugin/.github/plugin/plugin.json +1 -1
  173. package/plugin/agents/ase-meta-diagram.md +12 -8
  174. package/plugin/agents/ase-repo-review.md +322 -0
  175. package/plugin/hooks/hooks-codex.json +5 -0
  176. package/plugin/hooks/hooks-copilot.json +5 -0
  177. package/plugin/hooks/hooks.json +8 -0
  178. package/plugin/meta/ase-common-approach.md +117 -0
  179. package/plugin/meta/ase-common-changeset.md +256 -0
  180. package/plugin/meta/ase-common-code.md +10 -173
  181. package/plugin/meta/ase-common-grill.md +317 -0
  182. package/plugin/meta/ase-common-resolve.md +305 -0
  183. package/plugin/meta/ase-common-task.md +83 -4
  184. package/plugin/meta/ase-constitution.md +0 -2
  185. package/plugin/meta/ase-format-specbook.md +208 -25
  186. package/plugin/meta/ase-format-specbook.yaml +242 -851
  187. package/plugin/meta/ase-format-task.md +669 -125
  188. package/plugin/meta/ase-persona.md +3 -4
  189. package/plugin/meta/ase-skill.md +9 -0
  190. package/plugin/mods/ase-mods.ts +409 -0
  191. package/plugin/mods/claude-code.d.ts +13417 -0
  192. package/plugin/skills/ase-arch-analyze/SKILL.md +1 -1
  193. package/plugin/skills/ase-arch-analyze/help.md +2 -2
  194. package/plugin/skills/ase-code-analyze/SKILL.md +59 -8
  195. package/plugin/skills/ase-code-analyze/help.md +29 -4
  196. package/plugin/skills/ase-code-edit/SKILL.md +107 -181
  197. package/plugin/skills/ase-code-edit/help.md +118 -31
  198. package/plugin/skills/ase-code-lint/SKILL.md +64 -13
  199. package/plugin/skills/ase-code-lint/help.md +32 -2
  200. package/plugin/skills/ase-docs-proofread/SKILL.md +4 -4
  201. package/plugin/skills/ase-docs-proofread/help.md +1 -1
  202. package/plugin/skills/ase-docs-refine/SKILL.md +4 -4
  203. package/plugin/skills/ase-docs-shorten/SKILL.md +4 -4
  204. package/plugin/skills/ase-help-intent/data.md +2164 -1087
  205. package/plugin/skills/ase-help-intent/help.md +1 -1
  206. package/plugin/skills/ase-help-skill/catalog.md +12 -9
  207. package/plugin/skills/ase-meta-brainstorm/SKILL.md +1 -1
  208. package/plugin/skills/ase-meta-config/SKILL.md +3 -4
  209. package/plugin/skills/ase-meta-config/help.md +31 -10
  210. package/plugin/skills/ase-meta-mint/SKILL.md +5 -5
  211. package/plugin/skills/ase-meta-mint/help.md +10 -5
  212. package/plugin/skills/ase-meta-why/help.md +1 -1
  213. package/plugin/skills/ase-meta-workflow/SKILL.md +7 -7
  214. package/plugin/skills/ase-meta-workflow/help.md +4 -4
  215. package/plugin/skills/ase-meta-workflow/sample.md +3 -3
  216. package/plugin/skills/ase-meta-workflow/workflow.txt +22 -18
  217. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/SKILL.md +4 -3
  218. package/plugin/skills/{ase-meta-changelog → ase-repo-changelog}/help.md +5 -5
  219. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/SKILL.md +6 -6
  220. package/plugin/skills/{ase-meta-commit → ase-repo-commit}/help.md +5 -5
  221. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/SKILL.md +6 -6
  222. package/plugin/skills/{ase-meta-diff → ase-repo-diff}/help.md +8 -8
  223. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/SKILL.md +19 -19
  224. package/plugin/skills/{ase-code-dissect → ase-repo-dissect}/help.md +10 -12
  225. package/plugin/skills/ase-repo-merge/SKILL.md +346 -0
  226. package/plugin/skills/ase-repo-merge/help.md +107 -0
  227. package/plugin/skills/ase-repo-resolve/SKILL.md +158 -0
  228. package/plugin/skills/ase-repo-resolve/help.md +102 -0
  229. package/plugin/skills/ase-repo-review/SKILL.md +406 -0
  230. package/plugin/skills/ase-repo-review/help.md +181 -0
  231. package/plugin/skills/ase-spec-edit/SKILL.md +117 -183
  232. package/plugin/skills/ase-spec-edit/help.md +107 -26
  233. package/plugin/skills/ase-sync-reconcile/help.md +1 -1
  234. package/plugin/skills/ase-task-assign/SKILL.md +111 -0
  235. package/plugin/skills/ase-task-assign/help.md +119 -0
  236. package/plugin/skills/ase-task-condense/SKILL.md +21 -21
  237. package/plugin/skills/ase-task-condense/help.md +12 -10
  238. package/plugin/skills/ase-task-delete/SKILL.md +1 -1
  239. package/plugin/skills/ase-task-dissect/SKILL.md +71 -48
  240. package/plugin/skills/ase-task-dissect/help.md +10 -9
  241. package/plugin/skills/ase-task-edit/SKILL.md +379 -94
  242. package/plugin/skills/ase-task-edit/help.md +95 -22
  243. package/plugin/skills/ase-task-estimate/SKILL.md +492 -0
  244. package/plugin/skills/ase-task-estimate/help.md +158 -0
  245. package/plugin/skills/ase-task-grill/SKILL.md +246 -138
  246. package/plugin/skills/ase-task-grill/help.md +129 -26
  247. package/plugin/skills/ase-task-id/SKILL.md +8 -1
  248. package/plugin/skills/ase-task-id/help.md +6 -3
  249. package/plugin/skills/ase-task-implement/SKILL.md +535 -145
  250. package/plugin/skills/ase-task-implement/help.md +138 -47
  251. package/plugin/skills/ase-task-integrate/SKILL.md +549 -0
  252. package/plugin/skills/ase-task-integrate/help.md +187 -0
  253. package/plugin/skills/ase-task-list/SKILL.md +55 -23
  254. package/plugin/skills/ase-task-list/help.md +45 -21
  255. package/plugin/skills/ase-task-reboot/SKILL.md +84 -43
  256. package/plugin/skills/ase-task-reboot/help.md +28 -8
  257. package/plugin/skills/ase-task-rename/SKILL.md +10 -2
  258. package/plugin/skills/ase-task-research/SKILL.md +386 -0
  259. package/plugin/skills/ase-task-research/help.md +102 -0
  260. package/plugin/skills/ase-task-status/SKILL.md +137 -0
  261. package/plugin/skills/ase-task-status/help.md +80 -0
  262. package/plugin/skills/ase-task-view/SKILL.md +49 -24
  263. package/plugin/skills/ase-task-view/help.md +19 -9
  264. package/plugin/agents/ase-meta-review.md +0 -187
  265. package/plugin/skills/ase-code-craft/SKILL.md +0 -264
  266. package/plugin/skills/ase-code-craft/help.md +0 -122
  267. package/plugin/skills/ase-code-refactor/SKILL.md +0 -232
  268. package/plugin/skills/ase-code-refactor/help.md +0 -109
  269. package/plugin/skills/ase-code-resolve/SKILL.md +0 -289
  270. package/plugin/skills/ase-code-resolve/help.md +0 -116
  271. package/plugin/skills/ase-meta-review/SKILL.md +0 -210
  272. package/plugin/skills/ase-meta-review/help.md +0 -96
  273. package/plugin/skills/ase-task-preflight/SKILL.md +0 -166
  274. package/plugin/skills/ase-task-preflight/help.md +0 -82
  275. /package/dst/{ase-ignore.js → ase-lib-ignore.js} +0 -0
  276. /package/dst/{ase-stdio.js → ase-lib-stdio.js} +0 -0
  277. /package/dst/{ase-kv.js → ase-service-kv.js} +0 -0
  278. /package/dst/{ase-sleep.js → ase-service-sleep.js} +0 -0
  279. /package/dst/{ase-timestamp.js → ase-service-timestamp.js} +0 -0
@@ -0,0 +1,208 @@
1
+ /*
2
+ ** Agentic Software Engineering (ASE)
3
+ ** Copyright (c) 2025-2026 Dr. Ralf S. Engelschall <rse@engelschall.com>
4
+ ** Licensed under Apache 2.0 <https://spdx.org/licenses/Apache-2.0>
5
+ */
6
+ import { DateTime } from "luxon";
7
+ import { Task } from "./ase-task.js";
8
+ import * as TaskFormat from "./ase-task-format.js";
9
+ /* a parameter of an attachment type (else empty), where a quoted value
10
+ is unescaped (a backslash escapes the following character), and where the
11
+ parameters are scanned in sequence (so no quoted value is mistaken for one) */
12
+ export const typeParam = (type, name) => {
13
+ const key = name.toLowerCase();
14
+ for (const m of type.matchAll(/;\s*([^=;\s]+)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|([^;\s]+))/g))
15
+ if (m[1].toLowerCase() === key)
16
+ return m[2] !== undefined ? m[2].replace(/\\(.)/g, "$1") : m[3];
17
+ return "";
18
+ };
19
+ /* the quoted value of a parameter of an attachment type (a backslash escapes
20
+ a backslash and a double quote, and control characters become spaces) */
21
+ const typeQuote = (value) => `"${value.replace(/[\\"]/g, "\\$&").replace(/\p{Cc}/gu, " ")}"`;
22
+ /* the current timestamp of the attachments */
23
+ export const attachmentTime = () => DateTime.now().toFormat("yyyy-LL-dd HH:mm");
24
+ /* whether a request to a task in a status is refused (a finished status)
25
+ resp. deferred (an activity status, where the task is actively worked on) */
26
+ export const requestRefused = (lifecycle, status) => lifecycle.finished.includes(status);
27
+ export const requestDeferred = (lifecycle, status) => lifecycle.activity.includes(status);
28
+ /* the error of a refused request, carrying its reason */
29
+ export class RequestError extends Error {
30
+ reason;
31
+ constructor(reason, message) {
32
+ super(message);
33
+ this.reason = reason;
34
+ }
35
+ }
36
+ /* the requests to a request agent, attached to tasks as plain-text attachments (with the
37
+ prompt as their content), whose type carries their state as its "kind" parameter (e.g.
38
+ "edit" when requested, "edit-running" while being processed, and "edit-failed" when failed),
39
+ and whose aggregated state is mirrored as a tag in the task header (e.g.
40
+ "ase-agent-editor:pending"), as the dispatching of the agent and the task boards both see
41
+ the task headers only, where <name> names the requests (e.g. "edit"), <tag> is the
42
+ tag (e.g. "ase-agent-editor"), <done> describes a processed task (e.g. "edited"), and
43
+ <prompted> tells whether a request requires a prompt (else it may have an empty one,
44
+ as some request agents ignore the prompts, and the request agents consuming them refuse
45
+ an empty one themselves on processing the request) */
46
+ export class TaskRequests {
47
+ name;
48
+ tag;
49
+ done;
50
+ prompted;
51
+ kinds;
52
+ constructor(name, tag, done, prompted = false) {
53
+ this.name = name;
54
+ this.tag = tag;
55
+ this.done = done;
56
+ this.prompted = prompted;
57
+ this.kinds = { pending: name, active: `${name}-running`, failed: `${name}-failed` };
58
+ }
59
+ /* the state of an attachment type of a request (else undefined) */
60
+ state(type) {
61
+ if (!/^text\/plain\s*(?:;|$)/i.test(type.trim()))
62
+ return undefined;
63
+ const kind = typeParam(type, "kind");
64
+ return Object.keys(this.kinds).find((state) => this.kinds[state] === kind);
65
+ }
66
+ /* the attachment type of a request in a state, with additional parameters */
67
+ type(state, params = {}) {
68
+ return `text/plain; charset=utf-8; kind="${this.kinds[state]}"` +
69
+ Object.entries(params).map(([key, value]) => `; ${key}=${typeQuote(value)}`).join("");
70
+ }
71
+ /* the aggregated state of the requests of a task by its header tag (else empty) */
72
+ of(keys) {
73
+ const state = (keys.get("Tags") ?? "").split(",").map((tag) => tag.trim())
74
+ .find((tag) => tag.startsWith(`${this.tag}:`))?.slice(this.tag.length + 1) ?? "";
75
+ return state === "pending" || state === "active" || state === "failed" ? state : "";
76
+ }
77
+ /* the tags of a task plan without the request tag */
78
+ foreignTags(plan) {
79
+ const field = plan.header.Tags ?? [];
80
+ return (Array.isArray(field) ? field : field.split(","))
81
+ .map((tag) => tag.trim())
82
+ .filter((tag) => tag !== "" && tag !== this.tag && !tag.startsWith(`${this.tag}:`));
83
+ }
84
+ /* re-derive the tag of a task plan from its request attachments,
85
+ where a processed request dominates a requested one, which dominates a failed one */
86
+ retag(plan) {
87
+ const states = plan.attachment.map((att) => this.state(att.Type ?? ""));
88
+ const state = ["active", "pending", "failed"].find((s) => states.includes(s));
89
+ const tags = this.foreignTags(plan);
90
+ if (state !== undefined)
91
+ tags.push(`${this.tag}:${state}`);
92
+ if (tags.length > 0)
93
+ plan.header.Tags = tags;
94
+ else
95
+ delete plan.header.Tags;
96
+ }
97
+ /* finalize a processed request (at index <i>) of a task plan: remove it (state null), or turn
98
+ it back into a requested or into a failed one (with a description), restore the previous
99
+ assignee of the task (or hand it over to the given <assignee> instead, where an empty one
100
+ unassigns it), unless it was reassigned meanwhile, and re-derive the request tag */
101
+ finalize(plan, i, state, desc, assignee) {
102
+ const att = plan.attachment[i];
103
+ const type = att.Type ?? "";
104
+ if (String(plan.header.Assignee ?? "") === typeParam(type, "agent")) {
105
+ const previous = assignee ?? typeParam(type, "assignee");
106
+ if (previous !== "")
107
+ plan.header.Assignee = previous;
108
+ else
109
+ delete plan.header.Assignee;
110
+ }
111
+ if (state === null)
112
+ plan.attachment.splice(i, 1);
113
+ else
114
+ plan.attachment[i] = { ...att, Type: this.type(state), ...(desc !== undefined ? { Desc: desc } : {}), Modified: attachmentTime() };
115
+ this.retag(plan);
116
+ }
117
+ /* the prompt of the most recent failed request of a task plan (for its re-request), else empty */
118
+ failedPrompt(plan) {
119
+ const failed = plan.attachment.filter((att) => this.state(att.Type ?? "") === "failed");
120
+ return (failed.at(-1)?.Data ?? "").trim();
121
+ }
122
+ /* the prompt of the most recent failed request of a task (for its re-request), else empty */
123
+ async prompt(log, id) {
124
+ return (await Task.inspect(log, id, (plan) => this.failedPrompt(plan))) ?? "";
125
+ }
126
+ /* probe a task for a new request (loading it only once): the reason a request is
127
+ refused (a missing or finished task, or a request in progress), else the prompt
128
+ of its most recent failed request (for its re-request), else empty */
129
+ async probe(log, id) {
130
+ const result = await Task.inspect(log, id, (plan, lifecycle) => {
131
+ if (requestRefused(lifecycle, TaskFormat.taskStatus(plan.header, lifecycle)))
132
+ return { refused: "finished" };
133
+ if (this.running(plan))
134
+ return { refused: "running" };
135
+ return { prompt: this.failedPrompt(plan) };
136
+ });
137
+ return result ?? { refused: "missing" };
138
+ }
139
+ /* whether a task plan has a request being processed */
140
+ running(plan) {
141
+ return plan.attachment.some((att) => this.state(att.Type ?? "") === "active");
142
+ }
143
+ /* request the processing of a task by a prompt (which may be empty, unless the requests
144
+ require a prompt), replacing all its failed requests (refused for a finished task, and
145
+ while a request is being processed, as adding a request changes the task plan under the
146
+ agent processing the running one, whose conditional save of the task plan would then fail) */
147
+ async request(log, id, prompt) {
148
+ const text = prompt.trim();
149
+ if (text === "" && this.prompted)
150
+ throw new RequestError("empty", `empty ${this.name} prompt`);
151
+ let refused = "";
152
+ let running = false;
153
+ const exists = await Task.update(log, id, (plan, lifecycle) => {
154
+ const status = TaskFormat.taskStatus(plan.header, lifecycle);
155
+ if (requestRefused(lifecycle, status)) {
156
+ refused = status;
157
+ return false;
158
+ }
159
+ if (this.running(plan)) {
160
+ running = true;
161
+ return false;
162
+ }
163
+ const line = text !== "" ? text.replace(/\s+/g, " ") : `${this.name} request without prompt`;
164
+ const time = attachmentTime();
165
+ plan.attachment = plan.attachment.filter((att) => this.state(att.Type ?? "") !== "failed");
166
+ plan.attachment.push({
167
+ Type: this.type("pending"), Desc: line.length > 60 ? `${line.slice(0, 59)}…` : line,
168
+ Created: time, Modified: time, Data: text !== "" ? `${text}\n` : ""
169
+ });
170
+ this.retag(plan);
171
+ return true;
172
+ });
173
+ if (!exists)
174
+ throw new RequestError("missing", `no task "${id}"`);
175
+ if (refused !== "")
176
+ throw new RequestError("finished", `task "${id}" is finished (status "${refused}") -- ${this.name} refused`);
177
+ if (running)
178
+ throw new RequestError("running", `${this.name} of task "${id}" in progress -- new ${this.name} refused`);
179
+ }
180
+ }
181
+ /* the edit requests: requested ("edit"), being processed by an editor agent
182
+ ("edit-running"), and failed ("edit-failed", to be re-requested), mirrored
183
+ in the task header as tag "ase-agent-editor:<state>", always requiring a prompt */
184
+ export const edits = new TaskRequests("edit", "ase-agent-editor", "edited", true);
185
+ /* the valid names of requests: lower-case words, not ending in a state suffix of a request kind */
186
+ export const REQUEST_NAME_RE = /^(?!.*-(?:running|failed)$)[a-z][a-z0-9-]*$/;
187
+ /* the requests of a name (e.g. "lint", processed by a request agent of a definition),
188
+ mirrored in the task header as tag "ase-agent-<name>:<state>", where the edit requests
189
+ ("edit") are the ones of the editor agent */
190
+ export const requestsOf = (name) => {
191
+ if (!REQUEST_NAME_RE.test(name))
192
+ throw new Error(`invalid request name "${name}" ` +
193
+ "(expected a lower-case word of letters, digits, and dashes, not ending in \"-running\" or \"-failed\")");
194
+ if (["rebooter", "condenser", "implementer", "qualifier", "integrator", "editor", "estimator", "researcher"].includes(name))
195
+ throw new Error(`invalid request name "${name}" (its tag "ase-agent-${name}" is the one of a built-in agent)`);
196
+ return name === edits.name ? edits : new TaskRequests(name, `ase-agent-${name}`, "processed");
197
+ };
198
+ export const editOf = (keys) => edits.of(keys);
199
+ /* whether an edit request of a task in a status is refused (a finished status) */
200
+ export const editRefused = requestRefused;
201
+ /* the prompt of the most recent failed edit request of a task (for its re-request), else empty */
202
+ export const editPrompt = (log, id) => edits.prompt(log, id);
203
+ /* probe a task for a new edit request: the reason it is refused, else the prompt
204
+ of its most recent failed edit request (for its re-request), else empty */
205
+ export const editProbe = (log, id) => edits.probe(log, id);
206
+ /* request the edit of a task by a prompt, replacing all its failed edit requests
207
+ (refused for an empty prompt, a missing or finished task, or an edit in progress) */
208
+ export const requestEdit = (log, id, prompt) => edits.request(log, id, prompt);