@agimon-ai/doompi-task 0.0.1-alpha.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 (190) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +35 -0
  3. package/dist/_virtual/_rolldown/runtime.cjs +1 -0
  4. package/dist/commands.cjs +2 -0
  5. package/dist/commands.cjs.map +1 -0
  6. package/dist/commands.d.cts +14 -0
  7. package/dist/commands.d.cts.map +1 -0
  8. package/dist/commands.d.mts +14 -0
  9. package/dist/commands.d.mts.map +1 -0
  10. package/dist/commands.mjs +2 -0
  11. package/dist/commands.mjs.map +1 -0
  12. package/dist/config.cjs +2 -0
  13. package/dist/config.cjs.map +1 -0
  14. package/dist/config.d.cts +38 -0
  15. package/dist/config.d.cts.map +1 -0
  16. package/dist/config.d.mts +38 -0
  17. package/dist/config.d.mts.map +1 -0
  18. package/dist/config.mjs +2 -0
  19. package/dist/config.mjs.map +1 -0
  20. package/dist/delegation/manager.cjs +5 -0
  21. package/dist/delegation/manager.cjs.map +1 -0
  22. package/dist/delegation/manager.d.cts +189 -0
  23. package/dist/delegation/manager.d.cts.map +1 -0
  24. package/dist/delegation/manager.d.mts +189 -0
  25. package/dist/delegation/manager.d.mts.map +1 -0
  26. package/dist/delegation/manager.mjs +5 -0
  27. package/dist/delegation/manager.mjs.map +1 -0
  28. package/dist/extension.cjs +3 -0
  29. package/dist/extension.cjs.map +1 -0
  30. package/dist/extension.d.cts +12 -0
  31. package/dist/extension.d.cts.map +1 -0
  32. package/dist/extension.d.mts +12 -0
  33. package/dist/extension.d.mts.map +1 -0
  34. package/dist/extension.mjs +3 -0
  35. package/dist/extension.mjs.map +1 -0
  36. package/dist/extensions/doom.cjs +2 -0
  37. package/dist/extensions/doom.cjs.map +1 -0
  38. package/dist/extensions/doom.d.cts +6 -0
  39. package/dist/extensions/doom.d.cts.map +1 -0
  40. package/dist/extensions/doom.d.mts +7 -0
  41. package/dist/extensions/doom.d.mts.map +1 -0
  42. package/dist/extensions/doom.mjs +2 -0
  43. package/dist/extensions/doom.mjs.map +1 -0
  44. package/dist/extensions/pi.cjs +2 -0
  45. package/dist/extensions/pi.cjs.map +1 -0
  46. package/dist/extensions/pi.d.cts +2 -0
  47. package/dist/extensions/pi.d.mts +2 -0
  48. package/dist/extensions/pi.mjs +2 -0
  49. package/dist/extensions/pi.mjs.map +1 -0
  50. package/dist/index.cjs +1 -0
  51. package/dist/index.d.cts +15 -0
  52. package/dist/index.d.mts +15 -0
  53. package/dist/index.mjs +1 -0
  54. package/dist/logSinkTelemetry.cjs +2 -0
  55. package/dist/logSinkTelemetry.cjs.map +1 -0
  56. package/dist/logSinkTelemetry.d.cts +51 -0
  57. package/dist/logSinkTelemetry.d.cts.map +1 -0
  58. package/dist/logSinkTelemetry.d.mts +51 -0
  59. package/dist/logSinkTelemetry.d.mts.map +1 -0
  60. package/dist/logSinkTelemetry.mjs +2 -0
  61. package/dist/logSinkTelemetry.mjs.map +1 -0
  62. package/dist/store/invariants.cjs +2 -0
  63. package/dist/store/invariants.cjs.map +1 -0
  64. package/dist/store/invariants.d.cts +14 -0
  65. package/dist/store/invariants.d.cts.map +1 -0
  66. package/dist/store/invariants.d.mts +14 -0
  67. package/dist/store/invariants.d.mts.map +1 -0
  68. package/dist/store/invariants.mjs +2 -0
  69. package/dist/store/invariants.mjs.map +1 -0
  70. package/dist/store/paths.cjs +2 -0
  71. package/dist/store/paths.cjs.map +1 -0
  72. package/dist/store/paths.d.cts +23 -0
  73. package/dist/store/paths.d.cts.map +1 -0
  74. package/dist/store/paths.d.mts +23 -0
  75. package/dist/store/paths.d.mts.map +1 -0
  76. package/dist/store/paths.mjs +2 -0
  77. package/dist/store/paths.mjs.map +1 -0
  78. package/dist/store/processLiveness.cjs +2 -0
  79. package/dist/store/processLiveness.cjs.map +1 -0
  80. package/dist/store/processLiveness.d.cts +12 -0
  81. package/dist/store/processLiveness.d.cts.map +1 -0
  82. package/dist/store/processLiveness.d.mts +12 -0
  83. package/dist/store/processLiveness.d.mts.map +1 -0
  84. package/dist/store/processLiveness.mjs +2 -0
  85. package/dist/store/processLiveness.mjs.map +1 -0
  86. package/dist/store/reconcile.cjs +2 -0
  87. package/dist/store/reconcile.cjs.map +1 -0
  88. package/dist/store/reconcile.d.cts +34 -0
  89. package/dist/store/reconcile.d.cts.map +1 -0
  90. package/dist/store/reconcile.d.mts +34 -0
  91. package/dist/store/reconcile.d.mts.map +1 -0
  92. package/dist/store/reconcile.mjs +2 -0
  93. package/dist/store/reconcile.mjs.map +1 -0
  94. package/dist/store/reducer.cjs +3 -0
  95. package/dist/store/reducer.cjs.map +1 -0
  96. package/dist/store/reducer.d.cts +72 -0
  97. package/dist/store/reducer.d.cts.map +1 -0
  98. package/dist/store/reducer.d.mts +72 -0
  99. package/dist/store/reducer.d.mts.map +1 -0
  100. package/dist/store/reducer.mjs +3 -0
  101. package/dist/store/reducer.mjs.map +1 -0
  102. package/dist/store/taskGraph.cjs +2 -0
  103. package/dist/store/taskGraph.cjs.map +1 -0
  104. package/dist/store/taskGraph.d.cts +25 -0
  105. package/dist/store/taskGraph.d.cts.map +1 -0
  106. package/dist/store/taskGraph.d.mts +25 -0
  107. package/dist/store/taskGraph.d.mts.map +1 -0
  108. package/dist/store/taskGraph.mjs +2 -0
  109. package/dist/store/taskGraph.mjs.map +1 -0
  110. package/dist/store/taskStore.cjs +2 -0
  111. package/dist/store/taskStore.cjs.map +1 -0
  112. package/dist/store/taskStore.d.cts +77 -0
  113. package/dist/store/taskStore.d.cts.map +1 -0
  114. package/dist/store/taskStore.d.mts +77 -0
  115. package/dist/store/taskStore.d.mts.map +1 -0
  116. package/dist/store/taskStore.mjs +2 -0
  117. package/dist/store/taskStore.mjs.map +1 -0
  118. package/dist/store/types.cjs +2 -0
  119. package/dist/store/types.cjs.map +1 -0
  120. package/dist/store/types.d.cts +165 -0
  121. package/dist/store/types.d.cts.map +1 -0
  122. package/dist/store/types.d.mts +165 -0
  123. package/dist/store/types.d.mts.map +1 -0
  124. package/dist/store/types.mjs +2 -0
  125. package/dist/store/types.mjs.map +1 -0
  126. package/dist/tool/promptGuidelines.cjs +2 -0
  127. package/dist/tool/promptGuidelines.cjs.map +1 -0
  128. package/dist/tool/promptGuidelines.d.cts +5 -0
  129. package/dist/tool/promptGuidelines.d.cts.map +1 -0
  130. package/dist/tool/promptGuidelines.d.mts +5 -0
  131. package/dist/tool/promptGuidelines.d.mts.map +1 -0
  132. package/dist/tool/promptGuidelines.mjs +2 -0
  133. package/dist/tool/promptGuidelines.mjs.map +1 -0
  134. package/dist/tool/responseEnvelope.cjs +6 -0
  135. package/dist/tool/responseEnvelope.cjs.map +1 -0
  136. package/dist/tool/responseEnvelope.d.cts +39 -0
  137. package/dist/tool/responseEnvelope.d.cts.map +1 -0
  138. package/dist/tool/responseEnvelope.d.mts +39 -0
  139. package/dist/tool/responseEnvelope.d.mts.map +1 -0
  140. package/dist/tool/responseEnvelope.mjs +6 -0
  141. package/dist/tool/responseEnvelope.mjs.map +1 -0
  142. package/dist/tool/schema.cjs +2 -0
  143. package/dist/tool/schema.cjs.map +1 -0
  144. package/dist/tool/schema.d.cts +86 -0
  145. package/dist/tool/schema.d.cts.map +1 -0
  146. package/dist/tool/schema.d.mts +86 -0
  147. package/dist/tool/schema.d.mts.map +1 -0
  148. package/dist/tool/schema.mjs +2 -0
  149. package/dist/tool/schema.mjs.map +1 -0
  150. package/dist/tool/taskTool.cjs +3 -0
  151. package/dist/tool/taskTool.cjs.map +1 -0
  152. package/dist/tool/taskTool.d.cts +17 -0
  153. package/dist/tool/taskTool.d.cts.map +1 -0
  154. package/dist/tool/taskTool.d.mts +17 -0
  155. package/dist/tool/taskTool.d.mts.map +1 -0
  156. package/dist/tool/taskTool.mjs +3 -0
  157. package/dist/tool/taskTool.mjs.map +1 -0
  158. package/dist/tui/format.cjs +4 -0
  159. package/dist/tui/format.cjs.map +1 -0
  160. package/dist/tui/format.d.cts +62 -0
  161. package/dist/tui/format.d.cts.map +1 -0
  162. package/dist/tui/format.d.mts +62 -0
  163. package/dist/tui/format.d.mts.map +1 -0
  164. package/dist/tui/format.mjs +4 -0
  165. package/dist/tui/format.mjs.map +1 -0
  166. package/dist/tui/selectors.cjs +2 -0
  167. package/dist/tui/selectors.cjs.map +1 -0
  168. package/dist/tui/selectors.d.cts +45 -0
  169. package/dist/tui/selectors.d.cts.map +1 -0
  170. package/dist/tui/selectors.d.mts +45 -0
  171. package/dist/tui/selectors.d.mts.map +1 -0
  172. package/dist/tui/selectors.mjs +2 -0
  173. package/dist/tui/selectors.mjs.map +1 -0
  174. package/dist/tui/taskOverlay.cjs +2 -0
  175. package/dist/tui/taskOverlay.cjs.map +1 -0
  176. package/dist/tui/taskOverlay.d.cts +38 -0
  177. package/dist/tui/taskOverlay.d.cts.map +1 -0
  178. package/dist/tui/taskOverlay.d.mts +38 -0
  179. package/dist/tui/taskOverlay.d.mts.map +1 -0
  180. package/dist/tui/taskOverlay.mjs +2 -0
  181. package/dist/tui/taskOverlay.mjs.map +1 -0
  182. package/dist/tui/taskSpace.cjs +5 -0
  183. package/dist/tui/taskSpace.cjs.map +1 -0
  184. package/dist/tui/taskSpace.d.cts +61 -0
  185. package/dist/tui/taskSpace.d.cts.map +1 -0
  186. package/dist/tui/taskSpace.d.mts +61 -0
  187. package/dist/tui/taskSpace.d.mts.map +1 -0
  188. package/dist/tui/taskSpace.mjs +5 -0
  189. package/dist/tui/taskSpace.mjs.map +1 -0
  190. package/package.json +185 -0
@@ -0,0 +1,165 @@
1
+ import { InlineAgent } from "@agimon-ai/doompi-extension-contracts/subagent-tool";
2
+ //#region src/store/types.d.ts
3
+ type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';
4
+ declare const DELETED_STATUS: TaskStatus;
5
+ type TaskAction = 'upsert' | 'list' | 'get' | 'delete' | 'clear' | 'assign' | 'cancel';
6
+ type DelegationState = 'requested' | 'running' | 'completed' | 'failed' | 'cancelled';
7
+ /** Terminal result of a delegated subagent run, copied off the delegation response. */
8
+ interface DelegationResult {
9
+ status: string;
10
+ output?: string;
11
+ outputPath?: string;
12
+ sessionFile?: string;
13
+ error?: string;
14
+ durationMs?: number;
15
+ toolCount?: number;
16
+ }
17
+ /**
18
+ * Delegation bookkeeping attached to a task that was handed to a subagent.
19
+ *
20
+ * `pid` is the harness process that owns the run: it is the only way to tell an
21
+ * genuinely-running delegation from one orphaned by a harness crash, since the
22
+ * child dies with its parent but the file survives.
23
+ */
24
+ interface TaskDelegation {
25
+ requestId: string;
26
+ agent: string;
27
+ state: DelegationState;
28
+ sessionId?: string;
29
+ pid?: number;
30
+ runId?: string;
31
+ model?: string;
32
+ startedAt?: string;
33
+ endedAt?: string;
34
+ result?: DelegationResult;
35
+ }
36
+ interface Task {
37
+ id: number;
38
+ subject: string;
39
+ description?: string;
40
+ activeForm?: string;
41
+ status: TaskStatus;
42
+ blockedBy?: number[];
43
+ owner?: string;
44
+ metadata?: Record<string, unknown>;
45
+ createdAt?: string;
46
+ updatedAt?: string;
47
+ delegation?: TaskDelegation;
48
+ }
49
+ declare const STORE_SCHEMA_VERSION = 1;
50
+ /** The complete on-disk document. `rev` increments on every committed write. */
51
+ interface TaskDocument {
52
+ version: number;
53
+ rev: number;
54
+ nextId: number;
55
+ tasks: Task[];
56
+ }
57
+ declare function emptyDocument(): TaskDocument;
58
+ /**
59
+ * A dependency target inside an upsert item: an existing task id, or the `ref`
60
+ * of a task created earlier in the same call.
61
+ *
62
+ * Refs must start with a letter (see `REF_PATTERN`), so a ref is structurally
63
+ * unconfusable with a stringified id and the discrimination is just `typeof`.
64
+ */
65
+ type DepToken = number | string;
66
+ /**
67
+ * One entry of an `upsert` call. No `id` creates a task; an `id` updates one.
68
+ *
69
+ * `blockedBy` (absolute set) is create-only and `addBlockedBy`/`removeBlockedBy`
70
+ * (additive merge) are update-only, matching the split the two former actions
71
+ * had. A field used against the wrong kind fails that item rather than being
72
+ * silently ignored.
73
+ */
74
+ interface TaskItemMutation {
75
+ id?: number;
76
+ ref?: string;
77
+ subject?: string;
78
+ description?: string;
79
+ activeForm?: string;
80
+ status?: TaskStatus;
81
+ blockedBy?: DepToken[];
82
+ addBlockedBy?: DepToken[];
83
+ removeBlockedBy?: DepToken[];
84
+ owner?: string;
85
+ metadata?: Record<string, unknown>;
86
+ }
87
+ /**
88
+ * What one upsert item did. `index` is its position in the request array, so a
89
+ * model reading a partial result can tell which entries still need resending.
90
+ *
91
+ * `message` is unprefixed: the `item[N] failed:` framing belongs to the
92
+ * formatter, because the Task Space overlay shows this text on its own.
93
+ */
94
+ type UpsertItemOutcome = {
95
+ index: number;
96
+ kind: 'created';
97
+ id: number;
98
+ subject: string;
99
+ status: TaskStatus;
100
+ ref?: string;
101
+ blockedBy?: number[];
102
+ } | {
103
+ index: number;
104
+ kind: 'updated';
105
+ id: number;
106
+ fromStatus: TaskStatus;
107
+ toStatus: TaskStatus;
108
+ } | {
109
+ index: number;
110
+ kind: 'unchanged';
111
+ id: number;
112
+ status: TaskStatus;
113
+ } | {
114
+ index: number;
115
+ kind: 'failed';
116
+ message: string;
117
+ id?: number;
118
+ ref?: string;
119
+ };
120
+ /** Which tasks an upsert touched, so renderResult names them instead of guessing. */
121
+ interface UpsertSummary {
122
+ /** Ids of applied entries, in request order. A failed entry contributes nothing. */
123
+ applied: number[];
124
+ failed: number;
125
+ }
126
+ /**
127
+ * Open-shape input bag the reducer accepts. The index signature lets the
128
+ * runtime pass a TypeBox `Static<typeof TaskParamsSchema>` through without
129
+ * casting each field.
130
+ *
131
+ * Per-task fields live on `tasks[]`, not here: a top-level `subject` or
132
+ * `status` would be ambiguous once one call can carry many tasks.
133
+ */
134
+ interface TaskMutationParams {
135
+ [key: string]: unknown;
136
+ tasks?: TaskItemMutation[];
137
+ /** `list` filter only. To set a status, upsert the task by id. */
138
+ status?: TaskStatus;
139
+ /** `get`, `delete`, `assign` and `cancel` only. */
140
+ id?: number;
141
+ includeDeleted?: boolean;
142
+ agent?: string;
143
+ inlineAgent?: InlineAgent;
144
+ instructions?: string;
145
+ /** `assign` only: the context pack the parent hands to the child. */
146
+ relevantFiles?: string[];
147
+ priorFindings?: string;
148
+ model?: string;
149
+ context?: 'fresh' | 'fork';
150
+ }
151
+ /** Snapshot returned under a tool result's `details` for renderResult. */
152
+ interface TaskDetails {
153
+ action: TaskAction;
154
+ params: Record<string, unknown>;
155
+ tasks: Task[];
156
+ nextId: number;
157
+ rev: number;
158
+ error?: string;
159
+ upsert?: UpsertSummary;
160
+ }
161
+ /** A delegation is "live" while the owning run may still produce a response. */
162
+ declare function isDelegationActive(task: Task): boolean;
163
+ //#endregion
164
+ export { DELETED_STATUS, DelegationResult, DelegationState, DepToken, STORE_SCHEMA_VERSION, Task, TaskAction, TaskDelegation, TaskDetails, TaskDocument, TaskItemMutation, TaskMutationParams, TaskStatus, UpsertItemOutcome, UpsertSummary, emptyDocument, isDelegationActive };
165
+ //# sourceMappingURL=types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.cts","names":[],"sources":["../../src/store/types.ts"],"mappings":";;KAUY;cAEC,gBAAgB;KAEjB;KAEA;;UAGK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;UAUe;EACf;EACA;EACA,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA,WAAW;EACX;EACA;EACA,aAAa;;cAGF;;UAGI;EACf;EACA;EACA;EACA,OAAO;;iBAGO,iBAAiB;;;;;;;;KAWrB;;;;;;;;;UAUK;EACf;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,YAAY;EACZ,eAAe;EACf,kBAAkB;EAClB;EACA,WAAW;;;;;;;;;KAUD;EAEN;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;;EAEA;EAAe;EAAiB;EAAY,YAAY;EAAY,UAAU;;EAC9E;EAAe;EAAmB;EAAY,QAAQ;;EACtD;EAAe;EAAgB;EAAiB;EAAa;;;UAGlD;;EAEf;EACA;;;;;;;;;;UAWe;GACd;EACD,QAAQ;;EAER,SAAS;;EAET;EACA;EACA;EACA,cAAc;EACd;;EAEA;EACA;EACA;EACA;;;UAIe;EACf,QAAQ;EACR,QAAQ;EACR,OAAO;EACP;EACA;EACA;EACA,SAAS;;;iBAIK,mBAAmB,MAAM"}
@@ -0,0 +1,165 @@
1
+ import { InlineAgent } from "@agimon-ai/doompi-extension-contracts/subagent-tool";
2
+ //#region src/store/types.d.ts
3
+ type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';
4
+ declare const DELETED_STATUS: TaskStatus;
5
+ type TaskAction = 'upsert' | 'list' | 'get' | 'delete' | 'clear' | 'assign' | 'cancel';
6
+ type DelegationState = 'requested' | 'running' | 'completed' | 'failed' | 'cancelled';
7
+ /** Terminal result of a delegated subagent run, copied off the delegation response. */
8
+ interface DelegationResult {
9
+ status: string;
10
+ output?: string;
11
+ outputPath?: string;
12
+ sessionFile?: string;
13
+ error?: string;
14
+ durationMs?: number;
15
+ toolCount?: number;
16
+ }
17
+ /**
18
+ * Delegation bookkeeping attached to a task that was handed to a subagent.
19
+ *
20
+ * `pid` is the harness process that owns the run: it is the only way to tell an
21
+ * genuinely-running delegation from one orphaned by a harness crash, since the
22
+ * child dies with its parent but the file survives.
23
+ */
24
+ interface TaskDelegation {
25
+ requestId: string;
26
+ agent: string;
27
+ state: DelegationState;
28
+ sessionId?: string;
29
+ pid?: number;
30
+ runId?: string;
31
+ model?: string;
32
+ startedAt?: string;
33
+ endedAt?: string;
34
+ result?: DelegationResult;
35
+ }
36
+ interface Task {
37
+ id: number;
38
+ subject: string;
39
+ description?: string;
40
+ activeForm?: string;
41
+ status: TaskStatus;
42
+ blockedBy?: number[];
43
+ owner?: string;
44
+ metadata?: Record<string, unknown>;
45
+ createdAt?: string;
46
+ updatedAt?: string;
47
+ delegation?: TaskDelegation;
48
+ }
49
+ declare const STORE_SCHEMA_VERSION = 1;
50
+ /** The complete on-disk document. `rev` increments on every committed write. */
51
+ interface TaskDocument {
52
+ version: number;
53
+ rev: number;
54
+ nextId: number;
55
+ tasks: Task[];
56
+ }
57
+ declare function emptyDocument(): TaskDocument;
58
+ /**
59
+ * A dependency target inside an upsert item: an existing task id, or the `ref`
60
+ * of a task created earlier in the same call.
61
+ *
62
+ * Refs must start with a letter (see `REF_PATTERN`), so a ref is structurally
63
+ * unconfusable with a stringified id and the discrimination is just `typeof`.
64
+ */
65
+ type DepToken = number | string;
66
+ /**
67
+ * One entry of an `upsert` call. No `id` creates a task; an `id` updates one.
68
+ *
69
+ * `blockedBy` (absolute set) is create-only and `addBlockedBy`/`removeBlockedBy`
70
+ * (additive merge) are update-only, matching the split the two former actions
71
+ * had. A field used against the wrong kind fails that item rather than being
72
+ * silently ignored.
73
+ */
74
+ interface TaskItemMutation {
75
+ id?: number;
76
+ ref?: string;
77
+ subject?: string;
78
+ description?: string;
79
+ activeForm?: string;
80
+ status?: TaskStatus;
81
+ blockedBy?: DepToken[];
82
+ addBlockedBy?: DepToken[];
83
+ removeBlockedBy?: DepToken[];
84
+ owner?: string;
85
+ metadata?: Record<string, unknown>;
86
+ }
87
+ /**
88
+ * What one upsert item did. `index` is its position in the request array, so a
89
+ * model reading a partial result can tell which entries still need resending.
90
+ *
91
+ * `message` is unprefixed: the `item[N] failed:` framing belongs to the
92
+ * formatter, because the Task Space overlay shows this text on its own.
93
+ */
94
+ type UpsertItemOutcome = {
95
+ index: number;
96
+ kind: 'created';
97
+ id: number;
98
+ subject: string;
99
+ status: TaskStatus;
100
+ ref?: string;
101
+ blockedBy?: number[];
102
+ } | {
103
+ index: number;
104
+ kind: 'updated';
105
+ id: number;
106
+ fromStatus: TaskStatus;
107
+ toStatus: TaskStatus;
108
+ } | {
109
+ index: number;
110
+ kind: 'unchanged';
111
+ id: number;
112
+ status: TaskStatus;
113
+ } | {
114
+ index: number;
115
+ kind: 'failed';
116
+ message: string;
117
+ id?: number;
118
+ ref?: string;
119
+ };
120
+ /** Which tasks an upsert touched, so renderResult names them instead of guessing. */
121
+ interface UpsertSummary {
122
+ /** Ids of applied entries, in request order. A failed entry contributes nothing. */
123
+ applied: number[];
124
+ failed: number;
125
+ }
126
+ /**
127
+ * Open-shape input bag the reducer accepts. The index signature lets the
128
+ * runtime pass a TypeBox `Static<typeof TaskParamsSchema>` through without
129
+ * casting each field.
130
+ *
131
+ * Per-task fields live on `tasks[]`, not here: a top-level `subject` or
132
+ * `status` would be ambiguous once one call can carry many tasks.
133
+ */
134
+ interface TaskMutationParams {
135
+ [key: string]: unknown;
136
+ tasks?: TaskItemMutation[];
137
+ /** `list` filter only. To set a status, upsert the task by id. */
138
+ status?: TaskStatus;
139
+ /** `get`, `delete`, `assign` and `cancel` only. */
140
+ id?: number;
141
+ includeDeleted?: boolean;
142
+ agent?: string;
143
+ inlineAgent?: InlineAgent;
144
+ instructions?: string;
145
+ /** `assign` only: the context pack the parent hands to the child. */
146
+ relevantFiles?: string[];
147
+ priorFindings?: string;
148
+ model?: string;
149
+ context?: 'fresh' | 'fork';
150
+ }
151
+ /** Snapshot returned under a tool result's `details` for renderResult. */
152
+ interface TaskDetails {
153
+ action: TaskAction;
154
+ params: Record<string, unknown>;
155
+ tasks: Task[];
156
+ nextId: number;
157
+ rev: number;
158
+ error?: string;
159
+ upsert?: UpsertSummary;
160
+ }
161
+ /** A delegation is "live" while the owning run may still produce a response. */
162
+ declare function isDelegationActive(task: Task): boolean;
163
+ //#endregion
164
+ export { DELETED_STATUS, DelegationResult, DelegationState, DepToken, STORE_SCHEMA_VERSION, Task, TaskAction, TaskDelegation, TaskDetails, TaskDocument, TaskItemMutation, TaskMutationParams, TaskStatus, UpsertItemOutcome, UpsertSummary, emptyDocument, isDelegationActive };
165
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/store/types.ts"],"mappings":";;KAUY;cAEC,gBAAgB;KAEjB;KAEA;;UAGK;EACf;EACA;EACA;EACA;EACA;EACA;EACA;;;;;;;;;UAUe;EACf;EACA;EACA,OAAO;EACP;EACA;EACA;EACA;EACA;EACA;EACA,SAAS;;UAGM;EACf;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;EACA,WAAW;EACX;EACA;EACA,aAAa;;cAGF;;UAGI;EACf;EACA;EACA;EACA,OAAO;;iBAGO,iBAAiB;;;;;;;;KAWrB;;;;;;;;;UAUK;EACf;EACA;EACA;EACA;EACA;EACA,SAAS;EACT,YAAY;EACZ,eAAe;EACf,kBAAkB;EAClB;EACA,WAAW;;;;;;;;;KAUD;EAEN;EACA;EACA;EACA;EACA,QAAQ;EACR;EACA;;EAEA;EAAe;EAAiB;EAAY,YAAY;EAAY,UAAU;;EAC9E;EAAe;EAAmB;EAAY,QAAQ;;EACtD;EAAe;EAAgB;EAAiB;EAAa;;;UAGlD;;EAEf;EACA;;;;;;;;;;UAWe;GACd;EACD,QAAQ;;EAER,SAAS;;EAET;EACA;EACA;EACA,cAAc;EACd;;EAEA;EACA;EACA;EACA;;;UAIe;EACf,QAAQ;EACR,QAAQ;EACR,OAAO;EACP;EACA;EACA;EACA,SAAS;;;iBAIK,mBAAmB,MAAM"}
@@ -0,0 +1,2 @@
1
+ const e=`deleted`,t=1;function n(){return{version:1,rev:0,nextId:1,tasks:[]}}function r(e){let t=e.delegation?.state;return t===`requested`||t===`running`}export{e as DELETED_STATUS,t as STORE_SCHEMA_VERSION,n as emptyDocument,r as isDelegationActive};
2
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.mjs","names":[],"sources":["../../src/store/types.ts"],"sourcesContent":["/**\n * Domain types for the file-backed task store.\n *\n * The on-disk document is the durable source of truth (unlike rpiv-todo, which\n * replayed state from the transcript). Every field here round-trips through\n * JSON, so nothing may hold non-serializable values.\n */\n\nimport type { InlineAgent } from '@agimon-ai/doompi-extension-contracts/subagent-tool';\n\nexport type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'deleted';\n\nexport const DELETED_STATUS: TaskStatus = 'deleted';\n\nexport type TaskAction = 'upsert' | 'list' | 'get' | 'delete' | 'clear' | 'assign' | 'cancel';\n\nexport type DelegationState = 'requested' | 'running' | 'completed' | 'failed' | 'cancelled';\n\n/** Terminal result of a delegated subagent run, copied off the delegation response. */\nexport interface DelegationResult {\n status: string;\n output?: string;\n outputPath?: string;\n sessionFile?: string;\n error?: string;\n durationMs?: number;\n toolCount?: number;\n}\n\n/**\n * Delegation bookkeeping attached to a task that was handed to a subagent.\n *\n * `pid` is the harness process that owns the run: it is the only way to tell an\n * genuinely-running delegation from one orphaned by a harness crash, since the\n * child dies with its parent but the file survives.\n */\nexport interface TaskDelegation {\n requestId: string;\n agent: string;\n state: DelegationState;\n sessionId?: string;\n pid?: number;\n runId?: string;\n model?: string;\n startedAt?: string;\n endedAt?: string;\n result?: DelegationResult;\n}\n\nexport interface Task {\n id: number;\n subject: string;\n description?: string;\n activeForm?: string;\n status: TaskStatus;\n blockedBy?: number[];\n owner?: string;\n metadata?: Record<string, unknown>;\n createdAt?: string;\n updatedAt?: string;\n delegation?: TaskDelegation;\n}\n\nexport const STORE_SCHEMA_VERSION = 1;\n\n/** The complete on-disk document. `rev` increments on every committed write. */\nexport interface TaskDocument {\n version: number;\n rev: number;\n nextId: number;\n tasks: Task[];\n}\n\nexport function emptyDocument(): TaskDocument {\n return { version: STORE_SCHEMA_VERSION, rev: 0, nextId: 1, tasks: [] };\n}\n\n/**\n * A dependency target inside an upsert item: an existing task id, or the `ref`\n * of a task created earlier in the same call.\n *\n * Refs must start with a letter (see `REF_PATTERN`), so a ref is structurally\n * unconfusable with a stringified id and the discrimination is just `typeof`.\n */\nexport type DepToken = number | string;\n\n/**\n * One entry of an `upsert` call. No `id` creates a task; an `id` updates one.\n *\n * `blockedBy` (absolute set) is create-only and `addBlockedBy`/`removeBlockedBy`\n * (additive merge) are update-only, matching the split the two former actions\n * had. A field used against the wrong kind fails that item rather than being\n * silently ignored.\n */\nexport interface TaskItemMutation {\n id?: number;\n ref?: string;\n subject?: string;\n description?: string;\n activeForm?: string;\n status?: TaskStatus;\n blockedBy?: DepToken[];\n addBlockedBy?: DepToken[];\n removeBlockedBy?: DepToken[];\n owner?: string;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * What one upsert item did. `index` is its position in the request array, so a\n * model reading a partial result can tell which entries still need resending.\n *\n * `message` is unprefixed: the `item[N] failed:` framing belongs to the\n * formatter, because the Task Space overlay shows this text on its own.\n */\nexport type UpsertItemOutcome =\n | {\n index: number;\n kind: 'created';\n id: number;\n subject: string;\n status: TaskStatus;\n ref?: string;\n blockedBy?: number[];\n }\n | { index: number; kind: 'updated'; id: number; fromStatus: TaskStatus; toStatus: TaskStatus }\n | { index: number; kind: 'unchanged'; id: number; status: TaskStatus }\n | { index: number; kind: 'failed'; message: string; id?: number; ref?: string };\n\n/** Which tasks an upsert touched, so renderResult names them instead of guessing. */\nexport interface UpsertSummary {\n /** Ids of applied entries, in request order. A failed entry contributes nothing. */\n applied: number[];\n failed: number;\n}\n\n/**\n * Open-shape input bag the reducer accepts. The index signature lets the\n * runtime pass a TypeBox `Static<typeof TaskParamsSchema>` through without\n * casting each field.\n *\n * Per-task fields live on `tasks[]`, not here: a top-level `subject` or\n * `status` would be ambiguous once one call can carry many tasks.\n */\nexport interface TaskMutationParams {\n [key: string]: unknown;\n tasks?: TaskItemMutation[];\n /** `list` filter only. To set a status, upsert the task by id. */\n status?: TaskStatus;\n /** `get`, `delete`, `assign` and `cancel` only. */\n id?: number;\n includeDeleted?: boolean;\n agent?: string;\n inlineAgent?: InlineAgent;\n instructions?: string;\n /** `assign` only: the context pack the parent hands to the child. */\n relevantFiles?: string[];\n priorFindings?: string;\n model?: string;\n context?: 'fresh' | 'fork';\n}\n\n/** Snapshot returned under a tool result's `details` for renderResult. */\nexport interface TaskDetails {\n action: TaskAction;\n params: Record<string, unknown>;\n tasks: Task[];\n nextId: number;\n rev: number;\n error?: string;\n upsert?: UpsertSummary;\n}\n\n/** A delegation is \"live\" while the owning run may still produce a response. */\nexport function isDelegationActive(task: Task): boolean {\n const state = task.delegation?.state;\n return state === 'requested' || state === 'running';\n}\n"],"mappings":"AAYA,MAAa,EAA6B,UAmD7B,EAAuB,EAUpC,SAAgB,GAA8B,CAC5C,MAAO,CAAE,QAAA,EAA+B,IAAK,EAAG,OAAQ,EAAG,MAAO,CAAC,CAAE,CACvE,CAmGA,SAAgB,EAAmB,EAAqB,CACtD,IAAM,EAAQ,EAAK,YAAY,MAC/B,OAAO,IAAU,aAAe,IAAU,SAC5C"}
@@ -0,0 +1,2 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=["Use `task` for work with 3+ steps, when the user gives you a list of tasks, or immediately after receiving new instructions to capture requirements. Skip it for single trivial tasks and purely conversational requests.",`Capture a whole plan in one call: {"action":"upsert","tasks":[{"subject":"Research existing tool"},{"subject":"Write the reducer"},{"subject":"Add tests"}]}. Batch whenever you are writing the plan down — the initial list, a revised plan, or wiring dependencies across several tasks — because one call keeps ids and blockers consistent and shows the user the whole plan at once.`,`Do not batch progress. Mark a task in_progress with its own call BEFORE beginning work, and completed with its own call IMMEDIATELY when it is done. upsert accepts many tasks, but a batch of completions sent at the end of a turn is still wrong: batching is for writing a plan down, single calls are for reporting progress, and the user watches the task list to see where you are. Exactly one task should be in_progress for your own work; delegated tasks run in parallel and do not count against that.`,`Never mark a task completed if tests are failing, the implementation is partial, or you hit unresolved errors, use status "failed" or keep it in_progress and add a new task for the blocker in the same upsert.`,`When every non-deleted task is completed, review the full task list once more and call task {"action":"clear"} to close it. Do not leave an all-completed list open.`,`Status is a state machine: pending → in_progress → completed, plus failed (recoverable, can go back to pending or in_progress) and deleted as a tombstone. Pass activeForm (present-continuous, e.g. 'writing tests') when marking in_progress.`,`One call does both: an entry with an id changes that task, an entry without an id creates one. To change status, upsert the task by id, e.g. {"action":"upsert","tasks":[{"id":3,"status":"completed"}]}. Never omit the id when you meant to change an existing task — an entry with no id creates a new one instead. An entry that carries an id and no other field is rejected.`,`Use blockedBy for dependencies (A is blocked by B). On an entry with no id pass blockedBy as the initial set; on an entry with an id use addBlockedBy / removeBlockedBy (additive merge, do not resend the full array). To depend on a task created earlier in the SAME call, give that earlier entry a "ref" and list the ref string in place of an id: [{"ref":"api","subject":"Design the API"},{"subject":"Implement the API","blockedBy":["api"]}]. A ref must be declared before it is used. Cycles are rejected.`,`upsert applies each entry independently: the entries that pass are committed and the failures are reported with their array index. A failed entry changed nothing, so resend only the corrected failures — never resend the whole call, because an already-applied entry with no id would create a duplicate task.`,`Before assigning work, call subagent with {"action":"agents"} and match each task to an exact discovered agent name. Prefer a discovered general-purpose write-capable agent such as delegate or worker when no specialist fits. Use a focused inlineAgent only for read-only work.`,`Assign every unblocked pending task with task {"action":"assign","id":3,"agent":"reviewer"}, including implementation tasks. Do not use a direct subagent run for work already represented in the shared task list. Use task assign so ownership and terminal results stay visible.`,`Hand over what you already know when you assign. Pass relevantFiles with the paths you have actually read or located for that task, and priorFindings with the facts you established: symbol names, call sites, the approach you picked, what you ruled out. The child starts with none of your context and will otherwise spend most of its run re-reading the repo. Send at most a dozen files and only ones you really opened — a guessed path costs the child more than an omitted one — and keep priorFindings to a few lines of facts, not directives.`,`After assigning work, continue non-overlapping parent work or end the turn and wait. Do not poll or duplicate delegated scope.`,`When a delegated task completes and unblocks another task, repeat agent discovery if needed and assign that newly eligible task promptly. Do not poll in a loop. Completion notifications wake the parent session.`,`If a child asks for a decision through intercom, or an assignment fails to start for another concrete issue, respond, rescope, or retry explicitly. Do not silently leave the task pending.`,`assign refuses tasks that are blocked, already delegated, or completed. Resolve blockers first. Use {"action":"cancel","id":3} to stop a running delegation; the task returns to pending.`,`Doom Task records delegated lifecycle and results on the shared task. The child does not update task status directly. Read the completion or failure result before deciding what to do next.`,`The task list is scoped to this session tree: delegated subagents share it, while unrelated sessions start empty. It persists for later inspection until retention cleanup.`,`Subject must be short and imperative (e.g. 'Research existing tool'); description is long-form detail written when you plan the task, and the delegated brief is that description plus the assign-time instructions, relevantFiles and priorFindings. Put durable scope in description and what you learned while exploring in the assign-time pack — do not repeat one in the other.`];exports.DEFAULT_PROMPT_GUIDELINES=e;
2
+ //# sourceMappingURL=promptGuidelines.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptGuidelines.cjs","names":[],"sources":["../../src/tool/promptGuidelines.ts"],"sourcesContent":["export const DEFAULT_PROMPT_GUIDELINES: string[] = [\n 'Use `task` for work with 3+ steps, when the user gives you a list of tasks, or immediately after receiving new instructions to capture requirements. Skip it for single trivial tasks and purely conversational requests.',\n 'Capture a whole plan in one call: {\"action\":\"upsert\",\"tasks\":[{\"subject\":\"Research existing tool\"},{\"subject\":\"Write the reducer\"},{\"subject\":\"Add tests\"}]}. Batch whenever you are writing the plan down — the initial list, a revised plan, or wiring dependencies across several tasks — because one call keeps ids and blockers consistent and shows the user the whole plan at once.',\n 'Do not batch progress. Mark a task in_progress with its own call BEFORE beginning work, and completed with its own call IMMEDIATELY when it is done. upsert accepts many tasks, but a batch of completions sent at the end of a turn is still wrong: batching is for writing a plan down, single calls are for reporting progress, and the user watches the task list to see where you are. Exactly one task should be in_progress for your own work; delegated tasks run in parallel and do not count against that.',\n 'Never mark a task completed if tests are failing, the implementation is partial, or you hit unresolved errors, use status \"failed\" or keep it in_progress and add a new task for the blocker in the same upsert.',\n 'When every non-deleted task is completed, review the full task list once more and call task {\"action\":\"clear\"} to close it. Do not leave an all-completed list open.',\n \"Status is a state machine: pending → in_progress → completed, plus failed (recoverable, can go back to pending or in_progress) and deleted as a tombstone. Pass activeForm (present-continuous, e.g. 'writing tests') when marking in_progress.\",\n 'One call does both: an entry with an id changes that task, an entry without an id creates one. To change status, upsert the task by id, e.g. {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}. Never omit the id when you meant to change an existing task — an entry with no id creates a new one instead. An entry that carries an id and no other field is rejected.',\n 'Use blockedBy for dependencies (A is blocked by B). On an entry with no id pass blockedBy as the initial set; on an entry with an id use addBlockedBy / removeBlockedBy (additive merge, do not resend the full array). To depend on a task created earlier in the SAME call, give that earlier entry a \"ref\" and list the ref string in place of an id: [{\"ref\":\"api\",\"subject\":\"Design the API\"},{\"subject\":\"Implement the API\",\"blockedBy\":[\"api\"]}]. A ref must be declared before it is used. Cycles are rejected.',\n 'upsert applies each entry independently: the entries that pass are committed and the failures are reported with their array index. A failed entry changed nothing, so resend only the corrected failures — never resend the whole call, because an already-applied entry with no id would create a duplicate task.',\n 'Before assigning work, call subagent with {\"action\":\"agents\"} and match each task to an exact discovered agent name. Prefer a discovered general-purpose write-capable agent such as delegate or worker when no specialist fits. Use a focused inlineAgent only for read-only work.',\n 'Assign every unblocked pending task with task {\"action\":\"assign\",\"id\":3,\"agent\":\"reviewer\"}, including implementation tasks. Do not use a direct subagent run for work already represented in the shared task list. Use task assign so ownership and terminal results stay visible.',\n 'Hand over what you already know when you assign. Pass relevantFiles with the paths you have actually read or located for that task, and priorFindings with the facts you established: symbol names, call sites, the approach you picked, what you ruled out. The child starts with none of your context and will otherwise spend most of its run re-reading the repo. Send at most a dozen files and only ones you really opened — a guessed path costs the child more than an omitted one — and keep priorFindings to a few lines of facts, not directives.',\n 'After assigning work, continue non-overlapping parent work or end the turn and wait. Do not poll or duplicate delegated scope.',\n 'When a delegated task completes and unblocks another task, repeat agent discovery if needed and assign that newly eligible task promptly. Do not poll in a loop. Completion notifications wake the parent session.',\n 'If a child asks for a decision through intercom, or an assignment fails to start for another concrete issue, respond, rescope, or retry explicitly. Do not silently leave the task pending.',\n 'assign refuses tasks that are blocked, already delegated, or completed. Resolve blockers first. Use {\"action\":\"cancel\",\"id\":3} to stop a running delegation; the task returns to pending.',\n 'Doom Task records delegated lifecycle and results on the shared task. The child does not update task status directly. Read the completion or failure result before deciding what to do next.',\n 'The task list is scoped to this session tree: delegated subagents share it, while unrelated sessions start empty. It persists for later inspection until retention cleanup.',\n \"Subject must be short and imperative (e.g. 'Research existing tool'); description is long-form detail written when you plan the task, and the delegated brief is that description plus the assign-time instructions, relevantFiles and priorFindings. Put durable scope in description and what you learned while exploring in the assign-time pack — do not repeat one in the other.\",\n];\n"],"mappings":"mEAAA,MAAa,EAAsC,CACjD,4NACA,6XACA,ufACA,mNACA,uKACA,kPACA,qXACA,0fACA,qTACA,sRACA,sRACA,+hBACA,iIACA,qNACA,8LACA,4LACA,+LACA,8KACA,uXACF"}
@@ -0,0 +1,5 @@
1
+ //#region src/tool/promptGuidelines.d.ts
2
+ declare const DEFAULT_PROMPT_GUIDELINES: string[];
3
+ //#endregion
4
+ export { DEFAULT_PROMPT_GUIDELINES };
5
+ //# sourceMappingURL=promptGuidelines.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptGuidelines.d.cts","names":[],"sources":["../../src/tool/promptGuidelines.ts"],"mappings":";cAAa"}
@@ -0,0 +1,5 @@
1
+ //#region src/tool/promptGuidelines.d.ts
2
+ declare const DEFAULT_PROMPT_GUIDELINES: string[];
3
+ //#endregion
4
+ export { DEFAULT_PROMPT_GUIDELINES };
5
+ //# sourceMappingURL=promptGuidelines.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptGuidelines.d.mts","names":[],"sources":["../../src/tool/promptGuidelines.ts"],"mappings":";cAAa"}
@@ -0,0 +1,2 @@
1
+ const e=["Use `task` for work with 3+ steps, when the user gives you a list of tasks, or immediately after receiving new instructions to capture requirements. Skip it for single trivial tasks and purely conversational requests.",`Capture a whole plan in one call: {"action":"upsert","tasks":[{"subject":"Research existing tool"},{"subject":"Write the reducer"},{"subject":"Add tests"}]}. Batch whenever you are writing the plan down — the initial list, a revised plan, or wiring dependencies across several tasks — because one call keeps ids and blockers consistent and shows the user the whole plan at once.`,`Do not batch progress. Mark a task in_progress with its own call BEFORE beginning work, and completed with its own call IMMEDIATELY when it is done. upsert accepts many tasks, but a batch of completions sent at the end of a turn is still wrong: batching is for writing a plan down, single calls are for reporting progress, and the user watches the task list to see where you are. Exactly one task should be in_progress for your own work; delegated tasks run in parallel and do not count against that.`,`Never mark a task completed if tests are failing, the implementation is partial, or you hit unresolved errors, use status "failed" or keep it in_progress and add a new task for the blocker in the same upsert.`,`When every non-deleted task is completed, review the full task list once more and call task {"action":"clear"} to close it. Do not leave an all-completed list open.`,`Status is a state machine: pending → in_progress → completed, plus failed (recoverable, can go back to pending or in_progress) and deleted as a tombstone. Pass activeForm (present-continuous, e.g. 'writing tests') when marking in_progress.`,`One call does both: an entry with an id changes that task, an entry without an id creates one. To change status, upsert the task by id, e.g. {"action":"upsert","tasks":[{"id":3,"status":"completed"}]}. Never omit the id when you meant to change an existing task — an entry with no id creates a new one instead. An entry that carries an id and no other field is rejected.`,`Use blockedBy for dependencies (A is blocked by B). On an entry with no id pass blockedBy as the initial set; on an entry with an id use addBlockedBy / removeBlockedBy (additive merge, do not resend the full array). To depend on a task created earlier in the SAME call, give that earlier entry a "ref" and list the ref string in place of an id: [{"ref":"api","subject":"Design the API"},{"subject":"Implement the API","blockedBy":["api"]}]. A ref must be declared before it is used. Cycles are rejected.`,`upsert applies each entry independently: the entries that pass are committed and the failures are reported with their array index. A failed entry changed nothing, so resend only the corrected failures — never resend the whole call, because an already-applied entry with no id would create a duplicate task.`,`Before assigning work, call subagent with {"action":"agents"} and match each task to an exact discovered agent name. Prefer a discovered general-purpose write-capable agent such as delegate or worker when no specialist fits. Use a focused inlineAgent only for read-only work.`,`Assign every unblocked pending task with task {"action":"assign","id":3,"agent":"reviewer"}, including implementation tasks. Do not use a direct subagent run for work already represented in the shared task list. Use task assign so ownership and terminal results stay visible.`,`Hand over what you already know when you assign. Pass relevantFiles with the paths you have actually read or located for that task, and priorFindings with the facts you established: symbol names, call sites, the approach you picked, what you ruled out. The child starts with none of your context and will otherwise spend most of its run re-reading the repo. Send at most a dozen files and only ones you really opened — a guessed path costs the child more than an omitted one — and keep priorFindings to a few lines of facts, not directives.`,`After assigning work, continue non-overlapping parent work or end the turn and wait. Do not poll or duplicate delegated scope.`,`When a delegated task completes and unblocks another task, repeat agent discovery if needed and assign that newly eligible task promptly. Do not poll in a loop. Completion notifications wake the parent session.`,`If a child asks for a decision through intercom, or an assignment fails to start for another concrete issue, respond, rescope, or retry explicitly. Do not silently leave the task pending.`,`assign refuses tasks that are blocked, already delegated, or completed. Resolve blockers first. Use {"action":"cancel","id":3} to stop a running delegation; the task returns to pending.`,`Doom Task records delegated lifecycle and results on the shared task. The child does not update task status directly. Read the completion or failure result before deciding what to do next.`,`The task list is scoped to this session tree: delegated subagents share it, while unrelated sessions start empty. It persists for later inspection until retention cleanup.`,`Subject must be short and imperative (e.g. 'Research existing tool'); description is long-form detail written when you plan the task, and the delegated brief is that description plus the assign-time instructions, relevantFiles and priorFindings. Put durable scope in description and what you learned while exploring in the assign-time pack — do not repeat one in the other.`];export{e as DEFAULT_PROMPT_GUIDELINES};
2
+ //# sourceMappingURL=promptGuidelines.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptGuidelines.mjs","names":[],"sources":["../../src/tool/promptGuidelines.ts"],"sourcesContent":["export const DEFAULT_PROMPT_GUIDELINES: string[] = [\n 'Use `task` for work with 3+ steps, when the user gives you a list of tasks, or immediately after receiving new instructions to capture requirements. Skip it for single trivial tasks and purely conversational requests.',\n 'Capture a whole plan in one call: {\"action\":\"upsert\",\"tasks\":[{\"subject\":\"Research existing tool\"},{\"subject\":\"Write the reducer\"},{\"subject\":\"Add tests\"}]}. Batch whenever you are writing the plan down — the initial list, a revised plan, or wiring dependencies across several tasks — because one call keeps ids and blockers consistent and shows the user the whole plan at once.',\n 'Do not batch progress. Mark a task in_progress with its own call BEFORE beginning work, and completed with its own call IMMEDIATELY when it is done. upsert accepts many tasks, but a batch of completions sent at the end of a turn is still wrong: batching is for writing a plan down, single calls are for reporting progress, and the user watches the task list to see where you are. Exactly one task should be in_progress for your own work; delegated tasks run in parallel and do not count against that.',\n 'Never mark a task completed if tests are failing, the implementation is partial, or you hit unresolved errors, use status \"failed\" or keep it in_progress and add a new task for the blocker in the same upsert.',\n 'When every non-deleted task is completed, review the full task list once more and call task {\"action\":\"clear\"} to close it. Do not leave an all-completed list open.',\n \"Status is a state machine: pending → in_progress → completed, plus failed (recoverable, can go back to pending or in_progress) and deleted as a tombstone. Pass activeForm (present-continuous, e.g. 'writing tests') when marking in_progress.\",\n 'One call does both: an entry with an id changes that task, an entry without an id creates one. To change status, upsert the task by id, e.g. {\"action\":\"upsert\",\"tasks\":[{\"id\":3,\"status\":\"completed\"}]}. Never omit the id when you meant to change an existing task — an entry with no id creates a new one instead. An entry that carries an id and no other field is rejected.',\n 'Use blockedBy for dependencies (A is blocked by B). On an entry with no id pass blockedBy as the initial set; on an entry with an id use addBlockedBy / removeBlockedBy (additive merge, do not resend the full array). To depend on a task created earlier in the SAME call, give that earlier entry a \"ref\" and list the ref string in place of an id: [{\"ref\":\"api\",\"subject\":\"Design the API\"},{\"subject\":\"Implement the API\",\"blockedBy\":[\"api\"]}]. A ref must be declared before it is used. Cycles are rejected.',\n 'upsert applies each entry independently: the entries that pass are committed and the failures are reported with their array index. A failed entry changed nothing, so resend only the corrected failures — never resend the whole call, because an already-applied entry with no id would create a duplicate task.',\n 'Before assigning work, call subagent with {\"action\":\"agents\"} and match each task to an exact discovered agent name. Prefer a discovered general-purpose write-capable agent such as delegate or worker when no specialist fits. Use a focused inlineAgent only for read-only work.',\n 'Assign every unblocked pending task with task {\"action\":\"assign\",\"id\":3,\"agent\":\"reviewer\"}, including implementation tasks. Do not use a direct subagent run for work already represented in the shared task list. Use task assign so ownership and terminal results stay visible.',\n 'Hand over what you already know when you assign. Pass relevantFiles with the paths you have actually read or located for that task, and priorFindings with the facts you established: symbol names, call sites, the approach you picked, what you ruled out. The child starts with none of your context and will otherwise spend most of its run re-reading the repo. Send at most a dozen files and only ones you really opened — a guessed path costs the child more than an omitted one — and keep priorFindings to a few lines of facts, not directives.',\n 'After assigning work, continue non-overlapping parent work or end the turn and wait. Do not poll or duplicate delegated scope.',\n 'When a delegated task completes and unblocks another task, repeat agent discovery if needed and assign that newly eligible task promptly. Do not poll in a loop. Completion notifications wake the parent session.',\n 'If a child asks for a decision through intercom, or an assignment fails to start for another concrete issue, respond, rescope, or retry explicitly. Do not silently leave the task pending.',\n 'assign refuses tasks that are blocked, already delegated, or completed. Resolve blockers first. Use {\"action\":\"cancel\",\"id\":3} to stop a running delegation; the task returns to pending.',\n 'Doom Task records delegated lifecycle and results on the shared task. The child does not update task status directly. Read the completion or failure result before deciding what to do next.',\n 'The task list is scoped to this session tree: delegated subagents share it, while unrelated sessions start empty. It persists for later inspection until retention cleanup.',\n \"Subject must be short and imperative (e.g. 'Research existing tool'); description is long-form detail written when you plan the task, and the delegated brief is that description plus the assign-time instructions, relevantFiles and priorFindings. Put durable scope in description and what you learned while exploring in the assign-time pack — do not repeat one in the other.\",\n];\n"],"mappings":"AAAA,MAAa,EAAsC,CACjD,4NACA,6XACA,ufACA,mNACA,uKACA,kPACA,qXACA,0fACA,qTACA,sRACA,sRACA,+hBACA,iIACA,qNACA,8LACA,4LACA,+LACA,8KACA,uXACF"}
@@ -0,0 +1,6 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../store/taskGraph.cjs"),t=`All tasks are completed. Review the full task list once more, then close it with task {"action":"clear"}.`,n=`The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.`,r=`No task changed, so the whole call can be resent once corrected.`;function i(e){let t=e.blockedBy?.length?` ⛓ ${e.blockedBy.map(e=>`#${e}`).join(`,`)}`:``,n=e.status===`in_progress`&&e.activeForm?` (${e.activeForm})`:``,r=e.delegation&&e.delegation.state!==`cancelled`?` [${e.delegation.agent}]`:``;return`[${e.status}] #${e.id} ${e.subject}${n}${r}${t}`}function a(e){let t=e.delegation;if(!t)return[];let n=[` delegated to: ${t.agent} (${t.state})`];return t.model&&n.push(` model: ${t.model}`),t.result?.error&&n.push(` error: ${t.result.error}`),t.result?.outputPath&&n.push(` output file: ${t.result.outputPath}`),t.result?.output&&n.push(` output: ${t.result.output}`),n}function o(t,n){let r=e.deriveBlocks(n.tasks).get(t.id)??[],i=[`#${t.id} [${t.status}] ${t.subject}`];return t.description&&i.push(` description: ${t.description}`),t.activeForm&&i.push(` activeForm: ${t.activeForm}`),t.blockedBy?.length&&i.push(` blockedBy: ${t.blockedBy.map(e=>`#${e}`).join(`, `)}`),r.length&&i.push(` blocks: ${r.map(e=>`#${e}`).join(`, `)}`),t.owner&&i.push(` owner: ${t.owner}`),i.push(...a(t)),i.join(`
2
+ `)}function s(e){switch(e.kind){case`created`:{let t=e.ref?` (ref "${e.ref}")`:``,n=e.blockedBy?.length?` — blocked by ${e.blockedBy.map(e=>`#${e}`).join(`, `)}`:``;return`Created #${e.id}${t}: ${e.subject} (${e.status})${n}`}case`updated`:{let t=e.fromStatus===e.toStatus?``:` (${e.fromStatus} -> ${e.toStatus})`;return`Updated #${e.id}${t}`}case`unchanged`:return`No change: #${e.id} already matches the requested values (status: ${e.status})`;case`failed`:return`Failed${e.id===void 0?``:` #${e.id}`}: ${e.message}`}}function c(e){return e.items.length===1?e.items[0].kind===`failed`?e.items[0].message:`no entry was applied`:[`no entry was applied.`,...e.items.map(e=>`- [${e.index}] ${s(e)}`),r].join(`
3
+ `)}function l(r,a){switch(r.kind){case`upsert`:{let i=r.items.length===1?[s(r.items[0])]:[`Upsert applied ${r.applied}/${r.items.length} entries${r.failed>0?`; ${r.failed} failed`:``}.`,...r.items.map(e=>`- [${e.index}] ${s(e)}`),...r.failed>0?[``,n]:[]];return r.applied>0&&e.isTaskListComplete(a.tasks)&&i.push(t),i.join(`
4
+ `)}case`delete`:return`Deleted #${r.id}: ${r.subject}`;case`clear`:return`Closed task list (cleared ${r.count} tasks)`;case`list`:{let e=a.tasks;return r.includeDeleted||(e=e.filter(e=>e.status!==`deleted`)),r.statusFilter&&(e=e.filter(e=>e.status===r.statusFilter)),e.length===0?`No tasks`:e.map(i).join(`
5
+ `)}case`get`:return o(r.task,a);case`error`:return`Error: ${r.message}`}}function u(e,t,n,r){return{content:[{type:`text`,text:l(r,n)}],details:{action:e,params:t,tasks:n.tasks,nextId:n.nextId,rev:n.rev,...r.kind===`error`?{error:r.message}:{},...r.kind===`upsert`?{upsert:{applied:r.items.flatMap(e=>e.kind===`failed`?[]:[e.id]),failed:r.failed}}:{}}}}function d(e,t,n,r,i){return{content:[{type:`text`,text:i?`Error: ${i}`:r}],details:{action:e,params:t,tasks:n.tasks,nextId:n.nextId,rev:n.rev,...i?{error:i}:{}}}}exports.MSG_ALL_COMPLETE_CLEAR=t,exports.MSG_UPSERT_NONE_APPLIED=r,exports.MSG_UPSERT_PARTIAL=n,exports.buildTextResult=d,exports.buildToolResult=u,exports.formatContent=l,exports.formatUpsertFailureText=c;
6
+ //# sourceMappingURL=responseEnvelope.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseEnvelope.cjs","names":["deriveBlocks","isTaskListComplete"],"sources":["../../src/tool/responseEnvelope.ts"],"sourcesContent":["import type { Op } from '../store/reducer.ts';\nimport { deriveBlocks, isTaskListComplete } from '../store/taskGraph.ts';\nimport type {\n Task,\n TaskAction,\n TaskDetails,\n TaskDocument,\n TaskMutationParams,\n UpsertItemOutcome,\n} from '../store/types.ts';\n\nexport const MSG_ALL_COMPLETE_CLEAR =\n 'All tasks are completed. Review the full task list once more, then close it with task {\"action\":\"clear\"}.';\n\n/**\n * Steering for a mixed batch. Unlike a batch of spawned subagents, a failed\n * entry here had no side effect at all, so retrying the failures is the safe\n * move and the model must be told so or it will do nothing. The hazard is the\n * other half: resending an applied create would make a second task.\n */\nexport const MSG_UPSERT_PARTIAL =\n 'The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.';\n\nexport const MSG_UPSERT_NONE_APPLIED = 'No task changed, so the whole call can be resent once corrected.';\n\n/** `[status] #id subject (activeForm) [agent] ⛓ #dep` — the `list` line format. */\nfunction formatListLine(task: Task): string {\n const block = task.blockedBy?.length ? ` ⛓ ${task.blockedBy.map((id) => `#${id}`).join(',')}` : '';\n const form = task.status === 'in_progress' && task.activeForm ? ` (${task.activeForm})` : '';\n const delegated = task.delegation && task.delegation.state !== 'cancelled' ? ` [${task.delegation.agent}]` : '';\n return `[${task.status}] #${task.id} ${task.subject}${form}${delegated}${block}`;\n}\n\nfunction formatDelegationLines(task: Task): string[] {\n const delegation = task.delegation;\n if (!delegation) return [];\n\n const lines = [` delegated to: ${delegation.agent} (${delegation.state})`];\n if (delegation.model) lines.push(` model: ${delegation.model}`);\n if (delegation.result?.error) lines.push(` error: ${delegation.result.error}`);\n if (delegation.result?.outputPath) lines.push(` output file: ${delegation.result.outputPath}`);\n if (delegation.result?.output) lines.push(` output: ${delegation.result.output}`);\n return lines;\n}\n\nfunction formatGetLines(task: Task, document: TaskDocument): string {\n const blocks = deriveBlocks(document.tasks).get(task.id) ?? [];\n const lines = [`#${task.id} [${task.status}] ${task.subject}`];\n if (task.description) lines.push(` description: ${task.description}`);\n if (task.activeForm) lines.push(` activeForm: ${task.activeForm}`);\n if (task.blockedBy?.length) lines.push(` blockedBy: ${task.blockedBy.map((id) => `#${id}`).join(', ')}`);\n if (blocks.length) lines.push(` blocks: ${blocks.map((id) => `#${id}`).join(', ')}`);\n if (task.owner) lines.push(` owner: ${task.owner}`);\n lines.push(...formatDelegationLines(task));\n return lines.join('\\n');\n}\n\n/** One entry's outcome. Batch lines prefix this with `- [n] `. */\nfunction formatUpsertItem(item: UpsertItemOutcome): string {\n switch (item.kind) {\n case 'created': {\n const ref = item.ref ? ` (ref \"${item.ref}\")` : '';\n const deps = item.blockedBy?.length ? ` — blocked by ${item.blockedBy.map((id) => `#${id}`).join(', ')}` : '';\n return `Created #${item.id}${ref}: ${item.subject} (${item.status})${deps}`;\n }\n case 'updated': {\n const transition = item.fromStatus === item.toStatus ? '' : ` (${item.fromStatus} -> ${item.toStatus})`;\n return `Updated #${item.id}${transition}`;\n }\n case 'unchanged':\n return `No change: #${item.id} already matches the requested values (status: ${item.status})`;\n case 'failed':\n return `Failed${item.id === undefined ? '' : ` #${item.id}`}: ${item.message}`;\n }\n}\n\n/**\n * The thrown message when an upsert applied nothing. Kept separate from\n * `formatContent` because the caller wraps it in the actionable Options block\n * rather than returning it as a successful result.\n */\nexport function formatUpsertFailureText(op: Extract<Op, { kind: 'upsert' }>): string {\n if (op.items.length === 1) return op.items[0].kind === 'failed' ? op.items[0].message : 'no entry was applied';\n return [\n 'no entry was applied.',\n ...op.items.map((item) => `- [${item.index}] ${formatUpsertItem(item)}`),\n MSG_UPSERT_NONE_APPLIED,\n ].join('\\n');\n}\n\n/**\n * Pure formatter: `(op, document) -> string`. The switch is closed over `Op`,\n * so a new reducer variant fails to compile until it is handled here.\n */\nexport function formatContent(op: Op, document: TaskDocument): string {\n switch (op.kind) {\n case 'upsert': {\n // A batch of one is the common case and must not read like a bulk\n // report, so it keeps the exact single-line shape it has always had.\n const lines =\n op.items.length === 1\n ? [formatUpsertItem(op.items[0])]\n : [\n `Upsert applied ${op.applied}/${op.items.length} entries${op.failed > 0 ? `; ${op.failed} failed` : ''}.`,\n ...op.items.map((item) => `- [${item.index}] ${formatUpsertItem(item)}`),\n ...(op.failed > 0 ? ['', MSG_UPSERT_PARTIAL] : []),\n ];\n // Once, last, and only when something landed: emitting it per entry\n // would repeat it for every completion in a batch.\n if (op.applied > 0 && isTaskListComplete(document.tasks)) lines.push(MSG_ALL_COMPLETE_CLEAR);\n return lines.join('\\n');\n }\n case 'delete':\n return `Deleted #${op.id}: ${op.subject}`;\n case 'clear':\n return `Closed task list (cleared ${op.count} tasks)`;\n case 'list': {\n let view = document.tasks;\n if (!op.includeDeleted) view = view.filter((task) => task.status !== 'deleted');\n if (op.statusFilter) view = view.filter((task) => task.status === op.statusFilter);\n return view.length === 0 ? 'No tasks' : view.map(formatListLine).join('\\n');\n }\n case 'get':\n return formatGetLines(op.task, document);\n case 'error':\n return `Error: ${op.message}`;\n }\n}\n\nexport interface ToolResult {\n content: Array<{ type: 'text'; text: string }>;\n details: TaskDetails;\n}\n\n/** Build the LLM-facing envelope. `details` carries the post-mutation snapshot. */\nexport function buildToolResult(\n action: TaskAction,\n params: TaskMutationParams,\n document: TaskDocument,\n op: Op,\n): ToolResult {\n return {\n content: [{ type: 'text', text: formatContent(op, document) }],\n details: {\n action,\n params: params as Record<string, unknown>,\n tasks: document.tasks,\n nextId: document.nextId,\n rev: document.rev,\n ...(op.kind === 'error' ? { error: op.message } : {}),\n // Deliberately no `error` on a partial success: renderResult treats\n // `details.error` as total failure and would hide the rows for the\n // entries that did land.\n ...(op.kind === 'upsert'\n ? {\n upsert: {\n applied: op.items.flatMap((item) => (item.kind === 'failed' ? [] : [item.id])),\n failed: op.failed,\n },\n }\n : {}),\n },\n };\n}\n\n/** Envelope for delegation actions, which do not flow through the reducer. */\nexport function buildTextResult(\n action: TaskAction,\n params: TaskMutationParams,\n document: TaskDocument,\n text: string,\n error?: string,\n): ToolResult {\n return {\n content: [{ type: 'text', text: error ? `Error: ${error}` : text }],\n details: {\n action,\n params: params as Record<string, unknown>,\n tasks: document.tasks,\n nextId: document.nextId,\n rev: document.rev,\n ...(error ? { error } : {}),\n },\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { TaskAction, TaskDetails, TaskDocument, TaskMutationParams } from "../store/types.cjs";
2
+ import { Op } from "../store/reducer.cjs";
3
+ //#region src/tool/responseEnvelope.d.ts
4
+ declare const MSG_ALL_COMPLETE_CLEAR = "All tasks are completed. Review the full task list once more, then close it with task {\"action\":\"clear\"}.";
5
+ /**
6
+ * Steering for a mixed batch. Unlike a batch of spawned subagents, a failed
7
+ * entry here had no side effect at all, so retrying the failures is the safe
8
+ * move and the model must be told so or it will do nothing. The hazard is the
9
+ * other half: resending an applied create would make a second task.
10
+ */
11
+ declare const MSG_UPSERT_PARTIAL = "The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.";
12
+ declare const MSG_UPSERT_NONE_APPLIED = "No task changed, so the whole call can be resent once corrected.";
13
+ /**
14
+ * The thrown message when an upsert applied nothing. Kept separate from
15
+ * `formatContent` because the caller wraps it in the actionable Options block
16
+ * rather than returning it as a successful result.
17
+ */
18
+ declare function formatUpsertFailureText(op: Extract<Op, {
19
+ kind: 'upsert';
20
+ }>): string;
21
+ /**
22
+ * Pure formatter: `(op, document) -> string`. The switch is closed over `Op`,
23
+ * so a new reducer variant fails to compile until it is handled here.
24
+ */
25
+ declare function formatContent(op: Op, document: TaskDocument): string;
26
+ interface ToolResult {
27
+ content: Array<{
28
+ type: 'text';
29
+ text: string;
30
+ }>;
31
+ details: TaskDetails;
32
+ }
33
+ /** Build the LLM-facing envelope. `details` carries the post-mutation snapshot. */
34
+ declare function buildToolResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, op: Op): ToolResult;
35
+ /** Envelope for delegation actions, which do not flow through the reducer. */
36
+ declare function buildTextResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, text: string, error?: string): ToolResult;
37
+ //#endregion
38
+ export { MSG_ALL_COMPLETE_CLEAR, MSG_UPSERT_NONE_APPLIED, MSG_UPSERT_PARTIAL, ToolResult, buildTextResult, buildToolResult, formatContent, formatUpsertFailureText };
39
+ //# sourceMappingURL=responseEnvelope.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseEnvelope.d.cts","names":[],"sources":["../../src/tool/responseEnvelope.ts"],"mappings":";;;cAWa;;;;;;;cASA;cAGA;;;;;;iBA0DG,wBAAwB,IAAI,QAAQ;EAAM;;;;;;iBAa1C,cAAc,IAAI,IAAI,UAAU;UAmC/B;EACf,SAAS;IAAQ;IAAc;;EAC/B,SAAS;;;iBAIK,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,IAAI,KACH;;iBA0Ba,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,cACA,iBACC"}
@@ -0,0 +1,39 @@
1
+ import { TaskAction, TaskDetails, TaskDocument, TaskMutationParams } from "../store/types.mjs";
2
+ import { Op } from "../store/reducer.mjs";
3
+ //#region src/tool/responseEnvelope.d.ts
4
+ declare const MSG_ALL_COMPLETE_CLEAR = "All tasks are completed. Review the full task list once more, then close it with task {\"action\":\"clear\"}.";
5
+ /**
6
+ * Steering for a mixed batch. Unlike a batch of spawned subagents, a failed
7
+ * entry here had no side effect at all, so retrying the failures is the safe
8
+ * move and the model must be told so or it will do nothing. The hazard is the
9
+ * other half: resending an applied create would make a second task.
10
+ */
11
+ declare const MSG_UPSERT_PARTIAL = "The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.";
12
+ declare const MSG_UPSERT_NONE_APPLIED = "No task changed, so the whole call can be resent once corrected.";
13
+ /**
14
+ * The thrown message when an upsert applied nothing. Kept separate from
15
+ * `formatContent` because the caller wraps it in the actionable Options block
16
+ * rather than returning it as a successful result.
17
+ */
18
+ declare function formatUpsertFailureText(op: Extract<Op, {
19
+ kind: 'upsert';
20
+ }>): string;
21
+ /**
22
+ * Pure formatter: `(op, document) -> string`. The switch is closed over `Op`,
23
+ * so a new reducer variant fails to compile until it is handled here.
24
+ */
25
+ declare function formatContent(op: Op, document: TaskDocument): string;
26
+ interface ToolResult {
27
+ content: Array<{
28
+ type: 'text';
29
+ text: string;
30
+ }>;
31
+ details: TaskDetails;
32
+ }
33
+ /** Build the LLM-facing envelope. `details` carries the post-mutation snapshot. */
34
+ declare function buildToolResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, op: Op): ToolResult;
35
+ /** Envelope for delegation actions, which do not flow through the reducer. */
36
+ declare function buildTextResult(action: TaskAction, params: TaskMutationParams, document: TaskDocument, text: string, error?: string): ToolResult;
37
+ //#endregion
38
+ export { MSG_ALL_COMPLETE_CLEAR, MSG_UPSERT_NONE_APPLIED, MSG_UPSERT_PARTIAL, ToolResult, buildTextResult, buildToolResult, formatContent, formatUpsertFailureText };
39
+ //# sourceMappingURL=responseEnvelope.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseEnvelope.d.mts","names":[],"sources":["../../src/tool/responseEnvelope.ts"],"mappings":";;;cAWa;;;;;;;cASA;cAGA;;;;;;iBA0DG,wBAAwB,IAAI,QAAQ;EAAM;;;;;;iBAa1C,cAAc,IAAI,IAAI,UAAU;UAmC/B;EACf,SAAS;IAAQ;IAAc;;EAC/B,SAAS;;;iBAIK,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,IAAI,KACH;;iBA0Ba,gBACd,QAAQ,YACR,QAAQ,oBACR,UAAU,cACV,cACA,iBACC"}
@@ -0,0 +1,6 @@
1
+ import{deriveBlocks as e,isTaskListComplete as t}from"../store/taskGraph.mjs";const n=`All tasks are completed. Review the full task list once more, then close it with task {"action":"clear"}.`,r=`The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.`,i=`No task changed, so the whole call can be resent once corrected.`;function a(e){let t=e.blockedBy?.length?` ⛓ ${e.blockedBy.map(e=>`#${e}`).join(`,`)}`:``,n=e.status===`in_progress`&&e.activeForm?` (${e.activeForm})`:``,r=e.delegation&&e.delegation.state!==`cancelled`?` [${e.delegation.agent}]`:``;return`[${e.status}] #${e.id} ${e.subject}${n}${r}${t}`}function o(e){let t=e.delegation;if(!t)return[];let n=[` delegated to: ${t.agent} (${t.state})`];return t.model&&n.push(` model: ${t.model}`),t.result?.error&&n.push(` error: ${t.result.error}`),t.result?.outputPath&&n.push(` output file: ${t.result.outputPath}`),t.result?.output&&n.push(` output: ${t.result.output}`),n}function s(t,n){let r=e(n.tasks).get(t.id)??[],i=[`#${t.id} [${t.status}] ${t.subject}`];return t.description&&i.push(` description: ${t.description}`),t.activeForm&&i.push(` activeForm: ${t.activeForm}`),t.blockedBy?.length&&i.push(` blockedBy: ${t.blockedBy.map(e=>`#${e}`).join(`, `)}`),r.length&&i.push(` blocks: ${r.map(e=>`#${e}`).join(`, `)}`),t.owner&&i.push(` owner: ${t.owner}`),i.push(...o(t)),i.join(`
2
+ `)}function c(e){switch(e.kind){case`created`:{let t=e.ref?` (ref "${e.ref}")`:``,n=e.blockedBy?.length?` — blocked by ${e.blockedBy.map(e=>`#${e}`).join(`, `)}`:``;return`Created #${e.id}${t}: ${e.subject} (${e.status})${n}`}case`updated`:{let t=e.fromStatus===e.toStatus?``:` (${e.fromStatus} -> ${e.toStatus})`;return`Updated #${e.id}${t}`}case`unchanged`:return`No change: #${e.id} already matches the requested values (status: ${e.status})`;case`failed`:return`Failed${e.id===void 0?``:` #${e.id}`}: ${e.message}`}}function l(e){return e.items.length===1?e.items[0].kind===`failed`?e.items[0].message:`no entry was applied`:[`no entry was applied.`,...e.items.map(e=>`- [${e.index}] ${c(e)}`),i].join(`
3
+ `)}function u(e,i){switch(e.kind){case`upsert`:{let a=e.items.length===1?[c(e.items[0])]:[`Upsert applied ${e.applied}/${e.items.length} entries${e.failed>0?`; ${e.failed} failed`:``}.`,...e.items.map(e=>`- [${e.index}] ${c(e)}`),...e.failed>0?[``,r]:[]];return e.applied>0&&t(i.tasks)&&a.push(n),a.join(`
4
+ `)}case`delete`:return`Deleted #${e.id}: ${e.subject}`;case`clear`:return`Closed task list (cleared ${e.count} tasks)`;case`list`:{let t=i.tasks;return e.includeDeleted||(t=t.filter(e=>e.status!==`deleted`)),e.statusFilter&&(t=t.filter(t=>t.status===e.statusFilter)),t.length===0?`No tasks`:t.map(a).join(`
5
+ `)}case`get`:return s(e.task,i);case`error`:return`Error: ${e.message}`}}function d(e,t,n,r){return{content:[{type:`text`,text:u(r,n)}],details:{action:e,params:t,tasks:n.tasks,nextId:n.nextId,rev:n.rev,...r.kind===`error`?{error:r.message}:{},...r.kind===`upsert`?{upsert:{applied:r.items.flatMap(e=>e.kind===`failed`?[]:[e.id]),failed:r.failed}}:{}}}}function f(e,t,n,r,i){return{content:[{type:`text`,text:i?`Error: ${i}`:r}],details:{action:e,params:t,tasks:n.tasks,nextId:n.nextId,rev:n.rev,...i?{error:i}:{}}}}export{n as MSG_ALL_COMPLETE_CLEAR,i as MSG_UPSERT_NONE_APPLIED,r as MSG_UPSERT_PARTIAL,f as buildTextResult,d as buildToolResult,u as formatContent,l as formatUpsertFailureText};
6
+ //# sourceMappingURL=responseEnvelope.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseEnvelope.mjs","names":[],"sources":["../../src/tool/responseEnvelope.ts"],"sourcesContent":["import type { Op } from '../store/reducer.ts';\nimport { deriveBlocks, isTaskListComplete } from '../store/taskGraph.ts';\nimport type {\n Task,\n TaskAction,\n TaskDetails,\n TaskDocument,\n TaskMutationParams,\n UpsertItemOutcome,\n} from '../store/types.ts';\n\nexport const MSG_ALL_COMPLETE_CLEAR =\n 'All tasks are completed. Review the full task list once more, then close it with task {\"action\":\"clear\"}.';\n\n/**\n * Steering for a mixed batch. Unlike a batch of spawned subagents, a failed\n * entry here had no side effect at all, so retrying the failures is the safe\n * move and the model must be told so or it will do nothing. The hazard is the\n * other half: resending an applied create would make a second task.\n */\nexport const MSG_UPSERT_PARTIAL =\n 'The applied entries are committed. Resend only the failed entries, corrected — a failed entry changed nothing, so a corrected retry is safe. Do not resend an entry that already applied: an entry without an id creates a second task.';\n\nexport const MSG_UPSERT_NONE_APPLIED = 'No task changed, so the whole call can be resent once corrected.';\n\n/** `[status] #id subject (activeForm) [agent] ⛓ #dep` — the `list` line format. */\nfunction formatListLine(task: Task): string {\n const block = task.blockedBy?.length ? ` ⛓ ${task.blockedBy.map((id) => `#${id}`).join(',')}` : '';\n const form = task.status === 'in_progress' && task.activeForm ? ` (${task.activeForm})` : '';\n const delegated = task.delegation && task.delegation.state !== 'cancelled' ? ` [${task.delegation.agent}]` : '';\n return `[${task.status}] #${task.id} ${task.subject}${form}${delegated}${block}`;\n}\n\nfunction formatDelegationLines(task: Task): string[] {\n const delegation = task.delegation;\n if (!delegation) return [];\n\n const lines = [` delegated to: ${delegation.agent} (${delegation.state})`];\n if (delegation.model) lines.push(` model: ${delegation.model}`);\n if (delegation.result?.error) lines.push(` error: ${delegation.result.error}`);\n if (delegation.result?.outputPath) lines.push(` output file: ${delegation.result.outputPath}`);\n if (delegation.result?.output) lines.push(` output: ${delegation.result.output}`);\n return lines;\n}\n\nfunction formatGetLines(task: Task, document: TaskDocument): string {\n const blocks = deriveBlocks(document.tasks).get(task.id) ?? [];\n const lines = [`#${task.id} [${task.status}] ${task.subject}`];\n if (task.description) lines.push(` description: ${task.description}`);\n if (task.activeForm) lines.push(` activeForm: ${task.activeForm}`);\n if (task.blockedBy?.length) lines.push(` blockedBy: ${task.blockedBy.map((id) => `#${id}`).join(', ')}`);\n if (blocks.length) lines.push(` blocks: ${blocks.map((id) => `#${id}`).join(', ')}`);\n if (task.owner) lines.push(` owner: ${task.owner}`);\n lines.push(...formatDelegationLines(task));\n return lines.join('\\n');\n}\n\n/** One entry's outcome. Batch lines prefix this with `- [n] `. */\nfunction formatUpsertItem(item: UpsertItemOutcome): string {\n switch (item.kind) {\n case 'created': {\n const ref = item.ref ? ` (ref \"${item.ref}\")` : '';\n const deps = item.blockedBy?.length ? ` — blocked by ${item.blockedBy.map((id) => `#${id}`).join(', ')}` : '';\n return `Created #${item.id}${ref}: ${item.subject} (${item.status})${deps}`;\n }\n case 'updated': {\n const transition = item.fromStatus === item.toStatus ? '' : ` (${item.fromStatus} -> ${item.toStatus})`;\n return `Updated #${item.id}${transition}`;\n }\n case 'unchanged':\n return `No change: #${item.id} already matches the requested values (status: ${item.status})`;\n case 'failed':\n return `Failed${item.id === undefined ? '' : ` #${item.id}`}: ${item.message}`;\n }\n}\n\n/**\n * The thrown message when an upsert applied nothing. Kept separate from\n * `formatContent` because the caller wraps it in the actionable Options block\n * rather than returning it as a successful result.\n */\nexport function formatUpsertFailureText(op: Extract<Op, { kind: 'upsert' }>): string {\n if (op.items.length === 1) return op.items[0].kind === 'failed' ? op.items[0].message : 'no entry was applied';\n return [\n 'no entry was applied.',\n ...op.items.map((item) => `- [${item.index}] ${formatUpsertItem(item)}`),\n MSG_UPSERT_NONE_APPLIED,\n ].join('\\n');\n}\n\n/**\n * Pure formatter: `(op, document) -> string`. The switch is closed over `Op`,\n * so a new reducer variant fails to compile until it is handled here.\n */\nexport function formatContent(op: Op, document: TaskDocument): string {\n switch (op.kind) {\n case 'upsert': {\n // A batch of one is the common case and must not read like a bulk\n // report, so it keeps the exact single-line shape it has always had.\n const lines =\n op.items.length === 1\n ? [formatUpsertItem(op.items[0])]\n : [\n `Upsert applied ${op.applied}/${op.items.length} entries${op.failed > 0 ? `; ${op.failed} failed` : ''}.`,\n ...op.items.map((item) => `- [${item.index}] ${formatUpsertItem(item)}`),\n ...(op.failed > 0 ? ['', MSG_UPSERT_PARTIAL] : []),\n ];\n // Once, last, and only when something landed: emitting it per entry\n // would repeat it for every completion in a batch.\n if (op.applied > 0 && isTaskListComplete(document.tasks)) lines.push(MSG_ALL_COMPLETE_CLEAR);\n return lines.join('\\n');\n }\n case 'delete':\n return `Deleted #${op.id}: ${op.subject}`;\n case 'clear':\n return `Closed task list (cleared ${op.count} tasks)`;\n case 'list': {\n let view = document.tasks;\n if (!op.includeDeleted) view = view.filter((task) => task.status !== 'deleted');\n if (op.statusFilter) view = view.filter((task) => task.status === op.statusFilter);\n return view.length === 0 ? 'No tasks' : view.map(formatListLine).join('\\n');\n }\n case 'get':\n return formatGetLines(op.task, document);\n case 'error':\n return `Error: ${op.message}`;\n }\n}\n\nexport interface ToolResult {\n content: Array<{ type: 'text'; text: string }>;\n details: TaskDetails;\n}\n\n/** Build the LLM-facing envelope. `details` carries the post-mutation snapshot. */\nexport function buildToolResult(\n action: TaskAction,\n params: TaskMutationParams,\n document: TaskDocument,\n op: Op,\n): ToolResult {\n return {\n content: [{ type: 'text', text: formatContent(op, document) }],\n details: {\n action,\n params: params as Record<string, unknown>,\n tasks: document.tasks,\n nextId: document.nextId,\n rev: document.rev,\n ...(op.kind === 'error' ? { error: op.message } : {}),\n // Deliberately no `error` on a partial success: renderResult treats\n // `details.error` as total failure and would hide the rows for the\n // entries that did land.\n ...(op.kind === 'upsert'\n ? {\n upsert: {\n applied: op.items.flatMap((item) => (item.kind === 'failed' ? [] : [item.id])),\n failed: op.failed,\n },\n }\n : {}),\n },\n };\n}\n\n/** Envelope for delegation actions, which do not flow through the reducer. */\nexport function buildTextResult(\n action: TaskAction,\n params: TaskMutationParams,\n document: TaskDocument,\n text: string,\n error?: string,\n): ToolResult {\n return {\n content: [{ type: 'text', text: error ? `Error: ${error}` : text }],\n details: {\n action,\n params: params as Record<string, unknown>,\n tasks: document.tasks,\n nextId: document.nextId,\n rev: document.rev,\n ...(error ? { error } : {}),\n },\n };\n}\n"],"mappings":"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"}