@adhdev/daemon-core 0.9.82-rc.325 → 0.9.82-rc.327

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/index.js CHANGED
@@ -313,10 +313,10 @@ function readInjected(value) {
313
313
  }
314
314
  function getDaemonBuildInfo() {
315
315
  if (cached) return cached;
316
- const commit = readInjected(true ? "a0aeebdac30d9abea5b46e3f2618f864bbff19d0" : void 0) ?? "unknown";
317
- const commitShort = readInjected(true ? "a0aeebda" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
318
- const version = readInjected(true ? "0.9.82-rc.325" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
319
- const builtAt = readInjected(true ? "2026-06-19T08:24:25.509Z" : void 0);
316
+ const commit = readInjected(true ? "993e3922de8abe554822450e2b4c26c2c9f5f64a" : void 0) ?? "unknown";
317
+ const commitShort = readInjected(true ? "993e3922" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
318
+ const version = readInjected(true ? "0.9.82-rc.327" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
319
+ const builtAt = readInjected(true ? "2026-06-19T12:31:25.870Z" : void 0);
320
320
  cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
321
321
  return cached;
322
322
  }
@@ -1942,6 +1942,8 @@ function updateNode(meshId, nodeId, opts) {
1942
1942
  const node = mesh.nodes.find((n) => n.id === nodeId);
1943
1943
  if (!node) return void 0;
1944
1944
  if (opts.userOverrides) node.userOverrides = { ...node.userOverrides, ...opts.userOverrides };
1945
+ if (opts.reportedPlatform && opts.reportedPlatform.trim()) node.reportedPlatform = opts.reportedPlatform.trim();
1946
+ if (opts.reportedArch && opts.reportedArch.trim()) node.reportedArch = opts.reportedArch.trim();
1945
1947
  if (opts.policy) node.policy = { ...node.policy, ...opts.policy };
1946
1948
  if (opts.worktreeBootstrap) node.worktreeBootstrap = opts.worktreeBootstrap;
1947
1949
  if (Object.prototype.hasOwnProperty.call(opts, "systemPrompt")) {
@@ -3108,11 +3110,15 @@ function readNodeOverride(node, key) {
3108
3110
  const value = overrides[key];
3109
3111
  return typeof value === "string" && value.trim() ? value.trim() : null;
3110
3112
  }
3113
+ function readNodeReporter(node, key) {
3114
+ const value = key === "platform" ? node?.reportedPlatform : node?.reportedArch;
3115
+ return typeof value === "string" && value.trim() ? value.trim() : null;
3116
+ }
3111
3117
  function buildMeshNodeCapabilityTags(node, providerType) {
3112
3118
  const provider = typeof providerType === "string" && providerType.trim() ? providerType.trim() : firstProviderPriority(node?.policy);
3113
3119
  const worktreeBranch = typeof node?.worktreeBranch === "string" && node.worktreeBranch.trim() ? node.worktreeBranch.trim() : null;
3114
- const os30 = readNodeOverride(node, "platform") ?? process.platform;
3115
- const arch2 = readNodeOverride(node, "arch") ?? process.arch;
3120
+ const os30 = readNodeOverride(node, "platform") ?? readNodeReporter(node, "platform") ?? process.platform;
3121
+ const arch2 = readNodeOverride(node, "arch") ?? readNodeReporter(node, "arch") ?? process.arch;
3116
3122
  return normalizeMeshCapabilityTags([
3117
3123
  ...Array.isArray(node?.capabilities) ? node.capabilities : [],
3118
3124
  `os=${os30}`,
@@ -10134,6 +10140,644 @@ var init_mesh_events_coordinator = __esm({
10134
10140
  }
10135
10141
  });
10136
10142
 
10143
+ // src/providers/io-contracts.ts
10144
+ function normalizeInputEnvelope(input) {
10145
+ const normalized = normalizeInputEnvelopePayload(input);
10146
+ const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
10147
+ return {
10148
+ parts: normalized.parts,
10149
+ textFallback,
10150
+ ...normalized.metadata ? { metadata: normalized.metadata } : {}
10151
+ };
10152
+ }
10153
+ function normalizeMessageParts(content) {
10154
+ if (typeof content === "string") return [{ type: "text", text: content }];
10155
+ if (!Array.isArray(content)) {
10156
+ if (content && typeof content === "object" && typeof content.text === "string") {
10157
+ return [{ type: "text", text: String(content.text) }];
10158
+ }
10159
+ return [];
10160
+ }
10161
+ const parts = [];
10162
+ for (const raw of content) {
10163
+ if (typeof raw === "string") {
10164
+ parts.push({ type: "text", text: raw });
10165
+ continue;
10166
+ }
10167
+ if (!raw || typeof raw !== "object") continue;
10168
+ const part = normalizeMessagePartObject(raw);
10169
+ if (part) parts.push(part);
10170
+ }
10171
+ return parts;
10172
+ }
10173
+ function flattenMessageParts(parts) {
10174
+ return parts.map((part) => {
10175
+ if (part.type === "text") return part.text;
10176
+ if (part.type === "resource") return part.resource.text || "";
10177
+ if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
10178
+ if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
10179
+ if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
10180
+ if (part.type === "resource_link") return [part.name, part.description].filter(Boolean).join("\n");
10181
+ return "";
10182
+ }).filter((value) => value.length > 0).join("\n");
10183
+ }
10184
+ function normalizeInputEnvelopePayload(input) {
10185
+ if (typeof input === "string") {
10186
+ return { parts: [{ type: "text", text: input }], textFallback: input };
10187
+ }
10188
+ if (!input || typeof input !== "object") {
10189
+ return { parts: [], textFallback: "" };
10190
+ }
10191
+ const record = input;
10192
+ const nestedInput = record.input;
10193
+ if (nestedInput && typeof nestedInput === "object") {
10194
+ const nested = nestedInput;
10195
+ return {
10196
+ parts: normalizeInputParts(nested.parts ?? nested.prompt),
10197
+ textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
10198
+ metadata: normalizeInputMetadata(nested.metadata)
10199
+ };
10200
+ }
10201
+ const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
10202
+ if (directText !== void 0) {
10203
+ return { parts: [{ type: "text", text: directText }], textFallback: directText };
10204
+ }
10205
+ const directParts = normalizeInputParts(record.parts ?? record.prompt);
10206
+ return {
10207
+ parts: directParts,
10208
+ textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
10209
+ metadata: normalizeInputMetadata(record.metadata)
10210
+ };
10211
+ }
10212
+ function normalizeInputMetadata(value) {
10213
+ if (!value || typeof value !== "object") return void 0;
10214
+ const record = value;
10215
+ const metadata = {};
10216
+ if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
10217
+ metadata.source = record.source;
10218
+ }
10219
+ if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
10220
+ metadata.clientTimestamp = record.clientTimestamp;
10221
+ }
10222
+ return Object.keys(metadata).length > 0 ? metadata : void 0;
10223
+ }
10224
+ function normalizeInputParts(value) {
10225
+ if (!Array.isArray(value)) return [];
10226
+ const parts = [];
10227
+ for (const raw of value) {
10228
+ if (typeof raw === "string") {
10229
+ parts.push({ type: "text", text: raw });
10230
+ continue;
10231
+ }
10232
+ if (!raw || typeof raw !== "object") continue;
10233
+ const part = normalizeInputPartObject(raw);
10234
+ if (part) parts.push(part);
10235
+ }
10236
+ return parts;
10237
+ }
10238
+ function normalizeInputPartObject(raw) {
10239
+ const type = raw.type;
10240
+ if (type === "text" && typeof raw.text === "string") {
10241
+ return { type, text: raw.text };
10242
+ }
10243
+ if (type === "image" && typeof raw.mimeType === "string") {
10244
+ return {
10245
+ type,
10246
+ mimeType: raw.mimeType,
10247
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10248
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10249
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
10250
+ };
10251
+ }
10252
+ if (type === "audio" && typeof raw.mimeType === "string") {
10253
+ return {
10254
+ type,
10255
+ mimeType: raw.mimeType,
10256
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10257
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10258
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
10259
+ };
10260
+ }
10261
+ if (type === "video" && typeof raw.mimeType === "string") {
10262
+ return {
10263
+ type,
10264
+ mimeType: raw.mimeType,
10265
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10266
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10267
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
10268
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
10269
+ };
10270
+ }
10271
+ if (type === "resource" && typeof raw.uri === "string") {
10272
+ return {
10273
+ type,
10274
+ uri: raw.uri,
10275
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
10276
+ ...typeof raw.name === "string" ? { name: raw.name } : {},
10277
+ ...typeof raw.text === "string" ? { text: raw.text } : {},
10278
+ ...typeof raw.data === "string" ? { data: raw.data } : {}
10279
+ };
10280
+ }
10281
+ if (type === "resource_link" && typeof raw.uri === "string") {
10282
+ return {
10283
+ type,
10284
+ uri: raw.uri,
10285
+ name: typeof raw.name === "string" ? raw.name : getUriDisplayName(raw.uri, "resource"),
10286
+ ...typeof raw.title === "string" ? { title: raw.title } : {},
10287
+ ...typeof raw.description === "string" ? { description: raw.description } : {},
10288
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
10289
+ ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
10290
+ ...normalizeAnnotationsProperty(raw.annotations)
10291
+ };
10292
+ }
10293
+ return null;
10294
+ }
10295
+ function normalizeMessagePartObject(raw) {
10296
+ const type = raw.type;
10297
+ if (type === "text" && typeof raw.text === "string") {
10298
+ return { type, text: raw.text };
10299
+ }
10300
+ if (type === "image" && typeof raw.mimeType === "string") {
10301
+ return {
10302
+ type,
10303
+ mimeType: raw.mimeType,
10304
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10305
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10306
+ ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
10307
+ };
10308
+ }
10309
+ if (type === "audio" && typeof raw.mimeType === "string") {
10310
+ return {
10311
+ type,
10312
+ mimeType: raw.mimeType,
10313
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10314
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10315
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
10316
+ };
10317
+ }
10318
+ if (type === "video" && typeof raw.mimeType === "string") {
10319
+ return {
10320
+ type,
10321
+ mimeType: raw.mimeType,
10322
+ ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
10323
+ ...typeof raw.data === "string" ? { data: raw.data } : {},
10324
+ ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
10325
+ ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
10326
+ };
10327
+ }
10328
+ if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
10329
+ return {
10330
+ type,
10331
+ uri: raw.uri,
10332
+ name: raw.name,
10333
+ ...typeof raw.title === "string" ? { title: raw.title } : {},
10334
+ ...typeof raw.description === "string" ? { description: raw.description } : {},
10335
+ ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
10336
+ ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
10337
+ ...normalizeAnnotationsProperty(raw.annotations)
10338
+ };
10339
+ }
10340
+ if (type === "resource" && raw.resource && typeof raw.resource === "object") {
10341
+ const resource = raw.resource;
10342
+ if (typeof resource.uri !== "string") return null;
10343
+ return {
10344
+ type,
10345
+ resource: {
10346
+ uri: resource.uri,
10347
+ ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
10348
+ ...typeof resource.text === "string" ? { text: resource.text } : {},
10349
+ ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
10350
+ }
10351
+ };
10352
+ }
10353
+ return null;
10354
+ }
10355
+ function flattenInputParts(parts) {
10356
+ return parts.map((part) => {
10357
+ if (part.type === "text") return part.text;
10358
+ if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
10359
+ if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
10360
+ if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
10361
+ if (part.type === "resource_link") return [part.title, part.name, part.description, part.uri].filter(Boolean).join("\n");
10362
+ if (part.type === "resource") return part.text || part.name || part.uri;
10363
+ return "";
10364
+ }).filter((value) => value.length > 0).join("\n");
10365
+ }
10366
+ function getUriDisplayName(uri, fallback) {
10367
+ try {
10368
+ const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
10369
+ return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
10370
+ } catch {
10371
+ return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
10372
+ }
10373
+ }
10374
+ function normalizeAnnotationsProperty(value) {
10375
+ if (!value || typeof value !== "object") return {};
10376
+ const record = value;
10377
+ const annotations = {};
10378
+ if (Array.isArray(record.audience)) {
10379
+ const audience = record.audience.filter((item) => item === "user" || item === "assistant");
10380
+ if (audience.length > 0) annotations.audience = audience;
10381
+ }
10382
+ if (typeof record.priority === "number" && Number.isFinite(record.priority)) {
10383
+ annotations.priority = record.priority;
10384
+ }
10385
+ return Object.keys(annotations).length > 0 ? { annotations } : {};
10386
+ }
10387
+ var init_io_contracts = __esm({
10388
+ "src/providers/io-contracts.ts"() {
10389
+ "use strict";
10390
+ }
10391
+ });
10392
+
10393
+ // src/providers/contracts.ts
10394
+ function flattenContent(content) {
10395
+ if (typeof content === "string") return content;
10396
+ return flattenMessageParts(normalizeMessageParts(content));
10397
+ }
10398
+ var init_contracts = __esm({
10399
+ "src/providers/contracts.ts"() {
10400
+ "use strict";
10401
+ init_io_contracts();
10402
+ init_io_contracts();
10403
+ }
10404
+ });
10405
+
10406
+ // src/providers/chat-message-normalization.ts
10407
+ function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
10408
+ if (!Array.isArray(messages) || messages.length === 0) return "";
10409
+ for (let i = messages.length - 1; i >= 0; i--) {
10410
+ const msg = messages[i];
10411
+ if (!msg) continue;
10412
+ const classification = classifyChatMessageVisibility(msg);
10413
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
10414
+ const text = flattenContent(msg.content).trim();
10415
+ if (text) return text.slice(0, maxChars);
10416
+ }
10417
+ }
10418
+ return "";
10419
+ }
10420
+ function readChatMessageTimestampIso(message) {
10421
+ if (!message) return void 0;
10422
+ const record = message;
10423
+ for (const value of [record.timestamp, record.createdAt, record.created_at, record.updatedAt, record.time]) {
10424
+ if (typeof value === "number" && Number.isFinite(value)) {
10425
+ const ms = value > 1e10 ? value : value * 1e3;
10426
+ return new Date(ms).toISOString();
10427
+ }
10428
+ if (typeof value === "string" && value.trim()) {
10429
+ const ms = new Date(value.trim()).getTime();
10430
+ if (Number.isFinite(ms)) return new Date(ms).toISOString();
10431
+ }
10432
+ }
10433
+ return void 0;
10434
+ }
10435
+ function extractFinalAssistantSummaryEvidence(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
10436
+ if (!Array.isArray(messages) || messages.length === 0) return { finalSummary: "" };
10437
+ for (let i = messages.length - 1; i >= 0; i--) {
10438
+ const msg = messages[i];
10439
+ if (!msg) continue;
10440
+ const classification = classifyChatMessageVisibility(msg);
10441
+ if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
10442
+ const text = flattenContent(msg.content).trim();
10443
+ if (text) {
10444
+ return {
10445
+ finalSummary: text.slice(0, maxChars),
10446
+ transcriptMessageAt: readChatMessageTimestampIso(msg)
10447
+ };
10448
+ }
10449
+ }
10450
+ }
10451
+ return { finalSummary: "" };
10452
+ }
10453
+ function canonicalizeKindHint(value) {
10454
+ return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
10455
+ }
10456
+ function resolveBuiltinOrAliasKind(kind) {
10457
+ if (typeof kind !== "string") return null;
10458
+ const normalizedKind = canonicalizeKindHint(kind);
10459
+ if (!normalizedKind) return null;
10460
+ if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
10461
+ return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
10462
+ }
10463
+ function inferHintKind(value) {
10464
+ const direct = resolveBuiltinOrAliasKind(value);
10465
+ if (direct) return direct;
10466
+ if (typeof value !== "string") return null;
10467
+ const normalized = canonicalizeKindHint(value);
10468
+ if (!normalized) return null;
10469
+ if (/thought|thinking|reasoning/.test(normalized)) return "thought";
10470
+ if (/tool/.test(normalized)) return "tool";
10471
+ if (/terminal|command|shell|console/.test(normalized)) return "terminal";
10472
+ return null;
10473
+ }
10474
+ function inferKindFromToolCalls(message) {
10475
+ const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
10476
+ if (toolCalls.length === 0) return null;
10477
+ if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
10478
+ if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
10479
+ if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
10480
+ return "terminal";
10481
+ }
10482
+ return "tool";
10483
+ }
10484
+ function inferMissingChatMessageKind(message) {
10485
+ const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
10486
+ if (role === "system") return "system";
10487
+ const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
10488
+ const hintCandidates = [
10489
+ message?._sub,
10490
+ message?._type,
10491
+ meta?.label,
10492
+ typeof message?.senderName === "string" ? message.senderName : void 0
10493
+ ];
10494
+ for (const candidate of hintCandidates) {
10495
+ const inferred = inferHintKind(candidate);
10496
+ if (inferred) return inferred;
10497
+ }
10498
+ const inferredFromToolCalls = inferKindFromToolCalls(message);
10499
+ if (inferredFromToolCalls) return inferredFromToolCalls;
10500
+ return null;
10501
+ }
10502
+ function isBuiltinChatMessageKind(kind) {
10503
+ return resolveBuiltinOrAliasKind(kind) !== null;
10504
+ }
10505
+ function normalizeChatMessageKind(kind, role) {
10506
+ const resolvedKind = resolveBuiltinOrAliasKind(kind);
10507
+ if (resolvedKind) return resolvedKind;
10508
+ const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
10509
+ return normalizedRole === "system" ? "system" : "standard";
10510
+ }
10511
+ function resolveChatMessageKind(message) {
10512
+ const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
10513
+ if (explicitKind) return explicitKind;
10514
+ const inferredKind = inferMissingChatMessageKind(message);
10515
+ if (inferredKind) return inferredKind;
10516
+ return normalizeChatMessageKind(message?.kind, message?.role);
10517
+ }
10518
+ function buildChatMessage(message) {
10519
+ return {
10520
+ ...message,
10521
+ kind: resolveChatMessageKind(message)
10522
+ };
10523
+ }
10524
+ function buildSystemChatMessage(message) {
10525
+ return buildChatMessage({
10526
+ ...message,
10527
+ role: "system",
10528
+ kind: message?.kind || "system"
10529
+ });
10530
+ }
10531
+ function buildRuntimeSystemChatMessage(message) {
10532
+ return buildSystemChatMessage({
10533
+ ...message,
10534
+ senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
10535
+ });
10536
+ }
10537
+ function buildAssistantChatMessage(message) {
10538
+ return buildChatMessage({
10539
+ ...message,
10540
+ role: "assistant",
10541
+ kind: message?.kind || "standard"
10542
+ });
10543
+ }
10544
+ function buildThoughtChatMessage(message) {
10545
+ return buildAssistantChatMessage({
10546
+ ...message,
10547
+ kind: message?.kind || "thought"
10548
+ });
10549
+ }
10550
+ function buildToolChatMessage(message) {
10551
+ return buildAssistantChatMessage({
10552
+ ...message,
10553
+ kind: message?.kind || "tool"
10554
+ });
10555
+ }
10556
+ function buildTerminalChatMessage(message) {
10557
+ return buildAssistantChatMessage({
10558
+ ...message,
10559
+ kind: message?.kind || "terminal"
10560
+ });
10561
+ }
10562
+ function buildUserChatMessage(message) {
10563
+ return buildChatMessage({
10564
+ ...message,
10565
+ role: "user",
10566
+ kind: message?.kind || "standard"
10567
+ });
10568
+ }
10569
+ function normalizeChatMessage(message) {
10570
+ return buildChatMessage(message);
10571
+ }
10572
+ function normalizeChatMessages(messages) {
10573
+ return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
10574
+ }
10575
+ function readMessageMeta(message) {
10576
+ const meta = message?.meta;
10577
+ return meta && typeof meta === "object" && !Array.isArray(meta) ? meta : null;
10578
+ }
10579
+ function readStringField(value) {
10580
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
10581
+ }
10582
+ function readRecordField(message, meta, key) {
10583
+ const record = message;
10584
+ return record[key] ?? meta?.[key];
10585
+ }
10586
+ function readVisibilityField(message, meta) {
10587
+ return readStringField(readRecordField(message, meta, "visibility"));
10588
+ }
10589
+ function readTranscriptVisibilityField(message, meta) {
10590
+ const record = message;
10591
+ return readStringField(record.transcriptVisibility ?? meta?.transcriptVisibility ?? record.visibility ?? meta?.visibility);
10592
+ }
10593
+ function hasBooleanMarker(message, meta, keys) {
10594
+ const record = message;
10595
+ return keys.some((key) => record[key] === true || meta?.[key] === true);
10596
+ }
10597
+ function isActivityKind(kind) {
10598
+ return kind === "thought" || kind === "tool" || kind === "terminal";
10599
+ }
10600
+ function isOrdinaryVisibleTurn(message, role, kind) {
10601
+ if (role === "user" || role === "human") return kind === "standard" || kind === "";
10602
+ if (role === "assistant") return kind === "standard" || kind === "";
10603
+ return false;
10604
+ }
10605
+ function classifyChatMessageVisibility(message) {
10606
+ if (!message) {
10607
+ return {
10608
+ surface: "internal",
10609
+ isUserFacing: false,
10610
+ isActivityFacing: false,
10611
+ isInternal: true,
10612
+ explicitUserFacing: false,
10613
+ explicitHidden: true,
10614
+ role: "",
10615
+ kind: "standard",
10616
+ visibility: "",
10617
+ transcriptVisibility: "",
10618
+ audience: "",
10619
+ source: ""
10620
+ };
10621
+ }
10622
+ const meta = readMessageMeta(message);
10623
+ const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
10624
+ const kind = resolveChatMessageKind(message);
10625
+ const visibility = readVisibilityField(message, meta);
10626
+ const transcriptVisibility = readTranscriptVisibilityField(message, meta);
10627
+ const audience = readStringField(readRecordField(message, meta, "audience"));
10628
+ const source = readStringField(readRecordField(message, meta, "source"));
10629
+ const explicitHidden = EXPLICIT_HIDDEN_VISIBILITIES.has(visibility) || EXPLICIT_HIDDEN_VISIBILITIES.has(transcriptVisibility) || HIDDEN_AUDIENCES.has(audience) || hasBooleanMarker(message, meta, ["hidden", "internal", "isInternal", "debug", "statusOnly", "controlOnly"]);
10630
+ const explicitUserFacing = EXPLICIT_VISIBLE_VISIBILITIES.has(visibility) || EXPLICIT_VISIBLE_VISIBILITIES.has(transcriptVisibility) || audience === "chat" || hasBooleanMarker(message, meta, ["userFacing"]);
10631
+ if (explicitHidden) {
10632
+ const activityLike = isActivityKind(kind) || ACTIVITY_SOURCE_SET.has(source);
10633
+ return {
10634
+ surface: activityLike ? "activity" : "internal",
10635
+ isUserFacing: false,
10636
+ isActivityFacing: activityLike,
10637
+ isInternal: !activityLike,
10638
+ explicitUserFacing,
10639
+ explicitHidden,
10640
+ role,
10641
+ kind,
10642
+ visibility,
10643
+ transcriptVisibility,
10644
+ audience,
10645
+ source
10646
+ };
10647
+ }
10648
+ if (explicitUserFacing) {
10649
+ return {
10650
+ surface: "chat",
10651
+ isUserFacing: true,
10652
+ isActivityFacing: false,
10653
+ isInternal: false,
10654
+ explicitUserFacing,
10655
+ explicitHidden,
10656
+ role,
10657
+ kind,
10658
+ visibility,
10659
+ transcriptVisibility,
10660
+ audience,
10661
+ source
10662
+ };
10663
+ }
10664
+ if (INTERNAL_SOURCE_SET.has(source) || role === "system" || kind === "system") {
10665
+ return {
10666
+ surface: "internal",
10667
+ isUserFacing: false,
10668
+ isActivityFacing: false,
10669
+ isInternal: true,
10670
+ explicitUserFacing,
10671
+ explicitHidden,
10672
+ role,
10673
+ kind,
10674
+ visibility,
10675
+ transcriptVisibility,
10676
+ audience,
10677
+ source
10678
+ };
10679
+ }
10680
+ if (ACTIVITY_SOURCE_SET.has(source) || isActivityKind(kind)) {
10681
+ return {
10682
+ surface: "activity",
10683
+ isUserFacing: false,
10684
+ isActivityFacing: true,
10685
+ isInternal: false,
10686
+ explicitUserFacing,
10687
+ explicitHidden,
10688
+ role,
10689
+ kind,
10690
+ visibility,
10691
+ transcriptVisibility,
10692
+ audience,
10693
+ source
10694
+ };
10695
+ }
10696
+ const isUserFacing = isOrdinaryVisibleTurn(message, role, kind);
10697
+ return {
10698
+ surface: isUserFacing ? "chat" : "internal",
10699
+ isUserFacing,
10700
+ isActivityFacing: false,
10701
+ isInternal: !isUserFacing,
10702
+ explicitUserFacing,
10703
+ explicitHidden,
10704
+ role,
10705
+ kind,
10706
+ visibility,
10707
+ transcriptVisibility,
10708
+ audience,
10709
+ source
10710
+ };
10711
+ }
10712
+ function isUserFacingChatMessage(message) {
10713
+ return classifyChatMessageVisibility(message).isUserFacing;
10714
+ }
10715
+ function isActivityChatMessage(message) {
10716
+ return classifyChatMessageVisibility(message).isActivityFacing;
10717
+ }
10718
+ function isInternalChatMessage(message) {
10719
+ return classifyChatMessageVisibility(message).isInternal;
10720
+ }
10721
+ function filterUserFacingChatMessages(messages) {
10722
+ return (Array.isArray(messages) ? messages : []).filter((message) => isUserFacingChatMessage(message));
10723
+ }
10724
+ function filterActivityChatMessages(messages) {
10725
+ return (Array.isArray(messages) ? messages : []).filter((message) => isActivityChatMessage(message));
10726
+ }
10727
+ function filterInternalChatMessages(messages) {
10728
+ return (Array.isArray(messages) ? messages : []).filter((message) => isInternalChatMessage(message));
10729
+ }
10730
+ function filterChatMessagesByVisibility(messages, surface) {
10731
+ return (Array.isArray(messages) ? messages : []).filter((message) => classifyChatMessageVisibility(message).surface === surface);
10732
+ }
10733
+ var DEFAULT_FINAL_SUMMARY_MAX_CHARS, BUILTIN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_VISIBILITIES, CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES, CHAT_MESSAGE_AUDIENCES, CHAT_MESSAGE_SOURCES, CHAT_MESSAGE_ACTIVITY_SOURCES, CHAT_MESSAGE_INTERNAL_SOURCES, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES, EXPLICIT_HIDDEN_VISIBILITIES, EXPLICIT_VISIBLE_VISIBILITIES, HIDDEN_AUDIENCES, ACTIVITY_SOURCE_SET, INTERNAL_SOURCE_SET;
10734
+ var init_chat_message_normalization = __esm({
10735
+ "src/providers/chat-message-normalization.ts"() {
10736
+ "use strict";
10737
+ init_contracts();
10738
+ DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
10739
+ BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
10740
+ CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
10741
+ CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
10742
+ CHAT_MESSAGE_AUDIENCES = ["chat", "debug", "trace", "internal"];
10743
+ CHAT_MESSAGE_SOURCES = [
10744
+ "assistant_text",
10745
+ "tool_call",
10746
+ "terminal_command",
10747
+ "runtime_activity",
10748
+ "runtime_status",
10749
+ "provider_chrome",
10750
+ "control"
10751
+ ];
10752
+ CHAT_MESSAGE_ACTIVITY_SOURCES = ["tool_call", "terminal_command", "runtime_activity"];
10753
+ CHAT_MESSAGE_INTERNAL_SOURCES = ["runtime_status", "provider_chrome", "control"];
10754
+ KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
10755
+ CHAT_MESSAGE_KIND_ALIASES = {
10756
+ text: "standard",
10757
+ message: "standard",
10758
+ assistant: "standard",
10759
+ thinking: "thought",
10760
+ think: "thought",
10761
+ reasoning: "thought",
10762
+ reason: "thought",
10763
+ toolcall: "tool",
10764
+ tool_call: "tool",
10765
+ tooluse: "tool",
10766
+ tool_use: "tool",
10767
+ action: "tool",
10768
+ command: "terminal",
10769
+ cmd: "terminal",
10770
+ shell: "terminal",
10771
+ console: "terminal"
10772
+ };
10773
+ EXPLICIT_HIDDEN_VISIBILITIES = /* @__PURE__ */ new Set(["hidden", "debug", "internal"]);
10774
+ EXPLICIT_VISIBLE_VISIBILITIES = /* @__PURE__ */ new Set(["visible", "user", "chat"]);
10775
+ HIDDEN_AUDIENCES = /* @__PURE__ */ new Set(["debug", "trace", "internal"]);
10776
+ ACTIVITY_SOURCE_SET = new Set(CHAT_MESSAGE_ACTIVITY_SOURCES);
10777
+ INTERNAL_SOURCE_SET = new Set(CHAT_MESSAGE_INTERNAL_SOURCES);
10778
+ }
10779
+ });
10780
+
10137
10781
  // src/mesh/mesh-reconcile-loop.ts
10138
10782
  function resolveReconcileIntervalMs() {
10139
10783
  const raw = readNonEmptyString2(process.env.MESH_RECONCILE_INTERVAL_MS);
@@ -10237,6 +10881,15 @@ async function runMeshReconcileTick(components) {
10237
10881
  LOG.warn("MeshReconcile", `Pending-claim recovery trigger failed for mesh ${mesh.id}: ${e?.message || e}`);
10238
10882
  }
10239
10883
  }
10884
+ for (const mesh of listMeshes()) {
10885
+ const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
10886
+ if (!daemonHostsMesh(mesh, selfIds)) continue;
10887
+ try {
10888
+ await reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId);
10889
+ } catch (e) {
10890
+ LOG.warn("MeshReconcile", `Completion reconcile failed for mesh ${mesh.id}: ${e?.message || e}`);
10891
+ }
10892
+ }
10240
10893
  const coordinators = findLiveCoordinators(components);
10241
10894
  if (coordinators.length === 0) {
10242
10895
  return;
@@ -10330,6 +10983,95 @@ async function pullRemoteNodeQueues(components, mesh, localDaemonId, candidateDa
10330
10983
  }
10331
10984
  }
10332
10985
  }
10986
+ function unwrapReadChatPayload(raw) {
10987
+ let cursor = raw;
10988
+ for (let depth = 0; depth < 4 && cursor && typeof cursor === "object"; depth++) {
10989
+ const record = cursor;
10990
+ if (Array.isArray(record.messages)) return record;
10991
+ if (record.payload && typeof record.payload === "object") {
10992
+ cursor = record.payload;
10993
+ continue;
10994
+ }
10995
+ if (record.result && typeof record.result === "object") {
10996
+ cursor = record.result;
10997
+ continue;
10998
+ }
10999
+ if (record.data && typeof record.data === "object") {
11000
+ cursor = record.data;
11001
+ continue;
11002
+ }
11003
+ break;
11004
+ }
11005
+ return cursor && typeof cursor === "object" ? cursor : null;
11006
+ }
11007
+ function readChatPayloadStatus(payload) {
11008
+ return readNonEmptyString2(payload?.status).toLowerCase();
11009
+ }
11010
+ async function reconcileUnterminatedDirectDispatches(components, mesh, selfIds, localDaemonId) {
11011
+ const dispatches = getActiveDirectDispatches(mesh.id);
11012
+ if (dispatches.length === 0) return;
11013
+ const dispatchMeshCommand = components.dispatchMeshCommand;
11014
+ const nodeById = new Map(mesh.nodes.map((n) => [n.id, n]));
11015
+ for (const dispatch of dispatches) {
11016
+ const sessionId = readNonEmptyString2(dispatch.sessionId);
11017
+ const nodeId = readNonEmptyString2(dispatch.nodeId);
11018
+ const taskId = readNonEmptyString2(dispatch.taskId);
11019
+ if (!sessionId || !nodeId || !taskId) continue;
11020
+ const node = nodeById.get(nodeId);
11021
+ const nodeDaemonId = readNonEmptyString2(node?.daemonId);
11022
+ const isLocalNode = !nodeDaemonId || selfIds.includes(nodeDaemonId) || localDaemonId !== void 0 && nodeDaemonId === localDaemonId || !!components.instanceManager.getInstance(sessionId);
11023
+ const providerType = readNonEmptyString2(dispatch.providerType);
11024
+ const readArgs = {
11025
+ sessionId,
11026
+ targetSessionId: sessionId,
11027
+ tailLimit: 10,
11028
+ ...node?.workspace ? { workspace: node.workspace } : {},
11029
+ ...providerType ? { agentType: providerType, providerType } : {}
11030
+ };
11031
+ let payload = null;
11032
+ try {
11033
+ if (isLocalNode) {
11034
+ const result = await components.commandHandler.handle("read_chat", readArgs);
11035
+ if (result && result.success === false) continue;
11036
+ payload = unwrapReadChatPayload(result);
11037
+ } else if (dispatchMeshCommand) {
11038
+ const result = await dispatchMeshCommand(nodeDaemonId, "read_chat", readArgs);
11039
+ payload = unwrapReadChatPayload(result);
11040
+ if (payload && payload.success === false) continue;
11041
+ } else {
11042
+ continue;
11043
+ }
11044
+ } catch {
11045
+ continue;
11046
+ }
11047
+ if (!payload) continue;
11048
+ if (readChatPayloadStatus(payload) !== "idle") continue;
11049
+ const messages = Array.isArray(payload.messages) ? payload.messages : [];
11050
+ const evidence = extractFinalAssistantSummaryEvidence(messages);
11051
+ if (!evidence.finalSummary) continue;
11052
+ const providerSessionId = readNonEmptyString2(payload.providerSessionId);
11053
+ const coordinatorDaemonId = selfIds.find((id) => !!id);
11054
+ try {
11055
+ const result = reconcileDirectDispatchCompletionFromTranscript({
11056
+ meshId: mesh.id,
11057
+ nodeId,
11058
+ sessionId,
11059
+ providerType: providerType || void 0,
11060
+ providerSessionId: providerSessionId || void 0,
11061
+ taskId,
11062
+ finalSummary: evidence.finalSummary,
11063
+ ...evidence.transcriptMessageAt ? { transcriptMessageAt: evidence.transcriptMessageAt } : {},
11064
+ ...coordinatorDaemonId ? { targetCoordinatorDaemonId: coordinatorDaemonId } : {},
11065
+ source: "daemon_reconcile_transcript_completion"
11066
+ });
11067
+ if (result.reconciled) {
11068
+ LOG.info("MeshReconcile", `Synthesized missing completion (${result.kind}) for task ${taskId} on node ${nodeId} (mesh ${mesh.id})`);
11069
+ }
11070
+ } catch (e) {
11071
+ LOG.warn("MeshReconcile", `Transcript completion reconcile threw for task ${taskId}: ${e?.message || e}`);
11072
+ }
11073
+ }
11074
+ }
10333
11075
  function extractPendingEvents(raw) {
10334
11076
  if (Array.isArray(raw)) return raw;
10335
11077
  if (raw && typeof raw === "object") {
@@ -10379,6 +11121,9 @@ var init_mesh_reconcile_loop = __esm({
10379
11121
  init_mesh_events_coordinator();
10380
11122
  init_mesh_unresolved_forward_outbox();
10381
11123
  init_mesh_events_utils();
11124
+ init_mesh_work_queue();
11125
+ init_mesh_events_stale();
11126
+ init_chat_message_normalization();
10382
11127
  DEFAULT_RECONCILE_INTERVAL_MS = 4e3;
10383
11128
  }
10384
11129
  });
@@ -14149,6 +14894,8 @@ ${lastSnapshot}`;
14149
14894
  errorMessage: this.parseErrorMessage || this.engine.providerErrorMessage || void 0,
14150
14895
  errorReason: this.parseErrorMessage ? "parse_error" : this.engine.providerErrorReason || void 0,
14151
14896
  providerSessionId: this.providerSessionId || void 0,
14897
+ lastOutputAt: this.lastOutputAt,
14898
+ lastScreenChangeAt: this.lastScreenChangeAt,
14152
14899
  ...bufferState ? { bufferState } : {}
14153
14900
  };
14154
14901
  }
@@ -17190,7 +17937,8 @@ async function handleGitCommand(command, args, services = defaultGitCommandServi
17190
17937
  if (includeSubmodules !== void 0) statusParams.includeSubmodules = includeSubmodules;
17191
17938
  if (submoduleIgnorePaths && submoduleIgnorePaths.length > 0) statusParams.submoduleIgnorePaths = submoduleIgnorePaths;
17192
17939
  const status = await runService(() => services.getStatus(statusParams));
17193
- return "success" in status ? status : { success: true, status };
17940
+ if ("success" in status) return status;
17941
+ return { success: true, status, reporterPlatform: process.platform, reporterArch: process.arch };
17194
17942
  }
17195
17943
  case "git_diff_summary": {
17196
17944
  if (!services.getDiffSummary) return serviceNotImplemented(command);
@@ -20882,257 +21630,10 @@ var CdpDomHandlers = class {
20882
21630
 
20883
21631
  // src/providers/ide-provider-instance.ts
20884
21632
  var crypto2 = __toESM(require("crypto"));
21633
+ init_contracts();
20885
21634
 
20886
- // src/providers/io-contracts.ts
20887
- function normalizeInputEnvelope(input) {
20888
- const normalized = normalizeInputEnvelopePayload(input);
20889
- const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
20890
- return {
20891
- parts: normalized.parts,
20892
- textFallback,
20893
- ...normalized.metadata ? { metadata: normalized.metadata } : {}
20894
- };
20895
- }
20896
- function normalizeMessageParts(content) {
20897
- if (typeof content === "string") return [{ type: "text", text: content }];
20898
- if (!Array.isArray(content)) {
20899
- if (content && typeof content === "object" && typeof content.text === "string") {
20900
- return [{ type: "text", text: String(content.text) }];
20901
- }
20902
- return [];
20903
- }
20904
- const parts = [];
20905
- for (const raw of content) {
20906
- if (typeof raw === "string") {
20907
- parts.push({ type: "text", text: raw });
20908
- continue;
20909
- }
20910
- if (!raw || typeof raw !== "object") continue;
20911
- const part = normalizeMessagePartObject(raw);
20912
- if (part) parts.push(part);
20913
- }
20914
- return parts;
20915
- }
20916
- function flattenMessageParts(parts) {
20917
- return parts.map((part) => {
20918
- if (part.type === "text") return part.text;
20919
- if (part.type === "resource") return part.resource.text || "";
20920
- if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
20921
- if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
20922
- if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
20923
- if (part.type === "resource_link") return [part.name, part.description].filter(Boolean).join("\n");
20924
- return "";
20925
- }).filter((value) => value.length > 0).join("\n");
20926
- }
20927
- function normalizeInputEnvelopePayload(input) {
20928
- if (typeof input === "string") {
20929
- return { parts: [{ type: "text", text: input }], textFallback: input };
20930
- }
20931
- if (!input || typeof input !== "object") {
20932
- return { parts: [], textFallback: "" };
20933
- }
20934
- const record = input;
20935
- const nestedInput = record.input;
20936
- if (nestedInput && typeof nestedInput === "object") {
20937
- const nested = nestedInput;
20938
- return {
20939
- parts: normalizeInputParts(nested.parts ?? nested.prompt),
20940
- textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
20941
- metadata: normalizeInputMetadata(nested.metadata)
20942
- };
20943
- }
20944
- const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
20945
- if (directText !== void 0) {
20946
- return { parts: [{ type: "text", text: directText }], textFallback: directText };
20947
- }
20948
- const directParts = normalizeInputParts(record.parts ?? record.prompt);
20949
- return {
20950
- parts: directParts,
20951
- textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
20952
- metadata: normalizeInputMetadata(record.metadata)
20953
- };
20954
- }
20955
- function normalizeInputMetadata(value) {
20956
- if (!value || typeof value !== "object") return void 0;
20957
- const record = value;
20958
- const metadata = {};
20959
- if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
20960
- metadata.source = record.source;
20961
- }
20962
- if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
20963
- metadata.clientTimestamp = record.clientTimestamp;
20964
- }
20965
- return Object.keys(metadata).length > 0 ? metadata : void 0;
20966
- }
20967
- function normalizeInputParts(value) {
20968
- if (!Array.isArray(value)) return [];
20969
- const parts = [];
20970
- for (const raw of value) {
20971
- if (typeof raw === "string") {
20972
- parts.push({ type: "text", text: raw });
20973
- continue;
20974
- }
20975
- if (!raw || typeof raw !== "object") continue;
20976
- const part = normalizeInputPartObject(raw);
20977
- if (part) parts.push(part);
20978
- }
20979
- return parts;
20980
- }
20981
- function normalizeInputPartObject(raw) {
20982
- const type = raw.type;
20983
- if (type === "text" && typeof raw.text === "string") {
20984
- return { type, text: raw.text };
20985
- }
20986
- if (type === "image" && typeof raw.mimeType === "string") {
20987
- return {
20988
- type,
20989
- mimeType: raw.mimeType,
20990
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
20991
- ...typeof raw.data === "string" ? { data: raw.data } : {},
20992
- ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
20993
- };
20994
- }
20995
- if (type === "audio" && typeof raw.mimeType === "string") {
20996
- return {
20997
- type,
20998
- mimeType: raw.mimeType,
20999
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
21000
- ...typeof raw.data === "string" ? { data: raw.data } : {},
21001
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
21002
- };
21003
- }
21004
- if (type === "video" && typeof raw.mimeType === "string") {
21005
- return {
21006
- type,
21007
- mimeType: raw.mimeType,
21008
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
21009
- ...typeof raw.data === "string" ? { data: raw.data } : {},
21010
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
21011
- ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
21012
- };
21013
- }
21014
- if (type === "resource" && typeof raw.uri === "string") {
21015
- return {
21016
- type,
21017
- uri: raw.uri,
21018
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
21019
- ...typeof raw.name === "string" ? { name: raw.name } : {},
21020
- ...typeof raw.text === "string" ? { text: raw.text } : {},
21021
- ...typeof raw.data === "string" ? { data: raw.data } : {}
21022
- };
21023
- }
21024
- if (type === "resource_link" && typeof raw.uri === "string") {
21025
- return {
21026
- type,
21027
- uri: raw.uri,
21028
- name: typeof raw.name === "string" ? raw.name : getUriDisplayName(raw.uri, "resource"),
21029
- ...typeof raw.title === "string" ? { title: raw.title } : {},
21030
- ...typeof raw.description === "string" ? { description: raw.description } : {},
21031
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
21032
- ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
21033
- ...normalizeAnnotationsProperty(raw.annotations)
21034
- };
21035
- }
21036
- return null;
21037
- }
21038
- function normalizeMessagePartObject(raw) {
21039
- const type = raw.type;
21040
- if (type === "text" && typeof raw.text === "string") {
21041
- return { type, text: raw.text };
21042
- }
21043
- if (type === "image" && typeof raw.mimeType === "string") {
21044
- return {
21045
- type,
21046
- mimeType: raw.mimeType,
21047
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
21048
- ...typeof raw.data === "string" ? { data: raw.data } : {},
21049
- ...typeof raw.alt === "string" ? { alt: raw.alt } : {}
21050
- };
21051
- }
21052
- if (type === "audio" && typeof raw.mimeType === "string") {
21053
- return {
21054
- type,
21055
- mimeType: raw.mimeType,
21056
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
21057
- ...typeof raw.data === "string" ? { data: raw.data } : {},
21058
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
21059
- };
21060
- }
21061
- if (type === "video" && typeof raw.mimeType === "string") {
21062
- return {
21063
- type,
21064
- mimeType: raw.mimeType,
21065
- ...typeof raw.uri === "string" ? { uri: raw.uri } : {},
21066
- ...typeof raw.data === "string" ? { data: raw.data } : {},
21067
- ...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {},
21068
- ...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
21069
- };
21070
- }
21071
- if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
21072
- return {
21073
- type,
21074
- uri: raw.uri,
21075
- name: raw.name,
21076
- ...typeof raw.title === "string" ? { title: raw.title } : {},
21077
- ...typeof raw.description === "string" ? { description: raw.description } : {},
21078
- ...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
21079
- ...typeof raw.size === "number" && Number.isFinite(raw.size) ? { size: raw.size } : {},
21080
- ...normalizeAnnotationsProperty(raw.annotations)
21081
- };
21082
- }
21083
- if (type === "resource" && raw.resource && typeof raw.resource === "object") {
21084
- const resource = raw.resource;
21085
- if (typeof resource.uri !== "string") return null;
21086
- return {
21087
- type,
21088
- resource: {
21089
- uri: resource.uri,
21090
- ...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
21091
- ...typeof resource.text === "string" ? { text: resource.text } : {},
21092
- ...typeof resource.blob === "string" ? { blob: resource.blob } : {}
21093
- }
21094
- };
21095
- }
21096
- return null;
21097
- }
21098
- function flattenInputParts(parts) {
21099
- return parts.map((part) => {
21100
- if (part.type === "text") return part.text;
21101
- if (part.type === "image") return part.alt || (part.data ? `[image: ${part.mimeType}]` : "");
21102
- if (part.type === "audio") return part.transcript || (part.data ? `[audio: ${part.mimeType}]` : "");
21103
- if (part.type === "video") return part.transcript || (part.data ? `[video: ${part.mimeType}]` : "");
21104
- if (part.type === "resource_link") return [part.title, part.name, part.description, part.uri].filter(Boolean).join("\n");
21105
- if (part.type === "resource") return part.text || part.name || part.uri;
21106
- return "";
21107
- }).filter((value) => value.length > 0).join("\n");
21108
- }
21109
- function getUriDisplayName(uri, fallback) {
21110
- try {
21111
- const pathname = uri.startsWith("file://") ? new URL(uri).pathname : uri;
21112
- return pathname.split(/[\\/]/).filter(Boolean).pop() || fallback;
21113
- } catch {
21114
- return uri.split(/[\\/]/).filter(Boolean).pop() || fallback;
21115
- }
21116
- }
21117
- function normalizeAnnotationsProperty(value) {
21118
- if (!value || typeof value !== "object") return {};
21119
- const record = value;
21120
- const annotations = {};
21121
- if (Array.isArray(record.audience)) {
21122
- const audience = record.audience.filter((item) => item === "user" || item === "assistant");
21123
- if (audience.length > 0) annotations.audience = audience;
21124
- }
21125
- if (typeof record.priority === "number" && Number.isFinite(record.priority)) {
21126
- annotations.priority = record.priority;
21127
- }
21128
- return Object.keys(annotations).length > 0 ? { annotations } : {};
21129
- }
21130
-
21131
- // src/providers/contracts.ts
21132
- function flattenContent(content) {
21133
- if (typeof content === "string") return content;
21134
- return flattenMessageParts(normalizeMessageParts(content));
21135
- }
21635
+ // src/providers/extension-provider-instance.ts
21636
+ init_contracts();
21136
21637
 
21137
21638
  // src/providers/status-monitor.ts
21138
21639
  var DEFAULT_MONITOR_CONFIG = {
@@ -21246,342 +21747,9 @@ var StatusMonitor = class {
21246
21747
  }
21247
21748
  };
21248
21749
 
21249
- // src/providers/chat-message-normalization.ts
21250
- var DEFAULT_FINAL_SUMMARY_MAX_CHARS = 4e3;
21251
- function extractFinalSummaryFromMessages(messages, maxChars = DEFAULT_FINAL_SUMMARY_MAX_CHARS) {
21252
- if (!Array.isArray(messages) || messages.length === 0) return "";
21253
- for (let i = messages.length - 1; i >= 0; i--) {
21254
- const msg = messages[i];
21255
- if (!msg) continue;
21256
- const classification = classifyChatMessageVisibility(msg);
21257
- if (classification.isUserFacing && (msg.role === "assistant" || msg.role === "model")) {
21258
- const text = flattenContent(msg.content).trim();
21259
- if (text) return text.slice(0, maxChars);
21260
- }
21261
- }
21262
- return "";
21263
- }
21264
- var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
21265
- var CHAT_MESSAGE_VISIBILITIES = ["user", "debug", "internal", "hidden"];
21266
- var CHAT_MESSAGE_TRANSCRIPT_VISIBILITIES = ["visible", "chat", "user", "debug", "internal", "hidden"];
21267
- var CHAT_MESSAGE_AUDIENCES = ["chat", "debug", "trace", "internal"];
21268
- var CHAT_MESSAGE_SOURCES = [
21269
- "assistant_text",
21270
- "tool_call",
21271
- "terminal_command",
21272
- "runtime_activity",
21273
- "runtime_status",
21274
- "provider_chrome",
21275
- "control"
21276
- ];
21277
- var CHAT_MESSAGE_ACTIVITY_SOURCES = ["tool_call", "terminal_command", "runtime_activity"];
21278
- var CHAT_MESSAGE_INTERNAL_SOURCES = ["runtime_status", "provider_chrome", "control"];
21279
- var KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
21280
- var CHAT_MESSAGE_KIND_ALIASES = {
21281
- text: "standard",
21282
- message: "standard",
21283
- assistant: "standard",
21284
- thinking: "thought",
21285
- think: "thought",
21286
- reasoning: "thought",
21287
- reason: "thought",
21288
- toolcall: "tool",
21289
- tool_call: "tool",
21290
- tooluse: "tool",
21291
- tool_use: "tool",
21292
- action: "tool",
21293
- command: "terminal",
21294
- cmd: "terminal",
21295
- shell: "terminal",
21296
- console: "terminal"
21297
- };
21298
- function canonicalizeKindHint(value) {
21299
- return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
21300
- }
21301
- function resolveBuiltinOrAliasKind(kind) {
21302
- if (typeof kind !== "string") return null;
21303
- const normalizedKind = canonicalizeKindHint(kind);
21304
- if (!normalizedKind) return null;
21305
- if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
21306
- return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
21307
- }
21308
- function inferHintKind(value) {
21309
- const direct = resolveBuiltinOrAliasKind(value);
21310
- if (direct) return direct;
21311
- if (typeof value !== "string") return null;
21312
- const normalized = canonicalizeKindHint(value);
21313
- if (!normalized) return null;
21314
- if (/thought|thinking|reasoning/.test(normalized)) return "thought";
21315
- if (/tool/.test(normalized)) return "tool";
21316
- if (/terminal|command|shell|console/.test(normalized)) return "terminal";
21317
- return null;
21318
- }
21319
- function inferKindFromToolCalls(message) {
21320
- const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
21321
- if (toolCalls.length === 0) return null;
21322
- if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
21323
- if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
21324
- if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
21325
- return "terminal";
21326
- }
21327
- return "tool";
21328
- }
21329
- function inferMissingChatMessageKind(message) {
21330
- const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
21331
- if (role === "system") return "system";
21332
- const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
21333
- const hintCandidates = [
21334
- message?._sub,
21335
- message?._type,
21336
- meta?.label,
21337
- typeof message?.senderName === "string" ? message.senderName : void 0
21338
- ];
21339
- for (const candidate of hintCandidates) {
21340
- const inferred = inferHintKind(candidate);
21341
- if (inferred) return inferred;
21342
- }
21343
- const inferredFromToolCalls = inferKindFromToolCalls(message);
21344
- if (inferredFromToolCalls) return inferredFromToolCalls;
21345
- return null;
21346
- }
21347
- function isBuiltinChatMessageKind(kind) {
21348
- return resolveBuiltinOrAliasKind(kind) !== null;
21349
- }
21350
- function normalizeChatMessageKind(kind, role) {
21351
- const resolvedKind = resolveBuiltinOrAliasKind(kind);
21352
- if (resolvedKind) return resolvedKind;
21353
- const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
21354
- return normalizedRole === "system" ? "system" : "standard";
21355
- }
21356
- function resolveChatMessageKind(message) {
21357
- const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
21358
- if (explicitKind) return explicitKind;
21359
- const inferredKind = inferMissingChatMessageKind(message);
21360
- if (inferredKind) return inferredKind;
21361
- return normalizeChatMessageKind(message?.kind, message?.role);
21362
- }
21363
- function buildChatMessage(message) {
21364
- return {
21365
- ...message,
21366
- kind: resolveChatMessageKind(message)
21367
- };
21368
- }
21369
- function buildSystemChatMessage(message) {
21370
- return buildChatMessage({
21371
- ...message,
21372
- role: "system",
21373
- kind: message?.kind || "system"
21374
- });
21375
- }
21376
- function buildRuntimeSystemChatMessage(message) {
21377
- return buildSystemChatMessage({
21378
- ...message,
21379
- senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
21380
- });
21381
- }
21382
- function buildAssistantChatMessage(message) {
21383
- return buildChatMessage({
21384
- ...message,
21385
- role: "assistant",
21386
- kind: message?.kind || "standard"
21387
- });
21388
- }
21389
- function buildThoughtChatMessage(message) {
21390
- return buildAssistantChatMessage({
21391
- ...message,
21392
- kind: message?.kind || "thought"
21393
- });
21394
- }
21395
- function buildToolChatMessage(message) {
21396
- return buildAssistantChatMessage({
21397
- ...message,
21398
- kind: message?.kind || "tool"
21399
- });
21400
- }
21401
- function buildTerminalChatMessage(message) {
21402
- return buildAssistantChatMessage({
21403
- ...message,
21404
- kind: message?.kind || "terminal"
21405
- });
21406
- }
21407
- function buildUserChatMessage(message) {
21408
- return buildChatMessage({
21409
- ...message,
21410
- role: "user",
21411
- kind: message?.kind || "standard"
21412
- });
21413
- }
21414
- function normalizeChatMessage(message) {
21415
- return buildChatMessage(message);
21416
- }
21417
- function normalizeChatMessages(messages) {
21418
- return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
21419
- }
21420
- function readMessageMeta(message) {
21421
- const meta = message?.meta;
21422
- return meta && typeof meta === "object" && !Array.isArray(meta) ? meta : null;
21423
- }
21424
- function readStringField(value) {
21425
- return typeof value === "string" ? value.trim().toLowerCase() : "";
21426
- }
21427
- function readRecordField(message, meta, key) {
21428
- const record = message;
21429
- return record[key] ?? meta?.[key];
21430
- }
21431
- function readVisibilityField(message, meta) {
21432
- return readStringField(readRecordField(message, meta, "visibility"));
21433
- }
21434
- function readTranscriptVisibilityField(message, meta) {
21435
- const record = message;
21436
- return readStringField(record.transcriptVisibility ?? meta?.transcriptVisibility ?? record.visibility ?? meta?.visibility);
21437
- }
21438
- var EXPLICIT_HIDDEN_VISIBILITIES = /* @__PURE__ */ new Set(["hidden", "debug", "internal"]);
21439
- var EXPLICIT_VISIBLE_VISIBILITIES = /* @__PURE__ */ new Set(["visible", "user", "chat"]);
21440
- var HIDDEN_AUDIENCES = /* @__PURE__ */ new Set(["debug", "trace", "internal"]);
21441
- var ACTIVITY_SOURCE_SET = new Set(CHAT_MESSAGE_ACTIVITY_SOURCES);
21442
- var INTERNAL_SOURCE_SET = new Set(CHAT_MESSAGE_INTERNAL_SOURCES);
21443
- function hasBooleanMarker(message, meta, keys) {
21444
- const record = message;
21445
- return keys.some((key) => record[key] === true || meta?.[key] === true);
21446
- }
21447
- function isActivityKind(kind) {
21448
- return kind === "thought" || kind === "tool" || kind === "terminal";
21449
- }
21450
- function isOrdinaryVisibleTurn(message, role, kind) {
21451
- if (role === "user" || role === "human") return kind === "standard" || kind === "";
21452
- if (role === "assistant") return kind === "standard" || kind === "";
21453
- return false;
21454
- }
21455
- function classifyChatMessageVisibility(message) {
21456
- if (!message) {
21457
- return {
21458
- surface: "internal",
21459
- isUserFacing: false,
21460
- isActivityFacing: false,
21461
- isInternal: true,
21462
- explicitUserFacing: false,
21463
- explicitHidden: true,
21464
- role: "",
21465
- kind: "standard",
21466
- visibility: "",
21467
- transcriptVisibility: "",
21468
- audience: "",
21469
- source: ""
21470
- };
21471
- }
21472
- const meta = readMessageMeta(message);
21473
- const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
21474
- const kind = resolveChatMessageKind(message);
21475
- const visibility = readVisibilityField(message, meta);
21476
- const transcriptVisibility = readTranscriptVisibilityField(message, meta);
21477
- const audience = readStringField(readRecordField(message, meta, "audience"));
21478
- const source = readStringField(readRecordField(message, meta, "source"));
21479
- const explicitHidden = EXPLICIT_HIDDEN_VISIBILITIES.has(visibility) || EXPLICIT_HIDDEN_VISIBILITIES.has(transcriptVisibility) || HIDDEN_AUDIENCES.has(audience) || hasBooleanMarker(message, meta, ["hidden", "internal", "isInternal", "debug", "statusOnly", "controlOnly"]);
21480
- const explicitUserFacing = EXPLICIT_VISIBLE_VISIBILITIES.has(visibility) || EXPLICIT_VISIBLE_VISIBILITIES.has(transcriptVisibility) || audience === "chat" || hasBooleanMarker(message, meta, ["userFacing"]);
21481
- if (explicitHidden) {
21482
- const activityLike = isActivityKind(kind) || ACTIVITY_SOURCE_SET.has(source);
21483
- return {
21484
- surface: activityLike ? "activity" : "internal",
21485
- isUserFacing: false,
21486
- isActivityFacing: activityLike,
21487
- isInternal: !activityLike,
21488
- explicitUserFacing,
21489
- explicitHidden,
21490
- role,
21491
- kind,
21492
- visibility,
21493
- transcriptVisibility,
21494
- audience,
21495
- source
21496
- };
21497
- }
21498
- if (explicitUserFacing) {
21499
- return {
21500
- surface: "chat",
21501
- isUserFacing: true,
21502
- isActivityFacing: false,
21503
- isInternal: false,
21504
- explicitUserFacing,
21505
- explicitHidden,
21506
- role,
21507
- kind,
21508
- visibility,
21509
- transcriptVisibility,
21510
- audience,
21511
- source
21512
- };
21513
- }
21514
- if (INTERNAL_SOURCE_SET.has(source) || role === "system" || kind === "system") {
21515
- return {
21516
- surface: "internal",
21517
- isUserFacing: false,
21518
- isActivityFacing: false,
21519
- isInternal: true,
21520
- explicitUserFacing,
21521
- explicitHidden,
21522
- role,
21523
- kind,
21524
- visibility,
21525
- transcriptVisibility,
21526
- audience,
21527
- source
21528
- };
21529
- }
21530
- if (ACTIVITY_SOURCE_SET.has(source) || isActivityKind(kind)) {
21531
- return {
21532
- surface: "activity",
21533
- isUserFacing: false,
21534
- isActivityFacing: true,
21535
- isInternal: false,
21536
- explicitUserFacing,
21537
- explicitHidden,
21538
- role,
21539
- kind,
21540
- visibility,
21541
- transcriptVisibility,
21542
- audience,
21543
- source
21544
- };
21545
- }
21546
- const isUserFacing = isOrdinaryVisibleTurn(message, role, kind);
21547
- return {
21548
- surface: isUserFacing ? "chat" : "internal",
21549
- isUserFacing,
21550
- isActivityFacing: false,
21551
- isInternal: !isUserFacing,
21552
- explicitUserFacing,
21553
- explicitHidden,
21554
- role,
21555
- kind,
21556
- visibility,
21557
- transcriptVisibility,
21558
- audience,
21559
- source
21560
- };
21561
- }
21562
- function isUserFacingChatMessage(message) {
21563
- return classifyChatMessageVisibility(message).isUserFacing;
21564
- }
21565
- function isActivityChatMessage(message) {
21566
- return classifyChatMessageVisibility(message).isActivityFacing;
21567
- }
21568
- function isInternalChatMessage(message) {
21569
- return classifyChatMessageVisibility(message).isInternal;
21570
- }
21571
- function filterUserFacingChatMessages(messages) {
21572
- return (Array.isArray(messages) ? messages : []).filter((message) => isUserFacingChatMessage(message));
21573
- }
21574
- function filterActivityChatMessages(messages) {
21575
- return (Array.isArray(messages) ? messages : []).filter((message) => isActivityChatMessage(message));
21576
- }
21577
- function filterInternalChatMessages(messages) {
21578
- return (Array.isArray(messages) ? messages : []).filter((message) => isInternalChatMessage(message));
21579
- }
21580
- function filterChatMessagesByVisibility(messages, surface) {
21581
- return (Array.isArray(messages) ? messages : []).filter((message) => classifyChatMessageVisibility(message).surface === surface);
21582
- }
21583
-
21584
21750
  // src/providers/control-effects.ts
21751
+ init_contracts();
21752
+ init_chat_message_normalization();
21585
21753
  function extractProviderControlValues(controls, data) {
21586
21754
  if (!data || typeof data !== "object") return void 0;
21587
21755
  const values = {};
@@ -21778,6 +21946,7 @@ ${cleanBody}`;
21778
21946
  var fs6 = __toESM(require("fs"));
21779
21947
  var path14 = __toESM(require("path"));
21780
21948
  var os8 = __toESM(require("os"));
21949
+ init_chat_message_normalization();
21781
21950
  var HISTORY_DIR = path14.join(os8.homedir(), ".adhdev", "history");
21782
21951
  var RETAIN_DAYS = 30;
21783
21952
  var SAVED_HISTORY_INDEX_VERSION = 1;
@@ -23316,6 +23485,9 @@ function resolveProviderStateSurface(params) {
23316
23485
  };
23317
23486
  }
23318
23487
 
23488
+ // src/providers/extension-provider-instance.ts
23489
+ init_chat_message_normalization();
23490
+
23319
23491
  // src/providers/open-panel-support.ts
23320
23492
  var IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
23321
23493
  "read_chat",
@@ -23751,6 +23923,9 @@ ${effect.notification.body || ""}`.trim();
23751
23923
  // src/providers/ide-provider-instance.ts
23752
23924
  init_logger();
23753
23925
 
23926
+ // src/providers/read-chat-contract.ts
23927
+ init_contracts();
23928
+
23754
23929
  // src/providers/transcript-v2.ts
23755
23930
  var CHAT_CONTRACT_VERSION_V1 = "1.0";
23756
23931
 
@@ -23970,6 +24145,7 @@ function looksLikeActiveApprovalPromptText(content) {
23970
24145
  }
23971
24146
 
23972
24147
  // src/providers/ide-provider-instance.ts
24148
+ init_chat_message_normalization();
23973
24149
  async function withTimeout(promise, timeoutMs, label) {
23974
24150
  let timer = null;
23975
24151
  try {
@@ -25626,6 +25802,7 @@ var fs7 = __toESM(require("fs"));
25626
25802
  var os9 = __toESM(require("os"));
25627
25803
  var path15 = __toESM(require("path"));
25628
25804
  var import_node_crypto3 = require("crypto");
25805
+ init_contracts();
25629
25806
  init_logger();
25630
25807
 
25631
25808
  // src/logging/debug-trace.ts
@@ -26114,6 +26291,7 @@ function synthesiseV1UnitKey(providerType, sessionId, positionalSeq, message) {
26114
26291
  var CHAT_SOURCE_REGISTRY = new ChatSourceRegistry();
26115
26292
 
26116
26293
  // src/commands/chat-commands.ts
26294
+ init_chat_message_normalization();
26117
26295
  var RECENT_SEND_WINDOW_MS = 1200;
26118
26296
  var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
26119
26297
  var HOT_TAIL_MIN_LIMIT = 60;
@@ -30952,6 +31130,7 @@ var path24 = __toESM(require("path"));
30952
31130
  var crypto4 = __toESM(require("crypto"));
30953
31131
  var fs16 = __toESM(require("fs"));
30954
31132
  var import_node_module = require("module");
31133
+ init_contracts();
30955
31134
 
30956
31135
  // src/providers/spec/route.ts
30957
31136
  var fs15 = __toESM(require("fs"));
@@ -33488,6 +33667,9 @@ function normalizeProviderSessionId(provider, providerSessionId) {
33488
33667
  return normalizedId;
33489
33668
  }
33490
33669
 
33670
+ // src/providers/cli-provider-instance.ts
33671
+ init_chat_message_normalization();
33672
+
33491
33673
  // src/providers/working-dir.ts
33492
33674
  function workingDirBasename(p) {
33493
33675
  return (p || "").split(/[\\/]/).filter(Boolean).pop() || "session";
@@ -34618,7 +34800,7 @@ var CliProviderInstance = class _CliProviderInstance {
34618
34800
  const dirName = workingDirBasename(this.workingDir);
34619
34801
  const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
34620
34802
  const partial = this.adapter.getPartialResponse();
34621
- const progressFingerprint = newStatus === "generating" ? `${partial || ""}`.slice(-2e3) : void 0;
34803
+ const progressFingerprint = newStatus === "generating" ? `${`${partial || ""}`.slice(-2e3)}::scr=${adapterStatus.lastScreenChangeAt ?? 0}::out=${adapterStatus.lastOutputAt ?? 0}` : void 0;
34622
34804
  const previousStatus = this.lastStatus;
34623
34805
  if (newStatus !== this.lastStatus) {
34624
34806
  LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
@@ -35294,6 +35476,8 @@ var path25 = __toESM(require("path"));
35294
35476
  var import_stream = require("stream");
35295
35477
  var import_child_process5 = require("child_process");
35296
35478
  var import_sdk = require("@agentclientprotocol/sdk");
35479
+ init_contracts();
35480
+ init_chat_message_normalization();
35297
35481
  init_logger();
35298
35482
  function getPromptCapabilityFlags(agentCapabilities) {
35299
35483
  const prompt = agentCapabilities?.promptCapabilities || {};
@@ -36523,6 +36707,7 @@ ${rawInput}` : rawInput;
36523
36707
  };
36524
36708
 
36525
36709
  // src/commands/cli-manager.ts
36710
+ init_contracts();
36526
36711
  init_logger();
36527
36712
 
36528
36713
  // src/commands/hosted-runtime-restore.ts
@@ -43025,7 +43210,9 @@ function buildLivePeerGitConnection(connection, timestamp = (/* @__PURE__ */ new
43025
43210
  };
43026
43211
  }
43027
43212
  function recordInlineMeshDirectGitTruth(node, git, source) {
43028
- if (!node || typeof node !== "object" || Array.isArray(node)) return;
43213
+ if (!node || typeof node !== "object" || Array.isArray(node)) {
43214
+ return { reporterPlatform: null, reporterArch: null };
43215
+ }
43029
43216
  const checkedAt = readNumberValue(git.lastCheckedAt) ?? Date.now();
43030
43217
  const updatedAt = new Date(checkedAt).toISOString();
43031
43218
  const nextGit = {
@@ -43043,6 +43230,38 @@ function recordInlineMeshDirectGitTruth(node, git, source) {
43043
43230
  node.lastSeenAt = updatedAt;
43044
43231
  const repoRoot = readStringValue(nextGit.repoRoot);
43045
43232
  if (repoRoot && !readStringValue(node.repoRoot)) node.repoRoot = repoRoot;
43233
+ const isLocalSource = source === "selected_coordinator_local_git";
43234
+ const reporterPlatform = readStringValue(git.reporterPlatform) ?? (isLocalSource ? process.platform : null);
43235
+ const reporterArch = readStringValue(git.reporterArch) ?? (isLocalSource ? process.arch : null);
43236
+ stampNodeReporterPlatform(node, reporterPlatform, reporterArch);
43237
+ if (reporterPlatform) node.reportedPlatform = reporterPlatform;
43238
+ if (reporterArch) node.reportedArch = reporterArch;
43239
+ return { reporterPlatform, reporterArch };
43240
+ }
43241
+ function stampNodeReporterPlatform(node, platform10, arch2) {
43242
+ if (!node || typeof node !== "object" || Array.isArray(node)) return;
43243
+ if (!platform10 && !arch2) return;
43244
+ const overrides = node.userOverrides && typeof node.userOverrides === "object" && !Array.isArray(node.userOverrides) ? node.userOverrides : {};
43245
+ let changed = false;
43246
+ if (platform10 && !readStringValue(overrides.platform)) {
43247
+ overrides.platform = platform10;
43248
+ changed = true;
43249
+ }
43250
+ if (arch2 && !readStringValue(overrides.arch)) {
43251
+ overrides.arch = arch2;
43252
+ changed = true;
43253
+ }
43254
+ if (changed) node.userOverrides = overrides;
43255
+ }
43256
+ function persistNodeReporterPlatform(meshSource, mesh, nodeId, reporter) {
43257
+ if (meshSource !== "local_config") return;
43258
+ const meshId = readStringValue(mesh?.id);
43259
+ if (!meshId || !nodeId) return;
43260
+ const reportedPlatform = reporter.reporterPlatform ?? void 0;
43261
+ const reportedArch = reporter.reporterArch ?? void 0;
43262
+ if (!reportedPlatform && !reportedArch) return;
43263
+ void Promise.resolve().then(() => (init_mesh_config(), mesh_config_exports)).then(({ updateNode: updateNode2 }) => updateNode2(meshId, nodeId, { reportedPlatform, reportedArch })).catch(() => {
43264
+ });
43046
43265
  }
43047
43266
  function buildCachedInlineMeshGitStatus(node) {
43048
43267
  const liveGit = buildInlineMeshTransitGitStatus(node);
@@ -43536,7 +43755,13 @@ async function probeRemoteMeshGitStatus(args) {
43536
43755
  new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), args.timeoutMs))
43537
43756
  ]);
43538
43757
  const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
43539
- return remoteGit && typeof remoteGit === "object" && typeof remoteGit.isGitRepo === "boolean" ? remoteGit : null;
43758
+ if (!remoteGit || typeof remoteGit !== "object" || typeof remoteGit.isGitRepo !== "boolean") return null;
43759
+ const reporterPlatform = readStringValue(remoteResult?.reporterPlatform);
43760
+ const reporterArch = readStringValue(remoteResult?.reporterArch);
43761
+ const git = remoteGit;
43762
+ if (reporterPlatform) git.reporterPlatform = reporterPlatform;
43763
+ if (reporterArch) git.reporterArch = reporterArch;
43764
+ return git;
43540
43765
  }
43541
43766
  var MESH_DIRECT_PROBE_MAX_RETRIES = 2;
43542
43767
  function readMeshConnectionState(connection) {
@@ -43619,7 +43844,8 @@ async function hydrateInlineMeshDirectTruth(args) {
43619
43844
  try {
43620
43845
  const localGit = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
43621
43846
  if (localGit?.isGitRepo) {
43622
- recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
43847
+ const reporter = recordInlineMeshDirectGitTruth(node, localGit, "selected_coordinator_local_git");
43848
+ persistNodeReporterPlatform(args.meshSource, args.mesh, nodeId, reporter);
43623
43849
  localConfirmedCount += 1;
43624
43850
  continue;
43625
43851
  }
@@ -43649,7 +43875,8 @@ async function hydrateInlineMeshDirectTruth(args) {
43649
43875
  });
43650
43876
  const remoteGit = args.probeCache ? await args.probeCache.probe(daemonId, workspace, runProbe) : await runProbe();
43651
43877
  if (remoteGit) {
43652
- recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
43878
+ const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
43879
+ persistNodeReporterPlatform(args.meshSource, args.mesh, nodeId, reporter);
43653
43880
  peerConfirmedCount += 1;
43654
43881
  continue;
43655
43882
  }
@@ -49866,7 +50093,8 @@ ${ptyResult.output.slice(-2e3)}`);
49866
50093
  if (!connectionReported || connectionState === "unknown") {
49867
50094
  status.connection = buildLivePeerGitConnection(connection, refreshedAt);
49868
50095
  }
49869
- recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
50096
+ const reporter = recordInlineMeshDirectGitTruth(node, remoteGit, "selected_coordinator_mesh_p2p_git");
50097
+ persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
49870
50098
  remoteProbeApplied = true;
49871
50099
  }
49872
50100
  }
@@ -49898,7 +50126,8 @@ ${ptyResult.output.slice(-2e3)}`);
49898
50126
  try {
49899
50127
  const gitStatus = await getGitRepoStatus(workspace, { timeoutMs: 1e4, refreshUpstream: true });
49900
50128
  status.git = gitStatus;
49901
- recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
50129
+ const reporter = recordInlineMeshDirectGitTruth(node, gitStatus, "selected_coordinator_local_git");
50130
+ persistNodeReporterPlatform(meshRecord.source, mesh, nodeId, reporter);
49902
50131
  if (gitStatus.isGitRepo) {
49903
50132
  status.health = deriveMeshNodeHealthFromGit(gitStatus);
49904
50133
  } else {
@@ -50436,6 +50665,7 @@ var DEFAULT_DAEMON_PORT = 19222;
50436
50665
  var DAEMON_WS_PATH = "/ipc";
50437
50666
 
50438
50667
  // src/chat/subscription-updates.ts
50668
+ init_chat_message_normalization();
50439
50669
  function normalizeModalButtons(value) {
50440
50670
  return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
50441
50671
  }
@@ -50576,6 +50806,7 @@ async function runAsyncBatch(items, worker, options = {}) {
50576
50806
  }
50577
50807
 
50578
50808
  // src/agent-stream/provider-adapter.ts
50809
+ init_chat_message_normalization();
50579
50810
  var ProviderStreamAdapter = class {
50580
50811
  agentType;
50581
50812
  agentName;
@@ -51260,6 +51491,7 @@ var DaemonAgentStreamManager = class {
51260
51491
 
51261
51492
  // src/agent-stream/poller.ts
51262
51493
  init_logger();
51494
+ init_chat_message_normalization();
51263
51495
  var AgentStreamPoller = class {
51264
51496
  deps;
51265
51497
  timer = null;
@@ -51781,6 +52013,10 @@ var ProviderInstanceManager = class {
51781
52013
  }
51782
52014
  };
51783
52015
 
52016
+ // src/index.ts
52017
+ init_io_contracts();
52018
+ init_chat_message_normalization();
52019
+
51784
52020
  // src/providers/version-archive.ts
51785
52021
  var fs27 = __toESM(require("fs"));
51786
52022
  var path37 = __toESM(require("path"));