@botiverse/raft-daemon 0.70.0 → 0.70.1
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/{chunk-QDPBPYD7.js → chunk-SIGIQH6T.js} +776 -17
- package/dist/cli/index.js +193 -2
- package/dist/core.js +9 -1
- package/dist/{dist-I6ATP6I5.js → dist-D77BWHH4.js} +187 -2
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/core.ts
|
|
2
|
-
import
|
|
2
|
+
import path20 from "path";
|
|
3
3
|
import os8 from "os";
|
|
4
4
|
import { createRequire as createRequire3 } from "module";
|
|
5
5
|
import { accessSync } from "fs";
|
|
@@ -1105,6 +1105,7 @@ function projectTraceScopeAttrs(scope) {
|
|
|
1105
1105
|
addOptionalStringAttr(attrs, "route_pattern", scope.request?.routePattern);
|
|
1106
1106
|
addOptionalStringAttr(attrs, "method", scope.request?.method);
|
|
1107
1107
|
addOptionalStringAttr(attrs, "caller_kind", scope.request?.callerKind);
|
|
1108
|
+
addOptionalStringAttr(attrs, "user_id", scope.request?.userId);
|
|
1108
1109
|
if (typeof scope.request?.userIdPresent === "boolean") {
|
|
1109
1110
|
attrs.user_id_present = scope.request.userIdPresent;
|
|
1110
1111
|
}
|
|
@@ -1280,10 +1281,24 @@ var RecordingActiveSpan = class {
|
|
|
1280
1281
|
}
|
|
1281
1282
|
addEvent(name, attrs) {
|
|
1282
1283
|
if (this.ended) return;
|
|
1283
|
-
|
|
1284
|
+
const event = {
|
|
1284
1285
|
name,
|
|
1285
1286
|
timeMs: this.clock(),
|
|
1286
1287
|
...attrs ? { attrs } : {}
|
|
1288
|
+
};
|
|
1289
|
+
const eventIndex = this.events.length;
|
|
1290
|
+
this.events.push(event);
|
|
1291
|
+
this.sink.recordEvent?.({
|
|
1292
|
+
span: {
|
|
1293
|
+
context: this.context,
|
|
1294
|
+
name: this.name,
|
|
1295
|
+
surface: this.surface,
|
|
1296
|
+
kind: this.kind,
|
|
1297
|
+
startTimeMs: this.startTimeMs,
|
|
1298
|
+
...this.attrs ? { attrs: this.attrs } : {}
|
|
1299
|
+
},
|
|
1300
|
+
event,
|
|
1301
|
+
eventIndex
|
|
1287
1302
|
});
|
|
1288
1303
|
}
|
|
1289
1304
|
end(status = "ok", options = {}) {
|
|
@@ -1291,7 +1306,7 @@ var RecordingActiveSpan = class {
|
|
|
1291
1306
|
this.ended = true;
|
|
1292
1307
|
const endTimeMs = this.clock();
|
|
1293
1308
|
const attrs = mergeAttrs(this.attrs, options.attrs);
|
|
1294
|
-
|
|
1309
|
+
const completed = {
|
|
1295
1310
|
context: this.context,
|
|
1296
1311
|
name: this.name,
|
|
1297
1312
|
surface: this.surface,
|
|
@@ -1302,7 +1317,9 @@ var RecordingActiveSpan = class {
|
|
|
1302
1317
|
durationMs: Math.max(0, endTimeMs - this.startTimeMs),
|
|
1303
1318
|
...attrs ? { attrs } : {},
|
|
1304
1319
|
events: [...this.events]
|
|
1305
|
-
}
|
|
1320
|
+
};
|
|
1321
|
+
this.sink.recordSpanFact?.({ span: completed });
|
|
1322
|
+
this.sink.record(completed);
|
|
1306
1323
|
}
|
|
1307
1324
|
};
|
|
1308
1325
|
function mergeAttrs(base, extra) {
|
|
@@ -1337,6 +1354,125 @@ function randomHex(length) {
|
|
|
1337
1354
|
return [...bytes].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1338
1355
|
}
|
|
1339
1356
|
|
|
1357
|
+
// ../shared/src/tracing/eventRows.ts
|
|
1358
|
+
var PROMOTED_IDENTITY_ATTRS = [
|
|
1359
|
+
"server_id",
|
|
1360
|
+
"machine_id",
|
|
1361
|
+
"agent_id",
|
|
1362
|
+
"launch_id",
|
|
1363
|
+
"session_id",
|
|
1364
|
+
"request_id",
|
|
1365
|
+
"route_pattern",
|
|
1366
|
+
"caller_kind"
|
|
1367
|
+
];
|
|
1368
|
+
var PROMOTED_CLOSED_ATTRS = [
|
|
1369
|
+
"outcome",
|
|
1370
|
+
"reason",
|
|
1371
|
+
"event_kind",
|
|
1372
|
+
"source",
|
|
1373
|
+
"authority",
|
|
1374
|
+
"activity_write_site",
|
|
1375
|
+
"activity_source",
|
|
1376
|
+
"hint_source",
|
|
1377
|
+
"resolved_activity",
|
|
1378
|
+
"previous_activity",
|
|
1379
|
+
"next_activity",
|
|
1380
|
+
"repair_kind",
|
|
1381
|
+
"action",
|
|
1382
|
+
"error_class",
|
|
1383
|
+
"status_bucket",
|
|
1384
|
+
"shadow_agent_id",
|
|
1385
|
+
"shadow_signal_site",
|
|
1386
|
+
"shadow_observation_class",
|
|
1387
|
+
"shadow_prior_projection",
|
|
1388
|
+
"shadow_projection",
|
|
1389
|
+
"shadow_legacy_outcome",
|
|
1390
|
+
"shadow_action",
|
|
1391
|
+
"shadow_reason",
|
|
1392
|
+
"shadow_direction",
|
|
1393
|
+
"shadow_plan_kind"
|
|
1394
|
+
];
|
|
1395
|
+
var TRACE_EVENT_ROW_PROMOTED_ATTRS = [
|
|
1396
|
+
...PROMOTED_IDENTITY_ATTRS,
|
|
1397
|
+
...PROMOTED_CLOSED_ATTRS
|
|
1398
|
+
];
|
|
1399
|
+
|
|
1400
|
+
// ../shared/src/tracing/fields.ts
|
|
1401
|
+
function defineTraceFields(definitions) {
|
|
1402
|
+
for (const definition of definitions) {
|
|
1403
|
+
if (definition.fieldClass === "content_safety" && !definition.contentRule) {
|
|
1404
|
+
throw new Error(`Trace content-safety field "${definition.key}" must define a contentRule`);
|
|
1405
|
+
}
|
|
1406
|
+
if ((definition.fieldClass === "query_axis" || definition.fieldClass === "family_query_axis") && definition.valueKind === "content") {
|
|
1407
|
+
throw new Error(`Trace query-axis field "${definition.key}" cannot be content`);
|
|
1408
|
+
}
|
|
1409
|
+
if (definition.fieldClass === "family_query_axis" && !definition.scope) {
|
|
1410
|
+
throw new Error(`Trace family query-axis field "${definition.key}" must define a family scope`);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
return definitions;
|
|
1414
|
+
}
|
|
1415
|
+
var TRACE_B0_FIELD_DEFINITIONS = defineTraceFields([
|
|
1416
|
+
{ key: "row_kind", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "stable" },
|
|
1417
|
+
{ key: "trace_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1418
|
+
{ key: "span_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1419
|
+
{ key: "parent_span_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1420
|
+
{ key: "span_name", fieldClass: "query_axis", placement: "span", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1421
|
+
{ key: "span_surface", fieldClass: "query_axis", placement: "span", valueKind: "closed_enum", enumBinding: "stable" },
|
|
1422
|
+
{ key: "span_kind", fieldClass: "query_axis", placement: "span", valueKind: "closed_enum", enumBinding: "stable" },
|
|
1423
|
+
{ key: "span_status", fieldClass: "query_axis", placement: "span", valueKind: "closed_enum", enumBinding: "stable" },
|
|
1424
|
+
{ key: "event_name", fieldClass: "query_axis", placement: "event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1425
|
+
{ key: "event_kind", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1426
|
+
{ key: "event_index", fieldClass: "query_axis", placement: "event", valueKind: "identity" },
|
|
1427
|
+
{ key: "event_time", fieldClass: "query_axis", placement: "event", valueKind: "timestamp" },
|
|
1428
|
+
{ key: "event_time_ms", fieldClass: "query_axis", placement: "event", valueKind: "numeric" },
|
|
1429
|
+
{ key: "lifecycle_observed_at_ms", fieldClass: "query_axis", placement: "span_or_event", valueKind: "numeric" },
|
|
1430
|
+
{ key: "activity_observed_at_ms", fieldClass: "query_axis", placement: "span_or_event", valueKind: "numeric" },
|
|
1431
|
+
{ key: "advances_observed_clock", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1432
|
+
{ key: "duration_ms", fieldClass: "query_axis", placement: "span_or_event", valueKind: "numeric" },
|
|
1433
|
+
{ key: "request_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1434
|
+
{ key: "route_pattern", fieldClass: "query_axis", placement: "span", valueKind: "route" },
|
|
1435
|
+
{ key: "caller_kind", fieldClass: "query_axis", placement: "span", valueKind: "closed_enum", enumBinding: "stable" },
|
|
1436
|
+
{ key: "server_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1437
|
+
{ key: "machine_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1438
|
+
{ key: "agent_id", fieldClass: "query_axis", placement: "span_or_event", valueKind: "identity", highCardinality: true },
|
|
1439
|
+
{ key: "launch_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1440
|
+
{ key: "session_id", fieldClass: "query_axis", placement: "span", valueKind: "identity", highCardinality: true },
|
|
1441
|
+
{ key: "observation_class", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1442
|
+
{ key: "action", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1443
|
+
{ key: "source", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1444
|
+
{ key: "served_from", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1445
|
+
{ key: "authority", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1446
|
+
{ key: "decided_by", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1447
|
+
{ key: "error_class", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1448
|
+
{ key: "query_name", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "query_registry" },
|
|
1449
|
+
{ key: "phase", fieldClass: "query_axis", placement: "span_or_event", valueKind: "closed_enum", enumBinding: "pending_457" },
|
|
1450
|
+
{ key: "hint_source", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1451
|
+
{ key: "resolved_activity", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1452
|
+
{ key: "previous_activity", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1453
|
+
{ key: "next_activity", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1454
|
+
{ key: "repair_kind", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1455
|
+
{ key: "activity_write_site", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1456
|
+
{ key: "activity_source", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1457
|
+
{ key: "status_bucket", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:activity" },
|
|
1458
|
+
{ key: "shadow_agent_id", fieldClass: "family_query_axis", placement: "event", valueKind: "identity", scope: "family:lifecycle_shadow", highCardinality: true },
|
|
1459
|
+
{ key: "shadow_signal_site", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1460
|
+
{ key: "shadow_observation_class", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1461
|
+
{ key: "shadow_prior_projection", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1462
|
+
{ key: "shadow_projection", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1463
|
+
{ key: "shadow_legacy_outcome", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1464
|
+
{ key: "shadow_action", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1465
|
+
{ key: "shadow_reason", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1466
|
+
{ key: "shadow_direction", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1467
|
+
{ key: "shadow_plan_kind", fieldClass: "family_query_axis", placement: "event", valueKind: "closed_enum", scope: "family:lifecycle_shadow", enumBinding: "pending_457" },
|
|
1468
|
+
{ key: "row_count", fieldClass: "detail", placement: "span_or_event", valueKind: "detail" },
|
|
1469
|
+
{ key: "retry_count", fieldClass: "detail", placement: "span_or_event", valueKind: "detail" },
|
|
1470
|
+
{ key: "error_message", fieldClass: "detail", placement: "span_or_event", valueKind: "detail", contentRule: "scrub_and_short_retention" },
|
|
1471
|
+
{ key: "query_text", fieldClass: "content_safety", placement: "span_or_event", valueKind: "content", contentRule: "scrub_and_short_retention" },
|
|
1472
|
+
{ key: "raw_payload", fieldClass: "content_safety", placement: "span_or_event", valueKind: "content", contentRule: "drop" },
|
|
1473
|
+
{ key: "token", fieldClass: "content_safety", placement: "span_or_event", valueKind: "content", contentRule: "drop" }
|
|
1474
|
+
]);
|
|
1475
|
+
|
|
1340
1476
|
// ../shared/src/toolDisplay.ts
|
|
1341
1477
|
var TOOL_DISPLAY_METADATA = {
|
|
1342
1478
|
send_message: { logLabel: "Sending message", activityLabel: "Sending message\u2026", summaryKind: "message_target" },
|
|
@@ -1986,7 +2122,8 @@ var agentApiResolveChannelResponseSchema = passthroughObject({
|
|
|
1986
2122
|
channelId: z2.string().trim().min(1)
|
|
1987
2123
|
});
|
|
1988
2124
|
var agentApiThreadUnfollowBodySchema = passthroughObject({
|
|
1989
|
-
thread: z2.string().trim().min(1)
|
|
2125
|
+
thread: z2.string().trim().min(1),
|
|
2126
|
+
reason: z2.string().trim().min(1).max(200).optional()
|
|
1990
2127
|
});
|
|
1991
2128
|
var agentApiTaskClaimBodySchema = passthroughObject({
|
|
1992
2129
|
channel: z2.string().trim().min(1),
|
|
@@ -3187,6 +3324,55 @@ var SUPPORTED_TRANSLATION_LANGUAGE_SET = new Set(
|
|
|
3187
3324
|
SUPPORTED_TRANSLATION_LANGUAGE_CODES
|
|
3188
3325
|
);
|
|
3189
3326
|
|
|
3327
|
+
// ../shared/src/oauthScopes.ts
|
|
3328
|
+
var RAFT_OAUTH_SCOPE_CATALOG = {
|
|
3329
|
+
openid: {
|
|
3330
|
+
phase: "identity",
|
|
3331
|
+
defaultAllowed: true,
|
|
3332
|
+
publicDiscovery: true,
|
|
3333
|
+
requiresResource: false,
|
|
3334
|
+
label: "OpenID identity"
|
|
3335
|
+
},
|
|
3336
|
+
profile: {
|
|
3337
|
+
phase: "identity",
|
|
3338
|
+
defaultAllowed: true,
|
|
3339
|
+
publicDiscovery: true,
|
|
3340
|
+
requiresResource: false,
|
|
3341
|
+
label: "Basic profile"
|
|
3342
|
+
},
|
|
3343
|
+
identity: {
|
|
3344
|
+
phase: "identity",
|
|
3345
|
+
defaultAllowed: true,
|
|
3346
|
+
publicDiscovery: true,
|
|
3347
|
+
requiresResource: false,
|
|
3348
|
+
label: "Raft identity card"
|
|
3349
|
+
},
|
|
3350
|
+
"agent:event:write": {
|
|
3351
|
+
phase: "agent_inbound",
|
|
3352
|
+
defaultAllowed: false,
|
|
3353
|
+
publicDiscovery: true,
|
|
3354
|
+
requiresResource: true,
|
|
3355
|
+
label: "Send structured events to an agent"
|
|
3356
|
+
},
|
|
3357
|
+
"agent:notification:write": {
|
|
3358
|
+
phase: "agent_inbound",
|
|
3359
|
+
defaultAllowed: false,
|
|
3360
|
+
publicDiscovery: true,
|
|
3361
|
+
requiresResource: true,
|
|
3362
|
+
label: "Send notifications to an agent"
|
|
3363
|
+
},
|
|
3364
|
+
"agent:action_request:write": {
|
|
3365
|
+
phase: "agent_inbound",
|
|
3366
|
+
defaultAllowed: false,
|
|
3367
|
+
publicDiscovery: false,
|
|
3368
|
+
requiresResource: true,
|
|
3369
|
+
label: "Request agent action"
|
|
3370
|
+
}
|
|
3371
|
+
};
|
|
3372
|
+
var RAFT_OAUTH_SCOPES_SUPPORTED = Object.keys(RAFT_OAUTH_SCOPE_CATALOG);
|
|
3373
|
+
var RAFT_OAUTH_DEFAULT_ALLOWED_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].defaultAllowed);
|
|
3374
|
+
var RAFT_OAUTH_PUBLIC_DISCOVERY_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].publicDiscovery);
|
|
3375
|
+
|
|
3190
3376
|
// ../shared/src/testing/failpoints.ts
|
|
3191
3377
|
var NoopFailpointRegistry = class {
|
|
3192
3378
|
get enabled() {
|
|
@@ -4025,8 +4211,8 @@ async function executeResponseRequest(url, init, {
|
|
|
4025
4211
|
}
|
|
4026
4212
|
|
|
4027
4213
|
// src/directUploadCapability.ts
|
|
4028
|
-
function joinUrl(base,
|
|
4029
|
-
return `${base.replace(/\/+$/, "")}${
|
|
4214
|
+
function joinUrl(base, path21) {
|
|
4215
|
+
return `${base.replace(/\/+$/, "")}${path21}`;
|
|
4030
4216
|
}
|
|
4031
4217
|
function jsonHeaders(apiKey) {
|
|
4032
4218
|
return {
|
|
@@ -5659,7 +5845,7 @@ function shortMessageId2(value) {
|
|
|
5659
5845
|
return value.slice(0, 8);
|
|
5660
5846
|
}
|
|
5661
5847
|
function normalizeSenderType(value) {
|
|
5662
|
-
return value === "human" || value === "agent" || value === "system" ? value : void 0;
|
|
5848
|
+
return value === "human" || value === "agent" || value === "system" || value === "third_party_app" ? value : void 0;
|
|
5663
5849
|
}
|
|
5664
5850
|
function nonEmptyString(value) {
|
|
5665
5851
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -6047,6 +6233,10 @@ async function readRequestBody(req) {
|
|
|
6047
6233
|
function messageSeq3(message) {
|
|
6048
6234
|
return Number(message.seq ?? 0);
|
|
6049
6235
|
}
|
|
6236
|
+
function isThirdPartyAgentEvent(message) {
|
|
6237
|
+
const thirdPartyEvent = message.third_party_event;
|
|
6238
|
+
return typeof thirdPartyEvent?.id === "string" && thirdPartyEvent.id.length > 0;
|
|
6239
|
+
}
|
|
6050
6240
|
function localAgentApiInboxResponse(registration) {
|
|
6051
6241
|
const coordinator = registration.inboxCoordinator;
|
|
6052
6242
|
if (!coordinator) return void 0;
|
|
@@ -6097,6 +6287,7 @@ function localAgentApiEventsResponse(registration, target) {
|
|
|
6097
6287
|
const normalized = sortInboxMessagesBySeq(normalizeInboxVisibleMessages(pending));
|
|
6098
6288
|
const filtered = parsedQuery.sinceSeq !== null ? normalized.filter((message) => {
|
|
6099
6289
|
const seq = messageSeq3(message);
|
|
6290
|
+
if ((!Number.isFinite(seq) || seq <= 0) && isThirdPartyAgentEvent(message)) return true;
|
|
6100
6291
|
return Number.isFinite(seq) && seq > parsedQuery.sinceSeq;
|
|
6101
6292
|
}) : normalized;
|
|
6102
6293
|
const events = filtered.slice(0, parsedQuery.limit);
|
|
@@ -7665,7 +7856,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7665
7856
|
return null;
|
|
7666
7857
|
}
|
|
7667
7858
|
const sessionId = codexMessageThreadId(message);
|
|
7668
|
-
const
|
|
7859
|
+
const path21 = boundedString(params.path);
|
|
7669
7860
|
return {
|
|
7670
7861
|
kind: "runtime_diagnostic",
|
|
7671
7862
|
severity: "warning",
|
|
@@ -7673,7 +7864,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7673
7864
|
itemType: message.method,
|
|
7674
7865
|
message: diagnosticMessage,
|
|
7675
7866
|
...details ? { details } : {},
|
|
7676
|
-
...
|
|
7867
|
+
...path21 ? { path: path21 } : {},
|
|
7677
7868
|
...params.range !== void 0 ? { range: params.range } : {},
|
|
7678
7869
|
payloadBytes: payloadBytes(params),
|
|
7679
7870
|
...sessionId ? { sessionId } : {}
|
|
@@ -12531,6 +12722,9 @@ function computeTarget(channelType, channelName, parentChannelName, parentChanne
|
|
|
12531
12722
|
return `#${channelName}`;
|
|
12532
12723
|
}
|
|
12533
12724
|
function formatAgentMessageVisibleTarget(message) {
|
|
12725
|
+
if (message.third_party_event) {
|
|
12726
|
+
return `agent-event:${getMessageShortId(message.third_party_event.id)}`;
|
|
12727
|
+
}
|
|
12534
12728
|
return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
|
|
12535
12729
|
}
|
|
12536
12730
|
function formatProxyVisibleMessageTarget(message) {
|
|
@@ -18297,6 +18491,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18297
18491
|
const launchId = launchIdOverride || ap?.launchId || void 0;
|
|
18298
18492
|
const clientSeq = this.nextActivityClientSeq(agentId);
|
|
18299
18493
|
const producerFactId = this.buildActivityProducerFactId(agentId, launchId, clientSeq);
|
|
18494
|
+
const observedAtMs = Date.now();
|
|
18300
18495
|
this.sendToServer({
|
|
18301
18496
|
type: "agent:activity",
|
|
18302
18497
|
agentId,
|
|
@@ -18308,6 +18503,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18308
18503
|
launchId,
|
|
18309
18504
|
clientSeq,
|
|
18310
18505
|
producerFactId,
|
|
18506
|
+
observedAtMs,
|
|
18311
18507
|
isHeartbeat: false
|
|
18312
18508
|
});
|
|
18313
18509
|
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId, false);
|
|
@@ -18327,6 +18523,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18327
18523
|
const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
|
|
18328
18524
|
const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
|
|
18329
18525
|
const heartbeatProducerFactId = this.buildActivityProducerFactId(agentId, heartbeatLaunchId, heartbeatClientSeq);
|
|
18526
|
+
const heartbeatObservedAtMs = Date.now();
|
|
18330
18527
|
this.sendToServer({
|
|
18331
18528
|
type: "agent:activity",
|
|
18332
18529
|
agentId,
|
|
@@ -18337,6 +18534,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18337
18534
|
launchId: heartbeatLaunchId,
|
|
18338
18535
|
clientSeq: heartbeatClientSeq,
|
|
18339
18536
|
producerFactId: heartbeatProducerFactId,
|
|
18537
|
+
observedAtMs: heartbeatObservedAtMs,
|
|
18340
18538
|
// The one knowing site: this timer re-broadcasts stale
|
|
18341
18539
|
// lastActivity, so it declares its replay provenance.
|
|
18342
18540
|
isHeartbeat: true
|
|
@@ -21368,6 +21566,563 @@ function assertLegacyDaemonKeyNotAdoptedByComputer(options) {
|
|
|
21368
21566
|
if (match) throw new LegacyDaemonKeyAdoptedByComputerError(match);
|
|
21369
21567
|
}
|
|
21370
21568
|
|
|
21569
|
+
// src/agentMigrationExport.ts
|
|
21570
|
+
import { createHash as createHash7 } from "crypto";
|
|
21571
|
+
import { createReadStream } from "fs";
|
|
21572
|
+
import { lstat as lstat2, readdir as readdir4, readFile as readFile3, readlink } from "fs/promises";
|
|
21573
|
+
import path19 from "path";
|
|
21574
|
+
var AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION = "agent-bundle/v1";
|
|
21575
|
+
var REGENERABLE_DIRECTORY_NAMES = [
|
|
21576
|
+
".venv",
|
|
21577
|
+
"__pycache__",
|
|
21578
|
+
"dist",
|
|
21579
|
+
"node_modules",
|
|
21580
|
+
"target"
|
|
21581
|
+
];
|
|
21582
|
+
var SECRET_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
21583
|
+
".env",
|
|
21584
|
+
".env.local",
|
|
21585
|
+
".env.development",
|
|
21586
|
+
".env.production",
|
|
21587
|
+
".env.test",
|
|
21588
|
+
"credentials.json",
|
|
21589
|
+
"credential.json"
|
|
21590
|
+
]);
|
|
21591
|
+
var ENV_KEY_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
|
|
21592
|
+
async function buildAgentMigrationExportManifest(input) {
|
|
21593
|
+
const slockHome = path19.resolve(input.slockHome);
|
|
21594
|
+
const workspace = path19.resolve(input.workspacePath ?? path19.join(slockHome, "agents", input.agentId));
|
|
21595
|
+
const proposedIncludes = normalizeProposalPaths(input.cooperativeManifest?.include, workspace, "include");
|
|
21596
|
+
const proposedRegenerableExcludes = normalizeProposalPaths(input.cooperativeManifest?.exclude_regenerable, workspace, "exclude_regenerable");
|
|
21597
|
+
const cleanedProposal = normalizeProposalPaths(input.cooperativeManifest?.cleaned, workspace, "cleaned");
|
|
21598
|
+
const state = {
|
|
21599
|
+
workspace,
|
|
21600
|
+
files: [],
|
|
21601
|
+
excludedRegenerable: [],
|
|
21602
|
+
promotedIncludes: [],
|
|
21603
|
+
proposalRefusals: [
|
|
21604
|
+
...proposedIncludes.refusals,
|
|
21605
|
+
...proposedRegenerableExcludes.refusals,
|
|
21606
|
+
...cleanedProposal.refusals
|
|
21607
|
+
],
|
|
21608
|
+
unreachable: [],
|
|
21609
|
+
secretsDisclosed: [],
|
|
21610
|
+
seenWorkspacePaths: /* @__PURE__ */ new Set(),
|
|
21611
|
+
explicitIncludePaths: new Set(proposedIncludes.paths)
|
|
21612
|
+
};
|
|
21613
|
+
await walkWorkspace(workspace, "", new Set(proposedRegenerableExcludes.paths), state, { forceIncludeRegenerable: false });
|
|
21614
|
+
for (const requestedPath of proposedIncludes.paths) {
|
|
21615
|
+
if (!state.seenWorkspacePaths.has(requestedPath)) {
|
|
21616
|
+
await includeWorkspacePath(requestedPath, state, { forceIncludeRegenerable: true });
|
|
21617
|
+
}
|
|
21618
|
+
}
|
|
21619
|
+
for (const requestedPath of proposedRegenerableExcludes.paths) {
|
|
21620
|
+
if (isRegenerablePath(requestedPath)) continue;
|
|
21621
|
+
state.promotedIncludes.push({ path: requestedPath, reason: "exclude_not_regenerable" });
|
|
21622
|
+
await includeWorkspacePath(requestedPath, state, { forceIncludeRegenerable: true });
|
|
21623
|
+
}
|
|
21624
|
+
const crossTreeRefs = await buildCrossTreeRefs(input.runtimeSessionRefs ?? []);
|
|
21625
|
+
const secretDisclosureProposal = normalizeProposalPaths(input.cooperativeManifest?.secrets_disclosed, workspace, "secrets_disclosed");
|
|
21626
|
+
state.proposalRefusals.push(...secretDisclosureProposal.refusals);
|
|
21627
|
+
return {
|
|
21628
|
+
schemaVersion: AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION,
|
|
21629
|
+
agentId: input.agentId,
|
|
21630
|
+
mode: input.mode,
|
|
21631
|
+
createdAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
21632
|
+
roots: {
|
|
21633
|
+
slockHome,
|
|
21634
|
+
workspace
|
|
21635
|
+
},
|
|
21636
|
+
defaults: {
|
|
21637
|
+
unknownFiles: "include",
|
|
21638
|
+
excludePolicy: "regenerable_only",
|
|
21639
|
+
regenerableDirectoryNames: [...REGENERABLE_DIRECTORY_NAMES]
|
|
21640
|
+
},
|
|
21641
|
+
files: sortBundleEntries(state.files),
|
|
21642
|
+
excludedRegenerable: sortByPath(state.excludedRegenerable),
|
|
21643
|
+
promotedIncludes: sortByPath(state.promotedIncludes),
|
|
21644
|
+
proposalRefusals: sortByPath(state.proposalRefusals),
|
|
21645
|
+
unreachable: sortByPath(state.unreachable),
|
|
21646
|
+
secretsDisclosed: sortByPath([
|
|
21647
|
+
...state.secretsDisclosed,
|
|
21648
|
+
...normalizeProvidedSecretDisclosures(secretDisclosureProposal.paths)
|
|
21649
|
+
]),
|
|
21650
|
+
cleaned: cleanedProposal.paths,
|
|
21651
|
+
crossTreeRefs: crossTreeRefs.sort((a, b) => a.bundlePath.localeCompare(b.bundlePath))
|
|
21652
|
+
};
|
|
21653
|
+
}
|
|
21654
|
+
async function walkWorkspace(root, relativeDir, proposedRegenerableExcludes, state, opts) {
|
|
21655
|
+
const absoluteDir = path19.join(root, relativeDir);
|
|
21656
|
+
let entries;
|
|
21657
|
+
try {
|
|
21658
|
+
entries = await readdir4(absoluteDir, { withFileTypes: true });
|
|
21659
|
+
} catch {
|
|
21660
|
+
state.unreachable.push({
|
|
21661
|
+
path: relativeDir || ".",
|
|
21662
|
+
sourcePath: absoluteDir,
|
|
21663
|
+
reason: "read_error"
|
|
21664
|
+
});
|
|
21665
|
+
return;
|
|
21666
|
+
}
|
|
21667
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
21668
|
+
for (const entry of entries) {
|
|
21669
|
+
const relativePath = toPosixPath(path19.join(relativeDir, entry.name));
|
|
21670
|
+
if (entry.isDirectory()) {
|
|
21671
|
+
if (!opts.forceIncludeRegenerable && isRegenerablePath(relativePath)) {
|
|
21672
|
+
if (state.explicitIncludePaths.has(relativePath)) {
|
|
21673
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, { forceIncludeRegenerable: true });
|
|
21674
|
+
continue;
|
|
21675
|
+
}
|
|
21676
|
+
if (hasExplicitIncludeDescendant(relativePath, state.explicitIncludePaths)) {
|
|
21677
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, opts);
|
|
21678
|
+
continue;
|
|
21679
|
+
}
|
|
21680
|
+
state.excludedRegenerable.push({
|
|
21681
|
+
path: relativePath,
|
|
21682
|
+
reason: proposedRegenerableExcludes.has(relativePath) ? "cooperative_exclude_regenerable" : "regenerable_default",
|
|
21683
|
+
regenerableHint: `${entry.name} is treated as rebuildable/installable state and is not bundled by default`
|
|
21684
|
+
});
|
|
21685
|
+
continue;
|
|
21686
|
+
}
|
|
21687
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, opts);
|
|
21688
|
+
continue;
|
|
21689
|
+
}
|
|
21690
|
+
await includeWorkspacePath(relativePath, state, { forceIncludeRegenerable: opts.forceIncludeRegenerable });
|
|
21691
|
+
}
|
|
21692
|
+
}
|
|
21693
|
+
async function includeWorkspacePath(workspaceRelativePath, state, opts) {
|
|
21694
|
+
const normalizedRelativePath = normalizeRelativePath(workspaceRelativePath);
|
|
21695
|
+
if (state.seenWorkspacePaths.has(normalizedRelativePath)) return;
|
|
21696
|
+
const sourcePath = path19.join(state.workspace, normalizedRelativePath);
|
|
21697
|
+
let stat4;
|
|
21698
|
+
try {
|
|
21699
|
+
stat4 = await lstat2(sourcePath);
|
|
21700
|
+
} catch {
|
|
21701
|
+
state.unreachable.push({
|
|
21702
|
+
path: normalizedRelativePath,
|
|
21703
|
+
sourcePath,
|
|
21704
|
+
reason: "missing"
|
|
21705
|
+
});
|
|
21706
|
+
return;
|
|
21707
|
+
}
|
|
21708
|
+
if (stat4.isDirectory()) {
|
|
21709
|
+
if (!opts.forceIncludeRegenerable && isRegenerablePath(normalizedRelativePath)) {
|
|
21710
|
+
state.excludedRegenerable.push({
|
|
21711
|
+
path: normalizedRelativePath,
|
|
21712
|
+
reason: "cooperative_exclude_regenerable",
|
|
21713
|
+
regenerableHint: `${path19.basename(normalizedRelativePath)} is treated as rebuildable/installable state and is not bundled by default`
|
|
21714
|
+
});
|
|
21715
|
+
return;
|
|
21716
|
+
}
|
|
21717
|
+
await walkWorkspace(state.workspace, normalizedRelativePath, /* @__PURE__ */ new Set(), state, opts);
|
|
21718
|
+
return;
|
|
21719
|
+
}
|
|
21720
|
+
state.seenWorkspacePaths.add(normalizedRelativePath);
|
|
21721
|
+
const baseEntry = {
|
|
21722
|
+
source: "workspace",
|
|
21723
|
+
sourcePath,
|
|
21724
|
+
workspaceRelativePath: normalizedRelativePath,
|
|
21725
|
+
bundlePath: `workspace/${normalizedRelativePath}`,
|
|
21726
|
+
mode: stat4.mode,
|
|
21727
|
+
mtimeMs: stat4.mtimeMs
|
|
21728
|
+
};
|
|
21729
|
+
if (stat4.isSymbolicLink()) {
|
|
21730
|
+
state.files.push({
|
|
21731
|
+
...baseEntry,
|
|
21732
|
+
kind: "symlink",
|
|
21733
|
+
linkTarget: await readlink(sourcePath)
|
|
21734
|
+
});
|
|
21735
|
+
return;
|
|
21736
|
+
}
|
|
21737
|
+
if (!stat4.isFile()) {
|
|
21738
|
+
state.unreachable.push({
|
|
21739
|
+
path: normalizedRelativePath,
|
|
21740
|
+
sourcePath,
|
|
21741
|
+
reason: "unsupported_file_type"
|
|
21742
|
+
});
|
|
21743
|
+
return;
|
|
21744
|
+
}
|
|
21745
|
+
const secretShapes = await detectSecretShapes(sourcePath, normalizedRelativePath);
|
|
21746
|
+
if (secretShapes.length > 0) {
|
|
21747
|
+
state.secretsDisclosed.push({ path: normalizedRelativePath, shapes: secretShapes });
|
|
21748
|
+
}
|
|
21749
|
+
state.files.push({
|
|
21750
|
+
...baseEntry,
|
|
21751
|
+
kind: "file",
|
|
21752
|
+
sizeBytes: stat4.size,
|
|
21753
|
+
sha256: await sha256File(sourcePath),
|
|
21754
|
+
secretShapes: secretShapes.length > 0 ? secretShapes : void 0
|
|
21755
|
+
});
|
|
21756
|
+
}
|
|
21757
|
+
async function buildCrossTreeRefs(refs) {
|
|
21758
|
+
const result = [];
|
|
21759
|
+
for (const ref of refs) {
|
|
21760
|
+
const sourcePath = path19.resolve(ref.path);
|
|
21761
|
+
const bundlePath = `runtime/${safeBundleSegment(ref.runtime)}/${safeBundleSegment(ref.label)}/${safeBundleSegment(path19.basename(sourcePath) || "session")}`;
|
|
21762
|
+
const entry = {
|
|
21763
|
+
runtime: ref.runtime,
|
|
21764
|
+
label: ref.label,
|
|
21765
|
+
sourcePath,
|
|
21766
|
+
bundlePath,
|
|
21767
|
+
reachable: ref.reachable !== false,
|
|
21768
|
+
reason: ref.reason
|
|
21769
|
+
};
|
|
21770
|
+
try {
|
|
21771
|
+
const stat4 = await lstat2(sourcePath);
|
|
21772
|
+
if (stat4.isFile()) {
|
|
21773
|
+
entry.sizeBytes = stat4.size;
|
|
21774
|
+
entry.sha256 = await sha256File(sourcePath);
|
|
21775
|
+
}
|
|
21776
|
+
} catch {
|
|
21777
|
+
entry.reachable = false;
|
|
21778
|
+
}
|
|
21779
|
+
result.push(entry);
|
|
21780
|
+
}
|
|
21781
|
+
return result;
|
|
21782
|
+
}
|
|
21783
|
+
async function sha256File(filePath) {
|
|
21784
|
+
const hash = createHash7("sha256");
|
|
21785
|
+
await new Promise((resolve, reject) => {
|
|
21786
|
+
const stream = createReadStream(filePath);
|
|
21787
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
21788
|
+
stream.on("error", reject);
|
|
21789
|
+
stream.on("end", resolve);
|
|
21790
|
+
});
|
|
21791
|
+
return hash.digest("hex");
|
|
21792
|
+
}
|
|
21793
|
+
async function detectSecretShapes(sourcePath, relativePath) {
|
|
21794
|
+
const basename = path19.basename(relativePath);
|
|
21795
|
+
const lowerBasename = basename.toLowerCase();
|
|
21796
|
+
const shapes = /* @__PURE__ */ new Set();
|
|
21797
|
+
if (SECRET_FILE_NAMES.has(lowerBasename) || lowerBasename.startsWith(".env.")) {
|
|
21798
|
+
shapes.add(`file:${basename}`);
|
|
21799
|
+
try {
|
|
21800
|
+
const text = await readFile3(sourcePath, "utf8");
|
|
21801
|
+
for (const line of text.split(/\r?\n/)) {
|
|
21802
|
+
const match = ENV_KEY_PATTERN.exec(line);
|
|
21803
|
+
if (match) shapes.add(`env:${match[1]}`);
|
|
21804
|
+
}
|
|
21805
|
+
} catch {
|
|
21806
|
+
shapes.add("content:unreadable");
|
|
21807
|
+
}
|
|
21808
|
+
}
|
|
21809
|
+
if (/(?:secret|token|credential|api[-_]?key)/i.test(relativePath)) {
|
|
21810
|
+
shapes.add(`path:${basename}`);
|
|
21811
|
+
}
|
|
21812
|
+
return [...shapes].sort();
|
|
21813
|
+
}
|
|
21814
|
+
function normalizeProvidedSecretDisclosures(disclosures) {
|
|
21815
|
+
return disclosures.map((entry) => ({
|
|
21816
|
+
path: entry,
|
|
21817
|
+
shapes: ["provided"]
|
|
21818
|
+
}));
|
|
21819
|
+
}
|
|
21820
|
+
function normalizeProposalPaths(paths, workspace, source) {
|
|
21821
|
+
if (!paths) return { paths: [], refusals: [] };
|
|
21822
|
+
const result = [];
|
|
21823
|
+
const refusals = [];
|
|
21824
|
+
for (const value of paths) {
|
|
21825
|
+
const trimmed = value.trim();
|
|
21826
|
+
if (!trimmed) continue;
|
|
21827
|
+
if (path19.isAbsolute(trimmed)) {
|
|
21828
|
+
const relative = path19.relative(workspace, trimmed);
|
|
21829
|
+
if (relative.startsWith("..") || path19.isAbsolute(relative)) {
|
|
21830
|
+
refusals.push({
|
|
21831
|
+
path: trimmed,
|
|
21832
|
+
reason: "outside_workspace",
|
|
21833
|
+
source
|
|
21834
|
+
});
|
|
21835
|
+
continue;
|
|
21836
|
+
}
|
|
21837
|
+
try {
|
|
21838
|
+
result.push(normalizeRelativePath(relative));
|
|
21839
|
+
} catch {
|
|
21840
|
+
refusals.push({
|
|
21841
|
+
path: trimmed,
|
|
21842
|
+
reason: "unsafe_path",
|
|
21843
|
+
source
|
|
21844
|
+
});
|
|
21845
|
+
}
|
|
21846
|
+
continue;
|
|
21847
|
+
}
|
|
21848
|
+
try {
|
|
21849
|
+
result.push(normalizeRelativePath(trimmed));
|
|
21850
|
+
} catch {
|
|
21851
|
+
refusals.push({
|
|
21852
|
+
path: trimmed,
|
|
21853
|
+
reason: "unsafe_path",
|
|
21854
|
+
source
|
|
21855
|
+
});
|
|
21856
|
+
}
|
|
21857
|
+
}
|
|
21858
|
+
return { paths: [...new Set(result)], refusals };
|
|
21859
|
+
}
|
|
21860
|
+
function normalizeRelativePath(value) {
|
|
21861
|
+
const normalized = path19.normalize(value).replace(/^[\\/]+/, "");
|
|
21862
|
+
if (!normalized || normalized === "." || normalized.startsWith("..") || path19.isAbsolute(normalized)) {
|
|
21863
|
+
throw new Error(`unsafe migration export path: ${value}`);
|
|
21864
|
+
}
|
|
21865
|
+
return toPosixPath(normalized);
|
|
21866
|
+
}
|
|
21867
|
+
function isRegenerablePath(relativePath) {
|
|
21868
|
+
return normalizeRelativePath(relativePath).split("/").some((segment) => REGENERABLE_DIRECTORY_NAMES.includes(segment));
|
|
21869
|
+
}
|
|
21870
|
+
function hasExplicitIncludeDescendant(relativePath, explicitIncludePaths) {
|
|
21871
|
+
const prefix = `${relativePath}/`;
|
|
21872
|
+
for (const includePath of explicitIncludePaths) {
|
|
21873
|
+
if (includePath.startsWith(prefix)) return true;
|
|
21874
|
+
}
|
|
21875
|
+
return false;
|
|
21876
|
+
}
|
|
21877
|
+
function safeBundleSegment(value) {
|
|
21878
|
+
return value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "unknown";
|
|
21879
|
+
}
|
|
21880
|
+
function toPosixPath(value) {
|
|
21881
|
+
return value.split(path19.sep).join("/");
|
|
21882
|
+
}
|
|
21883
|
+
function sortBundleEntries(entries) {
|
|
21884
|
+
return [...entries].sort((a, b) => a.bundlePath.localeCompare(b.bundlePath));
|
|
21885
|
+
}
|
|
21886
|
+
function sortByPath(entries) {
|
|
21887
|
+
return [...entries].sort((a, b) => a.path.localeCompare(b.path));
|
|
21888
|
+
}
|
|
21889
|
+
|
|
21890
|
+
// src/agentMigrationHttpTransport.ts
|
|
21891
|
+
import { createHash as createHash8, randomBytes as randomBytes2, timingSafeEqual } from "crypto";
|
|
21892
|
+
import http2 from "http";
|
|
21893
|
+
var MigrationBundleStreamError = class extends Error {
|
|
21894
|
+
constructor(code) {
|
|
21895
|
+
super(code);
|
|
21896
|
+
this.code = code;
|
|
21897
|
+
}
|
|
21898
|
+
};
|
|
21899
|
+
var AgentMigrationGrantRegistry = class {
|
|
21900
|
+
grants = /* @__PURE__ */ new Map();
|
|
21901
|
+
now;
|
|
21902
|
+
constructor(now = () => /* @__PURE__ */ new Date()) {
|
|
21903
|
+
this.now = now;
|
|
21904
|
+
}
|
|
21905
|
+
createGrant(input) {
|
|
21906
|
+
const token = input.token ?? randomBytes2(32).toString("base64url");
|
|
21907
|
+
const manifestSha256 = sha256Buffer(canonicalJsonBuffer(input.manifest));
|
|
21908
|
+
const grant = {
|
|
21909
|
+
grantId: input.grantId ?? randomBytes2(16).toString("hex"),
|
|
21910
|
+
tokenHash: hashToken(token),
|
|
21911
|
+
expiresAt: input.expiresAt,
|
|
21912
|
+
oneTimeUse: input.oneTimeUse ?? true,
|
|
21913
|
+
state: "issued",
|
|
21914
|
+
manifest: input.manifest,
|
|
21915
|
+
manifestSha256,
|
|
21916
|
+
bundleEtag: `"agent-migration-${manifestSha256}"`
|
|
21917
|
+
};
|
|
21918
|
+
this.grants.set(grant.grantId, grant);
|
|
21919
|
+
return { grant, token };
|
|
21920
|
+
}
|
|
21921
|
+
get(grantId) {
|
|
21922
|
+
return this.grants.get(grantId);
|
|
21923
|
+
}
|
|
21924
|
+
authenticate(grantId, token) {
|
|
21925
|
+
const grant = this.grants.get(grantId);
|
|
21926
|
+
if (!grant || !token || !verifyTokenHash(token, grant.tokenHash)) {
|
|
21927
|
+
return { ok: false, status: 401, code: "migration_grant_auth_failed" };
|
|
21928
|
+
}
|
|
21929
|
+
if (grant.state === "revoked" || grant.state === "consumed") {
|
|
21930
|
+
return { ok: false, status: 410, code: "migration_grant_unavailable" };
|
|
21931
|
+
}
|
|
21932
|
+
if (this.now().getTime() >= grant.expiresAt.getTime()) {
|
|
21933
|
+
grant.state = "expired";
|
|
21934
|
+
return { ok: false, status: 410, code: "migration_grant_unavailable" };
|
|
21935
|
+
}
|
|
21936
|
+
return { ok: true, grant };
|
|
21937
|
+
}
|
|
21938
|
+
revokeAll() {
|
|
21939
|
+
for (const grant of this.grants.values()) {
|
|
21940
|
+
if (grant.state !== "consumed" && grant.state !== "expired") {
|
|
21941
|
+
grant.state = "revoked";
|
|
21942
|
+
}
|
|
21943
|
+
}
|
|
21944
|
+
}
|
|
21945
|
+
};
|
|
21946
|
+
function createAgentMigrationHttpTransport(options = {}) {
|
|
21947
|
+
const registry = new AgentMigrationGrantRegistry(options.now);
|
|
21948
|
+
const bundleStreamFactory = options.bundleStreamFactory ?? defaultBundleStream;
|
|
21949
|
+
const server = http2.createServer((req, res) => {
|
|
21950
|
+
void handleMigrationRequest(req, res, registry, bundleStreamFactory);
|
|
21951
|
+
});
|
|
21952
|
+
return {
|
|
21953
|
+
grants: registry,
|
|
21954
|
+
server,
|
|
21955
|
+
listen: (port = 0, host = "127.0.0.1") => new Promise((resolve, reject) => {
|
|
21956
|
+
server.once("error", reject);
|
|
21957
|
+
server.listen(port, host, () => {
|
|
21958
|
+
server.off("error", reject);
|
|
21959
|
+
const address = server.address();
|
|
21960
|
+
if (!address || typeof address === "string") {
|
|
21961
|
+
reject(new Error("migration transport listen did not produce a TCP address"));
|
|
21962
|
+
return;
|
|
21963
|
+
}
|
|
21964
|
+
resolve({ url: `http://${address.address}:${address.port}` });
|
|
21965
|
+
});
|
|
21966
|
+
}),
|
|
21967
|
+
close: () => new Promise((resolve, reject) => {
|
|
21968
|
+
registry.revokeAll();
|
|
21969
|
+
server.close((err) => {
|
|
21970
|
+
if (err) reject(err);
|
|
21971
|
+
else resolve();
|
|
21972
|
+
});
|
|
21973
|
+
})
|
|
21974
|
+
};
|
|
21975
|
+
}
|
|
21976
|
+
async function handleMigrationRequest(req, res, registry, bundleStreamFactory) {
|
|
21977
|
+
const parsed = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
21978
|
+
const match = /^\/migration\/([^/]+)\/([^/]+)(?:\/([^/]+))?$/.exec(parsed.pathname);
|
|
21979
|
+
if (!match) {
|
|
21980
|
+
sendJson(res, 404, { code: "migration_route_not_found" });
|
|
21981
|
+
return;
|
|
21982
|
+
}
|
|
21983
|
+
const [, grantId, resource, resourceId] = match;
|
|
21984
|
+
const auth = registry.authenticate(decodeURIComponent(grantId), extractBearerToken(req));
|
|
21985
|
+
if (!auth.ok) {
|
|
21986
|
+
sendJson(res, auth.status, { code: auth.code });
|
|
21987
|
+
return;
|
|
21988
|
+
}
|
|
21989
|
+
if (resource === "manifest" && req.method === "GET" && !resourceId) {
|
|
21990
|
+
sendJson(res, 200, {
|
|
21991
|
+
manifestSha256: auth.grant.manifestSha256,
|
|
21992
|
+
manifest: auth.grant.manifest
|
|
21993
|
+
}, {
|
|
21994
|
+
"X-Raft-Manifest-Sha": auth.grant.manifestSha256,
|
|
21995
|
+
ETag: `"manifest-${auth.grant.manifestSha256}"`
|
|
21996
|
+
});
|
|
21997
|
+
return;
|
|
21998
|
+
}
|
|
21999
|
+
if (resource === "bundle.tar" && !resourceId) {
|
|
22000
|
+
if (req.method === "HEAD") {
|
|
22001
|
+
sendHead(res, auth.grant);
|
|
22002
|
+
return;
|
|
22003
|
+
}
|
|
22004
|
+
if (req.method === "GET") {
|
|
22005
|
+
await streamBundle(res, auth.grant, bundleStreamFactory);
|
|
22006
|
+
return;
|
|
22007
|
+
}
|
|
22008
|
+
}
|
|
22009
|
+
if (resource === "chunk" && req.method === "GET" && resourceId) {
|
|
22010
|
+
sendJson(res, 501, { code: "migration_chunk_not_implemented" });
|
|
22011
|
+
return;
|
|
22012
|
+
}
|
|
22013
|
+
sendJson(res, 405, { code: "migration_method_not_allowed" });
|
|
22014
|
+
}
|
|
22015
|
+
function sendHead(res, grant) {
|
|
22016
|
+
res.statusCode = 200;
|
|
22017
|
+
res.setHeader("X-Raft-Manifest-Sha", grant.manifestSha256);
|
|
22018
|
+
res.setHeader("ETag", grant.bundleEtag);
|
|
22019
|
+
res.setHeader("Accept-Ranges", "none");
|
|
22020
|
+
res.setHeader("X-Raft-Bundle-Size", "unknown");
|
|
22021
|
+
res.end();
|
|
22022
|
+
}
|
|
22023
|
+
async function streamBundle(res, grant, bundleStreamFactory) {
|
|
22024
|
+
if (grant.state === "streaming") {
|
|
22025
|
+
sendJson(res, 409, { code: "migration_bundle_stream_in_progress" });
|
|
22026
|
+
return;
|
|
22027
|
+
}
|
|
22028
|
+
if (grant.oneTimeUse && grant.state !== "issued" && grant.state !== "interrupted") {
|
|
22029
|
+
sendJson(res, 410, { code: "migration_grant_unavailable" });
|
|
22030
|
+
return;
|
|
22031
|
+
}
|
|
22032
|
+
let stream;
|
|
22033
|
+
try {
|
|
22034
|
+
stream = bundleStreamFactory(grant);
|
|
22035
|
+
} catch (err) {
|
|
22036
|
+
const code = err instanceof MigrationBundleStreamError ? err.code : "migration_bundle_stream_failed";
|
|
22037
|
+
sendJson(res, 500, { code });
|
|
22038
|
+
return;
|
|
22039
|
+
}
|
|
22040
|
+
grant.state = "streaming";
|
|
22041
|
+
let completed = false;
|
|
22042
|
+
res.on("close", () => {
|
|
22043
|
+
if (!completed && grant.state === "streaming") {
|
|
22044
|
+
grant.state = "interrupted";
|
|
22045
|
+
}
|
|
22046
|
+
});
|
|
22047
|
+
try {
|
|
22048
|
+
res.statusCode = 200;
|
|
22049
|
+
res.setHeader("Content-Type", "application/x-tar");
|
|
22050
|
+
res.setHeader("X-Raft-Manifest-Sha", grant.manifestSha256);
|
|
22051
|
+
res.setHeader("ETag", grant.bundleEtag);
|
|
22052
|
+
for await (const chunk of stream) {
|
|
22053
|
+
if (!res.write(chunk)) {
|
|
22054
|
+
await onceDrain(res);
|
|
22055
|
+
}
|
|
22056
|
+
}
|
|
22057
|
+
completed = true;
|
|
22058
|
+
grant.state = "consumed";
|
|
22059
|
+
res.end();
|
|
22060
|
+
} catch {
|
|
22061
|
+
if (!completed && grant.state === "streaming") {
|
|
22062
|
+
grant.state = "interrupted";
|
|
22063
|
+
}
|
|
22064
|
+
if (!res.headersSent) {
|
|
22065
|
+
sendJson(res, 500, { code: "migration_bundle_stream_failed" });
|
|
22066
|
+
} else {
|
|
22067
|
+
res.destroy();
|
|
22068
|
+
}
|
|
22069
|
+
}
|
|
22070
|
+
}
|
|
22071
|
+
function defaultBundleStream(grant) {
|
|
22072
|
+
void grant;
|
|
22073
|
+
throw new MigrationBundleStreamError("migration_bundle_stream_not_wired");
|
|
22074
|
+
}
|
|
22075
|
+
function extractBearerToken(req) {
|
|
22076
|
+
const directHeader = singleHeader(req.headers["x-raft-migration-token"]);
|
|
22077
|
+
if (directHeader) return directHeader;
|
|
22078
|
+
const authorization = singleHeader(req.headers.authorization);
|
|
22079
|
+
if (!authorization) return null;
|
|
22080
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
22081
|
+
return match?.[1] ?? null;
|
|
22082
|
+
}
|
|
22083
|
+
function singleHeader(value) {
|
|
22084
|
+
if (!value) return null;
|
|
22085
|
+
return Array.isArray(value) ? value[0] ?? null : value;
|
|
22086
|
+
}
|
|
22087
|
+
function sendJson(res, status, body, headers = {}) {
|
|
22088
|
+
const payload = JSON.stringify(body);
|
|
22089
|
+
res.writeHead(status, {
|
|
22090
|
+
"Content-Type": "application/json",
|
|
22091
|
+
"Content-Length": Buffer.byteLength(payload).toString(),
|
|
22092
|
+
...headers
|
|
22093
|
+
});
|
|
22094
|
+
res.end(payload);
|
|
22095
|
+
}
|
|
22096
|
+
function hashToken(token) {
|
|
22097
|
+
return sha256Buffer(Buffer.from(token, "utf8"));
|
|
22098
|
+
}
|
|
22099
|
+
function verifyTokenHash(token, expectedHashHex) {
|
|
22100
|
+
const actual = Buffer.from(hashToken(token), "hex");
|
|
22101
|
+
const expected = Buffer.from(expectedHashHex, "hex");
|
|
22102
|
+
if (actual.byteLength !== expected.byteLength) return false;
|
|
22103
|
+
return timingSafeEqual(actual, expected);
|
|
22104
|
+
}
|
|
22105
|
+
function sha256Buffer(buffer) {
|
|
22106
|
+
return createHash8("sha256").update(buffer).digest("hex");
|
|
22107
|
+
}
|
|
22108
|
+
function canonicalJsonBuffer(value) {
|
|
22109
|
+
return Buffer.from(canonicalJson(value), "utf8");
|
|
22110
|
+
}
|
|
22111
|
+
function canonicalJson(value) {
|
|
22112
|
+
return JSON.stringify(sortJsonValue(value));
|
|
22113
|
+
}
|
|
22114
|
+
function sortJsonValue(value) {
|
|
22115
|
+
if (Array.isArray(value)) return value.map(sortJsonValue);
|
|
22116
|
+
if (!value || typeof value !== "object") return value;
|
|
22117
|
+
return Object.keys(value).sort().reduce((result, key) => {
|
|
22118
|
+
result[key] = sortJsonValue(value[key]);
|
|
22119
|
+
return result;
|
|
22120
|
+
}, {});
|
|
22121
|
+
}
|
|
22122
|
+
function onceDrain(res) {
|
|
22123
|
+
return new Promise((resolve) => res.once("drain", resolve));
|
|
22124
|
+
}
|
|
22125
|
+
|
|
21371
22126
|
// src/core.ts
|
|
21372
22127
|
var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
21373
22128
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
@@ -21549,13 +22304,13 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
|
|
|
21549
22304
|
}
|
|
21550
22305
|
}
|
|
21551
22306
|
function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
21552
|
-
const thisDir =
|
|
21553
|
-
const bundledDistPath =
|
|
22307
|
+
const thisDir = path20.dirname(fileURLToPath(moduleUrl));
|
|
22308
|
+
const bundledDistPath = path20.resolve(thisDir, "cli", "index.js");
|
|
21554
22309
|
try {
|
|
21555
22310
|
accessSync(bundledDistPath);
|
|
21556
22311
|
return bundledDistPath;
|
|
21557
22312
|
} catch {
|
|
21558
|
-
const workspaceDistPath =
|
|
22313
|
+
const workspaceDistPath = path20.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
|
|
21559
22314
|
accessSync(workspaceDistPath);
|
|
21560
22315
|
return workspaceDistPath;
|
|
21561
22316
|
}
|
|
@@ -21569,7 +22324,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
21569
22324
|
}
|
|
21570
22325
|
async function runBundledSlockCli(argv) {
|
|
21571
22326
|
process.argv = [process.execPath, "slock", ...argv];
|
|
21572
|
-
await import("./dist-
|
|
22327
|
+
await import("./dist-D77BWHH4.js");
|
|
21573
22328
|
}
|
|
21574
22329
|
function detectRuntimes(tracer = noopTracer) {
|
|
21575
22330
|
const ids = [];
|
|
@@ -21777,7 +22532,7 @@ var DaemonCore = class {
|
|
|
21777
22532
|
}
|
|
21778
22533
|
resolveMachineStateRoot() {
|
|
21779
22534
|
if (this.options.machineStateDir) return this.options.machineStateDir;
|
|
21780
|
-
if (this.options.dataDir) return
|
|
22535
|
+
if (this.options.dataDir) return path20.join(path20.dirname(this.options.dataDir), "machines");
|
|
21781
22536
|
return resolveDefaultMachineStateRoot();
|
|
21782
22537
|
}
|
|
21783
22538
|
shouldEnableLocalTrace() {
|
|
@@ -21805,7 +22560,7 @@ var DaemonCore = class {
|
|
|
21805
22560
|
sinks: [this.localTraceSink]
|
|
21806
22561
|
}));
|
|
21807
22562
|
this.agentManager.setTracer(this.tracer);
|
|
21808
|
-
this.agentManager.setCliTransportTraceDir(
|
|
22563
|
+
this.agentManager.setCliTransportTraceDir(path20.join(machineDir, "traces"));
|
|
21809
22564
|
}
|
|
21810
22565
|
installTraceBundleUploader(machineDir) {
|
|
21811
22566
|
if (!this.shouldEnableLocalTrace()) return;
|
|
@@ -22094,7 +22849,7 @@ var DaemonCore = class {
|
|
|
22094
22849
|
session_id_present: Boolean(msg.config.sessionId)
|
|
22095
22850
|
}, "error");
|
|
22096
22851
|
this.connection.send({ type: "agent:status", agentId: msg.agentId, status: "inactive", launchId: msg.launchId });
|
|
22097
|
-
this.connection.send({ type: "agent:activity", agentId: msg.agentId, activity: "offline", detail: classification.userMessage, launchId: msg.launchId });
|
|
22852
|
+
this.connection.send({ type: "agent:activity", agentId: msg.agentId, activity: "offline", detail: classification.userMessage, launchId: msg.launchId, observedAtMs: Date.now() });
|
|
22098
22853
|
});
|
|
22099
22854
|
break;
|
|
22100
22855
|
case "agent:stop":
|
|
@@ -22514,6 +23269,10 @@ export {
|
|
|
22514
23269
|
resolveWorkspaceDirectoryPath,
|
|
22515
23270
|
scanWorkspaceDirectories,
|
|
22516
23271
|
deleteWorkspaceDirectory,
|
|
23272
|
+
AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION,
|
|
23273
|
+
buildAgentMigrationExportManifest,
|
|
23274
|
+
AgentMigrationGrantRegistry,
|
|
23275
|
+
createAgentMigrationHttpTransport,
|
|
22517
23276
|
DAEMON_CORE_TRACE_ATTR_CONTRACTS,
|
|
22518
23277
|
DAEMON_CLI_USAGE,
|
|
22519
23278
|
parseDaemonCliArgs,
|