chainlesschain 0.45.11 → 0.45.19

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 (81) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/AppLayout-B00RARl2.js +1 -0
  3. package/src/assets/web-panel/assets/AppLayout-CFP4dGIJ.css +1 -0
  4. package/src/assets/web-panel/assets/{Chat-5f__rMCR.js → Chat-DXtvKoM0.js} +1 -1
  5. package/src/assets/web-panel/assets/{Cron-C4mrNC4c.js → Cron-BJ4ODHOy.js} +1 -1
  6. package/src/assets/web-panel/assets/Dashboard-3iIpp3zd.js +3 -0
  7. package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +1 -0
  8. package/src/assets/web-panel/assets/{Logs-CC_Zuh66.js → Logs-CSeKZEG_.js} +1 -1
  9. package/src/assets/web-panel/assets/{McpTools-B15GiN3u.js → McpTools-BYQAK11r.js} +2 -2
  10. package/src/assets/web-panel/assets/{Memory-Dbd7oLOH.js → Memory-gkUAPyuZ.js} +2 -2
  11. package/src/assets/web-panel/assets/{Notes-CEkc49fY.js → Notes-bjNrQgAo.js} +1 -1
  12. package/src/assets/web-panel/assets/{Providers-CjyPHW00.js → Providers-Dbf57Tbv.js} +1 -1
  13. package/src/assets/web-panel/assets/{Services-XFzHMRRd.js → Services-CS0oMdxh.js} +1 -1
  14. package/src/assets/web-panel/assets/{Skills-D8oxmB3U.js → Skills-B2fgruv8.js} +1 -1
  15. package/src/assets/web-panel/assets/Tasks-BJjN_YEm.css +1 -0
  16. package/src/assets/web-panel/assets/Tasks-qULws8pc.js +1 -0
  17. package/src/assets/web-panel/assets/{antd-ChLPLhSn.js → antd-CJSBocer.js} +1 -1
  18. package/src/assets/web-panel/assets/chat-DnH09sSR.js +1 -0
  19. package/src/assets/web-panel/assets/{index-DQ5xXK7O.js → index-CF2CqPYX.js} +2 -2
  20. package/src/assets/web-panel/assets/{markdown-DtbPhnFe.js → markdown-Bo5cVN4u.js} +1 -1
  21. package/src/assets/web-panel/assets/ws-DjelKkD6.js +1 -0
  22. package/src/assets/web-panel/index.html +2 -2
  23. package/src/commands/agent.js +7 -8
  24. package/src/commands/chat.js +9 -11
  25. package/src/commands/serve.js +11 -106
  26. package/src/commands/session.js +185 -18
  27. package/src/commands/ui.js +10 -151
  28. package/src/gateways/repl/agent-repl.js +1 -0
  29. package/src/gateways/repl/chat-repl.js +1 -0
  30. package/src/gateways/ui/web-ui-server.js +1 -0
  31. package/src/gateways/ws/action-protocol.js +83 -0
  32. package/src/gateways/ws/message-dispatcher.js +73 -0
  33. package/src/gateways/ws/session-protocol.js +396 -0
  34. package/src/gateways/ws/task-protocol.js +55 -0
  35. package/src/gateways/ws/worktree-protocol.js +315 -0
  36. package/src/gateways/ws/ws-server.js +4 -0
  37. package/src/gateways/ws/ws-session-gateway.js +1 -0
  38. package/src/harness/background-task-manager.js +506 -0
  39. package/src/harness/background-task-worker.js +48 -0
  40. package/src/harness/compression-telemetry.js +214 -0
  41. package/src/harness/feature-flags.js +157 -0
  42. package/src/harness/jsonl-session-store.js +452 -0
  43. package/src/harness/prompt-compressor.js +416 -0
  44. package/src/harness/worktree-isolator.js +845 -0
  45. package/src/lib/agent-core.js +246 -45
  46. package/src/lib/background-task-manager.js +1 -305
  47. package/src/lib/background-task-worker.js +1 -50
  48. package/src/lib/compression-telemetry.js +5 -0
  49. package/src/lib/feature-flags.js +7 -182
  50. package/src/lib/interaction-adapter.js +32 -6
  51. package/src/lib/jsonl-session-store.js +21 -237
  52. package/src/lib/prompt-compressor.js +10 -351
  53. package/src/lib/sub-agent-context.js +91 -0
  54. package/src/lib/worktree-isolator.js +13 -231
  55. package/src/lib/ws-agent-handler.js +1 -0
  56. package/src/lib/ws-server.js +155 -359
  57. package/src/lib/ws-session-manager.js +82 -1
  58. package/src/repl/agent-repl.js +114 -32
  59. package/src/runtime/agent-runtime.js +417 -0
  60. package/src/runtime/contracts/agent-turn.js +11 -0
  61. package/src/runtime/contracts/session-record.js +31 -0
  62. package/src/runtime/contracts/task-record.js +18 -0
  63. package/src/runtime/contracts/telemetry-record.js +23 -0
  64. package/src/runtime/contracts/worktree-record.js +14 -0
  65. package/src/runtime/index.js +13 -0
  66. package/src/runtime/policies/agent-policy.js +45 -0
  67. package/src/runtime/runtime-context.js +14 -0
  68. package/src/runtime/runtime-events.js +37 -0
  69. package/src/runtime/runtime-factory.js +50 -0
  70. package/src/tools/index.js +22 -0
  71. package/src/tools/legacy-agent-tools.js +171 -0
  72. package/src/tools/registry.js +141 -0
  73. package/src/tools/tool-context.js +28 -0
  74. package/src/tools/tool-permissions.js +28 -0
  75. package/src/tools/tool-telemetry.js +39 -0
  76. package/src/assets/web-panel/assets/AppLayout-19ZC8w11.js +0 -1
  77. package/src/assets/web-panel/assets/AppLayout-CjgO-ML6.css +0 -1
  78. package/src/assets/web-panel/assets/Dashboard-CRFnDUFh.css +0 -1
  79. package/src/assets/web-panel/assets/Dashboard-DsjXpZor.js +0 -3
  80. package/src/assets/web-panel/assets/chat-C_hu-qNs.js +0 -1
  81. package/src/assets/web-panel/assets/ws-DwluTqT5.js +0 -1
@@ -0,0 +1,315 @@
1
+ import { createWorktreeRecord } from "../../runtime/contracts/worktree-record.js";
2
+ import {
3
+ RUNTIME_EVENTS,
4
+ createRuntimeEvent,
5
+ } from "../../runtime/runtime-events.js";
6
+
7
+ export async function handleWorktreeDiff(server, id, ws, message) {
8
+ try {
9
+ const { diffWorktree } = await import("../../lib/worktree-isolator.js");
10
+ const { branch, baseBranch, filePath } = message;
11
+ if (!branch) {
12
+ server._send(ws, {
13
+ id,
14
+ type: "error",
15
+ code: "NO_BRANCH",
16
+ message: "branch required",
17
+ });
18
+ return;
19
+ }
20
+ const result = diffWorktree(process.cwd(), branch, {
21
+ baseBranch,
22
+ filePath,
23
+ });
24
+ server._send(ws, {
25
+ id,
26
+ type: "worktree-diff",
27
+ filePath: result.filePath || filePath || null,
28
+ files: result.files,
29
+ summary: result.summary,
30
+ diff: result.diff,
31
+ record: createWorktreeRecord({
32
+ branch,
33
+ baseBranch,
34
+ summary: result.summary,
35
+ previewEntrypoints: [
36
+ {
37
+ type: "worktree-diff",
38
+ branch,
39
+ },
40
+ ],
41
+ }),
42
+ });
43
+ server.emit(
44
+ RUNTIME_EVENTS.WORKTREE_DIFF_READY,
45
+ createRuntimeEvent(
46
+ RUNTIME_EVENTS.WORKTREE_DIFF_READY,
47
+ {
48
+ requestId: id,
49
+ filePath: result.filePath || filePath || null,
50
+ diff: result.diff,
51
+ record: createWorktreeRecord({
52
+ branch,
53
+ baseBranch,
54
+ summary: result.summary,
55
+ previewEntrypoints: [
56
+ {
57
+ type: "worktree-diff",
58
+ branch,
59
+ },
60
+ ],
61
+ }),
62
+ },
63
+ { kind: "server" },
64
+ ),
65
+ );
66
+ } catch (err) {
67
+ server._send(ws, {
68
+ id,
69
+ type: "error",
70
+ code: "WORKTREE_DIFF_FAILED",
71
+ message: err.message,
72
+ });
73
+ }
74
+ }
75
+
76
+ export async function handleWorktreeMerge(server, id, ws, message) {
77
+ try {
78
+ const { mergeWorktree } = await import("../../lib/worktree-isolator.js");
79
+ const { branch, strategy, commitMessage } = message;
80
+ if (!branch) {
81
+ server._send(ws, {
82
+ id,
83
+ type: "error",
84
+ code: "NO_BRANCH",
85
+ message: "branch required",
86
+ });
87
+ return;
88
+ }
89
+ const result = mergeWorktree(process.cwd(), branch, {
90
+ strategy: strategy || "merge",
91
+ message: commitMessage,
92
+ });
93
+ server._send(ws, {
94
+ id,
95
+ type: "worktree-merged",
96
+ ...result,
97
+ record: createWorktreeRecord(
98
+ {
99
+ branch,
100
+ summary: result.summary || null,
101
+ conflicts: result.conflicts || [],
102
+ previewEntrypoints: result.previewEntrypoints || [],
103
+ },
104
+ {
105
+ strategy: strategy || "merge",
106
+ success: result.success,
107
+ },
108
+ ),
109
+ });
110
+ server.emit(
111
+ RUNTIME_EVENTS.WORKTREE_MERGED,
112
+ createRuntimeEvent(
113
+ RUNTIME_EVENTS.WORKTREE_MERGED,
114
+ {
115
+ requestId: id,
116
+ suggestions: result.suggestions || [],
117
+ record: createWorktreeRecord(
118
+ {
119
+ branch,
120
+ summary: result.summary || null,
121
+ conflicts: result.conflicts || [],
122
+ previewEntrypoints: result.previewEntrypoints || [],
123
+ },
124
+ {
125
+ strategy: strategy || "merge",
126
+ success: result.success,
127
+ },
128
+ ),
129
+ },
130
+ { kind: "server" },
131
+ ),
132
+ );
133
+ } catch (err) {
134
+ server._send(ws, {
135
+ id,
136
+ type: "error",
137
+ code: "WORKTREE_MERGE_FAILED",
138
+ message: err.message,
139
+ });
140
+ }
141
+ }
142
+
143
+ export async function handleWorktreeMergePreview(server, id, ws, message) {
144
+ try {
145
+ const { previewWorktreeMerge } =
146
+ await import("../../lib/worktree-isolator.js");
147
+ const { branch, baseBranch, strategy } = message;
148
+ if (!branch) {
149
+ server._send(ws, {
150
+ id,
151
+ type: "error",
152
+ code: "NO_BRANCH",
153
+ message: "branch required",
154
+ });
155
+ return;
156
+ }
157
+
158
+ const result = previewWorktreeMerge(process.cwd(), branch, {
159
+ baseBranch,
160
+ strategy: strategy || "merge",
161
+ });
162
+ server._send(ws, {
163
+ id,
164
+ type: "worktree-merge-preview",
165
+ ...result,
166
+ record: createWorktreeRecord(
167
+ {
168
+ branch,
169
+ baseBranch: result.baseBranch || baseBranch || null,
170
+ summary: result.summary || null,
171
+ conflicts: result.conflicts || [],
172
+ previewEntrypoints: result.previewEntrypoints || [],
173
+ },
174
+ {
175
+ strategy: strategy || "merge",
176
+ success: result.success,
177
+ previewOnly: true,
178
+ },
179
+ ),
180
+ });
181
+ } catch (err) {
182
+ server._send(ws, {
183
+ id,
184
+ type: "error",
185
+ code: "WORKTREE_MERGE_PREVIEW_FAILED",
186
+ message: err.message,
187
+ });
188
+ }
189
+ }
190
+
191
+ export async function handleWorktreeAutomationApply(server, id, ws, message) {
192
+ try {
193
+ const { applyWorktreeAutomationCandidate } =
194
+ await import("../../lib/worktree-isolator.js");
195
+ const { branch, baseBranch, filePath, candidateId, conflictType } = message;
196
+ if (!branch) {
197
+ server._send(ws, {
198
+ id,
199
+ type: "error",
200
+ code: "NO_BRANCH",
201
+ message: "branch required",
202
+ });
203
+ return;
204
+ }
205
+ if (!filePath || !candidateId) {
206
+ server._send(ws, {
207
+ id,
208
+ type: "error",
209
+ code: "INVALID_WORKTREE_AUTOMATION",
210
+ message: "filePath and candidateId are required",
211
+ });
212
+ return;
213
+ }
214
+
215
+ const result = applyWorktreeAutomationCandidate(process.cwd(), branch, {
216
+ baseBranch,
217
+ filePath,
218
+ candidateId,
219
+ conflictType,
220
+ });
221
+
222
+ server._send(ws, {
223
+ id,
224
+ type: "worktree-automation-applied",
225
+ ...result,
226
+ record: createWorktreeRecord(
227
+ {
228
+ branch,
229
+ baseBranch: result.baseBranch || baseBranch || null,
230
+ hasChanges: (result.summary?.filesChanged || 0) > 0,
231
+ summary: result.summary || null,
232
+ conflicts: [],
233
+ previewEntrypoints:
234
+ result.filePath && (result.summary?.filesChanged || 0) > 0
235
+ ? [
236
+ {
237
+ type: "worktree-diff",
238
+ branch,
239
+ filePath: result.filePath,
240
+ },
241
+ ]
242
+ : [],
243
+ },
244
+ {
245
+ candidateId,
246
+ filePath,
247
+ conflictType: conflictType || null,
248
+ success: true,
249
+ },
250
+ ),
251
+ });
252
+ } catch (err) {
253
+ server._send(ws, {
254
+ id,
255
+ type: "error",
256
+ code: "WORKTREE_AUTOMATION_FAILED",
257
+ message: err.message,
258
+ });
259
+ }
260
+ }
261
+
262
+ export async function handleWorktreeList(server, id, ws) {
263
+ try {
264
+ const { listWorktrees } = await import("../../lib/worktree-isolator.js");
265
+ const worktrees = listWorktrees(process.cwd()).filter(
266
+ (wt) => wt.branch && wt.branch.startsWith("agent/"),
267
+ );
268
+ server._send(ws, { id, type: "worktree-list", worktrees });
269
+ } catch (err) {
270
+ server._send(ws, {
271
+ id,
272
+ type: "error",
273
+ code: "WORKTREE_LIST_FAILED",
274
+ message: err.message,
275
+ });
276
+ }
277
+ }
278
+
279
+ export async function handleCompressionStats(server, id, ws, message) {
280
+ try {
281
+ const { getCompressionTelemetrySummary } =
282
+ await import("../../lib/compression-telemetry.js");
283
+ const summary = getCompressionTelemetrySummary({
284
+ limit: message.limit,
285
+ windowMs: message.windowMs,
286
+ provider: message.provider,
287
+ model: message.model,
288
+ });
289
+ server._send(ws, { id, type: "compression-stats", summary });
290
+ server.emit(
291
+ RUNTIME_EVENTS.COMPRESSION_SUMMARY,
292
+ createRuntimeEvent(
293
+ RUNTIME_EVENTS.COMPRESSION_SUMMARY,
294
+ {
295
+ requestId: id,
296
+ summary,
297
+ filters: {
298
+ limit: message.limit ?? null,
299
+ windowMs: message.windowMs ?? null,
300
+ provider: message.provider ?? null,
301
+ model: message.model ?? null,
302
+ },
303
+ },
304
+ { kind: "server" },
305
+ ),
306
+ );
307
+ } catch (err) {
308
+ server._send(ws, {
309
+ id,
310
+ type: "error",
311
+ code: "COMPRESSION_STATS_FAILED",
312
+ message: err.message,
313
+ });
314
+ }
315
+ }
@@ -0,0 +1,4 @@
1
+ export {
2
+ ChainlessChainWSServer,
3
+ tokenizeCommand,
4
+ } from "../../lib/ws-server.js";
@@ -0,0 +1 @@
1
+ export { WSSessionManager } from "../../lib/ws-session-manager.js";