@botiverse/raft-daemon 0.69.0 → 0.70.0-play.20260706142959
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-URPIDKXK.js → chunk-KBLDM5DN.js} +1058 -84
- package/dist/cli/index.js +874 -354
- package/dist/core.js +13 -1
- package/dist/{dist-P3SAWND7.js → dist-PAW4LJQD.js} +852 -350
- package/dist/index.js +5 -3
- 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),
|
|
@@ -2146,6 +2283,7 @@ var agentApiServerInfoResponseSchema = passthroughObject({
|
|
|
2146
2283
|
serverId: z2.string(),
|
|
2147
2284
|
machineId: z2.string().nullable().optional(),
|
|
2148
2285
|
machineName: z2.string().nullable().optional(),
|
|
2286
|
+
machineDescription: z2.string().nullable().optional(),
|
|
2149
2287
|
machineHostname: z2.string().nullable().optional(),
|
|
2150
2288
|
machineOs: z2.string().nullable().optional(),
|
|
2151
2289
|
daemonVersion: z2.string().nullable().optional(),
|
|
@@ -2225,7 +2363,12 @@ var agentApiIntegrationLoginResponseSchema = passthroughObject({
|
|
|
2225
2363
|
status: z2.enum(["logged_in", "already_logged_in", "approval_required"]),
|
|
2226
2364
|
service: agentApiIntegrationServiceSchema,
|
|
2227
2365
|
scopes: z2.array(z2.string()),
|
|
2228
|
-
requestId: z2.string(),
|
|
2366
|
+
requestId: z2.string().optional(),
|
|
2367
|
+
session: passthroughObject({
|
|
2368
|
+
status: z2.literal("stored"),
|
|
2369
|
+
source: z2.enum(["cache", "fresh"]),
|
|
2370
|
+
path: nullableStringSchema
|
|
2371
|
+
}).optional(),
|
|
2229
2372
|
approval: passthroughObject({
|
|
2230
2373
|
requestId: z2.string(),
|
|
2231
2374
|
target: nullableStringSchema,
|
|
@@ -3003,6 +3146,14 @@ var daemonApiContract = {
|
|
|
3003
3146
|
})
|
|
3004
3147
|
};
|
|
3005
3148
|
|
|
3149
|
+
// ../shared/src/authRefreshTiming.ts
|
|
3150
|
+
var AUTH_REFRESH_ROTATED_REPLAY_GRACE_MS = 1e4;
|
|
3151
|
+
var AUTH_REFRESH_ROTATION_DISCOVERY_LAG_BUDGET_MS = 1e3;
|
|
3152
|
+
var AUTH_REFRESH_ROTATED_TOKEN_WAIT_MS = 4e3;
|
|
3153
|
+
var AUTH_REFRESH_ROTATION_RETRY_RTT_BUDGET_MS = 1e3;
|
|
3154
|
+
var AUTH_REFRESH_ROTATION_LOSER_WORST_CHAIN_MS = AUTH_REFRESH_ROTATION_DISCOVERY_LAG_BUDGET_MS + AUTH_REFRESH_ROTATED_TOKEN_WAIT_MS + AUTH_REFRESH_ROTATION_RETRY_RTT_BUDGET_MS;
|
|
3155
|
+
var AUTH_REFRESH_ROTATION_REPLAY_GRACE_MARGIN_MS = AUTH_REFRESH_ROTATED_REPLAY_GRACE_MS - AUTH_REFRESH_ROTATION_LOSER_WORST_CHAIN_MS;
|
|
3156
|
+
|
|
3006
3157
|
// ../shared/src/agentInbox.ts
|
|
3007
3158
|
function formatAgentInboxDelta(rows, options = {}) {
|
|
3008
3159
|
const totalPendingMessages = options.totalPendingMessages;
|
|
@@ -3182,6 +3333,55 @@ var SUPPORTED_TRANSLATION_LANGUAGE_SET = new Set(
|
|
|
3182
3333
|
SUPPORTED_TRANSLATION_LANGUAGE_CODES
|
|
3183
3334
|
);
|
|
3184
3335
|
|
|
3336
|
+
// ../shared/src/oauthScopes.ts
|
|
3337
|
+
var RAFT_OAUTH_SCOPE_CATALOG = {
|
|
3338
|
+
openid: {
|
|
3339
|
+
phase: "identity",
|
|
3340
|
+
defaultAllowed: true,
|
|
3341
|
+
publicDiscovery: true,
|
|
3342
|
+
requiresResource: false,
|
|
3343
|
+
label: "OpenID identity"
|
|
3344
|
+
},
|
|
3345
|
+
profile: {
|
|
3346
|
+
phase: "identity",
|
|
3347
|
+
defaultAllowed: true,
|
|
3348
|
+
publicDiscovery: true,
|
|
3349
|
+
requiresResource: false,
|
|
3350
|
+
label: "Basic profile"
|
|
3351
|
+
},
|
|
3352
|
+
identity: {
|
|
3353
|
+
phase: "identity",
|
|
3354
|
+
defaultAllowed: true,
|
|
3355
|
+
publicDiscovery: true,
|
|
3356
|
+
requiresResource: false,
|
|
3357
|
+
label: "Raft identity card"
|
|
3358
|
+
},
|
|
3359
|
+
"agent:event:write": {
|
|
3360
|
+
phase: "agent_inbound",
|
|
3361
|
+
defaultAllowed: false,
|
|
3362
|
+
publicDiscovery: true,
|
|
3363
|
+
requiresResource: true,
|
|
3364
|
+
label: "Send structured events to an agent"
|
|
3365
|
+
},
|
|
3366
|
+
"agent:notification:write": {
|
|
3367
|
+
phase: "agent_inbound",
|
|
3368
|
+
defaultAllowed: false,
|
|
3369
|
+
publicDiscovery: true,
|
|
3370
|
+
requiresResource: true,
|
|
3371
|
+
label: "Send notifications to an agent"
|
|
3372
|
+
},
|
|
3373
|
+
"agent:action_request:write": {
|
|
3374
|
+
phase: "agent_inbound",
|
|
3375
|
+
defaultAllowed: false,
|
|
3376
|
+
publicDiscovery: false,
|
|
3377
|
+
requiresResource: true,
|
|
3378
|
+
label: "Request agent action"
|
|
3379
|
+
}
|
|
3380
|
+
};
|
|
3381
|
+
var RAFT_OAUTH_SCOPES_SUPPORTED = Object.keys(RAFT_OAUTH_SCOPE_CATALOG);
|
|
3382
|
+
var RAFT_OAUTH_DEFAULT_ALLOWED_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].defaultAllowed);
|
|
3383
|
+
var RAFT_OAUTH_PUBLIC_DISCOVERY_SCOPES = RAFT_OAUTH_SCOPES_SUPPORTED.filter((scope) => RAFT_OAUTH_SCOPE_CATALOG[scope].publicDiscovery);
|
|
3384
|
+
|
|
3185
3385
|
// ../shared/src/testing/failpoints.ts
|
|
3186
3386
|
var NoopFailpointRegistry = class {
|
|
3187
3387
|
get enabled() {
|
|
@@ -3739,6 +3939,8 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
3739
3939
|
}
|
|
3740
3940
|
};
|
|
3741
3941
|
var FREE_MONTHLY_FILE_UPLOAD_LIMIT_BYTES = 100 * 1024 * 1024;
|
|
3942
|
+
var FREE_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 50 * 1024 * 1024;
|
|
3943
|
+
var PRO_SINGLE_FILE_UPLOAD_LIMIT_BYTES = 200 * 1024 * 1024;
|
|
3742
3944
|
var TRIAL_START_DATE = /* @__PURE__ */ new Date("2026-04-18T00:00:00Z");
|
|
3743
3945
|
var TRIAL_END_DATE = /* @__PURE__ */ new Date("2026-06-23T12:00:00Z");
|
|
3744
3946
|
var TRIAL_DURATION_DAYS = (TRIAL_END_DATE.getTime() - TRIAL_START_DATE.getTime()) / (24 * 60 * 60 * 1e3);
|
|
@@ -4018,8 +4220,8 @@ async function executeResponseRequest(url, init, {
|
|
|
4018
4220
|
}
|
|
4019
4221
|
|
|
4020
4222
|
// src/directUploadCapability.ts
|
|
4021
|
-
function joinUrl(base,
|
|
4022
|
-
return `${base.replace(/\/+$/, "")}${
|
|
4223
|
+
function joinUrl(base, path21) {
|
|
4224
|
+
return `${base.replace(/\/+$/, "")}${path21}`;
|
|
4023
4225
|
}
|
|
4024
4226
|
function jsonHeaders(apiKey) {
|
|
4025
4227
|
return {
|
|
@@ -4237,7 +4439,7 @@ Threads are sub-conversations attached to a specific message. They let you discu
|
|
|
4237
4439
|
- When you receive a message from a thread (the target has a \`:shortid\` suffix), **always reply using that same target** to keep the conversation in the thread.
|
|
4238
4440
|
- **Start a new thread**: Use the \`msg=\` field from the header as the thread suffix. For example, if you see \`[target=#general msg=00000000 ...]\`, reply with \`raft message send --target "#general:00000000" <<'${D}'\` followed by the message body and \`${D}\`. The thread will be auto-created if it doesn't exist yet. Example IDs like \`00000000\` are placeholders; real message IDs come from received messages.
|
|
4239
4441
|
- When you send a message, the response includes the message ID. You can use it to start a thread on your own message.
|
|
4240
|
-
- You can read thread history: \`raft message read --
|
|
4442
|
+
- You can read thread history: \`raft message read --target "#general:00000000"\`
|
|
4241
4443
|
- You can stop receiving ordinary delivery for a thread with \`raft thread unfollow --target "#general:00000000"\`. Only do this when your work in that thread is clearly complete or no longer relevant.
|
|
4242
4444
|
- Threads cannot be nested \u2014 you cannot start a thread inside a thread.`;
|
|
4243
4445
|
}
|
|
@@ -4245,7 +4447,7 @@ function buildDiscoverySection() {
|
|
|
4245
4447
|
return `### Discovering people and channels
|
|
4246
4448
|
|
|
4247
4449
|
Call \`raft server info\` to see all channels in this server, which ones you have joined, other agents, and humans.
|
|
4248
|
-
Visible public channels may appear even when \`joined=false\`. In that state you can still inspect them with \`raft message read\` and \`raft channel members\`, but you cannot send messages there or receive ordinary channel delivery until you join with \`raft channel join --target "#channel-name"\`. Private channels require a human with access to add you. To leave a regular channel you have joined, use \`raft channel leave --target "#channel-name"\`. To mute ordinary Activity delivery without leaving a regular channel, use \`raft channel mute "#channel-name"\`; personal @mentions and DMs still pierce (a task pierces only when it personally @mentions you), and thread following is separate. To reverse that setting, use \`raft channel unmute "#channel-name"\`. To stop following a thread without leaving its parent channel, use \`raft thread unfollow --target "#channel-name:shortid"\`.
|
|
4450
|
+
Visible public channels may appear even when \`joined=false\`. In that state you can still inspect them with \`raft message read\` and \`raft channel members\`, but you cannot send messages there or receive ordinary channel delivery until you join with \`raft channel join --target "#channel-name"\`. Private channels require a human with access to add you. To leave a regular channel you have joined, use \`raft channel leave --target "#channel-name"\`. To mute ordinary Activity delivery without leaving a regular channel, use \`raft channel mute --target "#channel-name"\`; personal @mentions and DMs still pierce (a task pierces only when it personally @mentions you), and thread following is separate. To reverse that setting, use \`raft channel unmute --target "#channel-name"\`. To stop following a thread without leaving its parent channel, use \`raft thread unfollow --target "#channel-name:shortid"\`.
|
|
4249
4451
|
Private channels are membership-gated. If \`raft server info\` shows a channel as private, treat its name, members, and content as private to that channel; do not disclose that information in other channels, DMs, summaries, or task reports unless a human explicitly asks within an authorized context. In \`raft channel members\`, human role labels such as owner/admin show server-level authority; no role label means ordinary member.`;
|
|
4250
4452
|
}
|
|
4251
4453
|
function buildChannelAwarenessSection() {
|
|
@@ -4259,9 +4461,9 @@ Each channel has a **name** and optionally a **description** that define its pur
|
|
|
4259
4461
|
function buildReadingHistorySection() {
|
|
4260
4462
|
return `### Reading history
|
|
4261
4463
|
|
|
4262
|
-
\`raft message read --
|
|
4464
|
+
\`raft message read --target "#channel-name"\` or \`raft message read --target dm:@peer-name\` or \`raft message read --target "#channel:shortid"\`
|
|
4263
4465
|
|
|
4264
|
-
To jump directly to a specific hit with nearby context, use \`raft message read --
|
|
4466
|
+
To jump directly to a specific hit with nearby context, use \`raft message read --target "..." --around "messageId"\` or \`raft message read --target "..." --around 12345\`.`;
|
|
4265
4467
|
}
|
|
4266
4468
|
function buildHistoricalReferencesSection() {
|
|
4267
4469
|
return `### Historical references
|
|
@@ -4290,7 +4492,7 @@ Only top-level channel / DM messages can become tasks. Messages inside threads a
|
|
|
4290
4492
|
**Assignee** is independent from status \u2014 a task can be claimed or unclaimed at any status except \`done\`.
|
|
4291
4493
|
|
|
4292
4494
|
**Workflow:**
|
|
4293
|
-
1. Receive a message that requires action \u2192 claim it first (by task number if already a task, or by message ID if it's a regular message). Use repeat flags: \`raft task claim --
|
|
4495
|
+
1. Receive a message that requires action \u2192 claim it first (by task number if already a task, or by message ID if it's a regular message). Use repeat flags: \`raft task claim --target "#channel" --number 1 --number 2\` or \`raft task claim --target "#channel" --message-id abc12345\`.
|
|
4294
4496
|
2. If the claim fails, someone else is working on it \u2014 do not work on that task unless an owner/admin explicitly redirects it to you
|
|
4295
4497
|
3. Post updates in the task's thread: \`raft message send --target "#channel:msgShortId" <<'${D}'\` followed by the message body and \`${D}\`
|
|
4296
4498
|
4. When done, set status to \`in_review\` so a human can validate via \`raft task update\`
|
|
@@ -4302,7 +4504,7 @@ Only top-level channel / DM messages can become tasks. Messages inside threads a
|
|
|
4302
4504
|
- \`raft task create\` only creates the task \u2014 to own it, call \`raft task claim\` afterward.
|
|
4303
4505
|
- Typical uses for \`raft task create\` are breaking down a larger task into parallel subtasks, or batch-creating genuinely new work for others to claim.
|
|
4304
4506
|
- If someone already sent the work item as a message, just claim that existing message/task instead of creating a new one.
|
|
4305
|
-
- If the work already exists as a message, reuse it via \`raft task claim --
|
|
4507
|
+
- If the work already exists as a message, reuse it via \`raft task claim --target "#channel" --message-id abc12345\`.
|
|
4306
4508
|
|
|
4307
4509
|
**Creating new tasks:**
|
|
4308
4510
|
- The task system exists to prevent duplicate work. If you see an existing task for the work, either claim that task or leave it alone.
|
|
@@ -4521,7 +4723,7 @@ function buildPrompt(config, opts) {
|
|
|
4521
4723
|
const channelAwarenessSection = cliGuideSections.channelAwareness;
|
|
4522
4724
|
const thirdPartyIntegrationsSection = `### Third-party integrations
|
|
4523
4725
|
|
|
4524
|
-
If a built-in Slock app or registered third-party service requires login, use Slock Agent Login through the CLI instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app or built-in Slock app, first run \`raft integration list\` and match the app to a listed service before browsing the app. Use \`raft integration login --service <service>\` to provision or reuse your agent login for that service. If the service exposes manifest-backed HTTP API actions, prefer \`raft integration invoke --service <service> --list-actions\` and then \`raft integration invoke --service <service> --action <name>\`; the CLI
|
|
4726
|
+
If a built-in Slock app or registered third-party service requires login, use Slock Agent Login through the CLI instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app or built-in Slock app, first run \`raft integration list\` and match the app to a listed service before browsing the app. Use \`raft integration login --service <service>\` to provision or reuse your agent login for that service; the CLI consumes the one-time Agent Login handoff internally and stores the service-owned session for this agent, so the successful output should be \`Agent login ready\` / \`Already logged in\`, not a raw request code you need to keep. If the service exposes manifest-backed HTTP API actions, prefer \`raft integration invoke --service <service> --list-actions\` and then \`raft integration invoke --service <service> --action <name>\`; the CLI uses the stored service session or refreshes it internally. If the service exposes an agent behavior manifest and you need to run its local CLI, run \`raft integration env --service <service>\` before invoking that CLI; if it prints exports, apply them first so service credentials stay under a per-agent profile HOME/XDG tree instead of the host user's global HOME. If it reports that no local env is required, do not invent HOME/XDG overrides; for HTTP API action services, use \`raft integration invoke\` instead. If it fails, do not run that local CLI with the host user's HOME; report that the service manifest is unsupported. Slock does not execute local commands from remote manifests automatically. If the CLI reports that the \`integration\` command is unknown, the local daemon/CLI is too old for Slock Agent Login; report that the machine must be upgraded/restarted instead of calling internal HTTP endpoints yourself. Do not store or reuse raw \`oauth_access_request\` request codes; those are one-time compatibility handoffs for services to exchange once for their own session/token. Prefer \`raft integration invoke\` over manually opening or curling callback URLs. Do not crawl third-party routes looking for a session before trying the registered-service login path. Do not open the human \`Login with Slock\` browser flow, use internal request IDs as OAuth callback codes outside the documented CLI flow, call internal Slock integration endpoints directly, or call third-party exchange endpoints unless a human explicitly asks you to debug that server-to-server protocol. If the service or human asks for your Slock Agent identity card, use \`raft profile show\`. Third-party pages may show \`Login with Slock\`; for agent-facing access, prefer the listed service / Slock Agent Login path.`;
|
|
4525
4727
|
const readingHistorySection = cliGuideSections.readingHistory;
|
|
4526
4728
|
const historicalReferenceSection = cliGuideSections.historicalReferences;
|
|
4527
4729
|
const tasksSection = cliGuideSections.tasks;
|
|
@@ -4709,6 +4911,19 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
4709
4911
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
4710
4912
|
}
|
|
4711
4913
|
|
|
4914
|
+
// src/authEnv.ts
|
|
4915
|
+
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
4916
|
+
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
4917
|
+
function scrubDaemonAuthEnv(env) {
|
|
4918
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
4919
|
+
return env;
|
|
4920
|
+
}
|
|
4921
|
+
function scrubDaemonChildEnv(env) {
|
|
4922
|
+
delete env[DAEMON_API_KEY_ENV];
|
|
4923
|
+
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
4924
|
+
return env;
|
|
4925
|
+
}
|
|
4926
|
+
|
|
4712
4927
|
// src/agentCredentialProxy.ts
|
|
4713
4928
|
import { randomBytes } from "crypto";
|
|
4714
4929
|
import http from "http";
|
|
@@ -5652,7 +5867,7 @@ function shortMessageId2(value) {
|
|
|
5652
5867
|
return value.slice(0, 8);
|
|
5653
5868
|
}
|
|
5654
5869
|
function normalizeSenderType(value) {
|
|
5655
|
-
return value === "human" || value === "agent" || value === "system" ? value : void 0;
|
|
5870
|
+
return value === "human" || value === "agent" || value === "system" || value === "third_party_app" ? value : void 0;
|
|
5656
5871
|
}
|
|
5657
5872
|
function nonEmptyString(value) {
|
|
5658
5873
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -6040,6 +6255,10 @@ async function readRequestBody(req) {
|
|
|
6040
6255
|
function messageSeq3(message) {
|
|
6041
6256
|
return Number(message.seq ?? 0);
|
|
6042
6257
|
}
|
|
6258
|
+
function isThirdPartyAgentEvent(message) {
|
|
6259
|
+
const thirdPartyEvent = message.third_party_event;
|
|
6260
|
+
return typeof thirdPartyEvent?.id === "string" && thirdPartyEvent.id.length > 0;
|
|
6261
|
+
}
|
|
6043
6262
|
function localAgentApiInboxResponse(registration) {
|
|
6044
6263
|
const coordinator = registration.inboxCoordinator;
|
|
6045
6264
|
if (!coordinator) return void 0;
|
|
@@ -6090,6 +6309,7 @@ function localAgentApiEventsResponse(registration, target) {
|
|
|
6090
6309
|
const normalized = sortInboxMessagesBySeq(normalizeInboxVisibleMessages(pending));
|
|
6091
6310
|
const filtered = parsedQuery.sinceSeq !== null ? normalized.filter((message) => {
|
|
6092
6311
|
const seq = messageSeq3(message);
|
|
6312
|
+
if ((!Number.isFinite(seq) || seq <= 0) && isThirdPartyAgentEvent(message)) return true;
|
|
6093
6313
|
return Number.isFinite(seq) && seq > parsedQuery.sinceSeq;
|
|
6094
6314
|
}) : normalized;
|
|
6095
6315
|
const events = filtered.slice(0, parsedQuery.limit);
|
|
@@ -6283,7 +6503,9 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
|
|
|
6283
6503
|
var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
|
|
6284
6504
|
var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
|
|
6285
6505
|
var RAW_CREDENTIAL_ENV_DENYLIST = [
|
|
6286
|
-
"
|
|
6506
|
+
"SLOCK_AGENT_TOKEN",
|
|
6507
|
+
"SLOCK_AGENT_CREDENTIAL_KEY",
|
|
6508
|
+
"SLOCK_AGENT_CREDENTIAL_KEY_FILE"
|
|
6287
6509
|
];
|
|
6288
6510
|
var WORKSPACE_CLI_TRANSPORT_FILENAMES = [
|
|
6289
6511
|
"agent-token",
|
|
@@ -6638,7 +6860,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
|
|
|
6638
6860
|
SLOCK_SERVER_URL: ctx.config.serverUrl,
|
|
6639
6861
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
6640
6862
|
};
|
|
6641
|
-
|
|
6863
|
+
scrubDaemonChildEnv(spawnEnv);
|
|
6642
6864
|
for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
|
|
6643
6865
|
delete spawnEnv[key];
|
|
6644
6866
|
}
|
|
@@ -7206,7 +7428,7 @@ function requiresWindowsShell(command, platform = process.platform) {
|
|
|
7206
7428
|
}
|
|
7207
7429
|
function resolveCommandOnPath(command, deps = {}) {
|
|
7208
7430
|
const platform = deps.platform ?? process.platform;
|
|
7209
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
7431
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
7210
7432
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
7211
7433
|
const existsSyncFn = deps.existsSyncFn ?? existsSync3;
|
|
7212
7434
|
if (platform === "win32") {
|
|
@@ -7232,7 +7454,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
7232
7454
|
return null;
|
|
7233
7455
|
}
|
|
7234
7456
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
7235
|
-
const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
|
|
7457
|
+
const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
|
|
7236
7458
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
7237
7459
|
try {
|
|
7238
7460
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -7658,7 +7880,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7658
7880
|
return null;
|
|
7659
7881
|
}
|
|
7660
7882
|
const sessionId = codexMessageThreadId(message);
|
|
7661
|
-
const
|
|
7883
|
+
const path21 = boundedString(params.path);
|
|
7662
7884
|
return {
|
|
7663
7885
|
kind: "runtime_diagnostic",
|
|
7664
7886
|
severity: "warning",
|
|
@@ -7666,7 +7888,7 @@ function codexNotificationDiagnosticEvent(message) {
|
|
|
7666
7888
|
itemType: message.method,
|
|
7667
7889
|
message: diagnosticMessage,
|
|
7668
7890
|
...details ? { details } : {},
|
|
7669
|
-
...
|
|
7891
|
+
...path21 ? { path: path21 } : {},
|
|
7670
7892
|
...params.range !== void 0 ? { range: params.range } : {},
|
|
7671
7893
|
payloadBytes: payloadBytes(params),
|
|
7672
7894
|
...sessionId ? { sessionId } : {}
|
|
@@ -9316,11 +9538,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
9316
9538
|
return parseCursorModelsOutput(String(result.stdout || ""));
|
|
9317
9539
|
}
|
|
9318
9540
|
function buildCursorModelProbeEnv(deps = {}) {
|
|
9319
|
-
return withWindowsUserEnvironment({
|
|
9541
|
+
return scrubDaemonChildEnv(withWindowsUserEnvironment({
|
|
9320
9542
|
...deps.env ?? process.env,
|
|
9321
9543
|
FORCE_COLOR: "0",
|
|
9322
9544
|
NO_COLOR: "1"
|
|
9323
|
-
}, deps);
|
|
9545
|
+
}, deps));
|
|
9324
9546
|
}
|
|
9325
9547
|
function runCursorModelsCommand() {
|
|
9326
9548
|
return spawnSync("cursor-agent", ["models"], {
|
|
@@ -9376,7 +9598,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
9376
9598
|
}
|
|
9377
9599
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
9378
9600
|
const existsSyncFn = deps.existsSyncFn ?? existsSync5;
|
|
9379
|
-
const env = deps.env ?? process.env;
|
|
9601
|
+
const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
|
|
9380
9602
|
const winPath = path8.win32;
|
|
9381
9603
|
let geminiEntry = null;
|
|
9382
9604
|
try {
|
|
@@ -9513,12 +9735,15 @@ var GeminiDriver = class {
|
|
|
9513
9735
|
// src/drivers/kimi.ts
|
|
9514
9736
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
9515
9737
|
import { spawn as spawn7 } from "child_process";
|
|
9516
|
-
import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
9738
|
+
import { chmodSync, existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
|
|
9517
9739
|
import os4 from "os";
|
|
9518
9740
|
import path9 from "path";
|
|
9519
9741
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
9520
9742
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
9521
9743
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
9744
|
+
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
9745
|
+
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
9746
|
+
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
9522
9747
|
function parseToolArguments(raw) {
|
|
9523
9748
|
if (typeof raw !== "string") return raw;
|
|
9524
9749
|
try {
|
|
@@ -9527,6 +9752,73 @@ function parseToolArguments(raw) {
|
|
|
9527
9752
|
return raw;
|
|
9528
9753
|
}
|
|
9529
9754
|
}
|
|
9755
|
+
function readKimiConfigSource(home = os4.homedir(), env = process.env) {
|
|
9756
|
+
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
9757
|
+
if (inlineConfig && inlineConfig.trim()) {
|
|
9758
|
+
return {
|
|
9759
|
+
raw: inlineConfig,
|
|
9760
|
+
explicitPath: null,
|
|
9761
|
+
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
9762
|
+
};
|
|
9763
|
+
}
|
|
9764
|
+
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
9765
|
+
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
|
|
9766
|
+
try {
|
|
9767
|
+
return {
|
|
9768
|
+
raw: readFileSync3(configPath, "utf8"),
|
|
9769
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
9770
|
+
sourcePath: configPath
|
|
9771
|
+
};
|
|
9772
|
+
} catch {
|
|
9773
|
+
return {
|
|
9774
|
+
raw: null,
|
|
9775
|
+
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
9776
|
+
sourcePath: configPath
|
|
9777
|
+
};
|
|
9778
|
+
}
|
|
9779
|
+
}
|
|
9780
|
+
function buildKimiSpawnEnv(env = process.env) {
|
|
9781
|
+
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
9782
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
9783
|
+
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
9784
|
+
return scrubDaemonChildEnv(spawnEnv);
|
|
9785
|
+
}
|
|
9786
|
+
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
9787
|
+
return {
|
|
9788
|
+
...process.env,
|
|
9789
|
+
...ctx.config.envVars || {},
|
|
9790
|
+
...overrideEnv || {}
|
|
9791
|
+
};
|
|
9792
|
+
}
|
|
9793
|
+
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
9794
|
+
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
9795
|
+
const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
|
|
9796
|
+
const args = [];
|
|
9797
|
+
let configFilePath = null;
|
|
9798
|
+
let configContent = null;
|
|
9799
|
+
if (source.explicitPath) {
|
|
9800
|
+
configFilePath = source.explicitPath;
|
|
9801
|
+
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
9802
|
+
configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
9803
|
+
configContent = source.raw;
|
|
9804
|
+
if (opts.writeGeneratedConfig !== false) {
|
|
9805
|
+
writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
9806
|
+
chmodSync(configFilePath, 384);
|
|
9807
|
+
}
|
|
9808
|
+
}
|
|
9809
|
+
if (configFilePath) {
|
|
9810
|
+
args.push("--config-file", configFilePath);
|
|
9811
|
+
}
|
|
9812
|
+
if (ctx.config.model && ctx.config.model !== "default") {
|
|
9813
|
+
args.push("--model", ctx.config.model);
|
|
9814
|
+
}
|
|
9815
|
+
return {
|
|
9816
|
+
args,
|
|
9817
|
+
env: buildKimiSpawnEnv(env),
|
|
9818
|
+
configFilePath,
|
|
9819
|
+
configContent
|
|
9820
|
+
};
|
|
9821
|
+
}
|
|
9530
9822
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
9531
9823
|
return {
|
|
9532
9824
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -9550,7 +9842,25 @@ var KimiDriver = class {
|
|
|
9550
9842
|
};
|
|
9551
9843
|
model = {
|
|
9552
9844
|
detectedModelsVerifiedAs: "launchable",
|
|
9553
|
-
toLaunchSpec: (modelId) =>
|
|
9845
|
+
toLaunchSpec: (modelId, ctx, opts) => {
|
|
9846
|
+
if (!ctx) return { args: ["--model", modelId] };
|
|
9847
|
+
const launchCtx = {
|
|
9848
|
+
...ctx,
|
|
9849
|
+
config: {
|
|
9850
|
+
...ctx.config,
|
|
9851
|
+
model: modelId
|
|
9852
|
+
}
|
|
9853
|
+
};
|
|
9854
|
+
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
9855
|
+
home: opts?.home,
|
|
9856
|
+
writeGeneratedConfig: false
|
|
9857
|
+
});
|
|
9858
|
+
return {
|
|
9859
|
+
args: launch.args,
|
|
9860
|
+
env: launch.env,
|
|
9861
|
+
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
9862
|
+
};
|
|
9863
|
+
}
|
|
9554
9864
|
};
|
|
9555
9865
|
supportsStdinNotification = true;
|
|
9556
9866
|
busyDeliveryMode = "direct";
|
|
@@ -9574,21 +9884,23 @@ var KimiDriver = class {
|
|
|
9574
9884
|
` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
|
|
9575
9885
|
""
|
|
9576
9886
|
].join("\n"), "utf8");
|
|
9887
|
+
const launch = buildKimiLaunchOptions(ctx);
|
|
9577
9888
|
const args = [
|
|
9578
9889
|
"--wire",
|
|
9579
9890
|
"--yolo",
|
|
9580
9891
|
"--agent-file",
|
|
9581
9892
|
agentFilePath,
|
|
9582
9893
|
"--session",
|
|
9583
|
-
this.sessionId
|
|
9894
|
+
this.sessionId,
|
|
9895
|
+
...launch.args
|
|
9584
9896
|
];
|
|
9585
9897
|
const launchRuntimeFields = runtimeConfigToLaunchFields(hydrateRuntimeConfig(ctx.config));
|
|
9586
9898
|
if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
|
|
9587
9899
|
args.push("--model", launchRuntimeFields.model);
|
|
9588
9900
|
}
|
|
9589
9901
|
const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
|
|
9590
|
-
const
|
|
9591
|
-
const proc = spawn7(
|
|
9902
|
+
const spawnTarget = resolveKimiSpawn(args);
|
|
9903
|
+
const proc = spawn7(spawnTarget.command, spawnTarget.args, {
|
|
9592
9904
|
cwd: ctx.workingDirectory,
|
|
9593
9905
|
stdio: ["pipe", "pipe", "pipe"],
|
|
9594
9906
|
env: spawnEnv,
|
|
@@ -9596,7 +9908,7 @@ var KimiDriver = class {
|
|
|
9596
9908
|
// and has an 8191-character command-line limit. Kimi's official
|
|
9597
9909
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
9598
9910
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
9599
|
-
shell:
|
|
9911
|
+
shell: spawnTarget.shell
|
|
9600
9912
|
});
|
|
9601
9913
|
proc.stdin?.write(JSON.stringify({
|
|
9602
9914
|
jsonrpc: "2.0",
|
|
@@ -9709,14 +10021,9 @@ var KimiDriver = class {
|
|
|
9709
10021
|
return detectKimiModels();
|
|
9710
10022
|
}
|
|
9711
10023
|
};
|
|
9712
|
-
function detectKimiModels(home = os4.homedir()) {
|
|
9713
|
-
const
|
|
9714
|
-
|
|
9715
|
-
try {
|
|
9716
|
-
raw = readFileSync3(configPath, "utf8");
|
|
9717
|
-
} catch {
|
|
9718
|
-
return null;
|
|
9719
|
-
}
|
|
10024
|
+
function detectKimiModels(home = os4.homedir(), opts = {}) {
|
|
10025
|
+
const raw = readKimiConfigSource(home, opts.env).raw;
|
|
10026
|
+
if (raw === null) return null;
|
|
9720
10027
|
const models = [];
|
|
9721
10028
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
9722
10029
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -10382,7 +10689,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
|
|
|
10382
10689
|
const platform = deps.platform ?? process.platform;
|
|
10383
10690
|
const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
|
|
10384
10691
|
const result = spawnSyncFn("opencode", ["models"], {
|
|
10385
|
-
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
10692
|
+
env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
|
|
10386
10693
|
encoding: "utf8",
|
|
10387
10694
|
timeout: 5e3,
|
|
10388
10695
|
shell: platform === "win32"
|
|
@@ -12524,6 +12831,9 @@ function computeTarget(channelType, channelName, parentChannelName, parentChanne
|
|
|
12524
12831
|
return `#${channelName}`;
|
|
12525
12832
|
}
|
|
12526
12833
|
function formatAgentMessageVisibleTarget(message) {
|
|
12834
|
+
if (message.third_party_event) {
|
|
12835
|
+
return `agent-event:${getMessageShortId(message.third_party_event.id)}`;
|
|
12836
|
+
}
|
|
12527
12837
|
return computeTarget(message.channel_type, message.channel_name, message.parent_channel_name, message.parent_channel_type);
|
|
12528
12838
|
}
|
|
12529
12839
|
function formatProxyVisibleMessageTarget(message) {
|
|
@@ -13371,24 +13681,38 @@ function safeSessionFilename(value) {
|
|
|
13371
13681
|
const normalized = value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
13372
13682
|
return normalized || "unknown-session";
|
|
13373
13683
|
}
|
|
13374
|
-
function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
|
|
13684
|
+
function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir, join, resolve) {
|
|
13375
13685
|
try {
|
|
13376
13686
|
const dir = path14.join(fallbackDir, ".slock", "runtime-sessions");
|
|
13377
13687
|
mkdirSync4(dir, { recursive: true });
|
|
13378
13688
|
const filePath = path14.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
|
|
13689
|
+
const searchedPaths = resolve?.searchedPaths ?? [];
|
|
13379
13690
|
writeFileSync4(filePath, JSON.stringify({
|
|
13380
13691
|
type: "runtime_session_handoff",
|
|
13381
13692
|
runtime,
|
|
13382
13693
|
sessionId,
|
|
13694
|
+
// Persisted L1<->L2 join keys (#460 V3): without these the
|
|
13695
|
+
// session->launch mapping lives only in daemon memory and old L1
|
|
13696
|
+
// transcripts can never re-join their launch after restart/adopt.
|
|
13697
|
+
// ids-only, closed fields (no content payload).
|
|
13698
|
+
launchId: join?.launchId ?? null,
|
|
13699
|
+
processInstanceId: join?.processInstanceId ?? null,
|
|
13700
|
+
// Negative-space (fruit#0 pt2): a resolve-miss is explicit evidence, not a
|
|
13701
|
+
// silent "not found". Recording the lookup method + the directories checked
|
|
13702
|
+
// makes "looked in the wrong place" distinguishable from "looked in the right
|
|
13703
|
+
// place and it is genuinely absent". ids/paths only — no transcript content.
|
|
13704
|
+
resolveStatus: "transcript_resolve_missing",
|
|
13705
|
+
lookupMethod: resolve?.lookupMethod ?? "none",
|
|
13706
|
+
searchedPaths,
|
|
13383
13707
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13384
|
-
note: "The native runtime transcript file was not found on this machine; this daemon-created handoff records the runtime session identity for diagnostics."
|
|
13708
|
+
note: "The native runtime transcript file was not found on this machine; this daemon-created handoff records the runtime session identity + the directories checked for diagnostics."
|
|
13385
13709
|
}) + "\n", { mode: 384 });
|
|
13386
13710
|
return {
|
|
13387
13711
|
label: sessionId,
|
|
13388
13712
|
path: filePath,
|
|
13389
13713
|
runtime,
|
|
13390
13714
|
reachable: true,
|
|
13391
|
-
reason:
|
|
13715
|
+
reason: `native session file path not found; using daemon handoff file; searched=[${searchedPaths.join(", ")}]`
|
|
13392
13716
|
};
|
|
13393
13717
|
} catch {
|
|
13394
13718
|
return null;
|
|
@@ -13413,12 +13737,16 @@ function ensureRuntimeHomeDir(config, defaultHomeDir, workspacePath, opts = {})
|
|
|
13413
13737
|
function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), fallbackDir, opts) {
|
|
13414
13738
|
let resolvedPath = null;
|
|
13415
13739
|
let lookupMethod = "none";
|
|
13740
|
+
const searchedPaths = [];
|
|
13416
13741
|
if (runtime === "claude") {
|
|
13417
13742
|
lookupMethod = "claude_jsonl";
|
|
13418
|
-
|
|
13743
|
+
const claudeRoot = path14.join(homeDir, ".claude", "projects");
|
|
13744
|
+
searchedPaths.push(claudeRoot);
|
|
13745
|
+
resolvedPath = findSessionJsonl(claudeRoot, (filename) => filename === `${sessionId}.jsonl`);
|
|
13419
13746
|
} else if (runtime === "codex") {
|
|
13420
13747
|
lookupMethod = "codex_jsonl";
|
|
13421
13748
|
for (const root of codexSessionRootCandidates(homeDir)) {
|
|
13749
|
+
searchedPaths.push(root);
|
|
13422
13750
|
resolvedPath = findSessionJsonl(root, (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId));
|
|
13423
13751
|
if (resolvedPath) break;
|
|
13424
13752
|
}
|
|
@@ -13430,7 +13758,13 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), f
|
|
|
13430
13758
|
resolvedPath = findPiSessionFile2(sessionId, opts?.workingDirectory, homeDir);
|
|
13431
13759
|
}
|
|
13432
13760
|
if (!resolvedPath && fallbackDir) {
|
|
13433
|
-
const fallback = writeRuntimeSessionHandoff(
|
|
13761
|
+
const fallback = writeRuntimeSessionHandoff(
|
|
13762
|
+
runtime,
|
|
13763
|
+
sessionId,
|
|
13764
|
+
fallbackDir,
|
|
13765
|
+
{ launchId: opts?.launchId, processInstanceId: opts?.processInstanceId },
|
|
13766
|
+
{ lookupMethod, searchedPaths }
|
|
13767
|
+
);
|
|
13434
13768
|
if (fallback) {
|
|
13435
13769
|
return {
|
|
13436
13770
|
...fallback,
|
|
@@ -13445,7 +13779,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), f
|
|
|
13445
13779
|
reachable: Boolean(resolvedPath)
|
|
13446
13780
|
};
|
|
13447
13781
|
if (!resolvedPath) {
|
|
13448
|
-
ref.reason = `session file path not found; attempted_lookup=${lookupMethod}`;
|
|
13782
|
+
ref.reason = `session file path not found; attempted_lookup=${lookupMethod}; searched=[${searchedPaths.join(", ")}]`;
|
|
13449
13783
|
}
|
|
13450
13784
|
return ref;
|
|
13451
13785
|
}
|
|
@@ -13499,7 +13833,7 @@ function formatIncomingMessage(message, options = {}) {
|
|
|
13499
13833
|
`[Slock thread context: you were added to a new thread via @mention.]`,
|
|
13500
13834
|
`parent: ${message.thread_join_context.parent_target}`,
|
|
13501
13835
|
`thread: ${message.thread_join_context.thread_target}`,
|
|
13502
|
-
`suggested next step: raft message read --
|
|
13836
|
+
`suggested next step: raft message read --target "${message.thread_join_context.suggested_read_history_target}"`,
|
|
13503
13837
|
"",
|
|
13504
13838
|
"Parent message:",
|
|
13505
13839
|
formatThreadContextMessage(message.thread_join_context.parent_message),
|
|
@@ -15329,7 +15663,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15329
15663
|
detailKind: activity.statusEntry.detailKind ?? "daemon_activity",
|
|
15330
15664
|
entries: activity.entries,
|
|
15331
15665
|
launchId: ap?.launchId || void 0,
|
|
15332
|
-
clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0
|
|
15666
|
+
clientSeq: ap ? this.nextActivityClientSeq(agentId) : void 0,
|
|
15667
|
+
isHeartbeat: false
|
|
15333
15668
|
});
|
|
15334
15669
|
}
|
|
15335
15670
|
recordRuntimeDiagnosticActivity(agentId, ap, event) {
|
|
@@ -15342,7 +15677,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15342
15677
|
detailKind: ap.lastActivityDetailKind || "none",
|
|
15343
15678
|
entries: [runtimeDiagnosticTrajectoryEntry(event)],
|
|
15344
15679
|
launchId: ap.launchId || void 0,
|
|
15345
|
-
clientSeq: this.nextActivityClientSeq(agentId)
|
|
15680
|
+
clientSeq: this.nextActivityClientSeq(agentId),
|
|
15681
|
+
isHeartbeat: false
|
|
15346
15682
|
});
|
|
15347
15683
|
this.recordDaemonTrace("daemon.runtime.diagnostic", {
|
|
15348
15684
|
agentId,
|
|
@@ -15393,7 +15729,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15393
15729
|
detailKind: ap.lastActivityDetailKind || "none",
|
|
15394
15730
|
entries: [runtimeRecoveryTrajectoryEntry(event)],
|
|
15395
15731
|
launchId: ap.launchId || void 0,
|
|
15396
|
-
clientSeq: this.nextActivityClientSeq(agentId)
|
|
15732
|
+
clientSeq: this.nextActivityClientSeq(agentId),
|
|
15733
|
+
isHeartbeat: false
|
|
15397
15734
|
});
|
|
15398
15735
|
this.recordDaemonTrace("daemon.runtime.recovery.visible", {
|
|
15399
15736
|
agentId,
|
|
@@ -15641,7 +15978,8 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
15641
15978
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
15642
15979
|
config: this.buildRestartSafeConfig(ap.config, nextConfigSessionId),
|
|
15643
15980
|
sessionId: nextConfigSessionId,
|
|
15644
|
-
launchId: nextLaunchId
|
|
15981
|
+
launchId: nextLaunchId,
|
|
15982
|
+
processInstanceId: ap.processInstanceId
|
|
15645
15983
|
});
|
|
15646
15984
|
this.recordStartRebind(agentId, start, reason, previousLaunchId, nextLaunchId, nextSessionId);
|
|
15647
15985
|
this.sendAgentStatus(agentId, "active", nextLaunchId);
|
|
@@ -16072,6 +16410,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16072
16410
|
config: this.buildRestartSafeConfig(runtimeConfig, runtimeConfig.sessionId || null),
|
|
16073
16411
|
sessionId: runtimeConfig.sessionId || null,
|
|
16074
16412
|
launchId: effectiveLaunchId
|
|
16413
|
+
// No live AgentProcess in this adoption branch — omit rather than
|
|
16414
|
+
// fabricate; the marker's processInstanceId is nullable by contract.
|
|
16075
16415
|
});
|
|
16076
16416
|
this.sendAgentStatus(agentId, "active", effectiveLaunchId);
|
|
16077
16417
|
this.broadcastActivity(agentId, "online", "Process idle", [], void 0, "idle");
|
|
@@ -16161,7 +16501,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16161
16501
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16162
16502
|
config: this.buildRestartSafeConfig(runtimeConfig, restartSessionId),
|
|
16163
16503
|
sessionId: restartSessionId,
|
|
16164
|
-
launchId: effectiveLaunchId
|
|
16504
|
+
launchId: effectiveLaunchId,
|
|
16505
|
+
processInstanceId: agentProcess.processInstanceId
|
|
16165
16506
|
});
|
|
16166
16507
|
if (pendingStartRebind) {
|
|
16167
16508
|
this.recordStartRebind(agentId, pendingStartRebind, "startup_registered", originalLaunchId, effectiveLaunchId, agentProcess.sessionId);
|
|
@@ -16363,7 +16704,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16363
16704
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16364
16705
|
config: nextConfig,
|
|
16365
16706
|
sessionId: ap.sessionId,
|
|
16366
|
-
launchId: ap.launchId
|
|
16707
|
+
launchId: ap.launchId,
|
|
16708
|
+
processInstanceId: ap.processInstanceId
|
|
16367
16709
|
});
|
|
16368
16710
|
this.broadcastMessageReceivedActivity(agentId);
|
|
16369
16711
|
this.lifecycleRecords.deleteRestartSnapshot(agentId);
|
|
@@ -16381,7 +16723,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16381
16723
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16382
16724
|
config: nextConfig,
|
|
16383
16725
|
sessionId: ap.sessionId,
|
|
16384
|
-
launchId: ap.launchId
|
|
16726
|
+
launchId: ap.launchId,
|
|
16727
|
+
processInstanceId: ap.processInstanceId
|
|
16385
16728
|
});
|
|
16386
16729
|
const report = this.recordSpawnFailure(agentId, "runner_credential_mint");
|
|
16387
16730
|
this.assertStartPendingDeliveryInvariants("queued-continuation-runner-credential-mint-failure");
|
|
@@ -16401,7 +16744,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16401
16744
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16402
16745
|
config: nextConfig,
|
|
16403
16746
|
sessionId: ap.sessionId,
|
|
16404
|
-
launchId: ap.launchId
|
|
16747
|
+
launchId: ap.launchId,
|
|
16748
|
+
processInstanceId: ap.processInstanceId
|
|
16405
16749
|
});
|
|
16406
16750
|
this.broadcastActivity(agentId, "online", "Process idle", [], void 0, "idle");
|
|
16407
16751
|
});
|
|
@@ -16410,7 +16754,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16410
16754
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16411
16755
|
config: this.buildRestartSafeConfig(ap.config, ap.sessionId),
|
|
16412
16756
|
sessionId: ap.sessionId,
|
|
16413
|
-
launchId: ap.launchId
|
|
16757
|
+
launchId: ap.launchId,
|
|
16758
|
+
processInstanceId: ap.processInstanceId
|
|
16414
16759
|
});
|
|
16415
16760
|
if (!ap.driver.supportsStdinNotification) {
|
|
16416
16761
|
logger.info(`[Agent ${agentId}] Turn completed; cached idle state for future restart`);
|
|
@@ -16422,7 +16767,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16422
16767
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16423
16768
|
config: this.buildRestartSafeConfig(ap.config, ap.sessionId),
|
|
16424
16769
|
sessionId: ap.sessionId,
|
|
16425
|
-
launchId: ap.launchId
|
|
16770
|
+
launchId: ap.launchId,
|
|
16771
|
+
processInstanceId: ap.processInstanceId
|
|
16426
16772
|
});
|
|
16427
16773
|
logger.warn(`[Agent ${agentId}] Recoverable provider stream failure (${reason}) \u2014 keeping agent wakeable`);
|
|
16428
16774
|
this.sendAgentStatus(agentId, "active", ap.launchId);
|
|
@@ -16638,7 +16984,8 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
16638
16984
|
this.lifecycleRecords.setRestartSnapshot(agentId, {
|
|
16639
16985
|
config: retryConfig,
|
|
16640
16986
|
sessionId: retrySessionId,
|
|
16641
|
-
launchId: ap.launchId
|
|
16987
|
+
launchId: ap.launchId,
|
|
16988
|
+
processInstanceId: ap.processInstanceId
|
|
16642
16989
|
});
|
|
16643
16990
|
this.recordDaemonTrace("daemon.agent.startup_timeout.retry_config_cached", {
|
|
16644
16991
|
agentId,
|
|
@@ -17552,7 +17899,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17552
17899
|
}
|
|
17553
17900
|
return result;
|
|
17554
17901
|
}
|
|
17555
|
-
buildRuntimeProfileReport(agentId, config, sessionId, launchId, observedRuntimeHomeDir) {
|
|
17902
|
+
buildRuntimeProfileReport(agentId, config, sessionId, launchId, observedRuntimeHomeDir, processInstanceId) {
|
|
17556
17903
|
const workspacePath = path14.join(this.dataDir, agentId);
|
|
17557
17904
|
const runtimeHomeDir = observedRuntimeHomeDir || resolveRuntimeHomeDir(config, this.runtimeSessionHomeDir, workspacePath, { agentId, slockHome: this.slockHome });
|
|
17558
17905
|
return {
|
|
@@ -17568,7 +17915,16 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17568
17915
|
path: workspacePath,
|
|
17569
17916
|
reachable: true
|
|
17570
17917
|
},
|
|
17571
|
-
sessionRef: sessionId ? resolveRuntimeSessionRef(config.runtime, sessionId, runtimeHomeDir, workspacePath, {
|
|
17918
|
+
sessionRef: sessionId ? resolveRuntimeSessionRef(config.runtime, sessionId, runtimeHomeDir, workspacePath, {
|
|
17919
|
+
agentId,
|
|
17920
|
+
workingDirectory: workspacePath,
|
|
17921
|
+
// Join keys come from the CALLER's context (running agent OR idle
|
|
17922
|
+
// restart snapshot) — reading only live state here left the
|
|
17923
|
+
// restart/adopt path writing launchId:null markers, exactly the
|
|
17924
|
+
// V3 class this exists to close (Leiysky review on #3863).
|
|
17925
|
+
launchId: launchId || void 0,
|
|
17926
|
+
processInstanceId: processInstanceId ?? this.agents.get(agentId)?.processInstanceId
|
|
17927
|
+
}) : null
|
|
17572
17928
|
}
|
|
17573
17929
|
};
|
|
17574
17930
|
}
|
|
@@ -17580,12 +17936,13 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17580
17936
|
running.config,
|
|
17581
17937
|
running.sessionId,
|
|
17582
17938
|
running.launchId,
|
|
17583
|
-
running.runtime.currentRuntimeHomeDir
|
|
17939
|
+
running.runtime.currentRuntimeHomeDir,
|
|
17940
|
+
running.processInstanceId
|
|
17584
17941
|
);
|
|
17585
17942
|
}
|
|
17586
17943
|
const idle = this.lifecycleRecords.getRestartSnapshot(agentId);
|
|
17587
17944
|
if (idle) {
|
|
17588
|
-
return this.buildRuntimeProfileReport(agentId, idle.config, idle.sessionId, idle.launchId);
|
|
17945
|
+
return this.buildRuntimeProfileReport(agentId, idle.config, idle.sessionId, idle.launchId, null, idle.processInstanceId);
|
|
17589
17946
|
}
|
|
17590
17947
|
return null;
|
|
17591
17948
|
}
|
|
@@ -17983,7 +18340,9 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
17983
18340
|
}
|
|
17984
18341
|
const ref = resolveRuntimeSessionRef(runtime, actualSessionId, homeDir, workspaceDir, {
|
|
17985
18342
|
agentId,
|
|
17986
|
-
workingDirectory: workspaceDir
|
|
18343
|
+
workingDirectory: workspaceDir,
|
|
18344
|
+
launchId: this.agents.get(agentId)?.launchId || void 0,
|
|
18345
|
+
processInstanceId: this.agents.get(agentId)?.processInstanceId
|
|
17987
18346
|
});
|
|
17988
18347
|
const tier = runtimeTier(runtime);
|
|
17989
18348
|
const span = this.tracer.startSpan("daemon.session_transcript.read", {
|
|
@@ -18241,6 +18600,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18241
18600
|
const launchId = launchIdOverride || ap?.launchId || void 0;
|
|
18242
18601
|
const clientSeq = this.nextActivityClientSeq(agentId);
|
|
18243
18602
|
const producerFactId = this.buildActivityProducerFactId(agentId, launchId, clientSeq);
|
|
18603
|
+
const observedAtMs = Date.now();
|
|
18244
18604
|
this.sendToServer({
|
|
18245
18605
|
type: "agent:activity",
|
|
18246
18606
|
agentId,
|
|
@@ -18251,9 +18611,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18251
18611
|
entries,
|
|
18252
18612
|
launchId,
|
|
18253
18613
|
clientSeq,
|
|
18254
|
-
producerFactId
|
|
18614
|
+
producerFactId,
|
|
18615
|
+
observedAtMs,
|
|
18616
|
+
isHeartbeat: false
|
|
18255
18617
|
});
|
|
18256
|
-
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId);
|
|
18618
|
+
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId, false);
|
|
18257
18619
|
if (ap) {
|
|
18258
18620
|
ap.lastActivityKind = activityKind;
|
|
18259
18621
|
ap.lastActivity = activityDisplay;
|
|
@@ -18270,6 +18632,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18270
18632
|
const heartbeatLaunchId = launchIdOverride || ap.launchId || void 0;
|
|
18271
18633
|
const heartbeatClientSeq = this.nextActivityClientSeq(agentId);
|
|
18272
18634
|
const heartbeatProducerFactId = this.buildActivityProducerFactId(agentId, heartbeatLaunchId, heartbeatClientSeq);
|
|
18635
|
+
const heartbeatObservedAtMs = Date.now();
|
|
18273
18636
|
this.sendToServer({
|
|
18274
18637
|
type: "agent:activity",
|
|
18275
18638
|
agentId,
|
|
@@ -18279,9 +18642,13 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18279
18642
|
detailKind: ap.lastActivityDetailKind,
|
|
18280
18643
|
launchId: heartbeatLaunchId,
|
|
18281
18644
|
clientSeq: heartbeatClientSeq,
|
|
18282
|
-
producerFactId: heartbeatProducerFactId
|
|
18645
|
+
producerFactId: heartbeatProducerFactId,
|
|
18646
|
+
observedAtMs: heartbeatObservedAtMs,
|
|
18647
|
+
// The one knowing site: this timer re-broadcasts stale
|
|
18648
|
+
// lastActivity, so it declares its replay provenance.
|
|
18649
|
+
isHeartbeat: true
|
|
18283
18650
|
});
|
|
18284
|
-
this.recordActivityProducedTrace(agentId, ap.lastActivityKind, ap.lastActivityDetail, ap.lastActivityDetailKind, [], ap, heartbeatLaunchId, heartbeatClientSeq, heartbeatProducerFactId);
|
|
18651
|
+
this.recordActivityProducedTrace(agentId, ap.lastActivityKind, ap.lastActivityDetail, ap.lastActivityDetailKind, [], ap, heartbeatLaunchId, heartbeatClientSeq, heartbeatProducerFactId, true);
|
|
18285
18652
|
}, ACTIVITY_HEARTBEAT_MS);
|
|
18286
18653
|
ap.activityHeartbeat = { kind: "active", timer };
|
|
18287
18654
|
}
|
|
@@ -18290,7 +18657,7 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18290
18657
|
}
|
|
18291
18658
|
}
|
|
18292
18659
|
}
|
|
18293
|
-
recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId) {
|
|
18660
|
+
recordActivityProducedTrace(agentId, activityKind, detail, detailKind, entries, ap, launchId, clientSeq, producerFactId, isHeartbeat) {
|
|
18294
18661
|
const runtimeContext = ap?.config.runtimeContext;
|
|
18295
18662
|
this.recordDaemonTrace("daemon.agent.activity.produced", {
|
|
18296
18663
|
agentId,
|
|
@@ -18312,6 +18679,11 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18312
18679
|
client_seq_present: typeof clientSeq === "number",
|
|
18313
18680
|
producerFactId,
|
|
18314
18681
|
producer_fact_id: producerFactId,
|
|
18682
|
+
// #460 V1: the wire's producer-declared replay-provenance bit must be
|
|
18683
|
+
// independently verifiable from daemon-side evidence (L2<->L3 seam);
|
|
18684
|
+
// closed boolean, mirrors the agent:activity isHeartbeat field exactly.
|
|
18685
|
+
isHeartbeat,
|
|
18686
|
+
is_heartbeat: isHeartbeat,
|
|
18315
18687
|
correlation_id: `agent:${agentId}:daemonActivity:${launchId ?? "legacy"}:${clientSeq ?? "unsequenced"}`,
|
|
18316
18688
|
session_id_present: Boolean(ap?.sessionId),
|
|
18317
18689
|
runtime: ap?.config.runtime
|
|
@@ -18360,9 +18732,10 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18360
18732
|
launchId,
|
|
18361
18733
|
probeId,
|
|
18362
18734
|
clientSeq,
|
|
18363
|
-
producerFactId
|
|
18735
|
+
producerFactId,
|
|
18736
|
+
isHeartbeat: false
|
|
18364
18737
|
});
|
|
18365
|
-
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, [], ap, launchId, clientSeq, producerFactId);
|
|
18738
|
+
this.recordActivityProducedTrace(agentId, activityKind, detail, detailKind, [], ap, launchId, clientSeq, producerFactId, false);
|
|
18366
18739
|
}
|
|
18367
18740
|
flushPendingTrajectory(agentId) {
|
|
18368
18741
|
const ap = this.agents.get(agentId);
|
|
@@ -18546,12 +18919,29 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
18546
18919
|
}
|
|
18547
18920
|
this.commitApmIdleState(agentId, ap, false);
|
|
18548
18921
|
}
|
|
18549
|
-
interruptCompactionIfActive(agentId) {
|
|
18922
|
+
interruptCompactionIfActive(agentId, options = {}) {
|
|
18550
18923
|
const ap = this.agents.get(agentId);
|
|
18551
|
-
if (!ap || ap.compaction.kind !== "active" && !ap.gatedSteering.compacting) return;
|
|
18924
|
+
if (!ap || ap.compaction.kind !== "active" && !ap.gatedSteering.compacting) return false;
|
|
18552
18925
|
this.clearCompactionWatchdog(ap);
|
|
18553
18926
|
const reduction = reduceApmGatedCompaction(ap.gatedSteering, { kind: "compaction_interrupted" });
|
|
18554
|
-
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState);
|
|
18927
|
+
this.commitGatedSteeringDecisionState(agentId, ap, reduction.nextState, { event: "compaction_interrupted" });
|
|
18928
|
+
if (options.traceAttrs) {
|
|
18929
|
+
this.recordRuntimeTraceEvent(agentId, ap, "runtime.context_compaction.interrupted", options.traceAttrs);
|
|
18930
|
+
}
|
|
18931
|
+
if (options.detail) {
|
|
18932
|
+
this.broadcastActivity(
|
|
18933
|
+
agentId,
|
|
18934
|
+
"error",
|
|
18935
|
+
options.detail,
|
|
18936
|
+
options.entries ?? [],
|
|
18937
|
+
void 0,
|
|
18938
|
+
options.detailKind ?? "runtime_error"
|
|
18939
|
+
);
|
|
18940
|
+
}
|
|
18941
|
+
if (options.flushBoundaryMessages) {
|
|
18942
|
+
this.flushCompactionBoundaryMessages(agentId, ap);
|
|
18943
|
+
}
|
|
18944
|
+
return true;
|
|
18555
18945
|
}
|
|
18556
18946
|
flushReviewBoundaryMessages(agentId, ap) {
|
|
18557
18947
|
const reduction = reduceApmGatedReviewBoundaryFlush(ap.gatedSteering, {
|
|
@@ -19279,6 +19669,17 @@ Use \`raft message read\` to catch up on the channels listed above, then stop. R
|
|
|
19279
19669
|
if (event.kind === "delivery_error") {
|
|
19280
19670
|
if (ap) {
|
|
19281
19671
|
this.restoreRuntimeDeliveryAfterAsyncRejection(agentId, ap, event);
|
|
19672
|
+
this.interruptCompactionIfActive(agentId, {
|
|
19673
|
+
detail: `Context compaction interrupted after runtime delivery failed: ${event.message}`,
|
|
19674
|
+
entries: [{ kind: "text", text: `Error: ${event.message}` }],
|
|
19675
|
+
flushBoundaryMessages: true,
|
|
19676
|
+
traceAttrs: {
|
|
19677
|
+
reason: "delivery_error",
|
|
19678
|
+
request_method: event.requestMethod,
|
|
19679
|
+
source: event.source,
|
|
19680
|
+
payloadBytes: event.payloadBytes
|
|
19681
|
+
}
|
|
19682
|
+
});
|
|
19282
19683
|
} else {
|
|
19283
19684
|
this.recordDaemonTrace("daemon.agent.delivery_error.received_without_process", {
|
|
19284
19685
|
agentId,
|
|
@@ -21302,6 +21703,563 @@ function assertLegacyDaemonKeyNotAdoptedByComputer(options) {
|
|
|
21302
21703
|
if (match) throw new LegacyDaemonKeyAdoptedByComputerError(match);
|
|
21303
21704
|
}
|
|
21304
21705
|
|
|
21706
|
+
// src/agentMigrationExport.ts
|
|
21707
|
+
import { createHash as createHash7 } from "crypto";
|
|
21708
|
+
import { createReadStream } from "fs";
|
|
21709
|
+
import { lstat as lstat2, readdir as readdir4, readFile as readFile3, readlink } from "fs/promises";
|
|
21710
|
+
import path19 from "path";
|
|
21711
|
+
var AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION = "agent-bundle/v1";
|
|
21712
|
+
var REGENERABLE_DIRECTORY_NAMES = [
|
|
21713
|
+
".venv",
|
|
21714
|
+
"__pycache__",
|
|
21715
|
+
"dist",
|
|
21716
|
+
"node_modules",
|
|
21717
|
+
"target"
|
|
21718
|
+
];
|
|
21719
|
+
var SECRET_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
21720
|
+
".env",
|
|
21721
|
+
".env.local",
|
|
21722
|
+
".env.development",
|
|
21723
|
+
".env.production",
|
|
21724
|
+
".env.test",
|
|
21725
|
+
"credentials.json",
|
|
21726
|
+
"credential.json"
|
|
21727
|
+
]);
|
|
21728
|
+
var ENV_KEY_PATTERN = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/;
|
|
21729
|
+
async function buildAgentMigrationExportManifest(input) {
|
|
21730
|
+
const slockHome = path19.resolve(input.slockHome);
|
|
21731
|
+
const workspace = path19.resolve(input.workspacePath ?? path19.join(slockHome, "agents", input.agentId));
|
|
21732
|
+
const proposedIncludes = normalizeProposalPaths(input.cooperativeManifest?.include, workspace, "include");
|
|
21733
|
+
const proposedRegenerableExcludes = normalizeProposalPaths(input.cooperativeManifest?.exclude_regenerable, workspace, "exclude_regenerable");
|
|
21734
|
+
const cleanedProposal = normalizeProposalPaths(input.cooperativeManifest?.cleaned, workspace, "cleaned");
|
|
21735
|
+
const state = {
|
|
21736
|
+
workspace,
|
|
21737
|
+
files: [],
|
|
21738
|
+
excludedRegenerable: [],
|
|
21739
|
+
promotedIncludes: [],
|
|
21740
|
+
proposalRefusals: [
|
|
21741
|
+
...proposedIncludes.refusals,
|
|
21742
|
+
...proposedRegenerableExcludes.refusals,
|
|
21743
|
+
...cleanedProposal.refusals
|
|
21744
|
+
],
|
|
21745
|
+
unreachable: [],
|
|
21746
|
+
secretsDisclosed: [],
|
|
21747
|
+
seenWorkspacePaths: /* @__PURE__ */ new Set(),
|
|
21748
|
+
explicitIncludePaths: new Set(proposedIncludes.paths)
|
|
21749
|
+
};
|
|
21750
|
+
await walkWorkspace(workspace, "", new Set(proposedRegenerableExcludes.paths), state, { forceIncludeRegenerable: false });
|
|
21751
|
+
for (const requestedPath of proposedIncludes.paths) {
|
|
21752
|
+
if (!state.seenWorkspacePaths.has(requestedPath)) {
|
|
21753
|
+
await includeWorkspacePath(requestedPath, state, { forceIncludeRegenerable: true });
|
|
21754
|
+
}
|
|
21755
|
+
}
|
|
21756
|
+
for (const requestedPath of proposedRegenerableExcludes.paths) {
|
|
21757
|
+
if (isRegenerablePath(requestedPath)) continue;
|
|
21758
|
+
state.promotedIncludes.push({ path: requestedPath, reason: "exclude_not_regenerable" });
|
|
21759
|
+
await includeWorkspacePath(requestedPath, state, { forceIncludeRegenerable: true });
|
|
21760
|
+
}
|
|
21761
|
+
const crossTreeRefs = await buildCrossTreeRefs(input.runtimeSessionRefs ?? []);
|
|
21762
|
+
const secretDisclosureProposal = normalizeProposalPaths(input.cooperativeManifest?.secrets_disclosed, workspace, "secrets_disclosed");
|
|
21763
|
+
state.proposalRefusals.push(...secretDisclosureProposal.refusals);
|
|
21764
|
+
return {
|
|
21765
|
+
schemaVersion: AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION,
|
|
21766
|
+
agentId: input.agentId,
|
|
21767
|
+
mode: input.mode,
|
|
21768
|
+
createdAt: (input.now ?? /* @__PURE__ */ new Date()).toISOString(),
|
|
21769
|
+
roots: {
|
|
21770
|
+
slockHome,
|
|
21771
|
+
workspace
|
|
21772
|
+
},
|
|
21773
|
+
defaults: {
|
|
21774
|
+
unknownFiles: "include",
|
|
21775
|
+
excludePolicy: "regenerable_only",
|
|
21776
|
+
regenerableDirectoryNames: [...REGENERABLE_DIRECTORY_NAMES]
|
|
21777
|
+
},
|
|
21778
|
+
files: sortBundleEntries(state.files),
|
|
21779
|
+
excludedRegenerable: sortByPath(state.excludedRegenerable),
|
|
21780
|
+
promotedIncludes: sortByPath(state.promotedIncludes),
|
|
21781
|
+
proposalRefusals: sortByPath(state.proposalRefusals),
|
|
21782
|
+
unreachable: sortByPath(state.unreachable),
|
|
21783
|
+
secretsDisclosed: sortByPath([
|
|
21784
|
+
...state.secretsDisclosed,
|
|
21785
|
+
...normalizeProvidedSecretDisclosures(secretDisclosureProposal.paths)
|
|
21786
|
+
]),
|
|
21787
|
+
cleaned: cleanedProposal.paths,
|
|
21788
|
+
crossTreeRefs: crossTreeRefs.sort((a, b) => a.bundlePath.localeCompare(b.bundlePath))
|
|
21789
|
+
};
|
|
21790
|
+
}
|
|
21791
|
+
async function walkWorkspace(root, relativeDir, proposedRegenerableExcludes, state, opts) {
|
|
21792
|
+
const absoluteDir = path19.join(root, relativeDir);
|
|
21793
|
+
let entries;
|
|
21794
|
+
try {
|
|
21795
|
+
entries = await readdir4(absoluteDir, { withFileTypes: true });
|
|
21796
|
+
} catch {
|
|
21797
|
+
state.unreachable.push({
|
|
21798
|
+
path: relativeDir || ".",
|
|
21799
|
+
sourcePath: absoluteDir,
|
|
21800
|
+
reason: "read_error"
|
|
21801
|
+
});
|
|
21802
|
+
return;
|
|
21803
|
+
}
|
|
21804
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
21805
|
+
for (const entry of entries) {
|
|
21806
|
+
const relativePath = toPosixPath(path19.join(relativeDir, entry.name));
|
|
21807
|
+
if (entry.isDirectory()) {
|
|
21808
|
+
if (!opts.forceIncludeRegenerable && isRegenerablePath(relativePath)) {
|
|
21809
|
+
if (state.explicitIncludePaths.has(relativePath)) {
|
|
21810
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, { forceIncludeRegenerable: true });
|
|
21811
|
+
continue;
|
|
21812
|
+
}
|
|
21813
|
+
if (hasExplicitIncludeDescendant(relativePath, state.explicitIncludePaths)) {
|
|
21814
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, opts);
|
|
21815
|
+
continue;
|
|
21816
|
+
}
|
|
21817
|
+
state.excludedRegenerable.push({
|
|
21818
|
+
path: relativePath,
|
|
21819
|
+
reason: proposedRegenerableExcludes.has(relativePath) ? "cooperative_exclude_regenerable" : "regenerable_default",
|
|
21820
|
+
regenerableHint: `${entry.name} is treated as rebuildable/installable state and is not bundled by default`
|
|
21821
|
+
});
|
|
21822
|
+
continue;
|
|
21823
|
+
}
|
|
21824
|
+
await walkWorkspace(root, relativePath, proposedRegenerableExcludes, state, opts);
|
|
21825
|
+
continue;
|
|
21826
|
+
}
|
|
21827
|
+
await includeWorkspacePath(relativePath, state, { forceIncludeRegenerable: opts.forceIncludeRegenerable });
|
|
21828
|
+
}
|
|
21829
|
+
}
|
|
21830
|
+
async function includeWorkspacePath(workspaceRelativePath, state, opts) {
|
|
21831
|
+
const normalizedRelativePath = normalizeRelativePath(workspaceRelativePath);
|
|
21832
|
+
if (state.seenWorkspacePaths.has(normalizedRelativePath)) return;
|
|
21833
|
+
const sourcePath = path19.join(state.workspace, normalizedRelativePath);
|
|
21834
|
+
let stat4;
|
|
21835
|
+
try {
|
|
21836
|
+
stat4 = await lstat2(sourcePath);
|
|
21837
|
+
} catch {
|
|
21838
|
+
state.unreachable.push({
|
|
21839
|
+
path: normalizedRelativePath,
|
|
21840
|
+
sourcePath,
|
|
21841
|
+
reason: "missing"
|
|
21842
|
+
});
|
|
21843
|
+
return;
|
|
21844
|
+
}
|
|
21845
|
+
if (stat4.isDirectory()) {
|
|
21846
|
+
if (!opts.forceIncludeRegenerable && isRegenerablePath(normalizedRelativePath)) {
|
|
21847
|
+
state.excludedRegenerable.push({
|
|
21848
|
+
path: normalizedRelativePath,
|
|
21849
|
+
reason: "cooperative_exclude_regenerable",
|
|
21850
|
+
regenerableHint: `${path19.basename(normalizedRelativePath)} is treated as rebuildable/installable state and is not bundled by default`
|
|
21851
|
+
});
|
|
21852
|
+
return;
|
|
21853
|
+
}
|
|
21854
|
+
await walkWorkspace(state.workspace, normalizedRelativePath, /* @__PURE__ */ new Set(), state, opts);
|
|
21855
|
+
return;
|
|
21856
|
+
}
|
|
21857
|
+
state.seenWorkspacePaths.add(normalizedRelativePath);
|
|
21858
|
+
const baseEntry = {
|
|
21859
|
+
source: "workspace",
|
|
21860
|
+
sourcePath,
|
|
21861
|
+
workspaceRelativePath: normalizedRelativePath,
|
|
21862
|
+
bundlePath: `workspace/${normalizedRelativePath}`,
|
|
21863
|
+
mode: stat4.mode,
|
|
21864
|
+
mtimeMs: stat4.mtimeMs
|
|
21865
|
+
};
|
|
21866
|
+
if (stat4.isSymbolicLink()) {
|
|
21867
|
+
state.files.push({
|
|
21868
|
+
...baseEntry,
|
|
21869
|
+
kind: "symlink",
|
|
21870
|
+
linkTarget: await readlink(sourcePath)
|
|
21871
|
+
});
|
|
21872
|
+
return;
|
|
21873
|
+
}
|
|
21874
|
+
if (!stat4.isFile()) {
|
|
21875
|
+
state.unreachable.push({
|
|
21876
|
+
path: normalizedRelativePath,
|
|
21877
|
+
sourcePath,
|
|
21878
|
+
reason: "unsupported_file_type"
|
|
21879
|
+
});
|
|
21880
|
+
return;
|
|
21881
|
+
}
|
|
21882
|
+
const secretShapes = await detectSecretShapes(sourcePath, normalizedRelativePath);
|
|
21883
|
+
if (secretShapes.length > 0) {
|
|
21884
|
+
state.secretsDisclosed.push({ path: normalizedRelativePath, shapes: secretShapes });
|
|
21885
|
+
}
|
|
21886
|
+
state.files.push({
|
|
21887
|
+
...baseEntry,
|
|
21888
|
+
kind: "file",
|
|
21889
|
+
sizeBytes: stat4.size,
|
|
21890
|
+
sha256: await sha256File(sourcePath),
|
|
21891
|
+
secretShapes: secretShapes.length > 0 ? secretShapes : void 0
|
|
21892
|
+
});
|
|
21893
|
+
}
|
|
21894
|
+
async function buildCrossTreeRefs(refs) {
|
|
21895
|
+
const result = [];
|
|
21896
|
+
for (const ref of refs) {
|
|
21897
|
+
const sourcePath = path19.resolve(ref.path);
|
|
21898
|
+
const bundlePath = `runtime/${safeBundleSegment(ref.runtime)}/${safeBundleSegment(ref.label)}/${safeBundleSegment(path19.basename(sourcePath) || "session")}`;
|
|
21899
|
+
const entry = {
|
|
21900
|
+
runtime: ref.runtime,
|
|
21901
|
+
label: ref.label,
|
|
21902
|
+
sourcePath,
|
|
21903
|
+
bundlePath,
|
|
21904
|
+
reachable: ref.reachable !== false,
|
|
21905
|
+
reason: ref.reason
|
|
21906
|
+
};
|
|
21907
|
+
try {
|
|
21908
|
+
const stat4 = await lstat2(sourcePath);
|
|
21909
|
+
if (stat4.isFile()) {
|
|
21910
|
+
entry.sizeBytes = stat4.size;
|
|
21911
|
+
entry.sha256 = await sha256File(sourcePath);
|
|
21912
|
+
}
|
|
21913
|
+
} catch {
|
|
21914
|
+
entry.reachable = false;
|
|
21915
|
+
}
|
|
21916
|
+
result.push(entry);
|
|
21917
|
+
}
|
|
21918
|
+
return result;
|
|
21919
|
+
}
|
|
21920
|
+
async function sha256File(filePath) {
|
|
21921
|
+
const hash = createHash7("sha256");
|
|
21922
|
+
await new Promise((resolve, reject) => {
|
|
21923
|
+
const stream = createReadStream(filePath);
|
|
21924
|
+
stream.on("data", (chunk) => hash.update(chunk));
|
|
21925
|
+
stream.on("error", reject);
|
|
21926
|
+
stream.on("end", resolve);
|
|
21927
|
+
});
|
|
21928
|
+
return hash.digest("hex");
|
|
21929
|
+
}
|
|
21930
|
+
async function detectSecretShapes(sourcePath, relativePath) {
|
|
21931
|
+
const basename = path19.basename(relativePath);
|
|
21932
|
+
const lowerBasename = basename.toLowerCase();
|
|
21933
|
+
const shapes = /* @__PURE__ */ new Set();
|
|
21934
|
+
if (SECRET_FILE_NAMES.has(lowerBasename) || lowerBasename.startsWith(".env.")) {
|
|
21935
|
+
shapes.add(`file:${basename}`);
|
|
21936
|
+
try {
|
|
21937
|
+
const text = await readFile3(sourcePath, "utf8");
|
|
21938
|
+
for (const line of text.split(/\r?\n/)) {
|
|
21939
|
+
const match = ENV_KEY_PATTERN.exec(line);
|
|
21940
|
+
if (match) shapes.add(`env:${match[1]}`);
|
|
21941
|
+
}
|
|
21942
|
+
} catch {
|
|
21943
|
+
shapes.add("content:unreadable");
|
|
21944
|
+
}
|
|
21945
|
+
}
|
|
21946
|
+
if (/(?:secret|token|credential|api[-_]?key)/i.test(relativePath)) {
|
|
21947
|
+
shapes.add(`path:${basename}`);
|
|
21948
|
+
}
|
|
21949
|
+
return [...shapes].sort();
|
|
21950
|
+
}
|
|
21951
|
+
function normalizeProvidedSecretDisclosures(disclosures) {
|
|
21952
|
+
return disclosures.map((entry) => ({
|
|
21953
|
+
path: entry,
|
|
21954
|
+
shapes: ["provided"]
|
|
21955
|
+
}));
|
|
21956
|
+
}
|
|
21957
|
+
function normalizeProposalPaths(paths, workspace, source) {
|
|
21958
|
+
if (!paths) return { paths: [], refusals: [] };
|
|
21959
|
+
const result = [];
|
|
21960
|
+
const refusals = [];
|
|
21961
|
+
for (const value of paths) {
|
|
21962
|
+
const trimmed = value.trim();
|
|
21963
|
+
if (!trimmed) continue;
|
|
21964
|
+
if (path19.isAbsolute(trimmed)) {
|
|
21965
|
+
const relative = path19.relative(workspace, trimmed);
|
|
21966
|
+
if (relative.startsWith("..") || path19.isAbsolute(relative)) {
|
|
21967
|
+
refusals.push({
|
|
21968
|
+
path: trimmed,
|
|
21969
|
+
reason: "outside_workspace",
|
|
21970
|
+
source
|
|
21971
|
+
});
|
|
21972
|
+
continue;
|
|
21973
|
+
}
|
|
21974
|
+
try {
|
|
21975
|
+
result.push(normalizeRelativePath(relative));
|
|
21976
|
+
} catch {
|
|
21977
|
+
refusals.push({
|
|
21978
|
+
path: trimmed,
|
|
21979
|
+
reason: "unsafe_path",
|
|
21980
|
+
source
|
|
21981
|
+
});
|
|
21982
|
+
}
|
|
21983
|
+
continue;
|
|
21984
|
+
}
|
|
21985
|
+
try {
|
|
21986
|
+
result.push(normalizeRelativePath(trimmed));
|
|
21987
|
+
} catch {
|
|
21988
|
+
refusals.push({
|
|
21989
|
+
path: trimmed,
|
|
21990
|
+
reason: "unsafe_path",
|
|
21991
|
+
source
|
|
21992
|
+
});
|
|
21993
|
+
}
|
|
21994
|
+
}
|
|
21995
|
+
return { paths: [...new Set(result)], refusals };
|
|
21996
|
+
}
|
|
21997
|
+
function normalizeRelativePath(value) {
|
|
21998
|
+
const normalized = path19.normalize(value).replace(/^[\\/]+/, "");
|
|
21999
|
+
if (!normalized || normalized === "." || normalized.startsWith("..") || path19.isAbsolute(normalized)) {
|
|
22000
|
+
throw new Error(`unsafe migration export path: ${value}`);
|
|
22001
|
+
}
|
|
22002
|
+
return toPosixPath(normalized);
|
|
22003
|
+
}
|
|
22004
|
+
function isRegenerablePath(relativePath) {
|
|
22005
|
+
return normalizeRelativePath(relativePath).split("/").some((segment) => REGENERABLE_DIRECTORY_NAMES.includes(segment));
|
|
22006
|
+
}
|
|
22007
|
+
function hasExplicitIncludeDescendant(relativePath, explicitIncludePaths) {
|
|
22008
|
+
const prefix = `${relativePath}/`;
|
|
22009
|
+
for (const includePath of explicitIncludePaths) {
|
|
22010
|
+
if (includePath.startsWith(prefix)) return true;
|
|
22011
|
+
}
|
|
22012
|
+
return false;
|
|
22013
|
+
}
|
|
22014
|
+
function safeBundleSegment(value) {
|
|
22015
|
+
return value.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "unknown";
|
|
22016
|
+
}
|
|
22017
|
+
function toPosixPath(value) {
|
|
22018
|
+
return value.split(path19.sep).join("/");
|
|
22019
|
+
}
|
|
22020
|
+
function sortBundleEntries(entries) {
|
|
22021
|
+
return [...entries].sort((a, b) => a.bundlePath.localeCompare(b.bundlePath));
|
|
22022
|
+
}
|
|
22023
|
+
function sortByPath(entries) {
|
|
22024
|
+
return [...entries].sort((a, b) => a.path.localeCompare(b.path));
|
|
22025
|
+
}
|
|
22026
|
+
|
|
22027
|
+
// src/agentMigrationHttpTransport.ts
|
|
22028
|
+
import { createHash as createHash8, randomBytes as randomBytes2, timingSafeEqual } from "crypto";
|
|
22029
|
+
import http2 from "http";
|
|
22030
|
+
var MigrationBundleStreamError = class extends Error {
|
|
22031
|
+
constructor(code) {
|
|
22032
|
+
super(code);
|
|
22033
|
+
this.code = code;
|
|
22034
|
+
}
|
|
22035
|
+
};
|
|
22036
|
+
var AgentMigrationGrantRegistry = class {
|
|
22037
|
+
grants = /* @__PURE__ */ new Map();
|
|
22038
|
+
now;
|
|
22039
|
+
constructor(now = () => /* @__PURE__ */ new Date()) {
|
|
22040
|
+
this.now = now;
|
|
22041
|
+
}
|
|
22042
|
+
createGrant(input) {
|
|
22043
|
+
const token = input.token ?? randomBytes2(32).toString("base64url");
|
|
22044
|
+
const manifestSha256 = sha256Buffer(canonicalJsonBuffer(input.manifest));
|
|
22045
|
+
const grant = {
|
|
22046
|
+
grantId: input.grantId ?? randomBytes2(16).toString("hex"),
|
|
22047
|
+
tokenHash: hashToken(token),
|
|
22048
|
+
expiresAt: input.expiresAt,
|
|
22049
|
+
oneTimeUse: input.oneTimeUse ?? true,
|
|
22050
|
+
state: "issued",
|
|
22051
|
+
manifest: input.manifest,
|
|
22052
|
+
manifestSha256,
|
|
22053
|
+
bundleEtag: `"agent-migration-${manifestSha256}"`
|
|
22054
|
+
};
|
|
22055
|
+
this.grants.set(grant.grantId, grant);
|
|
22056
|
+
return { grant, token };
|
|
22057
|
+
}
|
|
22058
|
+
get(grantId) {
|
|
22059
|
+
return this.grants.get(grantId);
|
|
22060
|
+
}
|
|
22061
|
+
authenticate(grantId, token) {
|
|
22062
|
+
const grant = this.grants.get(grantId);
|
|
22063
|
+
if (!grant || !token || !verifyTokenHash(token, grant.tokenHash)) {
|
|
22064
|
+
return { ok: false, status: 401, code: "migration_grant_auth_failed" };
|
|
22065
|
+
}
|
|
22066
|
+
if (grant.state === "revoked" || grant.state === "consumed") {
|
|
22067
|
+
return { ok: false, status: 410, code: "migration_grant_unavailable" };
|
|
22068
|
+
}
|
|
22069
|
+
if (this.now().getTime() >= grant.expiresAt.getTime()) {
|
|
22070
|
+
grant.state = "expired";
|
|
22071
|
+
return { ok: false, status: 410, code: "migration_grant_unavailable" };
|
|
22072
|
+
}
|
|
22073
|
+
return { ok: true, grant };
|
|
22074
|
+
}
|
|
22075
|
+
revokeAll() {
|
|
22076
|
+
for (const grant of this.grants.values()) {
|
|
22077
|
+
if (grant.state !== "consumed" && grant.state !== "expired") {
|
|
22078
|
+
grant.state = "revoked";
|
|
22079
|
+
}
|
|
22080
|
+
}
|
|
22081
|
+
}
|
|
22082
|
+
};
|
|
22083
|
+
function createAgentMigrationHttpTransport(options = {}) {
|
|
22084
|
+
const registry = new AgentMigrationGrantRegistry(options.now);
|
|
22085
|
+
const bundleStreamFactory = options.bundleStreamFactory ?? defaultBundleStream;
|
|
22086
|
+
const server = http2.createServer((req, res) => {
|
|
22087
|
+
void handleMigrationRequest(req, res, registry, bundleStreamFactory);
|
|
22088
|
+
});
|
|
22089
|
+
return {
|
|
22090
|
+
grants: registry,
|
|
22091
|
+
server,
|
|
22092
|
+
listen: (port = 0, host = "127.0.0.1") => new Promise((resolve, reject) => {
|
|
22093
|
+
server.once("error", reject);
|
|
22094
|
+
server.listen(port, host, () => {
|
|
22095
|
+
server.off("error", reject);
|
|
22096
|
+
const address = server.address();
|
|
22097
|
+
if (!address || typeof address === "string") {
|
|
22098
|
+
reject(new Error("migration transport listen did not produce a TCP address"));
|
|
22099
|
+
return;
|
|
22100
|
+
}
|
|
22101
|
+
resolve({ url: `http://${address.address}:${address.port}` });
|
|
22102
|
+
});
|
|
22103
|
+
}),
|
|
22104
|
+
close: () => new Promise((resolve, reject) => {
|
|
22105
|
+
registry.revokeAll();
|
|
22106
|
+
server.close((err) => {
|
|
22107
|
+
if (err) reject(err);
|
|
22108
|
+
else resolve();
|
|
22109
|
+
});
|
|
22110
|
+
})
|
|
22111
|
+
};
|
|
22112
|
+
}
|
|
22113
|
+
async function handleMigrationRequest(req, res, registry, bundleStreamFactory) {
|
|
22114
|
+
const parsed = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
22115
|
+
const match = /^\/migration\/([^/]+)\/([^/]+)(?:\/([^/]+))?$/.exec(parsed.pathname);
|
|
22116
|
+
if (!match) {
|
|
22117
|
+
sendJson(res, 404, { code: "migration_route_not_found" });
|
|
22118
|
+
return;
|
|
22119
|
+
}
|
|
22120
|
+
const [, grantId, resource, resourceId] = match;
|
|
22121
|
+
const auth = registry.authenticate(decodeURIComponent(grantId), extractBearerToken(req));
|
|
22122
|
+
if (!auth.ok) {
|
|
22123
|
+
sendJson(res, auth.status, { code: auth.code });
|
|
22124
|
+
return;
|
|
22125
|
+
}
|
|
22126
|
+
if (resource === "manifest" && req.method === "GET" && !resourceId) {
|
|
22127
|
+
sendJson(res, 200, {
|
|
22128
|
+
manifestSha256: auth.grant.manifestSha256,
|
|
22129
|
+
manifest: auth.grant.manifest
|
|
22130
|
+
}, {
|
|
22131
|
+
"X-Raft-Manifest-Sha": auth.grant.manifestSha256,
|
|
22132
|
+
ETag: `"manifest-${auth.grant.manifestSha256}"`
|
|
22133
|
+
});
|
|
22134
|
+
return;
|
|
22135
|
+
}
|
|
22136
|
+
if (resource === "bundle.tar" && !resourceId) {
|
|
22137
|
+
if (req.method === "HEAD") {
|
|
22138
|
+
sendHead(res, auth.grant);
|
|
22139
|
+
return;
|
|
22140
|
+
}
|
|
22141
|
+
if (req.method === "GET") {
|
|
22142
|
+
await streamBundle(res, auth.grant, bundleStreamFactory);
|
|
22143
|
+
return;
|
|
22144
|
+
}
|
|
22145
|
+
}
|
|
22146
|
+
if (resource === "chunk" && req.method === "GET" && resourceId) {
|
|
22147
|
+
sendJson(res, 501, { code: "migration_chunk_not_implemented" });
|
|
22148
|
+
return;
|
|
22149
|
+
}
|
|
22150
|
+
sendJson(res, 405, { code: "migration_method_not_allowed" });
|
|
22151
|
+
}
|
|
22152
|
+
function sendHead(res, grant) {
|
|
22153
|
+
res.statusCode = 200;
|
|
22154
|
+
res.setHeader("X-Raft-Manifest-Sha", grant.manifestSha256);
|
|
22155
|
+
res.setHeader("ETag", grant.bundleEtag);
|
|
22156
|
+
res.setHeader("Accept-Ranges", "none");
|
|
22157
|
+
res.setHeader("X-Raft-Bundle-Size", "unknown");
|
|
22158
|
+
res.end();
|
|
22159
|
+
}
|
|
22160
|
+
async function streamBundle(res, grant, bundleStreamFactory) {
|
|
22161
|
+
if (grant.state === "streaming") {
|
|
22162
|
+
sendJson(res, 409, { code: "migration_bundle_stream_in_progress" });
|
|
22163
|
+
return;
|
|
22164
|
+
}
|
|
22165
|
+
if (grant.oneTimeUse && grant.state !== "issued" && grant.state !== "interrupted") {
|
|
22166
|
+
sendJson(res, 410, { code: "migration_grant_unavailable" });
|
|
22167
|
+
return;
|
|
22168
|
+
}
|
|
22169
|
+
let stream;
|
|
22170
|
+
try {
|
|
22171
|
+
stream = bundleStreamFactory(grant);
|
|
22172
|
+
} catch (err) {
|
|
22173
|
+
const code = err instanceof MigrationBundleStreamError ? err.code : "migration_bundle_stream_failed";
|
|
22174
|
+
sendJson(res, 500, { code });
|
|
22175
|
+
return;
|
|
22176
|
+
}
|
|
22177
|
+
grant.state = "streaming";
|
|
22178
|
+
let completed = false;
|
|
22179
|
+
res.on("close", () => {
|
|
22180
|
+
if (!completed && grant.state === "streaming") {
|
|
22181
|
+
grant.state = "interrupted";
|
|
22182
|
+
}
|
|
22183
|
+
});
|
|
22184
|
+
try {
|
|
22185
|
+
res.statusCode = 200;
|
|
22186
|
+
res.setHeader("Content-Type", "application/x-tar");
|
|
22187
|
+
res.setHeader("X-Raft-Manifest-Sha", grant.manifestSha256);
|
|
22188
|
+
res.setHeader("ETag", grant.bundleEtag);
|
|
22189
|
+
for await (const chunk of stream) {
|
|
22190
|
+
if (!res.write(chunk)) {
|
|
22191
|
+
await onceDrain(res);
|
|
22192
|
+
}
|
|
22193
|
+
}
|
|
22194
|
+
completed = true;
|
|
22195
|
+
grant.state = "consumed";
|
|
22196
|
+
res.end();
|
|
22197
|
+
} catch {
|
|
22198
|
+
if (!completed && grant.state === "streaming") {
|
|
22199
|
+
grant.state = "interrupted";
|
|
22200
|
+
}
|
|
22201
|
+
if (!res.headersSent) {
|
|
22202
|
+
sendJson(res, 500, { code: "migration_bundle_stream_failed" });
|
|
22203
|
+
} else {
|
|
22204
|
+
res.destroy();
|
|
22205
|
+
}
|
|
22206
|
+
}
|
|
22207
|
+
}
|
|
22208
|
+
function defaultBundleStream(grant) {
|
|
22209
|
+
void grant;
|
|
22210
|
+
throw new MigrationBundleStreamError("migration_bundle_stream_not_wired");
|
|
22211
|
+
}
|
|
22212
|
+
function extractBearerToken(req) {
|
|
22213
|
+
const directHeader = singleHeader(req.headers["x-raft-migration-token"]);
|
|
22214
|
+
if (directHeader) return directHeader;
|
|
22215
|
+
const authorization = singleHeader(req.headers.authorization);
|
|
22216
|
+
if (!authorization) return null;
|
|
22217
|
+
const match = /^Bearer\s+(.+)$/i.exec(authorization);
|
|
22218
|
+
return match?.[1] ?? null;
|
|
22219
|
+
}
|
|
22220
|
+
function singleHeader(value) {
|
|
22221
|
+
if (!value) return null;
|
|
22222
|
+
return Array.isArray(value) ? value[0] ?? null : value;
|
|
22223
|
+
}
|
|
22224
|
+
function sendJson(res, status, body, headers = {}) {
|
|
22225
|
+
const payload = JSON.stringify(body);
|
|
22226
|
+
res.writeHead(status, {
|
|
22227
|
+
"Content-Type": "application/json",
|
|
22228
|
+
"Content-Length": Buffer.byteLength(payload).toString(),
|
|
22229
|
+
...headers
|
|
22230
|
+
});
|
|
22231
|
+
res.end(payload);
|
|
22232
|
+
}
|
|
22233
|
+
function hashToken(token) {
|
|
22234
|
+
return sha256Buffer(Buffer.from(token, "utf8"));
|
|
22235
|
+
}
|
|
22236
|
+
function verifyTokenHash(token, expectedHashHex) {
|
|
22237
|
+
const actual = Buffer.from(hashToken(token), "hex");
|
|
22238
|
+
const expected = Buffer.from(expectedHashHex, "hex");
|
|
22239
|
+
if (actual.byteLength !== expected.byteLength) return false;
|
|
22240
|
+
return timingSafeEqual(actual, expected);
|
|
22241
|
+
}
|
|
22242
|
+
function sha256Buffer(buffer) {
|
|
22243
|
+
return createHash8("sha256").update(buffer).digest("hex");
|
|
22244
|
+
}
|
|
22245
|
+
function canonicalJsonBuffer(value) {
|
|
22246
|
+
return Buffer.from(canonicalJson(value), "utf8");
|
|
22247
|
+
}
|
|
22248
|
+
function canonicalJson(value) {
|
|
22249
|
+
return JSON.stringify(sortJsonValue(value));
|
|
22250
|
+
}
|
|
22251
|
+
function sortJsonValue(value) {
|
|
22252
|
+
if (Array.isArray(value)) return value.map(sortJsonValue);
|
|
22253
|
+
if (!value || typeof value !== "object") return value;
|
|
22254
|
+
return Object.keys(value).sort().reduce((result, key) => {
|
|
22255
|
+
result[key] = sortJsonValue(value[key]);
|
|
22256
|
+
return result;
|
|
22257
|
+
}, {});
|
|
22258
|
+
}
|
|
22259
|
+
function onceDrain(res) {
|
|
22260
|
+
return new Promise((resolve) => res.once("drain", resolve));
|
|
22261
|
+
}
|
|
22262
|
+
|
|
21305
22263
|
// src/core.ts
|
|
21306
22264
|
var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
21307
22265
|
var RUNNER_CREDENTIAL_SCOPES = ["send", "read", "mentions", "tasks", "reactions", "server", "channels", "knowledge"];
|
|
@@ -21409,7 +22367,17 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
21409
22367
|
spanAttrs: ["running_agents_count", "idle_agents_count"]
|
|
21410
22368
|
},
|
|
21411
22369
|
"daemon.agent.activity.produced": {
|
|
21412
|
-
|
|
22370
|
+
// isHeartbeat/is_heartbeat (#460 V1) and process_instance_id (#460 V3)
|
|
22371
|
+
// were emitted by agentProcessManager but scrubbed here (pilot violation
|
|
22372
|
+
// V4): this list is a RUNTIME allowlist (SpanAttrContractTracer), so an
|
|
22373
|
+
// emission-site key that is not added here silently dies before disk.
|
|
22374
|
+
// Witness for the pair lives in agentProcessManager.builtin.e2e.test.ts
|
|
22375
|
+
// behind a contract-wrapped tracer (production-isomorphic oracle).
|
|
22376
|
+
// producerFactId/producer_fact_id and activity_kind/detail_kind are ALSO
|
|
22377
|
+
// emitted-and-scrubbed today; deliberately NOT added here — banned-join-
|
|
22378
|
+
// key discipline for the fact id (#460 classification ruling) means
|
|
22379
|
+
// widening needs its own ruling, not a drive-by.
|
|
22380
|
+
spanAttrs: ["agentId", "agent_id", "server_id", "machine_id", "activity", "detail_present", "entry_kinds", "ap_present", "launchId", "launch_id", "launch_id_present", "clientSeq", "client_seq", "client_seq_present", "correlation_id", "session_id_present", "runtime", "isHeartbeat", "is_heartbeat", "process_instance_id"]
|
|
21413
22381
|
},
|
|
21414
22382
|
"daemon.agent.activity.skipped": {
|
|
21415
22383
|
spanAttrs: ["agentId", "event_kind", "reason", "text_length"]
|
|
@@ -21418,7 +22386,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
|
|
|
21418
22386
|
spanAttrs: ["agentId", "event_kind", "runtime"]
|
|
21419
22387
|
}
|
|
21420
22388
|
};
|
|
21421
|
-
var DAEMON_CLI_USAGE =
|
|
22389
|
+
var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
|
|
21422
22390
|
var RunnerCredentialMintError2 = class extends Error {
|
|
21423
22391
|
code;
|
|
21424
22392
|
retryable;
|
|
@@ -21454,9 +22422,9 @@ function runnerCredentialErrorDetail2(error) {
|
|
|
21454
22422
|
async function waitForRunnerCredentialRetry2() {
|
|
21455
22423
|
await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
|
|
21456
22424
|
}
|
|
21457
|
-
function parseDaemonCliArgs(args) {
|
|
22425
|
+
function parseDaemonCliArgs(args, env = {}) {
|
|
21458
22426
|
let serverUrl = "";
|
|
21459
|
-
let apiKey = "";
|
|
22427
|
+
let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
|
|
21460
22428
|
for (let i = 0; i < args.length; i++) {
|
|
21461
22429
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
21462
22430
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -21473,13 +22441,13 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
|
|
|
21473
22441
|
}
|
|
21474
22442
|
}
|
|
21475
22443
|
function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
21476
|
-
const thisDir =
|
|
21477
|
-
const bundledDistPath =
|
|
22444
|
+
const thisDir = path20.dirname(fileURLToPath(moduleUrl));
|
|
22445
|
+
const bundledDistPath = path20.resolve(thisDir, "cli", "index.js");
|
|
21478
22446
|
try {
|
|
21479
22447
|
accessSync(bundledDistPath);
|
|
21480
22448
|
return bundledDistPath;
|
|
21481
22449
|
} catch {
|
|
21482
|
-
const workspaceDistPath =
|
|
22450
|
+
const workspaceDistPath = path20.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
|
|
21483
22451
|
accessSync(workspaceDistPath);
|
|
21484
22452
|
return workspaceDistPath;
|
|
21485
22453
|
}
|
|
@@ -21493,7 +22461,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
|
|
|
21493
22461
|
}
|
|
21494
22462
|
async function runBundledSlockCli(argv) {
|
|
21495
22463
|
process.argv = [process.execPath, "slock", ...argv];
|
|
21496
|
-
await import("./dist-
|
|
22464
|
+
await import("./dist-PAW4LJQD.js");
|
|
21497
22465
|
}
|
|
21498
22466
|
function detectRuntimes(tracer = noopTracer) {
|
|
21499
22467
|
const ids = [];
|
|
@@ -21701,7 +22669,7 @@ var DaemonCore = class {
|
|
|
21701
22669
|
}
|
|
21702
22670
|
resolveMachineStateRoot() {
|
|
21703
22671
|
if (this.options.machineStateDir) return this.options.machineStateDir;
|
|
21704
|
-
if (this.options.dataDir) return
|
|
22672
|
+
if (this.options.dataDir) return path20.join(path20.dirname(this.options.dataDir), "machines");
|
|
21705
22673
|
return resolveDefaultMachineStateRoot();
|
|
21706
22674
|
}
|
|
21707
22675
|
shouldEnableLocalTrace() {
|
|
@@ -21729,7 +22697,7 @@ var DaemonCore = class {
|
|
|
21729
22697
|
sinks: [this.localTraceSink]
|
|
21730
22698
|
}));
|
|
21731
22699
|
this.agentManager.setTracer(this.tracer);
|
|
21732
|
-
this.agentManager.setCliTransportTraceDir(
|
|
22700
|
+
this.agentManager.setCliTransportTraceDir(path20.join(machineDir, "traces"));
|
|
21733
22701
|
}
|
|
21734
22702
|
installTraceBundleUploader(machineDir) {
|
|
21735
22703
|
if (!this.shouldEnableLocalTrace()) return;
|
|
@@ -22018,7 +22986,7 @@ var DaemonCore = class {
|
|
|
22018
22986
|
session_id_present: Boolean(msg.config.sessionId)
|
|
22019
22987
|
}, "error");
|
|
22020
22988
|
this.connection.send({ type: "agent:status", agentId: msg.agentId, status: "inactive", launchId: msg.launchId });
|
|
22021
|
-
this.connection.send({ type: "agent:activity", agentId: msg.agentId, activity: "offline", detail: classification.userMessage, launchId: msg.launchId });
|
|
22989
|
+
this.connection.send({ type: "agent:activity", agentId: msg.agentId, activity: "offline", detail: classification.userMessage, launchId: msg.launchId, observedAtMs: Date.now() });
|
|
22022
22990
|
});
|
|
22023
22991
|
break;
|
|
22024
22992
|
case "agent:stop":
|
|
@@ -22435,9 +23403,15 @@ var DaemonCore = class {
|
|
|
22435
23403
|
|
|
22436
23404
|
export {
|
|
22437
23405
|
subscribeDaemonLogs,
|
|
23406
|
+
DAEMON_API_KEY_ENV,
|
|
23407
|
+
scrubDaemonAuthEnv,
|
|
22438
23408
|
resolveWorkspaceDirectoryPath,
|
|
22439
23409
|
scanWorkspaceDirectories,
|
|
22440
23410
|
deleteWorkspaceDirectory,
|
|
23411
|
+
AGENT_MIGRATION_BUNDLE_SCHEMA_VERSION,
|
|
23412
|
+
buildAgentMigrationExportManifest,
|
|
23413
|
+
AgentMigrationGrantRegistry,
|
|
23414
|
+
createAgentMigrationHttpTransport,
|
|
22441
23415
|
DAEMON_CORE_TRACE_ATTR_CONTRACTS,
|
|
22442
23416
|
DAEMON_CLI_USAGE,
|
|
22443
23417
|
parseDaemonCliArgs,
|