github-router 0.3.151 → 0.3.152
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/browser-ext/manifest.json +1 -1
- package/dist/{engine-DBIfCSAl.js → engine-CvY9mR3b.js} +1 -1
- package/dist/main.js +52 -21
- package/dist/main.js.map +1 -1
- package/dist/{peer-mcp-personas-Dm3UCpXz.js → peer-mcp-personas-BQVOxB1i.js} +354 -54
- package/dist/peer-mcp-personas-BQVOxB1i.js.map +1 -0
- package/package.json +1 -1
- package/dist/peer-mcp-personas-Dm3UCpXz.js.map +0 -1
|
@@ -1176,35 +1176,172 @@ var ArtifactError = class extends Error {
|
|
|
1176
1176
|
this.detail = args.detail;
|
|
1177
1177
|
}
|
|
1178
1178
|
};
|
|
1179
|
+
const AWAIT_DEFAULT_TIMEOUT_MS = 25e3;
|
|
1180
|
+
const AWAIT_ABORT_MARGIN_MS = 5e3;
|
|
1181
|
+
const DEFAULT_RETRY_BASE_MS = 250;
|
|
1182
|
+
const TRANSIENT_RETRIES = 2;
|
|
1183
|
+
const DEFAULT_RETRYABLE_CODES = new Set(["UNREACHABLE", "TIMEOUT"]);
|
|
1184
|
+
const AWAIT_RETRYABLE_CODES = new Set(["UNREACHABLE"]);
|
|
1179
1185
|
var ArtifactClient = class {
|
|
1180
1186
|
baseUrl;
|
|
1181
1187
|
token;
|
|
1182
1188
|
sessionId;
|
|
1183
1189
|
fetchFn;
|
|
1184
1190
|
insecureTLS;
|
|
1191
|
+
retryBaseMs;
|
|
1185
1192
|
constructor(options) {
|
|
1186
1193
|
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
1187
1194
|
this.token = options.token;
|
|
1188
1195
|
this.sessionId = options.sessionId;
|
|
1189
1196
|
this.fetchFn = options.fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
1190
1197
|
this.insecureTLS = options.insecureTLS ?? false;
|
|
1198
|
+
this.retryBaseMs = options.retryBaseMs ?? DEFAULT_RETRY_BASE_MS;
|
|
1191
1199
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1200
|
+
/**
|
|
1201
|
+
* Open (or replace) the review for this session. `mode` is advisory metadata
|
|
1202
|
+
* forwarded to the server (forward-compat: ignored if unknown); the actual
|
|
1203
|
+
* interactivity comes from the served HTML's `data-aod-*` markup. Retried on a
|
|
1204
|
+
* transient failure with a STABLE idempotency key so a retry-after-success does
|
|
1205
|
+
* not double-open.
|
|
1206
|
+
*/
|
|
1207
|
+
open(file, opts = {}) {
|
|
1208
|
+
const idempotencyKey = opts.idempotencyKey ?? randomUUID();
|
|
1209
|
+
const body = { file };
|
|
1210
|
+
if (opts.mode) body.mode = opts.mode;
|
|
1211
|
+
return this.withRetry(() => this.requestOnce({
|
|
1212
|
+
method: "POST",
|
|
1213
|
+
pathname: this.path("/open"),
|
|
1214
|
+
body,
|
|
1215
|
+
signal: opts.signal,
|
|
1216
|
+
idempotencyKey
|
|
1217
|
+
}), TRANSIENT_RETRIES, opts.signal);
|
|
1194
1218
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1219
|
+
/**
|
|
1220
|
+
* Replace the current review's content. Exactly one of `file` | `html` (the
|
|
1221
|
+
* caller-facing tool enforces that). `html` is written by the SERVER to the
|
|
1222
|
+
* review's existing sandboxed file, so `html` with no existing review is an
|
|
1223
|
+
* INVALID_REQUEST from the server. Retried with a stable idempotency key.
|
|
1224
|
+
*/
|
|
1225
|
+
update(opts) {
|
|
1226
|
+
const idempotencyKey = opts.idempotencyKey ?? randomUUID();
|
|
1227
|
+
const body = {};
|
|
1228
|
+
if (opts.file !== void 0) body.file = opts.file;
|
|
1229
|
+
if (opts.html !== void 0) body.html = opts.html;
|
|
1230
|
+
return this.withRetry(() => this.requestOnce({
|
|
1231
|
+
method: "POST",
|
|
1232
|
+
pathname: this.path("/update"),
|
|
1233
|
+
body,
|
|
1234
|
+
signal: opts.signal,
|
|
1235
|
+
idempotencyKey,
|
|
1236
|
+
allowEmptyJson: true
|
|
1237
|
+
}), TRANSIENT_RETRIES, opts.signal);
|
|
1238
|
+
}
|
|
1239
|
+
/** Force a reload from disk (no content change). Single-shot (idempotent, cheap). */
|
|
1240
|
+
refresh(signal) {
|
|
1241
|
+
return this.requestOnce({
|
|
1242
|
+
method: "POST",
|
|
1243
|
+
pathname: this.path("/refresh"),
|
|
1244
|
+
signal,
|
|
1245
|
+
allowEmptyJson: true
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
/** Hide the panel UI while keeping the review alive. Single-shot; server idempotent. */
|
|
1249
|
+
dismiss(signal) {
|
|
1250
|
+
return this.requestOnce({
|
|
1251
|
+
method: "POST",
|
|
1252
|
+
pathname: this.path("/dismiss"),
|
|
1253
|
+
signal,
|
|
1254
|
+
allowEmptyJson: true
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
/**
|
|
1258
|
+
* Typed drain (contract v2.2 §1/§2). Long-holds up to the server cap, returns
|
|
1259
|
+
* events with `id > cursor` plus the new high-water `cursor`. Idempotent by
|
|
1260
|
+
* (cursor, event.id): re-calling with the same cursor replays the same window
|
|
1261
|
+
* from the server's bounded buffer, so a lost cursor (compaction) is
|
|
1262
|
+
* recoverable. Retried on a transient network failure (the cursor makes retry
|
|
1263
|
+
* safe — no double-consumption).
|
|
1264
|
+
*/
|
|
1265
|
+
awaitEvents(opts = {}) {
|
|
1266
|
+
const serverTimeoutMs = typeof opts.timeoutMs === "number" && Number.isFinite(opts.timeoutMs) && opts.timeoutMs > 0 ? opts.timeoutMs : AWAIT_DEFAULT_TIMEOUT_MS;
|
|
1267
|
+
const clientTimeoutMs = serverTimeoutMs + AWAIT_ABORT_MARGIN_MS;
|
|
1268
|
+
return this.withRetry(() => this.requestOnce({
|
|
1269
|
+
method: "GET",
|
|
1270
|
+
pathname: this.path("/await"),
|
|
1271
|
+
query: {
|
|
1272
|
+
cursor: opts.cursor,
|
|
1273
|
+
timeoutMs: String(serverTimeoutMs)
|
|
1274
|
+
},
|
|
1275
|
+
signal: opts.signal,
|
|
1276
|
+
timeoutMsHint: clientTimeoutMs
|
|
1277
|
+
}), TRANSIENT_RETRIES, opts.signal, AWAIT_RETRYABLE_CODES);
|
|
1197
1278
|
}
|
|
1279
|
+
/** Free-text agent->human reply. SINGLE-SHOT (not retried): a retry-after-success
|
|
1280
|
+
* would render a duplicate chat bubble server-side. */
|
|
1198
1281
|
agentReply(text, signal) {
|
|
1199
|
-
return this.
|
|
1282
|
+
return this.requestOnce({
|
|
1283
|
+
method: "POST",
|
|
1284
|
+
pathname: this.path("/agent-reply"),
|
|
1285
|
+
body: { text },
|
|
1286
|
+
signal,
|
|
1287
|
+
allowEmptyJson: true
|
|
1288
|
+
});
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* End the review. Retried with a stable idempotency key; a NOT_FOUND (the
|
|
1292
|
+
* review is already ended — whether by a prior call or by a retry landing after
|
|
1293
|
+
* the first attempt succeeded) is mapped to a successful `{ ok, status:"ended" }`
|
|
1294
|
+
* rather than surfaced as a 404 (contract v2.2 §1.1).
|
|
1295
|
+
*/
|
|
1296
|
+
async end(signal) {
|
|
1297
|
+
const idempotencyKey = randomUUID();
|
|
1298
|
+
try {
|
|
1299
|
+
return await this.withRetry(() => this.requestOnce({
|
|
1300
|
+
method: "POST",
|
|
1301
|
+
pathname: this.path("/end"),
|
|
1302
|
+
signal,
|
|
1303
|
+
idempotencyKey,
|
|
1304
|
+
allowEmptyJson: true
|
|
1305
|
+
}), TRANSIENT_RETRIES, signal);
|
|
1306
|
+
} catch (err) {
|
|
1307
|
+
if (err instanceof ArtifactError && err.code === "NOT_FOUND") return {
|
|
1308
|
+
ok: true,
|
|
1309
|
+
status: "ended"
|
|
1310
|
+
};
|
|
1311
|
+
throw err;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* FROZEN legacy long-poll (contract v2.2 §1). Old payload shape,
|
|
1316
|
+
* comment-equivalent only. New agents use `awaitEvents`. Single request per
|
|
1317
|
+
* call (the caller-facing tool owns the bounded re-poll budget).
|
|
1318
|
+
*/
|
|
1319
|
+
poll(timeoutMsHint, signal) {
|
|
1320
|
+
return this.requestOnce({
|
|
1321
|
+
method: "GET",
|
|
1322
|
+
pathname: this.path("/poll"),
|
|
1323
|
+
signal,
|
|
1324
|
+
timeoutMsHint
|
|
1325
|
+
});
|
|
1200
1326
|
}
|
|
1201
|
-
|
|
1202
|
-
return
|
|
1327
|
+
path(suffix) {
|
|
1328
|
+
return `/api/artifact/${encodeURIComponent(this.sessionId)}${suffix}`;
|
|
1329
|
+
}
|
|
1330
|
+
async withRetry(fn, retries, signal, retryableCodes = DEFAULT_RETRYABLE_CODES) {
|
|
1331
|
+
let attempt = 0;
|
|
1332
|
+
for (;;) try {
|
|
1333
|
+
return await fn();
|
|
1334
|
+
} catch (err) {
|
|
1335
|
+
attempt += 1;
|
|
1336
|
+
if (!(err instanceof ArtifactError && err.retryable && retryableCodes.has(err.code)) || attempt > retries || signal?.aborted) throw err;
|
|
1337
|
+
const base = this.retryBaseMs;
|
|
1338
|
+
await sleep$1(base <= 0 ? 0 : Math.round(base * 2 ** (attempt - 1) * (.5 + Math.random() * .5)), signal);
|
|
1339
|
+
}
|
|
1203
1340
|
}
|
|
1204
|
-
async
|
|
1341
|
+
async requestOnce(o) {
|
|
1205
1342
|
let url;
|
|
1206
1343
|
try {
|
|
1207
|
-
url = new URL(pathname, `${this.baseUrl}/`);
|
|
1344
|
+
url = new URL(o.pathname, `${this.baseUrl}/`);
|
|
1208
1345
|
} catch (err) {
|
|
1209
1346
|
throw new ArtifactError({
|
|
1210
1347
|
code: "UNREACHABLE",
|
|
@@ -1213,48 +1350,73 @@ var ArtifactClient = class {
|
|
|
1213
1350
|
detail: err
|
|
1214
1351
|
});
|
|
1215
1352
|
}
|
|
1216
|
-
|
|
1217
|
-
|
|
1353
|
+
if (o.query) {
|
|
1354
|
+
for (const [key, value] of Object.entries(o.query)) if (value !== void 0) url.searchParams.set(key, value);
|
|
1355
|
+
}
|
|
1356
|
+
const timeout = combineSignalAndTimeout(o.signal, o.timeoutMsHint);
|
|
1218
1357
|
try {
|
|
1358
|
+
const headers = { Authorization: `Bearer ${this.token}` };
|
|
1359
|
+
if (o.body !== void 0) headers["Content-Type"] = "application/json";
|
|
1360
|
+
if (o.idempotencyKey) headers["Idempotency-Key"] = o.idempotencyKey;
|
|
1219
1361
|
const init = {
|
|
1220
|
-
method,
|
|
1221
|
-
headers
|
|
1222
|
-
|
|
1223
|
-
...body === void 0 ? {} : { "Content-Type": "application/json" }
|
|
1224
|
-
},
|
|
1225
|
-
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
1362
|
+
method: o.method,
|
|
1363
|
+
headers,
|
|
1364
|
+
body: o.body === void 0 ? void 0 : JSON.stringify(o.body),
|
|
1226
1365
|
redirect: "error",
|
|
1227
1366
|
signal: timeout.signal
|
|
1228
1367
|
};
|
|
1229
1368
|
if (this.insecureTLS) applyInsecureTls(init);
|
|
1230
|
-
response = await this.fetchFn(url.toString(), init);
|
|
1369
|
+
const response = await this.fetchFn(url.toString(), init);
|
|
1370
|
+
if (!response.ok) throw await mapHttpError$1(response);
|
|
1371
|
+
let text;
|
|
1372
|
+
try {
|
|
1373
|
+
text = await response.text();
|
|
1374
|
+
} catch (err) {
|
|
1375
|
+
if (isAbortLike$2(err)) throw mapNetworkError$1(err);
|
|
1376
|
+
throw new ArtifactError({
|
|
1377
|
+
code: "INVALID_RESPONSE",
|
|
1378
|
+
message: "artifact API response body could not be read",
|
|
1379
|
+
retryable: false,
|
|
1380
|
+
detail: err
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
if (!text && o.allowEmptyJson) return {};
|
|
1384
|
+
try {
|
|
1385
|
+
return JSON.parse(text);
|
|
1386
|
+
} catch (err) {
|
|
1387
|
+
throw new ArtifactError({
|
|
1388
|
+
code: "INVALID_RESPONSE",
|
|
1389
|
+
message: "artifact API returned a non-JSON response",
|
|
1390
|
+
retryable: false,
|
|
1391
|
+
detail: err
|
|
1392
|
+
});
|
|
1393
|
+
}
|
|
1231
1394
|
} catch (err) {
|
|
1395
|
+
if (err instanceof ArtifactError) throw err;
|
|
1232
1396
|
throw mapNetworkError$1(err);
|
|
1233
1397
|
} finally {
|
|
1234
1398
|
timeout.cleanup();
|
|
1235
1399
|
}
|
|
1236
|
-
if (!response.ok) throw await mapHttpError$1(response);
|
|
1237
|
-
const text = await response.text().catch((err) => {
|
|
1238
|
-
throw new ArtifactError({
|
|
1239
|
-
code: "INVALID_RESPONSE",
|
|
1240
|
-
message: "artifact API response body could not be read",
|
|
1241
|
-
retryable: false,
|
|
1242
|
-
detail: err
|
|
1243
|
-
});
|
|
1244
|
-
});
|
|
1245
|
-
if (!text && allowEmptyJson) return {};
|
|
1246
|
-
try {
|
|
1247
|
-
return JSON.parse(text);
|
|
1248
|
-
} catch (err) {
|
|
1249
|
-
throw new ArtifactError({
|
|
1250
|
-
code: "INVALID_RESPONSE",
|
|
1251
|
-
message: "artifact API returned a non-JSON response",
|
|
1252
|
-
retryable: false,
|
|
1253
|
-
detail: err
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
1400
|
}
|
|
1257
1401
|
};
|
|
1402
|
+
function sleep$1(ms, signal) {
|
|
1403
|
+
if (ms <= 0) return Promise.resolve();
|
|
1404
|
+
return new Promise((resolve, reject) => {
|
|
1405
|
+
const onAbort = () => {
|
|
1406
|
+
clearTimeout(timer);
|
|
1407
|
+
reject(new DOMException("retry backoff aborted", "AbortError"));
|
|
1408
|
+
};
|
|
1409
|
+
const timer = setTimeout(() => {
|
|
1410
|
+
signal?.removeEventListener("abort", onAbort);
|
|
1411
|
+
resolve();
|
|
1412
|
+
}, ms);
|
|
1413
|
+
if (signal?.aborted) {
|
|
1414
|
+
onAbort();
|
|
1415
|
+
return;
|
|
1416
|
+
}
|
|
1417
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
1418
|
+
});
|
|
1419
|
+
}
|
|
1258
1420
|
function combineSignalAndTimeout(signal, timeoutMsHint) {
|
|
1259
1421
|
const timeoutMs = typeof timeoutMsHint === "number" && Number.isFinite(timeoutMsHint) && timeoutMsHint > 0 ? timeoutMsHint : void 0;
|
|
1260
1422
|
if (timeoutMs === void 0) return {
|
|
@@ -1311,6 +1473,13 @@ async function mapHttpError$1(response) {
|
|
|
1311
1473
|
status: response.status,
|
|
1312
1474
|
detail
|
|
1313
1475
|
});
|
|
1476
|
+
if (response.status === 400 && detailToCode(detail)?.toUpperCase() === "INVALID_REQUEST") return new ArtifactError({
|
|
1477
|
+
code: "INVALID_REQUEST",
|
|
1478
|
+
message: `artifact API rejected the request (400)${suffix}`,
|
|
1479
|
+
retryable: false,
|
|
1480
|
+
status: response.status,
|
|
1481
|
+
detail
|
|
1482
|
+
});
|
|
1314
1483
|
return new ArtifactError({
|
|
1315
1484
|
code: "UPSTREAM_ERROR",
|
|
1316
1485
|
message: `artifact API returned HTTP ${response.status}${suffix}`,
|
|
@@ -1355,6 +1524,18 @@ function detailToMessage$1(detail) {
|
|
|
1355
1524
|
}
|
|
1356
1525
|
if (typeof record.message === "string") return record.message;
|
|
1357
1526
|
}
|
|
1527
|
+
/** Extract a machine `code` from an upstream error body (`{error:{code}}` or
|
|
1528
|
+
* `{code}`) so a tagged 400 can be classified (INVALID_REQUEST). */
|
|
1529
|
+
function detailToCode(detail) {
|
|
1530
|
+
if (typeof detail !== "object" || detail === null) return void 0;
|
|
1531
|
+
const record = detail;
|
|
1532
|
+
const error = record.error;
|
|
1533
|
+
if (typeof error === "object" && error !== null) {
|
|
1534
|
+
const code = error.code;
|
|
1535
|
+
if (typeof code === "string") return code;
|
|
1536
|
+
}
|
|
1537
|
+
if (typeof record.code === "string") return record.code;
|
|
1538
|
+
}
|
|
1358
1539
|
function isAbortLike$2(err) {
|
|
1359
1540
|
return err instanceof Error && (err.name === "AbortError" || err.name === "TimeoutError");
|
|
1360
1541
|
}
|
|
@@ -1383,27 +1564,86 @@ function tool(toolNameHttp, description, inputSchema, handler) {
|
|
|
1383
1564
|
};
|
|
1384
1565
|
}
|
|
1385
1566
|
const ARTIFACT_TOOLS = Object.freeze([
|
|
1386
|
-
tool("artifact_open", "Open a workspace file in ai-or-die's Artifact review panel for human review. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1567
|
+
tool("artifact_open", "Open a workspace file in ai-or-die's Artifact review panel for human review. Pass mode:\"interactive\" when the HTML carries data-aod-* action controls. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1568
|
+
file: stringProp$2("Workspace-relative or absolute file path to show in the Artifact panel."),
|
|
1569
|
+
mode: enumProp(["static", "interactive"], "Advisory. \"interactive\" signals the HTML contains data-aod-* action controls the panel should wire; \"static\" (default) is a read-and-annotate artifact.")
|
|
1570
|
+
}, ["file"]), async (args, signal) => {
|
|
1387
1571
|
const env = readArtifactEnv();
|
|
1388
1572
|
if (!env) return missingEnvResult();
|
|
1389
1573
|
const file = requiredString$2(args, "file");
|
|
1574
|
+
const mode = optionalEnum(args, "mode", ["static", "interactive"]);
|
|
1575
|
+
const response = await clientFromEnv(env).open(file, {
|
|
1576
|
+
mode,
|
|
1577
|
+
signal
|
|
1578
|
+
});
|
|
1390
1579
|
return ok$2({
|
|
1391
|
-
viewUrl:
|
|
1392
|
-
|
|
1580
|
+
viewUrl: response.viewUrl,
|
|
1581
|
+
sessionId: response.sessionId,
|
|
1582
|
+
key: response.key,
|
|
1583
|
+
next_step: "Tell the user to review at the Artifact panel, then call artifact_await to receive their feedback."
|
|
1393
1584
|
});
|
|
1394
1585
|
}),
|
|
1395
|
-
tool("
|
|
1586
|
+
tool("artifact_update", "Replace the current Artifact review's content in place. Provide EXACTLY ONE of file (a workspace file path) or html (raw HTML the server writes to the review's sandboxed file). html requires an already-open review. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1587
|
+
file: stringProp$2("Workspace-relative or absolute file path to become the review's new content."),
|
|
1588
|
+
html: stringProp$2("Raw HTML to write into the review's existing sandboxed file, then reload."),
|
|
1589
|
+
idempotencyKey: stringProp$2("Optional stable key so a retried update is de-duplicated by the server.")
|
|
1590
|
+
}, []), async (args, signal) => {
|
|
1396
1591
|
const env = readArtifactEnv();
|
|
1397
1592
|
if (!env) return missingEnvResult();
|
|
1398
|
-
|
|
1593
|
+
const file = optionalString$2(args, "file");
|
|
1594
|
+
const html = optionalString$2(args, "html");
|
|
1595
|
+
if (file === void 0 === (html === void 0)) throw new ArtifactToolInputError("INVALID_ARGUMENT", "artifact_update requires EXACTLY ONE of arguments.file or arguments.html");
|
|
1596
|
+
const idempotencyKey = optionalString$2(args, "idempotencyKey");
|
|
1597
|
+
return ok$2({
|
|
1598
|
+
...await clientFromEnv(env).update({
|
|
1599
|
+
file,
|
|
1600
|
+
html,
|
|
1601
|
+
idempotencyKey,
|
|
1602
|
+
signal
|
|
1603
|
+
}),
|
|
1604
|
+
ok: true,
|
|
1605
|
+
next_step: "The panel now shows the updated content. Call artifact_await for further feedback."
|
|
1606
|
+
});
|
|
1607
|
+
}),
|
|
1608
|
+
tool("artifact_refresh", "Force the ai-or-die Artifact panel to reload the current artifact from disk (no content change). Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({}, []), async (_args, signal) => {
|
|
1609
|
+
const env = readArtifactEnv();
|
|
1610
|
+
if (!env) return missingEnvResult();
|
|
1611
|
+
return ok$2({
|
|
1612
|
+
...await clientFromEnv(env).refresh(signal),
|
|
1613
|
+
ok: true,
|
|
1614
|
+
next_step: "The panel reloaded the artifact. Call artifact_await for feedback."
|
|
1615
|
+
});
|
|
1616
|
+
}),
|
|
1617
|
+
tool("artifact_await", "Wait for the human's next Artifact review events (typed drain: comments AND structured action-button/checkbox events) and return them with a cursor. Pass the returned cursor on the next call to receive only newer events. Supersedes artifact_poll. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({
|
|
1618
|
+
cursor: stringProp$2("High-water cursor from the previous artifact_await response. Omit on the first call."),
|
|
1619
|
+
timeoutMs: numberProp$2("Optional server long-hold budget in ms (default ~25000).")
|
|
1620
|
+
}, []), async (args, signal) => {
|
|
1621
|
+
const env = readArtifactEnv();
|
|
1622
|
+
if (!env) return missingEnvResult();
|
|
1623
|
+
const cursor = optionalString$2(args, "cursor");
|
|
1624
|
+
const timeoutMs = optionalNumber$2(args, "timeoutMs");
|
|
1625
|
+
return ok$2(formatAwaitResponse(await clientFromEnv(env).awaitEvents({
|
|
1626
|
+
cursor,
|
|
1627
|
+
timeoutMs,
|
|
1628
|
+
signal
|
|
1629
|
+
})));
|
|
1630
|
+
}),
|
|
1631
|
+
tool("artifact_dismiss", "Hide the ai-or-die Artifact panel UI while keeping the review alive (queued feedback preserved, channel open, re-openable). Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({}, []), async (_args, signal) => {
|
|
1632
|
+
const env = readArtifactEnv();
|
|
1633
|
+
if (!env) return missingEnvResult();
|
|
1634
|
+
return ok$2({
|
|
1635
|
+
...await clientFromEnv(env).dismiss(signal),
|
|
1636
|
+
ok: true,
|
|
1637
|
+
next_step: "The panel is hidden but the review is still live. Re-open the artifact or call artifact_await when ready."
|
|
1638
|
+
});
|
|
1399
1639
|
}),
|
|
1400
1640
|
tool("artifact_reply", "Send the agent's reply back to the ai-or-die Artifact review panel after applying or responding to human feedback. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({ text: stringProp$2("Agent reply text to deliver to the human Artifact review panel.") }, ["text"]), async (args, signal) => {
|
|
1401
1641
|
const env = readArtifactEnv();
|
|
1402
1642
|
if (!env) return missingEnvResult();
|
|
1403
1643
|
const text = requiredString$2(args, "text");
|
|
1404
1644
|
return ok$2({
|
|
1405
|
-
ok: true,
|
|
1406
1645
|
...await clientFromEnv(env).agentReply(text, signal),
|
|
1646
|
+
ok: true,
|
|
1407
1647
|
next_step: "Wait for further human review, or continue if the review loop is complete."
|
|
1408
1648
|
});
|
|
1409
1649
|
}),
|
|
@@ -1411,10 +1651,15 @@ const ARTIFACT_TOOLS = Object.freeze([
|
|
|
1411
1651
|
const env = readArtifactEnv();
|
|
1412
1652
|
if (!env) return missingEnvResult();
|
|
1413
1653
|
return ok$2({
|
|
1414
|
-
ok: true,
|
|
1415
1654
|
...await clientFromEnv(env).end(signal),
|
|
1655
|
+
ok: true,
|
|
1416
1656
|
next_step: "Artifact review loop ended."
|
|
1417
1657
|
});
|
|
1658
|
+
}),
|
|
1659
|
+
tool("artifact_poll", "FROZEN legacy alias for artifact_await (old payload, human comments only, no structured actions). New agents should call artifact_await instead. Only works inside an ai-or-die tab-backed Claude session.", objectSchema$2({ timeoutMs: numberProp$2("Optional per-call budget hint in ms (advisory).") }, []), async (_args, signal) => {
|
|
1660
|
+
const env = readArtifactEnv();
|
|
1661
|
+
if (!env) return missingEnvResult();
|
|
1662
|
+
return ok$2(formatPollResponse(await pollUntilReady(clientFromEnv(env), signal)));
|
|
1418
1663
|
})
|
|
1419
1664
|
]);
|
|
1420
1665
|
function readArtifactEnv() {
|
|
@@ -1489,6 +1734,30 @@ function formatPollResponse(response) {
|
|
|
1489
1734
|
next_step: response.next_step ?? defaultPollNextStep(response.status)
|
|
1490
1735
|
});
|
|
1491
1736
|
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Shape the typed drain for the model: pass events through verbatim (unknown
|
|
1739
|
+
* `kind`s preserved — the model ignores what it does not understand), echo the
|
|
1740
|
+
* cursor to thread into the next call, and pick a next_step from the events.
|
|
1741
|
+
*/
|
|
1742
|
+
function formatAwaitResponse(response) {
|
|
1743
|
+
const events$1 = Array.isArray(response.events) ? response.events : [];
|
|
1744
|
+
const status = typeof response.status === "string" ? response.status : void 0;
|
|
1745
|
+
return definedObject$1({
|
|
1746
|
+
events: events$1,
|
|
1747
|
+
status,
|
|
1748
|
+
cursor: response.cursor,
|
|
1749
|
+
next_step: awaitNextStep(status ?? "", events$1)
|
|
1750
|
+
});
|
|
1751
|
+
}
|
|
1752
|
+
function awaitNextStep(status, events$1) {
|
|
1753
|
+
if ((status ?? "").toLowerCase() === "ended") return "The review has ended. No further feedback will arrive.";
|
|
1754
|
+
if (events$1.length === 0) return "No feedback yet. Call artifact_await again, passing the returned cursor.";
|
|
1755
|
+
const hasAction = events$1.some((e) => e.kind === "action");
|
|
1756
|
+
const hasComment = events$1.some((e) => e.kind === "comment");
|
|
1757
|
+
if (hasAction && hasComment) return "Act on the action events (buttons/checkboxes) and the comments, reply with artifact_reply, then call artifact_await with the returned cursor.";
|
|
1758
|
+
if (hasAction) return "The human triggered action controls. Act on them, optionally artifact_reply, then call artifact_await with the returned cursor.";
|
|
1759
|
+
return "Apply the human comments, call artifact_reply with a concise summary, then artifact_await with the returned cursor.";
|
|
1760
|
+
}
|
|
1492
1761
|
function defaultPollNextStep(status) {
|
|
1493
1762
|
return isWaitingStatus(status) ? "No human feedback is ready yet. Call artifact_poll again." : "Apply the human Artifact review feedback, then call artifact_reply with a concise summary.";
|
|
1494
1763
|
}
|
|
@@ -1501,6 +1770,24 @@ function requiredString$2(args, key) {
|
|
|
1501
1770
|
if (typeof value !== "string" || value.trim() === "") throw new ArtifactToolInputError("INVALID_ARGUMENT", `arguments.${key} is required and must be a non-empty string`);
|
|
1502
1771
|
return value;
|
|
1503
1772
|
}
|
|
1773
|
+
function optionalString$2(args, key) {
|
|
1774
|
+
const value = args[key];
|
|
1775
|
+
if (value === void 0 || value === null) return void 0;
|
|
1776
|
+
if (typeof value !== "string" || value.trim() === "") throw new ArtifactToolInputError("INVALID_ARGUMENT", `arguments.${key} must be a non-empty string when provided`);
|
|
1777
|
+
return value;
|
|
1778
|
+
}
|
|
1779
|
+
function optionalNumber$2(args, key) {
|
|
1780
|
+
const value = args[key];
|
|
1781
|
+
if (value === void 0 || value === null) return void 0;
|
|
1782
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) throw new ArtifactToolInputError("INVALID_ARGUMENT", `arguments.${key} must be a positive number when provided`);
|
|
1783
|
+
return value;
|
|
1784
|
+
}
|
|
1785
|
+
function optionalEnum(args, key, allowed) {
|
|
1786
|
+
const value = optionalString$2(args, key);
|
|
1787
|
+
if (value === void 0) return void 0;
|
|
1788
|
+
if (!allowed.includes(value)) throw new ArtifactToolInputError("INVALID_ARGUMENT", `arguments.${key} must be one of ${allowed.join(", ")}`);
|
|
1789
|
+
return value;
|
|
1790
|
+
}
|
|
1504
1791
|
var ArtifactToolInputError = class extends Error {
|
|
1505
1792
|
code;
|
|
1506
1793
|
constructor(code, message) {
|
|
@@ -1565,6 +1852,19 @@ function stringProp$2(description) {
|
|
|
1565
1852
|
description
|
|
1566
1853
|
};
|
|
1567
1854
|
}
|
|
1855
|
+
function numberProp$2(description) {
|
|
1856
|
+
return {
|
|
1857
|
+
type: "number",
|
|
1858
|
+
description
|
|
1859
|
+
};
|
|
1860
|
+
}
|
|
1861
|
+
function enumProp(values, description) {
|
|
1862
|
+
return {
|
|
1863
|
+
type: "string",
|
|
1864
|
+
enum: [...values],
|
|
1865
|
+
description
|
|
1866
|
+
};
|
|
1867
|
+
}
|
|
1568
1868
|
|
|
1569
1869
|
//#endregion
|
|
1570
1870
|
//#region src/lib/fleet/mesh-egress-agent.ts
|
|
@@ -2769,7 +3069,7 @@ function isHardNotReady(reason) {
|
|
|
2769
3069
|
*/
|
|
2770
3070
|
async function waitForMessageReady(client, localId, options = {}) {
|
|
2771
3071
|
const now = options.now ?? Date.now;
|
|
2772
|
-
const sleep$
|
|
3072
|
+
const sleep$2 = options.sleep ?? realSleep;
|
|
2773
3073
|
const waitMs = Math.max(0, options.waitMs ?? 0);
|
|
2774
3074
|
const pollMs = Math.max(1, options.pollMs ?? DEFAULT_READY_POLL_MS);
|
|
2775
3075
|
const deadline = now() + waitMs;
|
|
@@ -2801,7 +3101,7 @@ async function waitForMessageReady(client, localId, options = {}) {
|
|
|
2801
3101
|
ready: false,
|
|
2802
3102
|
readiness: last
|
|
2803
3103
|
};
|
|
2804
|
-
await sleep$
|
|
3104
|
+
await sleep$2(Math.min(pollMs, remaining));
|
|
2805
3105
|
}
|
|
2806
3106
|
}
|
|
2807
3107
|
/**
|
|
@@ -2879,7 +3179,7 @@ async function primeTurnCursor(client, localId, timeoutMs, signal) {
|
|
|
2879
3179
|
*/
|
|
2880
3180
|
async function waitForTurnSettled(client, localId, options) {
|
|
2881
3181
|
const now = options.now ?? Date.now;
|
|
2882
|
-
const sleep$
|
|
3182
|
+
const sleep$2 = options.sleep ?? realSleep;
|
|
2883
3183
|
const pollTimeoutMs = Math.max(1, options.pollTimeoutMs ?? DEFAULT_TURN_POLL_MS);
|
|
2884
3184
|
const budget = Number.isFinite(options.timeoutMs) ? Math.max(0, options.timeoutMs) : 0;
|
|
2885
3185
|
const deadline = now() + budget;
|
|
@@ -2911,7 +3211,7 @@ async function waitForTurnSettled(client, localId, options) {
|
|
|
2911
3211
|
reason: "timeout",
|
|
2912
3212
|
cursor
|
|
2913
3213
|
};
|
|
2914
|
-
await sleep$
|
|
3214
|
+
await sleep$2(Math.min(TURN_POLL_ERROR_BACKOFF_MS, Math.max(0, deadline - now())));
|
|
2915
3215
|
continue;
|
|
2916
3216
|
}
|
|
2917
3217
|
cursor = response.cursor;
|
|
@@ -3028,13 +3328,13 @@ async function readTail(client, localId, lines, signal) {
|
|
|
3028
3328
|
async function driveTask(deps) {
|
|
3029
3329
|
const { client, localId, prompt, timeoutMs, expectReport, idempotencyKey, interruptKey, reportId, signal } = deps;
|
|
3030
3330
|
const now = deps.now ?? Date.now;
|
|
3031
|
-
const sleep$
|
|
3331
|
+
const sleep$2 = deps.sleep ?? realSleep;
|
|
3032
3332
|
const tailLines = deps.tailLines ?? DEFAULT_TAIL_LINES;
|
|
3033
3333
|
const pollTimeoutMs = deps.pollTimeoutMs;
|
|
3034
3334
|
const readyResult = await waitForMessageReady(client, localId, {
|
|
3035
3335
|
waitMs: deps.idleWaitMs ?? DEFAULT_IDLE_WAIT_MS,
|
|
3036
3336
|
now,
|
|
3037
|
-
sleep: sleep$
|
|
3337
|
+
sleep: sleep$2,
|
|
3038
3338
|
signal
|
|
3039
3339
|
});
|
|
3040
3340
|
if (!readyResult.ready && isHardNotReady(readyResult.readiness.reason)) return {
|
|
@@ -3077,7 +3377,7 @@ async function driveTask(deps) {
|
|
|
3077
3377
|
pollTimeoutMs,
|
|
3078
3378
|
cursor,
|
|
3079
3379
|
now,
|
|
3080
|
-
sleep: sleep$
|
|
3380
|
+
sleep: sleep$2,
|
|
3081
3381
|
signal
|
|
3082
3382
|
});
|
|
3083
3383
|
cursor = settle.cursor;
|
|
@@ -3099,7 +3399,7 @@ async function driveTask(deps) {
|
|
|
3099
3399
|
pollTimeoutMs,
|
|
3100
3400
|
cursor,
|
|
3101
3401
|
now,
|
|
3102
|
-
sleep: sleep$
|
|
3402
|
+
sleep: sleep$2,
|
|
3103
3403
|
signal
|
|
3104
3404
|
});
|
|
3105
3405
|
recovered = recovery.settled;
|
|
@@ -26890,4 +27190,4 @@ async function runStandInToolCall(args, signal) {
|
|
|
26890
27190
|
|
|
26891
27191
|
//#endregion
|
|
26892
27192
|
export { logStreamError as $, copilotBaseUrl as $t, BROWSE_DEFAULT_MODEL as A, UPSTREAM_FETCH_TIMEOUT_MS as At, toolbeltEnabled as B, cacheCopilotVersion as Bt, repoFingerprint as C, ArtifactClient as Ct, trustRepo as D, DEFAULT_CODEX_MODEL as Dt, stopReviewStateDir as E, DEFAULT_CLAUDE_MODEL_FALLBACKS as Et, appendPlanReminder as F, withInstallLock as Ft, searchWeb as G, resolveCodexModel as Gt, vscodeRipgrepPath as H, cacheVSCodeVersion as Ht, runWorkerAgent as I, setupCopilotToken as It, buildAdvisorStream as J, getModels as Jt, ADVISOR_INTERNAL_TOOL_NAME as K, resolveModel as Kt, withNoOutputRetry as L, setupGitHubAgentToken as Lt, IMPLEMENT_DEFAULT_MODEL as M, generateRandomPort as Mt, PLAN_DEFAULT_MODEL as N, pickClaudeDefault as Nt, resolveSealedGate as O, DEFAULT_CODEX_MODEL_FALLBACKS as Ot, REVIEW_DEFAULT_MODEL as P, getPackageVersion as Pt, isControllerClosedError as Q, GITHUB_API_BASE_URL as Qt, availableToolCommands as R, setupGitHubToken as Rt, isSubagentContext as S, shouldUseInsecureTls as St, stopGateEnabledForRepo as T, toolbeltPathOverride as Tt, TOOLBELT_TOOLS$1 as U, filterBetaHeader as Ut, toolbeltSkipSet as V, cacheModels as Vt, assetFor as W, isNullish as Wt, isAdvisorRequested as X, HTTPError as Xt, injectAdvisorTool as Y, fetchWithTransientRetry as Yt, buildOpenAIErrorEvent as Z, forwardError as Zt, stopReviewEnabled as _, provisionBrowserAssets as _t, buildPeerAwarenessSnippet as a, browserToolsEnabled as at, fileLastPromptStore as b, extractTarGzMember as bt, buildSessionBindHookCommand as c, workerToolsEnabled as ct, decideStopHook as d, getTokenCount as dt, copilotHeaders as en, readIteratorWithTimeout as et, fileBlockBudget as f, createResponses as ft, stopGateId as g, parseJsonOrDiagnose as gt, stopGateDisabled as h, readResponseBodyCapped as ht, buildAgentPrompt as i, agentToolsEnabled as it, DEFAULT_MODEL as j, UPSTREAM_INACTIVITY_TIMEOUT_MS as jt, liveExec as k, DEFAULT_PORT as kt, buildStopHookCommand as l, countTokens as lt, launchBaselineKey as m, MAX_RESPONSE_BODY_BYTES as mt, MCP_GROUPS as n, state as nn, handleMcpDelete as nt, personasFor as o, fleetToolsEnabled as ot, injectStopHookIntoSettingsFile as p, createChatCompletions as pt, ADVISOR_TOOL_INSTRUCTIONS as q, sleep as qt, assertMcpToolSurfaceConsistent as r, handleMcpPost as rt, buildArtifactOpenHookCommand as s, standInToolEnabled as st, GROUP_META as t, githubHeaders as tn, relayAnthropicStream as tt, captureLaunchBaseline as u, createMessages as ut, fileBaselineStore as v, hasSupportedBrowserInstalled as vt, repoRoot as w, collapsePathKeys as wt, fileReviewDebounce as x, extractZipMember as xt, fileFindingsStore as y, provisionAndIndexColbert as yt, buildToolbeltAwareness as z, tryRefreshAndRetry as zt };
|
|
26893
|
-
//# sourceMappingURL=peer-mcp-personas-
|
|
27193
|
+
//# sourceMappingURL=peer-mcp-personas-BQVOxB1i.js.map
|