bazilion 0.16.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/cli.js +399 -83
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +1840 -132
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0001_init.sql +62 -0
  6. package/dist/web/client/assets/ChatPane-BI3QVX2A.js +76 -0
  7. package/dist/web/client/assets/{ConfirmDialog-MicTTwdy.js → ConfirmDialog-Qam6Ut08.js} +1 -1
  8. package/dist/web/client/assets/{FieldRow-DJ2Gx4Du.js → FieldRow-swJ5qn2h.js} +1 -1
  9. package/dist/web/client/assets/ProductionTeamPolicyEditor-LGw1UuF-.js +7 -0
  10. package/dist/web/client/assets/ProfileCommunicationEditor-raoau_YB.js +1 -0
  11. package/dist/web/client/assets/{ResultSourceConversation-CtzJ8QA-.js → ResultSourceConversation-BEwkhFog.js} +1 -1
  12. package/dist/web/client/assets/TeamTabs-BDdTLGIf.js +1 -0
  13. package/dist/web/client/assets/TemplatesTabs-BX5hhEJ7.js +1 -0
  14. package/dist/web/client/assets/{UnsavedChangesGuard-BCsLw-mU.js → UnsavedChangesGuard-CVJtmR1D.js} +1 -1
  15. package/dist/web/client/assets/{_id-BEDmIXVf.js → _id-BQPOE3gj.js} +1 -1
  16. package/dist/web/client/assets/{_id-BFM_tn_s.js → _id-BkYrUP0R.js} +1 -1
  17. package/dist/web/client/assets/{_id-B5Ov7cdO.js → _id-CriixlZD.js} +1 -1
  18. package/dist/web/client/assets/_id-DHqq2W34.js +1 -0
  19. package/dist/web/client/assets/{_id-DxopIW-y.js → _id-DmEVZIlx.js} +1 -1
  20. package/dist/web/client/assets/activity-Bzr8R18n.js +1 -0
  21. package/dist/web/client/assets/{agents-CMPOFcs-.js → agents-13oafeOA.js} +1 -1
  22. package/dist/web/client/assets/{agents-O4soKZND.js → agents-DF4NALmJ.js} +1 -1
  23. package/dist/web/client/assets/{approvals-CwDu_lrA.js → approvals-DsG0Ijls.js} +1 -1
  24. package/dist/web/client/assets/{attention-BY8MMuM_.js → attention-DG7K25mz.js} +1 -1
  25. package/dist/web/client/assets/chevron-right-DFqFHtLy.js +1 -0
  26. package/dist/web/client/assets/config-DAaDbFhS.js +3 -0
  27. package/dist/web/client/assets/createServerFn-Dzfjt7mA.js +3 -0
  28. package/dist/web/client/assets/git-review-presentation-CzHQulDk.js +1 -0
  29. package/dist/web/client/assets/{inbox-CWXql0K3.js → inbox-C9e7QjsX.js} +1 -1
  30. package/dist/web/client/assets/index-Dsstm2hf.js +50 -0
  31. package/dist/web/client/assets/{learning-DAm4dyyc.js → learning-23arTd21.js} +1 -1
  32. package/dist/web/client/assets/login-BIXnBsuj.js +1 -0
  33. package/dist/web/client/assets/{mcp-loLB0wuh.js → mcp-Cdx9qAl8.js} +1 -1
  34. package/dist/web/client/assets/{members-BJ0ikkTl.js → members-fotOz4rR.js} +1 -1
  35. package/dist/web/client/assets/{memory-Drn9Gv53.js → memory-C7UznVot.js} +1 -1
  36. package/dist/web/client/assets/policy-CactLW1X.js +1 -0
  37. package/dist/web/client/assets/{results-9exU6f7m.js → results-DqEuYnQH.js} +1 -1
  38. package/dist/web/client/assets/review-CnBSYclb.js +1 -0
  39. package/dist/web/client/assets/routes-COxMuwVz.js +1 -0
  40. package/dist/web/client/assets/{services-BLso1BhA.js → services-xEANwZAu.js} +1 -1
  41. package/dist/web/client/assets/{skills-BodqX3OI.js → skills-CamV6wYM.js} +1 -1
  42. package/dist/web/client/assets/{styles-d1yjBpud.css → styles-C6br2xxl.css} +1 -1
  43. package/dist/web/client/assets/{teams-ByQedXZi.js → teams-B12dMSjW.js} +1 -1
  44. package/dist/web/client/assets/{teams-SYsF1bOR.js → teams-CbH43zSG.js} +1 -1
  45. package/dist/web/client/assets/{telegram-DC9PLFbB.js → telegram-muIql4u-.js} +1 -1
  46. package/dist/web/client/assets/{tokens-DGy8Ijpo.js → tokens-DGFmApdF.js} +1 -1
  47. package/dist/web/client/assets/{triggers-BXpVmHDG.js → triggers-D8n3sCBW.js} +1 -1
  48. package/dist/web/client/assets/welcome-CMHWRZhs.js +1 -0
  49. package/dist/web/client/assets/x-BGCHwZOH.js +1 -0
  50. package/dist/web/server/assets/{ChatPane-CS5oI7ef.js → ChatPane-DybH39WK.js} +301 -14
  51. package/dist/web/server/assets/{ResultSourceConversation-BpVWBRYq.js → ResultSourceConversation-BmXTcEOA.js} +1 -1
  52. package/dist/web/server/assets/{TeamTabs-TCKjCvMA.js → TeamTabs-DQXh-3ij.js} +4 -0
  53. package/dist/web/server/assets/{_id-5pgKoid8.js → _id-BN1BPEDI.js} +1 -1
  54. package/dist/web/server/assets/{_id-DFHB9JFQ.js → _id-BYKpT2Tu.js} +1 -1
  55. package/dist/web/server/assets/{_id-B_-CDHOi2.js → _id-BqWTB8Wl.js} +1 -1
  56. package/dist/web/server/assets/{_id-BG2nkGxa.js → _id-CPfILjMa.js} +1 -1
  57. package/dist/web/server/assets/{_id-BnqodC1c2.js → _id-C_2er0_G.js} +3 -3
  58. package/dist/web/server/assets/{_id-DtIYuJJX.js → _id-DDyA9CGX.js} +1 -1
  59. package/dist/web/server/assets/{_id-DrB9uR1b.js → _id-DSPFJMzf.js} +1 -1
  60. package/dist/web/server/assets/{_id-DwZXhLlL.js → _id-DtJn-yzu.js} +2 -2
  61. package/dist/web/server/assets/{_id-CeyHEsCZ.js → _id-Dw3gKOGv.js} +1 -1
  62. package/dist/web/server/assets/{_id-DOnInzLb.js → _id-XkxlX036.js} +1 -1
  63. package/dist/web/server/assets/{_tanstack-start-manifest_v-D7gKv6m6.js → _tanstack-start-manifest_v-vOXRfKJD.js} +91 -78
  64. package/dist/web/server/assets/{activity-C88qrNqv.js → activity-BX1jZBPQ.js} +1 -1
  65. package/dist/web/server/assets/{activity-5fWKPDxj.js → activity-bozPMU2v.js} +2 -2
  66. package/dist/web/server/assets/{activity-0VUkStOu.js → activity-pYQPT3QT.js} +1 -1
  67. package/dist/web/server/assets/{agents-CSXLaM2W.js → agents-BKBfW700.js} +1 -1
  68. package/dist/web/server/assets/{agents-C86K6HvS.js → agents-CVCfxnE2.js} +1 -1
  69. package/dist/web/server/assets/{approvals-C3MysI6l.js → approvals-C3ya6B6U.js} +1 -1
  70. package/dist/web/server/assets/{attention-DLeLCKah.js → attention-l28hGCHS.js} +1 -1
  71. package/dist/web/server/assets/{auth-CDZp9aEk.js → auth-AvDFNeOv.js} +1 -1
  72. package/dist/web/server/assets/{config-BVTHvljR.js → config-BWKn4XII.js} +1 -1
  73. package/dist/web/server/assets/{daemon-client-xWyYKAcx.js → daemon-client-Cgx-YW4l.js} +30 -0
  74. package/dist/web/server/assets/git-review-BB3M9nYg.js +26 -0
  75. package/dist/web/server/assets/git-review-f_uta4Mx.js +179 -0
  76. package/dist/web/server/assets/git-review-presentation-TJiHJhen.js +81 -0
  77. package/dist/web/server/assets/{inbox-PQTrjtOw.js → inbox-BBZiOOQs.js} +1 -1
  78. package/dist/web/server/assets/{learning-K0cmDsZR.js → learning-CheVay1i.js} +1 -1
  79. package/dist/web/server/assets/{mcp-Rtraochg.js → mcp-DCBDmNtQ.js} +1 -1
  80. package/dist/web/server/assets/{members-grAKFWgv.js → members-C2He8mrU.js} +1 -1
  81. package/dist/web/server/assets/{members-CD3GiTfF.js → members-C5FQruRZ.js} +1 -1
  82. package/dist/web/server/assets/{members-cc5SeEaW.js → members-C_2xB9pr.js} +2 -2
  83. package/dist/web/server/assets/{memory-CVqnyUaM.js → memory-4tI-UbOf.js} +1 -1
  84. package/dist/web/server/assets/{memory-C5i_GxlY.js → memory-BTcmf0sD.js} +2 -2
  85. package/dist/web/server/assets/{memory-egFpBD1g.js → memory-rmiFNj7T.js} +1 -1
  86. package/dist/web/server/assets/{policy-Dgjb0_gK.js → policy-BGILKGHz.js} +2 -2
  87. package/dist/web/server/assets/{policy-bLKwvnja.js → policy-C3D2Q1EA.js} +1 -1
  88. package/dist/web/server/assets/{policy-ooSBgiDS.js → policy-DS7LGe--.js} +1 -1
  89. package/dist/web/server/assets/{results-DXdYtHaq.js → results-C6H42tjq.js} +1 -1
  90. package/dist/web/server/assets/{results-CfNsFncJ.js → results-Cgx7SrFt.js} +3 -3
  91. package/dist/web/server/assets/{results-N-kP4iFT.js → results-_6K_zXQS.js} +1 -1
  92. package/dist/web/server/assets/review-DHhiL-JQ.js +393 -0
  93. package/dist/web/server/assets/review-DSTMCwP4.js +14 -0
  94. package/dist/web/server/assets/{router-B6g_s7W3.js → router-ElARvZzI.js} +34 -27
  95. package/dist/web/server/assets/{routes-pcRy_Sf8.js → routes-B6x3pEW8.js} +1 -1
  96. package/dist/web/server/assets/{routes-BqSaZvlu.js → routes-BgMvLvS-.js} +1 -1
  97. package/dist/web/server/assets/{routes-Dsh8F_7i.js → routes-DsUzzxk4.js} +2 -2
  98. package/dist/web/server/assets/{services-DlZA8fRL.js → services-yHZroxsi.js} +1 -1
  99. package/dist/web/server/assets/{skills-i2duvgW-.js → skills--bIKID1Q.js} +1 -1
  100. package/dist/web/server/assets/{teams-B1AI3NfN.js → teams--a956vWL.js} +1 -1
  101. package/dist/web/server/assets/{teams-6RYIj1Xm.js → teams-BbRfuVXY.js} +1 -1
  102. package/dist/web/server/assets/{telegram-C4q0YTVn.js → telegram-4kMxRtVZ.js} +1 -1
  103. package/dist/web/server/assets/{tokens-RFquA2Bx.js → tokens-BYwTN9JZ.js} +1 -1
  104. package/dist/web/server/assets/{triggers-DVD-iE-N.js → triggers-BM6mzLuH.js} +1 -1
  105. package/dist/web/server/server.js +56 -28
  106. package/dist/worker.js +292 -75
  107. package/dist/worker.js.map +1 -1
  108. package/package.json +3 -3
  109. package/dist/web/client/assets/ChatPane-CQZzxOir.js +0 -76
  110. package/dist/web/client/assets/ProductionTeamPolicyEditor-DqUnN_ce.js +0 -7
  111. package/dist/web/client/assets/ProfileCommunicationEditor-DArXub0b.js +0 -1
  112. package/dist/web/client/assets/TeamTabs-DbIk5vvT.js +0 -1
  113. package/dist/web/client/assets/TemplatesTabs-CatJIjGi.js +0 -1
  114. package/dist/web/client/assets/_id-CrnEVcw8.js +0 -1
  115. package/dist/web/client/assets/activity-CrG8Bg60.js +0 -1
  116. package/dist/web/client/assets/chevron-right-Cf6vKeLq.js +0 -1
  117. package/dist/web/client/assets/config-Cn4iBJFz.js +0 -3
  118. package/dist/web/client/assets/index-Bq2zrG2_.js +0 -52
  119. package/dist/web/client/assets/login-BsABI8Ux.js +0 -1
  120. package/dist/web/client/assets/policy-pQadZyk0.js +0 -1
  121. package/dist/web/client/assets/routes-jw1PuqiR.js +0 -1
  122. package/dist/web/client/assets/welcome-BKsnsCxJ.js +0 -1
  123. package/dist/web/client/assets/x-BK4xNCzS.js +0 -1
package/dist/worker.js CHANGED
@@ -1108,6 +1108,41 @@ function qmdBackend(root, options = {}) {
1108
1108
  };
1109
1109
  }
1110
1110
 
1111
+ // ../daemon/src/lib/coding-environment/receipt-reference.ts
1112
+ function codingLogReference(content) {
1113
+ const parsed = objectFrom(textContent(content));
1114
+ if (!parsed) return null;
1115
+ return referenceFrom(parsed) ?? referenceFrom(objectFrom(parsed.receipt));
1116
+ }
1117
+ function referenceFrom(value) {
1118
+ if (!value) return null;
1119
+ const commandId = value.id;
1120
+ const teamId = value.teamId;
1121
+ if (typeof commandId !== "string" || commandId.length === 0) return null;
1122
+ if (typeof teamId !== "string" || teamId.length === 0) return null;
1123
+ return { commandId, teamId };
1124
+ }
1125
+ function textContent(content) {
1126
+ if (typeof content === "string") return content;
1127
+ if (!Array.isArray(content)) return "";
1128
+ let out = "";
1129
+ for (const block of content) {
1130
+ if (block && block.type === "text" && typeof block.text === "string") out += block.text;
1131
+ }
1132
+ return out;
1133
+ }
1134
+ function objectFrom(value) {
1135
+ if (typeof value === "string") {
1136
+ try {
1137
+ return objectFrom(JSON.parse(value));
1138
+ } catch {
1139
+ return null;
1140
+ }
1141
+ }
1142
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return null;
1143
+ return value;
1144
+ }
1145
+
1111
1146
  // ../daemon/src/runtime/pi/events.ts
1112
1147
  function translatePiEvent(e) {
1113
1148
  switch (e.type) {
@@ -1147,6 +1182,22 @@ function translatePiEvent(e) {
1147
1182
  }
1148
1183
  return out;
1149
1184
  }
1185
+ case "tool_execution_update": {
1186
+ if (e.toolName !== "coding_command") return [];
1187
+ const progress = e.partialResult?.details?.codingProgress;
1188
+ if (!progress || typeof progress.id !== "string" || typeof progress.commandId !== "string" || typeof progress.output !== "string" || typeof progress.elapsedMs !== "number")
1189
+ return [];
1190
+ return [
1191
+ {
1192
+ type: "coding_progress",
1193
+ id: progress.id,
1194
+ commandId: progress.commandId,
1195
+ output: progress.output,
1196
+ truncated: progress.truncated === true,
1197
+ elapsedMs: Math.max(0, Math.floor(progress.elapsedMs))
1198
+ }
1199
+ ];
1200
+ }
1150
1201
  case "tool_execution_end": {
1151
1202
  if (e.toolName === "ask_user")
1152
1203
  return [
@@ -1254,14 +1305,22 @@ function piMessagesToProviderView(messages, questionResultVisible) {
1254
1305
  }
1255
1306
  case "toolResult": {
1256
1307
  const tr = m;
1257
- if (["repository_context", "coding_environment", "coding_command", "coding_receipt"].includes(
1258
- tr.toolName ?? ""
1259
- )) {
1308
+ if ([
1309
+ "repository_context",
1310
+ "coding_environment",
1311
+ "coding_command",
1312
+ "coding_receipt",
1313
+ "coding_log",
1314
+ // BAZ-042: a snapshot result names withheld paths, so history must not render it.
1315
+ "source_snapshot"
1316
+ ].includes(tr.toolName ?? "")) {
1317
+ const codingLog = codingLogReference(tr.content);
1260
1318
  out.push({
1261
1319
  role: "tool",
1262
1320
  toolCallId: tr.toolCallId,
1263
1321
  toolName: tr.toolName,
1264
- content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result."
1322
+ content: "Coding context or command evidence retained privately. Captured transport output follows its communication approval; ask the Agent for the relevant result.",
1323
+ ...codingLog ? { codingLog } : {}
1265
1324
  });
1266
1325
  break;
1267
1326
  }
@@ -1298,6 +1357,107 @@ function extractResultReference(value) {
1298
1357
  return typeof id === "string" && /^[a-f0-9-]{36}$/.test(id) ? { resultId: id } : void 0;
1299
1358
  }
1300
1359
 
1360
+ // ../daemon/src/lib/coding-environment/diagnostics.ts
1361
+ var CODING_OUTPUT_BYTES = 64 * 1024;
1362
+ var CODING_RETAINED_BYTES = 2 * 1024 * 1024;
1363
+ var CODING_LIVE_BYTES = 8 * 1024;
1364
+ function diagnosticTail(value, limit) {
1365
+ const bytes = Buffer.from(value);
1366
+ if (bytes.length <= limit) return { text: value, truncated: false };
1367
+ let offset = bytes.length - limit;
1368
+ while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
1369
+ return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
1370
+ }
1371
+ var CodingDiagnostics = class {
1372
+ decoder = new TextDecoder();
1373
+ secrets;
1374
+ lookbehind;
1375
+ retainBytes;
1376
+ pending = "";
1377
+ text = "";
1378
+ truncated = false;
1379
+ observedBytes = 0;
1380
+ redactions = 0;
1381
+ finished = false;
1382
+ constructor(secrets, retainBytes = CODING_OUTPUT_BYTES) {
1383
+ this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
1384
+ this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
1385
+ this.retainBytes = retainBytes;
1386
+ }
1387
+ append(bytes) {
1388
+ if (this.finished) throw new Error("Coding diagnostics already finalized");
1389
+ this.observedBytes += bytes.length;
1390
+ for (let offset = 0; offset < bytes.length; offset += 8192) {
1391
+ this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
1392
+ this.flush(false);
1393
+ }
1394
+ }
1395
+ /**
1396
+ * Redacted cumulative tail for a live update. Unlike `finish()` this does not seal
1397
+ * the diagnostics: more output may follow. It deliberately excludes the trailing
1398
+ * lookbehind bytes so a credential split across chunks cannot leak before the next
1399
+ * chunk resolves it.
1400
+ */
1401
+ preview(limit = CODING_LIVE_BYTES) {
1402
+ return diagnosticTail(this.text, limit);
1403
+ }
1404
+ finish() {
1405
+ if (!this.finished) {
1406
+ this.pending += this.decoder.decode();
1407
+ this.flush(true);
1408
+ this.finished = true;
1409
+ }
1410
+ return {
1411
+ diagnostic: this.text,
1412
+ truncated: this.truncated,
1413
+ observedBytes: this.observedBytes,
1414
+ redacted: this.redactions > 0
1415
+ };
1416
+ }
1417
+ flush(final) {
1418
+ let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
1419
+ const last = this.pending.charCodeAt(end - 1);
1420
+ if (!final && last >= 55296 && last <= 56319) end--;
1421
+ let offset = 0;
1422
+ let safe = "";
1423
+ while (offset < end) {
1424
+ const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
1425
+ if (secret) {
1426
+ safe += "[redacted]";
1427
+ this.redactions++;
1428
+ offset += secret.length;
1429
+ } else {
1430
+ const code = this.pending.charCodeAt(offset);
1431
+ const char = this.pending[offset] ?? "";
1432
+ safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
1433
+ offset++;
1434
+ }
1435
+ }
1436
+ this.pending = this.pending.slice(offset);
1437
+ const tail = diagnosticTail(this.text + safe, this.retainBytes);
1438
+ this.text = tail.text;
1439
+ this.truncated ||= tail.truncated;
1440
+ }
1441
+ };
1442
+ function codingSecrets(env) {
1443
+ const values = /* @__PURE__ */ new Set();
1444
+ function collect(value, depth = 0) {
1445
+ if (depth > 8) return;
1446
+ if (typeof value === "string" && value.length >= 4) values.add(value);
1447
+ else if (value && typeof value === "object")
1448
+ for (const entry of Object.values(value)) collect(entry, depth + 1);
1449
+ }
1450
+ for (const [key, value] of Object.entries(env)) {
1451
+ if (!value || !/KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH/i.test(key)) continue;
1452
+ values.add(value);
1453
+ try {
1454
+ collect(JSON.parse(value));
1455
+ } catch {
1456
+ }
1457
+ }
1458
+ return [...values];
1459
+ }
1460
+
1301
1461
  // ../daemon/src/lib/result-source.ts
1302
1462
  import { closeSync as closeSync2, constants as constants2, fstatSync as fstatSync2, openSync as openSync2, readSync, realpathSync as realpathSync2 } from "fs";
1303
1463
  import { basename as basename2, join as join13 } from "path";
@@ -1387,67 +1547,6 @@ function validateCodingCommand(input) {
1387
1547
  };
1388
1548
  }
1389
1549
 
1390
- // ../daemon/src/lib/coding-environment/diagnostics.ts
1391
- var CODING_OUTPUT_BYTES = 64 * 1024;
1392
- function diagnosticTail(value, limit) {
1393
- const bytes = Buffer.from(value);
1394
- if (bytes.length <= limit) return { text: value, truncated: false };
1395
- let offset = bytes.length - limit;
1396
- while (offset < bytes.length && ((bytes[offset] ?? 0) & 192) === 128) offset++;
1397
- return { text: bytes.subarray(offset).toString("utf8"), truncated: true };
1398
- }
1399
- var CodingDiagnostics = class {
1400
- decoder = new TextDecoder();
1401
- secrets;
1402
- lookbehind;
1403
- pending = "";
1404
- text = "";
1405
- truncated = false;
1406
- finished = false;
1407
- constructor(secrets) {
1408
- this.secrets = [...new Set(secrets.filter(Boolean))].sort((a, b) => b.length - a.length);
1409
- this.lookbehind = Math.max(1, ...this.secrets.map((secret) => secret.length)) - 1;
1410
- }
1411
- append(bytes) {
1412
- if (this.finished) throw new Error("Coding diagnostics already finalized");
1413
- for (let offset = 0; offset < bytes.length; offset += 8192) {
1414
- this.pending += this.decoder.decode(bytes.subarray(offset, offset + 8192), { stream: true });
1415
- this.flush(false);
1416
- }
1417
- }
1418
- finish() {
1419
- if (!this.finished) {
1420
- this.pending += this.decoder.decode();
1421
- this.flush(true);
1422
- this.finished = true;
1423
- }
1424
- return { diagnostic: this.text, truncated: this.truncated };
1425
- }
1426
- flush(final) {
1427
- let end = final ? this.pending.length : Math.max(0, this.pending.length - this.lookbehind);
1428
- const last = this.pending.charCodeAt(end - 1);
1429
- if (!final && last >= 55296 && last <= 56319) end--;
1430
- let offset = 0;
1431
- let safe = "";
1432
- while (offset < end) {
1433
- const secret = this.secrets.find((value) => this.pending.startsWith(value, offset));
1434
- if (secret) {
1435
- safe += "[redacted]";
1436
- offset += secret.length;
1437
- } else {
1438
- const code = this.pending.charCodeAt(offset);
1439
- const char = this.pending[offset] ?? "";
1440
- safe += code < 32 && code !== 9 && code !== 10 || code >= 127 && code <= 159 ? `\\u${code.toString(16).padStart(4, "0")}` : char;
1441
- offset++;
1442
- }
1443
- }
1444
- this.pending = this.pending.slice(offset);
1445
- const tail = diagnosticTail(this.text + safe, CODING_OUTPUT_BYTES);
1446
- this.text = tail.text;
1447
- this.truncated ||= tail.truncated;
1448
- }
1449
- };
1450
-
1451
1550
  // ../daemon/src/runtime/coding-directory.ts
1452
1551
  import { realpathSync as realpathSync4 } from "fs";
1453
1552
  import { join as join15 } from "path";
@@ -2895,6 +2994,7 @@ function runCleanupCommand(dockerPath, args, processEnv) {
2895
2994
 
2896
2995
  // ../daemon/src/runtime/pi/coding.ts
2897
2996
  function codingTools(input) {
2997
+ const readSecrets = () => typeof input.secrets === "function" ? input.secrets() : input.secrets ?? [];
2898
2998
  const hostOperations = input.docker ? null : createLocalBashOperations();
2899
2999
  return [
2900
3000
  {
@@ -2935,7 +3035,7 @@ function codingTools(input) {
2935
3035
  { additionalProperties: false }
2936
3036
  ),
2937
3037
  executionMode: "sequential",
2938
- async execute(toolCallId, params, signal) {
3038
+ async execute(toolCallId, params, signal, onUpdate) {
2939
3039
  const command = validateCodingCommand(params);
2940
3040
  const context = await input.context(command.cwd);
2941
3041
  if (context.instructions.state !== "complete")
@@ -2945,7 +3045,27 @@ function codingTools(input) {
2945
3045
  toolCallId,
2946
3046
  input: command
2947
3047
  });
2948
- const output = new CodingDiagnostics(input.secrets ?? []);
3048
+ const output = new CodingDiagnostics(readSecrets());
3049
+ let lastProgressAt = 0;
3050
+ const emitProgress = (force) => {
3051
+ if (!onUpdate) return;
3052
+ const now = Date.now();
3053
+ if (!force && now - lastProgressAt < 400) return;
3054
+ lastProgressAt = now;
3055
+ const preview = output.preview(CODING_LIVE_BYTES);
3056
+ onUpdate({
3057
+ content: [{ type: "text", text: preview.text }],
3058
+ details: {
3059
+ codingProgress: {
3060
+ id: toolCallId,
3061
+ commandId: started.id,
3062
+ output: preview.text,
3063
+ truncated: preview.truncated,
3064
+ elapsedMs: Math.max(0, now - started.startedAt)
3065
+ }
3066
+ }
3067
+ });
3068
+ };
2949
3069
  let outcome;
2950
3070
  try {
2951
3071
  if (input.approval)
@@ -2966,8 +3086,16 @@ function codingTools(input) {
2966
3086
  const result = await operations.exec(
2967
3087
  command.command,
2968
3088
  input.docker ? input.root : cwd.path,
2969
- { onData: (bytes) => output.append(bytes), signal, timeout: command.timeoutSeconds }
3089
+ {
3090
+ onData: (bytes) => {
3091
+ output.append(bytes);
3092
+ emitProgress(false);
3093
+ },
3094
+ signal,
3095
+ timeout: command.timeoutSeconds
3096
+ }
2970
3097
  );
3098
+ emitProgress(true);
2971
3099
  outcome = {
2972
3100
  state: result.exitCode === 0 ? "succeeded" : result.exitCode === null ? "interrupted" : "failed",
2973
3101
  exitCode: result.exitCode,
@@ -3012,6 +3140,74 @@ function codingTools(input) {
3012
3140
  details: { codingEvidence: value }
3013
3141
  };
3014
3142
  }
3143
+ },
3144
+ {
3145
+ name: "coding_log",
3146
+ label: "Read retained command output",
3147
+ description: "Read a bounded page of retained diagnostic output for a coding receipt, or search it. Producing Agents may read their own logs; a teammate must pass the id of the policy-authorized message that carried coding-receipt:<id>. Output is bounded and may be truncated, expired, deleted or unavailable \u2014 report that state honestly and do not infer completeness from an exit code.",
3148
+ parameters: Type.Object(
3149
+ {
3150
+ id: Type.String({ maxLength: 64 }),
3151
+ messageId: Type.Optional(Type.String({ maxLength: 64 })),
3152
+ search: Type.Optional(Type.String({ minLength: 1, maxLength: 256 })),
3153
+ offset: Type.Optional(Type.Integer({ minimum: 0 })),
3154
+ limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 65536 }))
3155
+ },
3156
+ { additionalProperties: false }
3157
+ ),
3158
+ executionMode: "sequential",
3159
+ async execute(_id, params) {
3160
+ const values = params;
3161
+ if (values.search !== void 0) {
3162
+ const result = await input.host.invoke({
3163
+ action: "log-search",
3164
+ id: values.id,
3165
+ query: values.search,
3166
+ ...values.messageId !== void 0 ? { messageId: values.messageId } : {}
3167
+ });
3168
+ return {
3169
+ content: [{ type: "text", text: JSON.stringify(result) }],
3170
+ details: { codingLogSearch: result }
3171
+ };
3172
+ }
3173
+ const value = await input.host.invoke({
3174
+ action: "log",
3175
+ id: values.id,
3176
+ ...values.messageId !== void 0 ? { messageId: values.messageId } : {},
3177
+ ...values.offset !== void 0 ? { offset: values.offset } : {},
3178
+ ...values.limit !== void 0 ? { limit: values.limit } : {}
3179
+ });
3180
+ return {
3181
+ content: [{ type: "text", text: JSON.stringify(value) }],
3182
+ details: { codingLog: value }
3183
+ };
3184
+ }
3185
+ },
3186
+ {
3187
+ name: "source_snapshot",
3188
+ label: "Capture the current source state",
3189
+ description: "Capture a bounded snapshot of the repository source you are about to work from, and quote its reference in your summary. Call this once before you start editing: the reference is how a later change or verification is tied to the version it actually applies to. It is read-only and never changes the repository. The result may be incomplete \u2014 when it is, say so, because an incomplete snapshot cannot support a claim that code is unchanged. Untracked file content is never included unless you name each path.",
3190
+ parameters: Type.Object(
3191
+ {
3192
+ includeUntracked: Type.Optional(
3193
+ Type.Array(Type.String({ maxLength: 4096 }), { maxItems: 1e3 })
3194
+ )
3195
+ },
3196
+ { additionalProperties: false }
3197
+ ),
3198
+ executionMode: "sequential",
3199
+ async execute(toolCallId, params) {
3200
+ const values = params;
3201
+ const value = await input.host.invoke({
3202
+ action: "snapshot",
3203
+ toolCallId,
3204
+ ...values.includeUntracked ? { includeUntracked: values.includeUntracked } : {}
3205
+ });
3206
+ return {
3207
+ content: [{ type: "text", text: JSON.stringify(value) }],
3208
+ details: { sourceSnapshot: value }
3209
+ };
3210
+ }
3015
3211
  }
3016
3212
  ];
3017
3213
  }
@@ -3349,6 +3545,20 @@ function fallbackApi(providerName) {
3349
3545
  return "openai-completions";
3350
3546
  }
3351
3547
  }
3548
+ var UnknownModelError = class extends Error {
3549
+ providerName;
3550
+ modelId;
3551
+ // Fields are declared explicitly, not as constructor parameter properties:
3552
+ // worker subprocesses run Node's strip-only TypeScript, which rejects them.
3553
+ constructor(providerName, modelId) {
3554
+ super(
3555
+ `Unknown model "${modelId}" for provider "${providerName}": it is not in that provider's catalog, and no endpoint is configured for it. Choose a catalogued model, or configure an endpoint for a custom one.`
3556
+ );
3557
+ this.name = "UnknownModelError";
3558
+ this.providerName = providerName;
3559
+ this.modelId = modelId;
3560
+ }
3561
+ };
3352
3562
  function fallbackPiModel(providerName, modelId, baseUrl) {
3353
3563
  return {
3354
3564
  id: modelId,
@@ -3420,6 +3630,7 @@ async function createProtectedPiRuntime(options) {
3420
3630
  function resolvePiModel(runtime, providerName, modelId, baseUrl) {
3421
3631
  const known = runtime.getModel(piProviderName(providerName), modelId);
3422
3632
  if (known) return baseUrl ? { ...known, baseUrl } : known;
3633
+ if (!baseUrl) throw new UnknownModelError(providerName, modelId);
3423
3634
  return fallbackPiModel(providerName, modelId, baseUrl);
3424
3635
  }
3425
3636
 
@@ -6006,6 +6217,7 @@ async function createBazilionSession(opts) {
6006
6217
  if (repository) bazilionTools.push(repository.tool);
6007
6218
  if (repository && opts.codingHost && shellTools && shellTools.config.sandboxMode === "docker" && !opts.preparedDocker)
6008
6219
  throw new Error("Coding commands require the admitted Docker runtime");
6220
+ const redactionSecrets = uniqueSecrets(codingSecrets(env));
6009
6221
  if (repository && opts.codingHost && shellTools)
6010
6222
  bazilionTools.push(
6011
6223
  ...codingTools({
@@ -6016,7 +6228,7 @@ async function createBazilionSession(opts) {
6016
6228
  lifecycle: opts.dockerLifecycle,
6017
6229
  approval: shellTools.config.approvalMode === "dangerous",
6018
6230
  approvalHost: bashApprovalHost,
6019
- secrets: Object.entries(env).filter(([key]) => /KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL|AUTH/i.test(key)).map(([, value]) => value ?? "")
6231
+ secrets: () => redactionSecrets
6020
6232
  })
6021
6233
  );
6022
6234
  const customTools = shellTools?.customBash ? [...bazilionTools, shellTools.customBash] : bazilionTools;
@@ -6038,7 +6250,9 @@ async function createBazilionSession(opts) {
6038
6250
  session.agent.getApiKey = async (requestedProvider) => {
6039
6251
  if (requestedProvider !== piProviderName(providerName)) return void 0;
6040
6252
  try {
6041
- return await refreshApiKey(providerName);
6253
+ const token = await refreshApiKey(providerName);
6254
+ if (token && !redactionSecrets.includes(token)) redactionSecrets.push(token);
6255
+ return token;
6042
6256
  } catch {
6043
6257
  return void 0;
6044
6258
  }
@@ -6123,6 +6337,7 @@ async function createProtectedBazilionSession(opts) {
6123
6337
  sessionId: sessionManager.getSessionId()
6124
6338
  });
6125
6339
  if (repository) bazilionTools.push(repository.tool);
6340
+ const redactionSecrets = uniqueSecrets(protectedRuntimeSecrets(opts.runtime));
6126
6341
  if (repository && opts.codingHost)
6127
6342
  bazilionTools.push(
6128
6343
  ...codingTools({
@@ -6133,7 +6348,7 @@ async function createProtectedBazilionSession(opts) {
6133
6348
  lifecycle: opts.dockerLifecycle,
6134
6349
  approval: true,
6135
6350
  approvalHost: opts.bashApprovalHost,
6136
- secrets: protectedRuntimeSecrets(opts.runtime)
6351
+ secrets: () => redactionSecrets
6137
6352
  })
6138
6353
  );
6139
6354
  if (!shellTools.customBash) throw new Error("protected Docker bash tool is unavailable");
@@ -6157,7 +6372,7 @@ async function createProtectedBazilionSession(opts) {
6157
6372
  installProtectedCredentialBoundary(
6158
6373
  session,
6159
6374
  opts.runtime.providerName,
6160
- protectedRuntimeSecrets(opts.runtime),
6375
+ redactionSecrets,
6161
6376
  opts.refreshApiKey
6162
6377
  );
6163
6378
  return sessionHandle(session);
@@ -6208,11 +6423,14 @@ async function createRestrictedReviewSession(opts) {
6208
6423
  installProtectedCredentialBoundary(
6209
6424
  session,
6210
6425
  opts.runtime.providerName,
6211
- protectedRuntimeSecrets(opts.runtime),
6426
+ uniqueSecrets(protectedRuntimeSecrets(opts.runtime)),
6212
6427
  opts.refreshApiKey
6213
6428
  );
6214
6429
  return sessionHandle(session);
6215
6430
  }
6431
+ function uniqueSecrets(values) {
6432
+ return [...new Set(values.filter(Boolean))];
6433
+ }
6216
6434
  function materializeProtectedCredentialFile(runtime, scratch) {
6217
6435
  const fields = [...runtime.credentialEnv ?? []];
6218
6436
  if (runtime.credentialFile) {
@@ -6237,8 +6455,7 @@ function createInMemorySettingsManager() {
6237
6455
  }
6238
6456
  });
6239
6457
  }
6240
- function installProtectedCredentialBoundary(session, providerName, initialSecrets, refreshApiKey) {
6241
- const activeTokens = [...new Set(initialSecrets.filter(Boolean))];
6458
+ function installProtectedCredentialBoundary(session, providerName, activeTokens, refreshApiKey) {
6242
6459
  session.agent.state.messages = redactJsonValue(session.agent.state.messages, activeTokens);
6243
6460
  const originalStream = session.agent.streamFunction;
6244
6461
  session.agent.streamFunction = async (model, context, options) => {