@ra3orblade/swarm 0.13.2 → 0.14.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.
- package/dist/swarm-hook.js +687 -166
- package/dist/swarm-mcp.js +2 -1
- package/dist/swarm.js +711 -239
- package/dist/swarmd.js +2573 -870
- package/package.json +1 -1
- package/web/dashboard.js +18 -18
- package/web/release-notes.js +1 -1
package/dist/swarm-hook.js
CHANGED
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __esm = (fn, res, err) => () => {
|
|
4
|
+
if (fn)
|
|
5
|
+
try {
|
|
6
|
+
res = fn(fn = 0);
|
|
7
|
+
} catch (e) {
|
|
8
|
+
err = [e];
|
|
9
|
+
}
|
|
10
|
+
if (err)
|
|
11
|
+
throw err[0];
|
|
12
|
+
return res;
|
|
13
|
+
};
|
|
3
14
|
|
|
4
|
-
// packages/
|
|
5
|
-
|
|
6
|
-
import { dirname, join as join2 } from "path";
|
|
15
|
+
// packages/client/src/bins.ts
|
|
16
|
+
var init_bins = () => {};
|
|
7
17
|
|
|
8
18
|
// packages/client/src/daemon.ts
|
|
9
19
|
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
|
|
@@ -12,8 +22,6 @@ import { join } from "path";
|
|
|
12
22
|
function swarmHome() {
|
|
13
23
|
return process.env.SWARM_HOME ?? join(homedir(), ".swarm");
|
|
14
24
|
}
|
|
15
|
-
var DEFAULT_PORT = Number(process.env.SWARM_PORT ?? 7777);
|
|
16
|
-
var infoFile = () => join(swarmHome(), "daemon.json");
|
|
17
25
|
function readDaemonInfo() {
|
|
18
26
|
const file = infoFile();
|
|
19
27
|
if (!existsSync(file))
|
|
@@ -24,7 +32,6 @@ function readDaemonInfo() {
|
|
|
24
32
|
return null;
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
|
-
var tokenFile = (home = swarmHome()) => join(home, "token");
|
|
28
35
|
function readToken(home = swarmHome()) {
|
|
29
36
|
try {
|
|
30
37
|
const t = readFileSync(tokenFile(home), "utf8").trim();
|
|
@@ -33,153 +40,229 @@ function readToken(home = swarmHome()) {
|
|
|
33
40
|
return null;
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
|
-
|
|
43
|
+
function resolveBaseUrl(explicit) {
|
|
44
|
+
const raw = explicit ?? process.env.SWARM_URL ?? readDaemonInfo()?.url ?? `http://127.0.0.1:${DEFAULT_PORT}`;
|
|
45
|
+
return raw.replace(/\/$/, "");
|
|
46
|
+
}
|
|
47
|
+
var DEFAULT_PORT, infoFile = () => join(swarmHome(), "daemon.json"), tokenFile = (home = swarmHome()) => join(home, "token"), authedFetch = (input, init) => {
|
|
37
48
|
const h = new Headers(init?.headers);
|
|
38
49
|
const t = readToken();
|
|
39
50
|
if (t && !h.has("authorization"))
|
|
40
51
|
h.set("authorization", `Bearer ${t}`);
|
|
41
52
|
return fetch(input, { ...init, headers: h });
|
|
42
53
|
};
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
54
|
+
var init_daemon = __esm(() => {
|
|
55
|
+
init_bins();
|
|
56
|
+
DEFAULT_PORT = Number(process.env.SWARM_PORT ?? 7777);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// packages/client/src/index.ts
|
|
60
|
+
var init_src = __esm(() => {
|
|
61
|
+
init_daemon();
|
|
62
|
+
init_bins();
|
|
63
|
+
init_daemon();
|
|
64
|
+
});
|
|
47
65
|
// packages/core/src/actor.ts
|
|
48
|
-
var HUMAN_ALIASES
|
|
49
|
-
var
|
|
66
|
+
var HUMAN_ALIASES, DAEMON_ALIASES;
|
|
67
|
+
var init_actor = __esm(() => {
|
|
68
|
+
HUMAN_ALIASES = new Set(["cli", "dashboard", "me", "desktop", "human"]);
|
|
69
|
+
DAEMON_ALIASES = new Set(["daemon", "system", "swarm"]);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// packages/core/src/adapters/aider/history.ts
|
|
73
|
+
var init_history = () => {};
|
|
74
|
+
// packages/core/src/adapters/claude-code/adapter.ts
|
|
75
|
+
var init_adapter = () => {};
|
|
76
|
+
|
|
77
|
+
// packages/core/src/adapters/codex/rollout.ts
|
|
78
|
+
var init_rollout = () => {};
|
|
79
|
+
|
|
80
|
+
// packages/core/src/adapters/gemini/chats.ts
|
|
81
|
+
var init_chats = () => {};
|
|
82
|
+
|
|
83
|
+
// packages/core/src/adapters/grok/updates.ts
|
|
84
|
+
var init_updates = () => {};
|
|
85
|
+
|
|
86
|
+
// packages/core/src/adapters/opencode/db.ts
|
|
87
|
+
var init_db = () => {};
|
|
88
|
+
// packages/core/src/adapters/index.ts
|
|
89
|
+
var init_adapters = __esm(() => {
|
|
90
|
+
init_history();
|
|
91
|
+
init_adapter();
|
|
92
|
+
init_rollout();
|
|
93
|
+
init_chats();
|
|
94
|
+
init_updates();
|
|
95
|
+
init_db();
|
|
96
|
+
init_history();
|
|
97
|
+
init_adapter();
|
|
98
|
+
init_rollout();
|
|
99
|
+
init_chats();
|
|
100
|
+
init_updates();
|
|
101
|
+
init_db();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// packages/core/src/adapters/claude-code/hooks.ts
|
|
105
|
+
var init_hooks = () => {};
|
|
106
|
+
|
|
50
107
|
// packages/core/src/art.ts
|
|
51
|
-
var ROBOT
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
108
|
+
var ROBOT, HEAD;
|
|
109
|
+
var init_art = __esm(() => {
|
|
110
|
+
ROBOT = [
|
|
111
|
+
" MM MM ",
|
|
112
|
+
" LL LL ",
|
|
113
|
+
" LL LL ",
|
|
114
|
+
" LM MM ",
|
|
115
|
+
" MD MS ",
|
|
116
|
+
" LE LE ",
|
|
117
|
+
" ME ME ",
|
|
118
|
+
" MS MS ",
|
|
119
|
+
" KK KK ",
|
|
120
|
+
" SSDDDSDDDDDDDDDDDDDDDDDDDDDDDDDDDDS ",
|
|
121
|
+
" SSDSDDDDDDDDDDDDDDDDDDDDDDDDDDDDDSS ",
|
|
122
|
+
" SSDOOOOOOOOOOOOOOOOOOOOOOOOOOOOOKSS ",
|
|
123
|
+
" SSOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMOSS ",
|
|
124
|
+
" DDKMMLLLMLLMMMMMMMMMMMMMMMMMMMMMODD ",
|
|
125
|
+
" DDOMMLMMMMMMMMMMMMMMMMMMMMMMMMMMODD ",
|
|
126
|
+
" SSSSODDOMMLMMMMMMMMMMMMMMMMMMMMMMMMMMODDOSSSS ",
|
|
127
|
+
" SSSSODDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODDOSSSS ",
|
|
128
|
+
" SMMMMODDOMMLMMMMMMMMMMMMMMMMMMMMMMMMMMODDOSMMMS ",
|
|
129
|
+
" DMSSSODDOMMMMOOOOOOMMMMMMMMMOOOOOOMMMMODDOSSSED ",
|
|
130
|
+
" DSSSSODDOMMMMODDDDDMMMMMMMMMODDDDDMMMMODDOSSSSK ",
|
|
131
|
+
" DSMMSODDOMMMMDDDDDDMMMMMMMMMKDDDDDMMMMODDOSMMSK ",
|
|
132
|
+
" DSSSSODDOMMMMDDDDDDMMMMMMMMMDDDDDDMMMMODDOSSSSK ",
|
|
133
|
+
" DSSSSODDOMMMMDDDDDDMMMMMMMMMDDDDDDMMMMODDODSSSK ",
|
|
134
|
+
" DSSSSODDOMMMMDDDDDDMMMMMMMMMDDDDDDMMMMODDODSSSK ",
|
|
135
|
+
" DSSSKODDOMMMMDDDDDDMMMMMMMMMDDDDDDMMMMODDODSSSD ",
|
|
136
|
+
" OKKKKODDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODDOKKKKO ",
|
|
137
|
+
" KKKKODDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODDOOKKK ",
|
|
138
|
+
" KKKOODDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODDOOKKK ",
|
|
139
|
+
" DDOMMMMDDDDDDDDDDDDDDDDDDDDDMMMMODD ",
|
|
140
|
+
" DDOMMMMDDDDDDDDDDDDDDDDDDDDDMMMMODD ",
|
|
141
|
+
" DDOMMMMDDDDDDDDDDDDDDDDDDDDDMMMMODD ",
|
|
142
|
+
" DDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODD ",
|
|
143
|
+
" DDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODD ",
|
|
144
|
+
" DDOMMMMMMMMMMMMMMMMMMMMMMMMMMMMMODD ",
|
|
145
|
+
" DDDOOOOOOOOOOOOOOOOOOOOOOOOOOOOOKDD ",
|
|
146
|
+
" DDDDDDDDDDDDDDDDDDDDDDDDDDDDDKDDDDD ",
|
|
147
|
+
" DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD ",
|
|
148
|
+
" OOOOOOOOOOO ",
|
|
149
|
+
" OODDDDDKKOO ",
|
|
150
|
+
" DSMMMMMMSDD ",
|
|
151
|
+
" OOOOOOOOOOO ",
|
|
152
|
+
" KDSMMMMMESSKK ",
|
|
153
|
+
" MMMMMMSSKOOKDSMMMMMSSSDKOODSEMMMMMM ",
|
|
154
|
+
" SSSSDO MMMMMMSSKKOOOOOOOOOOOOOOOOOKSSSMMMMMM ODSSSS ",
|
|
155
|
+
" EEESSSSOOLLLLMMMMMESSSSSSSSSSSSSSSSSSSSMMMMMLLLLOOSSSSMME ",
|
|
156
|
+
" SMMSSSSKOEELLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLEEOOSSSSEMS ",
|
|
157
|
+
" DSSSSSSSOOSEEKSMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMSOEEDOOSSSSSSSK ",
|
|
158
|
+
" DSSSSSSDOOSEOSKEMMMMMMMMMMMMMMMMMMMMMMMMMMMMMEOSDEDOODSSSSSSK ",
|
|
159
|
+
" KSSSSSSKOODSSOSEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEESOEEDOOKSSSSSSK ",
|
|
160
|
+
" DKSSSSKKOODSMEEMLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMSEMSDOOKKSSSSDK ",
|
|
161
|
+
" OKDDKDKKOOKSMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMSKOOKKKKKKKO ",
|
|
162
|
+
" OOOOOKKKOOKSMMMMESSSSSSSSSSSSSMMMMEEEEEESSSSEMMMMSKOOKKKOOOOO ",
|
|
163
|
+
" OOOOOOKKOOKSMMMSSKKKKKKKKKKKKKKMMMDKOOOOOOOODDMMMSKOOKKOOOOOO ",
|
|
164
|
+
" OKSSKOOOOOKSMMMKKMLLLLLLLLLLLMKMMMDDSSSSSSSSDDMMMSKOOOOODSSKO ",
|
|
165
|
+
" SDOKKK KSMMMKDLLLLLLLLLLLLLKMMMKDKKKDDKKKDKMMMSK KKKKDS ",
|
|
166
|
+
" DMLLMKO KSMMMKDLLLLLLLLLLLLLKMMMDDDDDDDDDSKDMMMSK ODMLLMD ",
|
|
167
|
+
" DELLMSD KSMMMKKMLLLLLLLLLLLLKMMMDKKKKKKKKKDDMMMSK DSMLLEO ",
|
|
168
|
+
" KSKKKKDO KSMMMEDDDDKKDDDKKKDKSMMMDDDDDDDDDSDDMMMSK ODDKKKSK ",
|
|
169
|
+
" EMLLMDO KSMMMMLLLLLLLLLLLLLLLMMMDOOOOOOOOODDMMMSK ODMLLME ",
|
|
170
|
+
" KMLLMSD KSMMMMMMMMMMMMMMMMMMMMMMDDSSDDSSSSDDMMMSK SSMLLEK ",
|
|
171
|
+
" KSKKKKSO KSMMMMMOOMMOOMKOEMOOMMMMDOOOOOOOOODDMMMSK OSKKKKSO ",
|
|
172
|
+
" SMLLMDO KSMMMMMKKMMKKMDKEMKKMMMMKDDDDSSSSDDDMMMSK ODMLLMS ",
|
|
173
|
+
" SMMMMSD KSMMMMMEEMMEEMEEMMEEMMMMDSOOOOOOOODDMMSSK DSMMMMD ",
|
|
174
|
+
" OOOOOOO KSSMMMMMMMMMMMMMMMMMMMMMDDDDDDDDDDDDMSSSK OOOOOOO ",
|
|
175
|
+
" KSMLLLMMSKO KSSSSMMMMMMMMMMMMMMMMMMMSOOOOOOOOOOSSSSSK OKSMLLLLMSO ",
|
|
176
|
+
" DSMMMEEESKK KSSKSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSOSSK KDSMMMMMESD ",
|
|
177
|
+
" DSMMMMMESKK KSOOKSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSOOKSK KKSMMMMMMSD ",
|
|
178
|
+
" DSMMMMMESKK OKSKSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSDSKO KDSMMMMMMSD ",
|
|
179
|
+
" KDDDDDDDDKK KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK KKDDDDDDDDO ",
|
|
180
|
+
" OOOOOOOOOOO OOOOOOOOO OOOOOOOOO OOOOOOOOOOO ",
|
|
181
|
+
"DSDO OSSO ODKKKKKKK OKKKKKKKO KEDO ODEK",
|
|
182
|
+
"SMDO OSMD KDSSSSSSK KDSSSSSKO SMDO ODMS",
|
|
183
|
+
"DEKO OOED OOKKKOOO OOOKKOOO SSOO OKMS",
|
|
184
|
+
"DEKO OOED SEMMMMSK OSMMMMED SSKO OKES",
|
|
185
|
+
"DSSO OESK SEMMMMSK OSMMMMED KSSO OSSK",
|
|
186
|
+
"KSMS EEDO OOKKKKKO OOKKKKKO OSEE EMSO",
|
|
187
|
+
" DSS SSK OSEEESDO ODSEEESO KSS SSD ",
|
|
188
|
+
" OOO OO SEMMMMSK OSMMMMED OO OOO ",
|
|
189
|
+
" KSSSSSDO OKSSESSK ",
|
|
190
|
+
" DKKDDDDDDKKDK KDKDDDDDDDKDK ",
|
|
191
|
+
" SSMLLMMMMMMLMSK DSSMMMMMMMLLMSS ",
|
|
192
|
+
" SMLMMMMMMMMLLED SEMMMMMMMMMMLMS ",
|
|
193
|
+
" DMMMMMMMMMMMMMMD SMMMMMMMMMMMMMSK ",
|
|
194
|
+
" ODSSSSSSSSSSSSSSDO ODSSSSSSSSSSSSSSKO ",
|
|
195
|
+
" OOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOO ",
|
|
196
|
+
" OKSSSSSSSSSSSSSSK KSSSSSSSSSSSSSSKO ",
|
|
197
|
+
" OKDDDDDDDDDDDDDDK KDDDDDDDDDDDDDDOO "
|
|
198
|
+
];
|
|
199
|
+
HEAD = ROBOT.slice(0, 37);
|
|
200
|
+
});
|
|
201
|
+
|
|
141
202
|
// packages/core/src/audit.ts
|
|
142
|
-
var AUDIT_TYPES
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
203
|
+
var AUDIT_TYPES, AUDIT_TYPES_SQL;
|
|
204
|
+
var init_audit = __esm(() => {
|
|
205
|
+
AUDIT_TYPES = new Set([
|
|
206
|
+
"session.started",
|
|
207
|
+
"session.ended",
|
|
208
|
+
"tool.denied",
|
|
209
|
+
"claim.acquired",
|
|
210
|
+
"claim.renewed",
|
|
211
|
+
"claim.released",
|
|
212
|
+
"claim.expired",
|
|
213
|
+
"claim.orphaned",
|
|
214
|
+
"claim.denied",
|
|
215
|
+
"rules.changed",
|
|
216
|
+
"worktree.reclaimed",
|
|
217
|
+
"worktree.created",
|
|
218
|
+
"worktree.removed",
|
|
219
|
+
"worktree.bootstrapped",
|
|
220
|
+
"pr.opened",
|
|
221
|
+
"question.asked",
|
|
222
|
+
"question.answered",
|
|
223
|
+
"dispatch.queued",
|
|
224
|
+
"dispatch.started",
|
|
225
|
+
"dispatch.finished",
|
|
226
|
+
"resource.acquired",
|
|
227
|
+
"resource.released",
|
|
228
|
+
"resource.reaped",
|
|
229
|
+
"process.started",
|
|
230
|
+
"process.exited",
|
|
231
|
+
"gate.recorded",
|
|
232
|
+
"gate.blocked",
|
|
233
|
+
"codify.applied",
|
|
234
|
+
"handoff.recorded",
|
|
235
|
+
"permission.requested",
|
|
236
|
+
"permission.resolved",
|
|
237
|
+
"incident.opened",
|
|
238
|
+
"incident.acked",
|
|
239
|
+
"run.result",
|
|
240
|
+
"workflow.started",
|
|
241
|
+
"workflow.finished"
|
|
242
|
+
]);
|
|
243
|
+
AUDIT_TYPES_SQL = [...AUDIT_TYPES].map((t) => `'${t}'`).join(", ");
|
|
244
|
+
});
|
|
245
|
+
|
|
179
246
|
// packages/core/src/budget.ts
|
|
180
|
-
var BUDGET_ASK_TOOLS
|
|
247
|
+
var BUDGET_ASK_TOOLS;
|
|
248
|
+
var init_budget = __esm(() => {
|
|
249
|
+
BUDGET_ASK_TOOLS = new Set(["Bash", "Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
250
|
+
});
|
|
251
|
+
// packages/core/src/workflows.ts
|
|
252
|
+
var init_workflows = () => {};
|
|
253
|
+
|
|
254
|
+
// packages/core/src/config.ts
|
|
255
|
+
var init_config = __esm(() => {
|
|
256
|
+
init_audit();
|
|
257
|
+
init_workflows();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
// packages/core/src/context.ts
|
|
261
|
+
var init_context = () => {};
|
|
262
|
+
|
|
263
|
+
// packages/core/src/dag.ts
|
|
264
|
+
var init_dag = () => {};
|
|
181
265
|
// packages/core/src/rules.ts
|
|
182
|
-
var LIVE_WINDOW_MS = 10 * 60000;
|
|
183
266
|
function otherLiveInSameTree(current, sessions, now, withinMs = LIVE_WINDOW_MS) {
|
|
184
267
|
if (!current.toplevel)
|
|
185
268
|
return null;
|
|
@@ -196,7 +279,6 @@ function otherLiveInSameTree(current, sessions, now, withinMs = LIVE_WINDOW_MS)
|
|
|
196
279
|
}
|
|
197
280
|
return null;
|
|
198
281
|
}
|
|
199
|
-
var GIT_GLOBAL_OPTS = "(?:\\s+(?:-C\\s+\\S+|-c\\s+\\S+|--git-dir(?:=|\\s+)\\S+|--work-tree(?:=|\\s+)\\S+|--namespace(?:=|\\s+)\\S+|--no-pager|--paginate|--bare|--literal-pathspecs|--exec-path(?:=\\S+)?))*";
|
|
200
282
|
function gitVerb(verb, tail) {
|
|
201
283
|
return new RegExp(`\\bgit${GIT_GLOBAL_OPTS}\\s+${verb}${tail}`);
|
|
202
284
|
}
|
|
@@ -230,21 +312,114 @@ function killedPorts(cmd) {
|
|
|
230
312
|
ports.add(Number(m[1]));
|
|
231
313
|
return [...ports];
|
|
232
314
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
315
|
+
function isSingleCommand(cmd) {
|
|
316
|
+
return !/[&|;<>`\n]/.test(cmd) && !cmd.includes("$(");
|
|
317
|
+
}
|
|
318
|
+
function stripFlagsOutsideQuotes(cmd, flags) {
|
|
319
|
+
let out = "";
|
|
320
|
+
let quote = null;
|
|
321
|
+
let i = 0;
|
|
322
|
+
while (i < cmd.length) {
|
|
323
|
+
const ch = cmd[i];
|
|
324
|
+
if (quote) {
|
|
325
|
+
out += ch;
|
|
326
|
+
if (ch === quote && cmd[i - 1] !== "\\")
|
|
327
|
+
quote = null;
|
|
328
|
+
i++;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (ch === '"' || ch === "'") {
|
|
332
|
+
quote = ch;
|
|
333
|
+
out += ch;
|
|
334
|
+
i++;
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
const rest = cmd.slice(i);
|
|
338
|
+
const hit = flags.find((f) => rest.startsWith(f) && /^(\s|$)/.test(rest.slice(f.length)));
|
|
339
|
+
if (hit) {
|
|
340
|
+
out = out.replace(/[ \t]+$/, "");
|
|
341
|
+
i += hit.length;
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
out += ch;
|
|
345
|
+
i++;
|
|
346
|
+
}
|
|
347
|
+
return out;
|
|
348
|
+
}
|
|
349
|
+
function rewriteNoVerify(cmd) {
|
|
350
|
+
if (!isSingleCommand(cmd) || !/^\s*git\s/.test(cmd))
|
|
351
|
+
return null;
|
|
352
|
+
if (!/--no-(verify|gpg-sign)\b/.test(cmd))
|
|
353
|
+
return null;
|
|
354
|
+
const out = stripFlagsOutsideQuotes(cmd, ["--no-verify", "--no-gpg-sign"]);
|
|
355
|
+
return out === cmd ? null : out;
|
|
356
|
+
}
|
|
357
|
+
function rewriteDryRun(cmd) {
|
|
358
|
+
if (!isSingleCommand(cmd))
|
|
359
|
+
return null;
|
|
360
|
+
const key = cmd.replace(/\s+/g, " ").trim();
|
|
361
|
+
if (/^\s*terraform\s+apply\b/.test(cmd)) {
|
|
362
|
+
const tail = cmd.replace(/^\s*terraform\s+apply\b/, "").trim();
|
|
363
|
+
if (tail.length > 0 && tail.split(/\s+/).some((a) => !a.startsWith("-")))
|
|
364
|
+
return null;
|
|
365
|
+
return {
|
|
366
|
+
key,
|
|
367
|
+
command: cmd.replace(/^(\s*)terraform\s+apply\b/, "$1terraform plan").replace(/\s+-auto-approve\b/g, "").replace(/ {2,}/g, " ").trimEnd()
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
if (/^\s*kubectl\s+delete\b/.test(cmd) && !/--dry-run\b/.test(cmd))
|
|
371
|
+
return { key, command: `${cmd.trimEnd()} --dry-run=client` };
|
|
372
|
+
if (/^\s*helm\s+(uninstall|delete)\b/.test(cmd) && !/--dry-run\b/.test(cmd))
|
|
373
|
+
return { key, command: `${cmd.trimEnd()} --dry-run` };
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
function compiled(rule) {
|
|
377
|
+
const hit = customRe.get(rule);
|
|
378
|
+
if (hit !== undefined)
|
|
379
|
+
return hit;
|
|
380
|
+
let re = null;
|
|
381
|
+
try {
|
|
382
|
+
re = new RegExp(rule.match, rule.action === "rewrite" ? "g" : "");
|
|
383
|
+
} catch {
|
|
384
|
+
re = null;
|
|
385
|
+
}
|
|
386
|
+
customRe.set(rule, re);
|
|
387
|
+
return re;
|
|
388
|
+
}
|
|
389
|
+
function applyCustomRule(rule, cmd) {
|
|
390
|
+
const re = compiled(rule);
|
|
391
|
+
if (!re)
|
|
392
|
+
return null;
|
|
393
|
+
if (rule.action === "off" || !re.test(cmd))
|
|
394
|
+
return null;
|
|
395
|
+
const id = `custom:${rule.name}`;
|
|
396
|
+
const reason = rule.reason ?? `matches custom rule "${rule.name}" (${rule.match})`;
|
|
397
|
+
if (rule.action !== "rewrite")
|
|
398
|
+
return { action: rule.action, rule: id, reason };
|
|
399
|
+
if (!isSingleCommand(cmd))
|
|
400
|
+
return {
|
|
401
|
+
action: "ask",
|
|
402
|
+
rule: id,
|
|
403
|
+
reason: `${reason} \u2014 not rewritten: the command chains or redirects`
|
|
404
|
+
};
|
|
405
|
+
re.lastIndex = 0;
|
|
406
|
+
const out = cmd.replace(re, rule.replace ?? "").trim();
|
|
407
|
+
return out === cmd ? null : { action: "rewrite", rule: id, reason, command: out };
|
|
408
|
+
}
|
|
409
|
+
function guardBash(cmd, current, sessions, now, modes = DEFAULT_MODES, ctx = {}) {
|
|
243
410
|
const other = () => otherLiveInSameTree(current, sessions, now);
|
|
244
411
|
const hit = (rule, reason) => {
|
|
245
412
|
const mode = modes[rule];
|
|
246
413
|
return mode === "off" ? { action: "allow" } : { action: mode, rule, reason };
|
|
247
414
|
};
|
|
415
|
+
const fix = (rule, reason, command, key) => {
|
|
416
|
+
const mode = modes[rule] ?? "off";
|
|
417
|
+
if (mode === "off")
|
|
418
|
+
return { action: "allow" };
|
|
419
|
+
if (mode === "rewrite")
|
|
420
|
+
return { action: "rewrite", rule, reason, command, ...key ? { key } : {} };
|
|
421
|
+
return { action: mode, rule, reason };
|
|
422
|
+
};
|
|
248
423
|
if (modes.protected_ports !== "off" && modes.protected.ports.length) {
|
|
249
424
|
const target = killedPorts(cmd).filter((p) => modes.protected.ports.includes(p));
|
|
250
425
|
if (target.length) {
|
|
@@ -274,6 +449,23 @@ function guardBash(cmd, current, sessions, now, modes = DEFAULT_MODES) {
|
|
|
274
449
|
return d;
|
|
275
450
|
}
|
|
276
451
|
}
|
|
452
|
+
for (const rule of modes.custom ?? []) {
|
|
453
|
+
const d = applyCustomRule(rule, cmd);
|
|
454
|
+
if (d)
|
|
455
|
+
return d;
|
|
456
|
+
}
|
|
457
|
+
const nv = rewriteNoVerify(cmd);
|
|
458
|
+
if (nv) {
|
|
459
|
+
const d = fix("no_verify", "Hooks and signing exist for a reason: `--no-verify` / `--no-gpg-sign` was dropped. If a hook is wrong, fix the hook.", nv);
|
|
460
|
+
if (d.action !== "allow")
|
|
461
|
+
return d;
|
|
462
|
+
}
|
|
463
|
+
const dr = rewriteDryRun(cmd);
|
|
464
|
+
if (dr && !ctx.rewritesDone?.has(dr.key)) {
|
|
465
|
+
const d = fix("dry_run_first", `The first \`${dr.key}\` in a session runs as a dry run so you can read what it would change; run the real one next.`, dr.command, dr.key);
|
|
466
|
+
if (d.action !== "allow")
|
|
467
|
+
return d;
|
|
468
|
+
}
|
|
277
469
|
return { action: "allow" };
|
|
278
470
|
}
|
|
279
471
|
function norm(p) {
|
|
@@ -302,7 +494,6 @@ function absolutePath(path, cwd) {
|
|
|
302
494
|
return path;
|
|
303
495
|
return `${cwd.replace(/\/+$/, "")}/${path}`;
|
|
304
496
|
}
|
|
305
|
-
var WRITE_TOOLS = new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
|
|
306
497
|
function guardWrite(target, current, claims, modes = DEFAULT_MODES, kind = "file") {
|
|
307
498
|
const hit = (rule, reason) => {
|
|
308
499
|
const mode = modes[rule];
|
|
@@ -328,22 +519,89 @@ function guardWrite(target, current, claims, modes = DEFAULT_MODES, kind = "file
|
|
|
328
519
|
}
|
|
329
520
|
return { action: "allow" };
|
|
330
521
|
}
|
|
522
|
+
var LIVE_WINDOW_MS, GIT_GLOBAL_OPTS = "(?:\\s+(?:-C\\s+\\S+|-c\\s+\\S+|--git-dir(?:=|\\s+)\\S+|--work-tree(?:=|\\s+)\\S+|--namespace(?:=|\\s+)\\S+|--no-pager|--paginate|--bare|--literal-pathspecs|--exec-path(?:=\\S+)?))*", DEFAULT_MODES, customRe, WRITE_TOOLS;
|
|
523
|
+
var init_rules = __esm(() => {
|
|
524
|
+
LIVE_WINDOW_MS = 10 * 60000;
|
|
525
|
+
DEFAULT_MODES = {
|
|
526
|
+
shared_tree: "ask",
|
|
527
|
+
destructive_git: "ask",
|
|
528
|
+
pattern_kill: "ask",
|
|
529
|
+
protected_ports: "ask",
|
|
530
|
+
no_foreign_worktree: "ask",
|
|
531
|
+
claim_required_to_write: "off",
|
|
532
|
+
no_verify: "off",
|
|
533
|
+
dry_run_first: "off",
|
|
534
|
+
custom: [],
|
|
535
|
+
protected: { ports: [] }
|
|
536
|
+
};
|
|
537
|
+
customRe = new WeakMap;
|
|
538
|
+
WRITE_TOOLS = new Set(["Write", "Edit", "MultiEdit", "NotebookEdit"]);
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
// packages/core/src/dryrun.ts
|
|
542
|
+
var init_dryrun = __esm(() => {
|
|
543
|
+
init_rules();
|
|
544
|
+
});
|
|
545
|
+
// packages/core/src/gatehealth.ts
|
|
546
|
+
var init_gatehealth = () => {};
|
|
547
|
+
|
|
548
|
+
// packages/core/src/gates.ts
|
|
549
|
+
var init_gates = () => {};
|
|
550
|
+
|
|
551
|
+
// packages/core/src/graphs.ts
|
|
552
|
+
var init_graphs = __esm(() => {
|
|
553
|
+
init_rules();
|
|
554
|
+
});
|
|
555
|
+
|
|
556
|
+
// packages/core/src/heat.ts
|
|
557
|
+
var init_heat = __esm(() => {
|
|
558
|
+
init_rules();
|
|
559
|
+
});
|
|
560
|
+
|
|
561
|
+
// packages/core/src/worktree.ts
|
|
562
|
+
var init_worktree = __esm(() => {
|
|
563
|
+
init_config();
|
|
564
|
+
});
|
|
565
|
+
|
|
331
566
|
// packages/core/src/hygiene.ts
|
|
332
|
-
var HYGIENE_DEFAULTS
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
567
|
+
var HYGIENE_DEFAULTS;
|
|
568
|
+
var init_hygiene = __esm(() => {
|
|
569
|
+
init_worktree();
|
|
570
|
+
HYGIENE_DEFAULTS = {
|
|
571
|
+
staleDays: 2,
|
|
572
|
+
abandonedDays: 30,
|
|
573
|
+
hungryRssKb: 1024 * 1024,
|
|
574
|
+
heavyKb: 2 * 1024 * 1024
|
|
575
|
+
};
|
|
576
|
+
});
|
|
577
|
+
|
|
338
578
|
// packages/core/src/ledger.ts
|
|
339
|
-
var EDIT_TOOLS
|
|
579
|
+
var EDIT_TOOLS;
|
|
580
|
+
var init_ledger = __esm(() => {
|
|
581
|
+
EDIT_TOOLS = new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
582
|
+
});
|
|
583
|
+
// packages/core/src/lessons-apply.ts
|
|
584
|
+
var init_lessons_apply = () => {};
|
|
585
|
+
|
|
586
|
+
// packages/core/src/lineage.ts
|
|
587
|
+
var init_lineage = __esm(() => {
|
|
588
|
+
init_dag();
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
// packages/core/src/mcphealth.ts
|
|
592
|
+
var init_mcphealth = __esm(() => {
|
|
593
|
+
init_gatehealth();
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
// packages/core/src/memory.ts
|
|
597
|
+
var init_memory = () => {};
|
|
340
598
|
// packages/core/src/outcomes.ts
|
|
341
|
-
var DEFAULT_BRANCHES
|
|
599
|
+
var DEFAULT_BRANCHES;
|
|
600
|
+
var init_outcomes = __esm(() => {
|
|
601
|
+
DEFAULT_BRANCHES = new Set(["main", "master", "develop", "trunk"]);
|
|
602
|
+
});
|
|
342
603
|
// packages/core/src/policy.ts
|
|
343
604
|
import { createHash } from "crypto";
|
|
344
|
-
var POLICY_CACHE_VERSION = 1;
|
|
345
|
-
var POLICY_CACHE_FILE = "policy.cache.json";
|
|
346
|
-
var digest = (body) => createHash("sha256").update(JSON.stringify(body)).digest("hex");
|
|
347
605
|
function verifyPolicyCache(raw) {
|
|
348
606
|
if (!raw || typeof raw !== "object")
|
|
349
607
|
return null;
|
|
@@ -376,10 +634,273 @@ function evaluateOffline(cache, raw, toplevel, now = Date.now()) {
|
|
|
376
634
|
return { action: "allow" };
|
|
377
635
|
return guardBash(cmd, current, cache.sessions, now, modes);
|
|
378
636
|
}
|
|
637
|
+
var POLICY_CACHE_VERSION = 1, POLICY_CACHE_FILE = "policy.cache.json", digest = (body) => createHash("sha256").update(JSON.stringify(body)).digest("hex");
|
|
638
|
+
var init_policy = __esm(() => {
|
|
639
|
+
init_hooks();
|
|
640
|
+
init_rules();
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
// packages/core/src/pricing.ts
|
|
644
|
+
var init_pricing = () => {};
|
|
645
|
+
// packages/core/src/provenance.ts
|
|
646
|
+
var init_provenance = () => {};
|
|
647
|
+
// packages/core/src/quota.ts
|
|
648
|
+
var BURN_MIN_SPAN_MS;
|
|
649
|
+
var init_quota = __esm(() => {
|
|
650
|
+
BURN_MIN_SPAN_MS = 10 * 60000;
|
|
651
|
+
});
|
|
652
|
+
// packages/core/src/security.ts
|
|
653
|
+
var init_security = () => {};
|
|
654
|
+
|
|
655
|
+
// packages/core/src/stall.ts
|
|
656
|
+
var init_stall = () => {};
|
|
657
|
+
|
|
658
|
+
// packages/core/src/statusline.ts
|
|
659
|
+
function parseStatuslinePayload(text) {
|
|
660
|
+
try {
|
|
661
|
+
const v = JSON.parse(text);
|
|
662
|
+
return v && typeof v === "object" && !Array.isArray(v) ? v : null;
|
|
663
|
+
} catch {
|
|
664
|
+
return null;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
function pct(color, label, value) {
|
|
668
|
+
const s = `${label} ${Math.round(value)}%`;
|
|
669
|
+
if (value >= 90)
|
|
670
|
+
return red(color, s);
|
|
671
|
+
if (value >= 70)
|
|
672
|
+
return yellow(color, s);
|
|
673
|
+
return s;
|
|
674
|
+
}
|
|
675
|
+
function money(usd) {
|
|
676
|
+
return usd >= 10 ? `$${usd.toFixed(0)}` : `$${usd.toFixed(2)}`;
|
|
677
|
+
}
|
|
678
|
+
function renderStatusline(payload, state, opts = {}) {
|
|
679
|
+
const color = opts.color ?? false;
|
|
680
|
+
const local = [];
|
|
681
|
+
const model = payload.model?.display_name ?? payload.model?.id;
|
|
682
|
+
if (model)
|
|
683
|
+
local.push(bold(color, model));
|
|
684
|
+
const ctx = payload.context_window?.used_percentage;
|
|
685
|
+
if (typeof ctx === "number")
|
|
686
|
+
local.push(pct(color, "ctx", ctx));
|
|
687
|
+
const cost = payload.cost?.total_cost_usd;
|
|
688
|
+
if (typeof cost === "number")
|
|
689
|
+
local.push(money(cost));
|
|
690
|
+
const five = payload.rate_limits?.five_hour?.used_percentage;
|
|
691
|
+
if (typeof five === "number")
|
|
692
|
+
local.push(pct(color, "5h", five));
|
|
693
|
+
const week = payload.rate_limits?.seven_day?.used_percentage;
|
|
694
|
+
if (typeof week === "number")
|
|
695
|
+
local.push(pct(color, "7d", week));
|
|
696
|
+
const swarm = [];
|
|
697
|
+
if (state) {
|
|
698
|
+
if (state.task)
|
|
699
|
+
swarm.push(`${state.task.id} ${dim(color, `${state.task.leftMin}m`)}`);
|
|
700
|
+
if (state.budget && state.budget.level !== "ok")
|
|
701
|
+
swarm.push((state.budget.level === "exceeded" ? red : yellow)(color, `budget ${state.budget.level} ${Math.round(state.budget.pct * 100)}%`));
|
|
702
|
+
if (state.incidents > 0)
|
|
703
|
+
swarm.push(yellow(color, `${state.incidents} incident${state.incidents === 1 ? "" : "s"}`));
|
|
704
|
+
if (state.waitingOn > 0)
|
|
705
|
+
swarm.push(red(color, `waiting on you${state.waitingOn > 1 ? ` \xD7${state.waitingOn}` : ""}`));
|
|
706
|
+
if (state.inbox > 0)
|
|
707
|
+
swarm.push(`inbox ${state.inbox}`);
|
|
708
|
+
if (state.quota) {
|
|
709
|
+
const short = { five_hour: "5h", seven_day: "7d", spend_limit: "spend" }[state.quota.window];
|
|
710
|
+
const h = state.quota.hoursToLimit;
|
|
711
|
+
if (h == null)
|
|
712
|
+
swarm.push(red(color, `${short} limit reached`));
|
|
713
|
+
else {
|
|
714
|
+
const s = `${short} limit in ${h < 1 ? `${Math.max(1, Math.round(h * 60))}m` : `${Math.round(h)}h`}`;
|
|
715
|
+
swarm.push(h < 1 ? red(color, s) : h < 3 ? yellow(color, s) : s);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
const sep = dim(color, " \xB7 ");
|
|
720
|
+
const bar = dim(color, " \u2502 ");
|
|
721
|
+
const left = local.join(sep);
|
|
722
|
+
if (!swarm.length)
|
|
723
|
+
return left;
|
|
724
|
+
const right = swarm.join(sep);
|
|
725
|
+
return left ? `${left}${bar}${right}` : right;
|
|
726
|
+
}
|
|
727
|
+
var ESC = "\x1B[", paint = (color, code, s) => color ? `${ESC}${code}m${s}${ESC}0m` : s, dim = (c, s) => paint(c, "2", s), yellow = (c, s) => paint(c, "33", s), red = (c, s) => paint(c, "31", s), bold = (c, s) => paint(c, "1", s);
|
|
728
|
+
|
|
729
|
+
// packages/core/src/tasks.ts
|
|
730
|
+
var init_tasks = () => {};
|
|
731
|
+
|
|
732
|
+
// packages/core/src/team.ts
|
|
733
|
+
var init_team = () => {};
|
|
734
|
+
|
|
735
|
+
// packages/core/src/teamsetup.ts
|
|
736
|
+
var init_teamsetup = () => {};
|
|
737
|
+
|
|
738
|
+
// packages/core/src/transitions.ts
|
|
739
|
+
var init_transitions = () => {};
|
|
740
|
+
|
|
741
|
+
// packages/core/src/types.ts
|
|
742
|
+
var init_types = () => {};
|
|
743
|
+
|
|
744
|
+
// packages/core/src/waiting.ts
|
|
745
|
+
var init_waiting = () => {};
|
|
746
|
+
|
|
747
|
+
// packages/core/src/index.ts
|
|
748
|
+
var init_src2 = __esm(() => {
|
|
749
|
+
init_actor();
|
|
750
|
+
init_adapters();
|
|
751
|
+
init_hooks();
|
|
752
|
+
init_art();
|
|
753
|
+
init_audit();
|
|
754
|
+
init_budget();
|
|
755
|
+
init_config();
|
|
756
|
+
init_context();
|
|
757
|
+
init_dag();
|
|
758
|
+
init_dryrun();
|
|
759
|
+
init_gatehealth();
|
|
760
|
+
init_gates();
|
|
761
|
+
init_graphs();
|
|
762
|
+
init_heat();
|
|
763
|
+
init_hygiene();
|
|
764
|
+
init_ledger();
|
|
765
|
+
init_lessons_apply();
|
|
766
|
+
init_lineage();
|
|
767
|
+
init_mcphealth();
|
|
768
|
+
init_memory();
|
|
769
|
+
init_outcomes();
|
|
770
|
+
init_policy();
|
|
771
|
+
init_pricing();
|
|
772
|
+
init_provenance();
|
|
773
|
+
init_quota();
|
|
774
|
+
init_rules();
|
|
775
|
+
init_security();
|
|
776
|
+
init_stall();
|
|
777
|
+
init_tasks();
|
|
778
|
+
init_team();
|
|
779
|
+
init_teamsetup();
|
|
780
|
+
init_transitions();
|
|
781
|
+
init_types();
|
|
782
|
+
init_waiting();
|
|
783
|
+
init_workflows();
|
|
784
|
+
init_worktree();
|
|
785
|
+
});
|
|
786
|
+
|
|
787
|
+
// packages/hook/src/wait.ts
|
|
788
|
+
async function waitForWake(sessionId, opts = {}) {
|
|
789
|
+
const maxMs = opts.maxMs ?? 55 * 60000;
|
|
790
|
+
const pollMs = opts.pollMs ?? 11 * 60000;
|
|
791
|
+
const started = Date.now();
|
|
792
|
+
let base = opts.baseUrl ?? resolveBaseUrl();
|
|
793
|
+
const fallback = `http://127.0.0.1:${DEFAULT_PORT}`;
|
|
794
|
+
while (Date.now() - started < maxMs) {
|
|
795
|
+
let body = null;
|
|
796
|
+
try {
|
|
797
|
+
const r = await authedFetch(`${base}/v1/wake`, {
|
|
798
|
+
method: "POST",
|
|
799
|
+
headers: { "content-type": "application/json" },
|
|
800
|
+
body: JSON.stringify({ session_id: sessionId }),
|
|
801
|
+
signal: AbortSignal.timeout(pollMs)
|
|
802
|
+
});
|
|
803
|
+
if (r.ok)
|
|
804
|
+
body = await r.json();
|
|
805
|
+
} catch {
|
|
806
|
+
if (base !== fallback && !opts.baseUrl) {
|
|
807
|
+
base = fallback;
|
|
808
|
+
continue;
|
|
809
|
+
}
|
|
810
|
+
return { exit: 0, reason: "daemon unreachable" };
|
|
811
|
+
}
|
|
812
|
+
if (!body)
|
|
813
|
+
return { exit: 0, reason: "daemon refused" };
|
|
814
|
+
if (body.wake && body.text)
|
|
815
|
+
return { exit: 2, text: body.text };
|
|
816
|
+
if (body.reason && body.reason !== "timeout")
|
|
817
|
+
return { exit: 0, reason: body.reason };
|
|
818
|
+
}
|
|
819
|
+
return { exit: 0, reason: "gave up" };
|
|
820
|
+
}
|
|
821
|
+
var init_wait = __esm(() => {
|
|
822
|
+
init_src();
|
|
823
|
+
});
|
|
824
|
+
|
|
825
|
+
// packages/hook/src/statusline.ts
|
|
826
|
+
async function fetchStatuslineState(payload, opts = {}) {
|
|
827
|
+
const timeout = opts.timeoutMs ?? Number(process.env.SWARM_HOOK_TIMEOUT_MS ?? 400);
|
|
828
|
+
const post = async (base) => {
|
|
829
|
+
const r = await authedFetch(`${base}/v1/statusline`, {
|
|
830
|
+
method: "POST",
|
|
831
|
+
headers: { "content-type": "application/json" },
|
|
832
|
+
body: JSON.stringify(payload),
|
|
833
|
+
signal: AbortSignal.timeout(timeout)
|
|
834
|
+
});
|
|
835
|
+
return r.ok ? await r.json() : null;
|
|
836
|
+
};
|
|
837
|
+
const base = opts.baseUrl ?? resolveBaseUrl();
|
|
838
|
+
const fallback = `http://127.0.0.1:${DEFAULT_PORT}`;
|
|
839
|
+
try {
|
|
840
|
+
const s = await post(base);
|
|
841
|
+
if (s)
|
|
842
|
+
return s;
|
|
843
|
+
} catch {}
|
|
844
|
+
if (base !== fallback && !opts.baseUrl) {
|
|
845
|
+
try {
|
|
846
|
+
return await post(fallback);
|
|
847
|
+
} catch {}
|
|
848
|
+
}
|
|
849
|
+
return null;
|
|
850
|
+
}
|
|
851
|
+
async function runStatusline(input, opts = {}) {
|
|
852
|
+
const payload = parseStatuslinePayload(input) ?? {};
|
|
853
|
+
const state = await fetchStatuslineState(payload, opts);
|
|
854
|
+
const color = opts.color ?? !process.env.NO_COLOR;
|
|
855
|
+
return renderStatusline(payload, state, { color });
|
|
856
|
+
}
|
|
857
|
+
var init_statusline = __esm(() => {
|
|
858
|
+
init_src();
|
|
859
|
+
init_src2();
|
|
860
|
+
});
|
|
861
|
+
|
|
379
862
|
// packages/hook/src/bin.ts
|
|
863
|
+
init_src();
|
|
864
|
+
init_src2();
|
|
865
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
866
|
+
import { dirname, join as join2 } from "path";
|
|
380
867
|
var event = process.argv[2] ?? "Unknown";
|
|
381
868
|
var input = await Bun.stdin.text();
|
|
382
|
-
|
|
869
|
+
if (event === "wait") {
|
|
870
|
+
await Promise.resolve().then(() => init_wait());
|
|
871
|
+
let sid = "";
|
|
872
|
+
try {
|
|
873
|
+
sid = String(JSON.parse(input || "{}").session_id ?? "");
|
|
874
|
+
} catch {}
|
|
875
|
+
if (!sid)
|
|
876
|
+
process.exit(0);
|
|
877
|
+
const out = await waitForWake(sid);
|
|
878
|
+
if (out.exit === 2)
|
|
879
|
+
process.stderr.write(`${out.text}
|
|
880
|
+
`);
|
|
881
|
+
process.exit(out.exit);
|
|
882
|
+
}
|
|
883
|
+
if (event === "statusline") {
|
|
884
|
+
await Promise.resolve().then(() => init_statusline());
|
|
885
|
+
process.stdout.write(`${await runStatusline(input)}
|
|
886
|
+
`);
|
|
887
|
+
process.exit(0);
|
|
888
|
+
}
|
|
889
|
+
var fast = Number(process.env.SWARM_HOOK_TIMEOUT_MS ?? 400);
|
|
890
|
+
async function repairArmed() {
|
|
891
|
+
try {
|
|
892
|
+
const cwd = String(JSON.parse(input || "{}").cwd ?? "");
|
|
893
|
+
if (!cwd)
|
|
894
|
+
return false;
|
|
895
|
+
const r = await authedFetch(`${resolveBaseUrl()}/v1/repair?cwd=${encodeURIComponent(cwd)}`, {
|
|
896
|
+
signal: AbortSignal.timeout(fast)
|
|
897
|
+
});
|
|
898
|
+
return r.ok && (await r.json()).block === true;
|
|
899
|
+
} catch {
|
|
900
|
+
return false;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
var timeout = event === "Stop" ? await repairArmed() ? Number(process.env.SWARM_STOP_TIMEOUT_MS ?? 330000) : fast : event === "PermissionRequest" ? Number(process.env.SWARM_PERMISSION_TIMEOUT_MS ?? 130000) : fast;
|
|
383
904
|
var post = async (base) => {
|
|
384
905
|
const r = await authedFetch(`${base}/v1/hook/${event}`, {
|
|
385
906
|
method: "POST",
|