bazilion 0.19.0 → 0.20.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 (91) hide show
  1. package/dist/cli.js +272 -129
  2. package/dist/cli.js.map +1 -1
  3. package/dist/daemon.js +1689 -709
  4. package/dist/daemon.js.map +1 -1
  5. package/dist/migrations/0001_init.sql +46 -0
  6. package/dist/web/client/assets/{ChatPane-DCyGcqdh.js → ChatPane-CGCtAuD3.js} +1 -1
  7. package/dist/web/client/assets/{ConfirmDialog-C908TxS5.js → ConfirmDialog-Br19uXWH.js} +1 -1
  8. package/dist/web/client/assets/{FieldRow-CELqI-1V.js → FieldRow-Csy3_cH5.js} +1 -1
  9. package/dist/web/client/assets/{ProductionTeamPolicyEditor-DnTcWhG8.js → ProductionTeamPolicyEditor-DG1x4Cqz.js} +1 -1
  10. package/dist/web/client/assets/{ProfileCommunicationEditor-BVIEaW3s.js → ProfileCommunicationEditor-C3odNVkK.js} +1 -1
  11. package/dist/web/client/assets/{ResultSourceConversation-4gbZCh_s.js → ResultSourceConversation-5PFWqXTY.js} +1 -1
  12. package/dist/web/client/assets/{TeamTabs-V17b45X5.js → TeamTabs-BHB_COm0.js} +1 -1
  13. package/dist/web/client/assets/{TemplatesTabs-BMK3Qok_.js → TemplatesTabs-YyytjW7k.js} +1 -1
  14. package/dist/web/client/assets/{UnsavedChangesGuard-BaE-UzyS.js → UnsavedChangesGuard-CredyC3E.js} +1 -1
  15. package/dist/web/client/assets/{_id-CArZR-IO.js → _id-BLm9LVlZ.js} +1 -1
  16. package/dist/web/client/assets/{_id-BU1l9gP7.js → _id-BZ_-4M4s.js} +1 -1
  17. package/dist/web/client/assets/{_id-Bvh5LyUv.js → _id-CIkPtQY0.js} +1 -1
  18. package/dist/web/client/assets/{_id-BVANQm00.js → _id-KXX6nuKc.js} +1 -1
  19. package/dist/web/client/assets/{_id-tUkSe5li.js → _id-nDbQY7f_.js} +1 -1
  20. package/dist/web/client/assets/{activity-CWCnqjqj.js → activity-BE7jG1Mz.js} +1 -1
  21. package/dist/web/client/assets/{agents-CdCnhH06.js → agents-S9lzXrrs.js} +1 -1
  22. package/dist/web/client/assets/{agents-CX4STmGK.js → agents-vOPd-upn.js} +1 -1
  23. package/dist/web/client/assets/{approvals-CnNpwG78.js → approvals-BUfhlUAX.js} +1 -1
  24. package/dist/web/client/assets/{attention-CEE-wWrx.js → attention-C3r-2GSp.js} +1 -1
  25. package/dist/web/client/assets/chevron-right-C7P3Z105.js +1 -0
  26. package/dist/web/client/assets/{config-CSEtI-dq.js → config-AL_EM57n.js} +1 -1
  27. package/dist/web/client/assets/{inbox-MYnBtPdF.js → inbox-LlCpJrMH.js} +1 -1
  28. package/dist/web/client/assets/{index-Ct31TjS-.js → index-CwMw0pnV.js} +2 -2
  29. package/dist/web/client/assets/{learning-BIR5FTgQ.js → learning-zvTJ_9vM.js} +1 -1
  30. package/dist/web/client/assets/{login-DIeceuOs.js → login-BpQ54z8Y.js} +1 -1
  31. package/dist/web/client/assets/{mcp-CX3kJpGu.js → mcp-BD6VzXg_.js} +1 -1
  32. package/dist/web/client/assets/{members-DlhSjye1.js → members-SEDi8SFo.js} +1 -1
  33. package/dist/web/client/assets/{memory-CsDd6b2l.js → memory-zi_dPlMA.js} +1 -1
  34. package/dist/web/client/assets/{policy-DkWDhG0x.js → policy-URjQAAdN.js} +1 -1
  35. package/dist/web/client/assets/{results-BHdhNHJJ.js → results-Bcuy4Flp.js} +1 -1
  36. package/dist/web/client/assets/review-CVH7X9-d.js +1 -0
  37. package/dist/web/client/assets/{routes-DtYD4WJL.js → routes-BJEX6yAE.js} +1 -1
  38. package/dist/web/client/assets/{services-WUlW7oEo.js → services-BTG4F5FL.js} +1 -1
  39. package/dist/web/client/assets/{skills-jNoUfUSZ.js → skills-DwiHS7eD.js} +1 -1
  40. package/dist/web/client/assets/{teams-C1kYRrtP.js → teams-DcROmSGB.js} +1 -1
  41. package/dist/web/client/assets/{teams-D3FaSKE7.js → teams-DfpwQu1i.js} +1 -1
  42. package/dist/web/client/assets/{telegram-D86AO6V9.js → telegram-BLyaaUXE.js} +1 -1
  43. package/dist/web/client/assets/{tokens-B42KDisP.js → tokens-Dp9Vwvfx.js} +1 -1
  44. package/dist/web/client/assets/{triggers-yEfWnQ_K.js → triggers-CtVhrAGA.js} +1 -1
  45. package/dist/web/client/assets/verifications-TC0ccGLY.js +2 -0
  46. package/dist/web/client/assets/{welcome-D8IbF_P0.js → welcome-DML3X1ha.js} +1 -1
  47. package/dist/web/client/assets/{x-CXKABZ7C.js → x-D8yuCam7.js} +1 -1
  48. package/dist/web/server/assets/{_id-bVispdh-.js → _id-Bazctexc.js} +1 -1
  49. package/dist/web/server/assets/{_id-Dab2CVtO2.js → _id-BjvOb4CK2.js} +1 -1
  50. package/dist/web/server/assets/{_id-DL-SnSnK.js → _id-Bn0w00AG.js} +1 -1
  51. package/dist/web/server/assets/{_id-D2bDA1iV.js → _id-DFf_uQiI.js} +1 -1
  52. package/dist/web/server/assets/{_tanstack-start-manifest_v-BcTOb0oj.js → _tanstack-start-manifest_v-BGSoO6CK.js} +79 -79
  53. package/dist/web/server/assets/{activity-CLDAy6rk.js → activity-j_Enmf3L.js} +1 -1
  54. package/dist/web/server/assets/{agents-CdB2kuNN.js → agents-BAi0dE66.js} +1 -1
  55. package/dist/web/server/assets/{agents-DfHcb2H2.js → agents-BHUbTrm7.js} +1 -1
  56. package/dist/web/server/assets/{approvals-Bq846WaP.js → approvals-BcUm6IOo.js} +1 -1
  57. package/dist/web/server/assets/{attention-Sm-U7s_0.js → attention-BQBa0Bu5.js} +1 -1
  58. package/dist/web/server/assets/{auth-PB5dVyvX.js → auth-PDNSxrT-.js} +1 -1
  59. package/dist/web/server/assets/{config-BNGTBu80.js → config-Cf7hhsUR.js} +1 -1
  60. package/dist/web/server/assets/{daemon-client-CWQvck6B.js → daemon-client-DY4jE6KU.js} +15 -0
  61. package/dist/web/server/assets/{git-review-C_h_tezf.js → git-review-RvzReZyD.js} +1 -1
  62. package/dist/web/server/assets/{inbox-DJoU-bla.js → inbox-Du1guYth.js} +1 -1
  63. package/dist/web/server/assets/{learning-DVb0I_3Z.js → learning-CjcixPRH.js} +1 -1
  64. package/dist/web/server/assets/{mcp-CeZqOiDG.js → mcp-BCalFLvt.js} +1 -1
  65. package/dist/web/server/assets/{members-CcYjuqxB.js → members-C4TpK50B.js} +1 -1
  66. package/dist/web/server/assets/{memory-CH2yNT89.js → memory-CLZs-XRY.js} +1 -1
  67. package/dist/web/server/assets/{policy-DrRKinMr.js → policy-BrIXpwxZ.js} +1 -1
  68. package/dist/web/server/assets/publications-BrX3-WJf.js +57 -0
  69. package/dist/web/server/assets/{results-fT2zyiJx.js → results-CJR6dNzB.js} +1 -1
  70. package/dist/web/server/assets/{review-CvUPk4HA.js → review-CRHiZfC8.js} +1 -1
  71. package/dist/web/server/assets/{review-DYcYdUTv.js → review-Dqdts12v.js} +205 -3
  72. package/dist/web/server/assets/{review-packets-e36PsTSX.js → review-packets-D3bZ7QYU.js} +1 -1
  73. package/dist/web/server/assets/{router-NYhuYQCd.js → router-BVhdWkwP.js} +3 -3
  74. package/dist/web/server/assets/{routes-RdppWPiW.js → routes-DizvfkfZ.js} +1 -1
  75. package/dist/web/server/assets/{services-Dgu7dcTC.js → services-DDRj180j.js} +1 -1
  76. package/dist/web/server/assets/{skills-DL7UIWa8.js → skills-Bck9L5oo.js} +1 -1
  77. package/dist/web/server/assets/{teams-DiC-MBg4.js → teams-CSqR5mWl.js} +1 -1
  78. package/dist/web/server/assets/{teams-Cmn7mdx9.js → teams-C_PicOsj.js} +1 -1
  79. package/dist/web/server/assets/{telegram-CLOFnLjF.js → telegram-D0odXx1E.js} +1 -1
  80. package/dist/web/server/assets/{tokens-BVva7GHu.js → tokens-B2O0Di4p.js} +1 -1
  81. package/dist/web/server/assets/{triggers-D4orksJq.js → triggers-DtKMYL2r.js} +1 -1
  82. package/dist/web/server/assets/{verification-C1SHMTX8.js → verification-no5BrOeR.js} +1 -1
  83. package/dist/web/server/assets/{verifications-Ci49n2Km.js → verifications-CM-Bbgjt.js} +114 -91
  84. package/dist/web/server/assets/{verifications-C_ycXrPK.js → verifications-DhGe86E1.js} +1 -1
  85. package/dist/web/server/server.js +56 -48
  86. package/dist/worker.js +52 -1
  87. package/dist/worker.js.map +1 -1
  88. package/package.json +3 -3
  89. package/dist/web/client/assets/chevron-right-CvCEwfSl.js +0 -1
  90. package/dist/web/client/assets/review-Dyw47eM1.js +0 -1
  91. package/dist/web/client/assets/verifications-DrHQEQFx.js +0 -2
package/dist/daemon.js CHANGED
@@ -271,12 +271,12 @@ var require_path_key = __commonJS({
271
271
  "../../node_modules/.pnpm/path-key@3.1.1/node_modules/path-key/index.js"(exports, module) {
272
272
  "use strict";
273
273
  var pathKey = (options = {}) => {
274
- const environment = options.env || process.env;
274
+ const environment2 = options.env || process.env;
275
275
  const platform = options.platform || process.platform;
276
276
  if (platform !== "win32") {
277
277
  return "PATH";
278
278
  }
279
- return Object.keys(environment).reverse().find((key3) => key3.toUpperCase() === "PATH") || "Path";
279
+ return Object.keys(environment2).reverse().find((key3) => key3.toUpperCase() === "PATH") || "Path";
280
280
  };
281
281
  module.exports = pathKey;
282
282
  module.exports.default = pathKey;
@@ -19276,14 +19276,14 @@ function remove(db, id) {
19276
19276
  db.raw.run("DELETE FROM agents WHERE id = ?", [id]);
19277
19277
  }
19278
19278
  function getTelegramTopicId(db, agentId) {
19279
- const row = db.raw.query(
19279
+ const row2 = db.raw.query(
19280
19280
  "SELECT telegram_topic_id FROM agents WHERE id = ?"
19281
19281
  ).get(agentId);
19282
- return row?.telegram_topic_id ?? null;
19282
+ return row2?.telegram_topic_id ?? null;
19283
19283
  }
19284
19284
  function findByTelegramTopicId(db, topicId) {
19285
- const row = db.raw.query("SELECT * FROM agents WHERE telegram_topic_id = ?").get(topicId);
19286
- return row ? toAgent(row) : null;
19285
+ const row2 = db.raw.query("SELECT * FROM agents WHERE telegram_topic_id = ?").get(topicId);
19286
+ return row2 ? toAgent(row2) : null;
19287
19287
  }
19288
19288
  function setTelegramTopicId(db, agentId, topicId) {
19289
19289
  db.raw.run(
@@ -19303,10 +19303,10 @@ function findByName(db, name) {
19303
19303
  ).all(name).map(toAgent);
19304
19304
  }
19305
19305
  function findByNameInGroup(db, teamId, name) {
19306
- const row = db.raw.query(
19306
+ const row2 = db.raw.query(
19307
19307
  "SELECT * FROM agents WHERE team_id = ? AND name = ? AND status != 'archived' LIMIT 1"
19308
19308
  ).get(teamId, name);
19309
- return row ? toAgent(row) : null;
19309
+ return row2 ? toAgent(row2) : null;
19310
19310
  }
19311
19311
  function listBoundUnlockedTopicsInGroup(db, teamId) {
19312
19312
  return db.raw.query(
@@ -19376,25 +19376,25 @@ __export(teamPolicies_exports, {
19376
19376
  replacePolicy: () => replacePolicy
19377
19377
  });
19378
19378
  function get2(db, teamId) {
19379
- const row = db.raw.query("SELECT * FROM team_policies WHERE team_id = ?").get(teamId);
19380
- return row ? {
19381
- teamId: row.team_id,
19382
- revision: row.revision,
19383
- baselineInstantiationId: row.baseline_instantiation_id,
19384
- updatedAt: row.updated_at
19379
+ const row2 = db.raw.query("SELECT * FROM team_policies WHERE team_id = ?").get(teamId);
19380
+ return row2 ? {
19381
+ teamId: row2.team_id,
19382
+ revision: row2.revision,
19383
+ baselineInstantiationId: row2.baseline_instantiation_id,
19384
+ updatedAt: row2.updated_at
19385
19385
  } : null;
19386
19386
  }
19387
19387
  function edges(db, teamId) {
19388
19388
  return db.raw.query(
19389
19389
  `SELECT * FROM team_policy_edges WHERE team_id = ?
19390
19390
  ORDER BY source_kind, source_id, target_kind, target_id`
19391
- ).all(teamId).map((row) => ({
19392
- teamId: row.team_id,
19393
- sourceKind: row.source_kind,
19394
- sourceId: row.source_id || null,
19395
- targetKind: row.target_kind,
19396
- targetId: row.target_id || null,
19397
- posture: row.posture
19391
+ ).all(teamId).map((row2) => ({
19392
+ teamId: row2.team_id,
19393
+ sourceKind: row2.source_kind,
19394
+ sourceId: row2.source_id || null,
19395
+ targetKind: row2.target_kind,
19396
+ targetId: row2.target_id || null,
19397
+ posture: row2.posture
19398
19398
  }));
19399
19399
  }
19400
19400
  function detail(db, teamId) {
@@ -19464,7 +19464,7 @@ function placementEdgesPreview(db, teamId, agentId, placement, profileId) {
19464
19464
  };
19465
19465
  const peers = db.raw.query(
19466
19466
  "SELECT id FROM agents WHERE team_id = ? AND id <> ? ORDER BY id"
19467
- ).all(teamId, agentId).map((row) => row.id);
19467
+ ).all(teamId, agentId).map((row2) => row2.id);
19468
19468
  const defaults = db.raw.query("SELECT * FROM profile_communication_defaults WHERE profile_id = ?").get(profileId);
19469
19469
  if (!defaults) return [];
19470
19470
  if (defaults.user_input) add2("user", null, "agent", agentId);
@@ -19492,12 +19492,12 @@ function instantiations(db, teamId) {
19492
19492
  return db.raw.query(
19493
19493
  `SELECT * FROM template_instantiations WHERE team_id = ?
19494
19494
  ORDER BY created_at ASC, id ASC`
19495
- ).all(teamId).map((row) => ({
19496
- id: row.id,
19497
- teamId: row.team_id,
19498
- templateId: row.template_id,
19499
- templateRevision: row.template_revision,
19500
- createdAt: row.created_at
19495
+ ).all(teamId).map((row2) => ({
19496
+ id: row2.id,
19497
+ teamId: row2.team_id,
19498
+ templateId: row2.template_id,
19499
+ templateRevision: row2.template_revision,
19500
+ createdAt: row2.created_at
19501
19501
  }));
19502
19502
  }
19503
19503
  function bindings(db, teamId) {
@@ -19505,18 +19505,18 @@ function bindings(db, teamId) {
19505
19505
  `SELECT b.* FROM source_slot_bindings b
19506
19506
  JOIN template_instantiations i ON i.id = b.instantiation_id
19507
19507
  WHERE i.team_id = ? ORDER BY b.agent_id ASC`
19508
- ).all(teamId).map((row) => ({
19509
- agentId: row.agent_id,
19510
- instantiationId: row.instantiation_id,
19511
- sourceSlotId: row.source_slot_id
19508
+ ).all(teamId).map((row2) => ({
19509
+ agentId: row2.agent_id,
19510
+ instantiationId: row2.instantiation_id,
19511
+ sourceSlotId: row2.source_slot_id
19512
19512
  }));
19513
19513
  }
19514
19514
  function agentState(db, teamId) {
19515
- return db.raw.query("SELECT * FROM team_agent_state WHERE team_id = ? ORDER BY agent_id ASC").all(teamId).map((row) => ({
19516
- agentId: row.agent_id,
19517
- teamId: row.team_id,
19518
- position: row.position_x === null || row.position_y === null ? null : { x: row.position_x, y: row.position_y },
19519
- display: row.display_json ? JSON.parse(row.display_json) : null
19515
+ return db.raw.query("SELECT * FROM team_agent_state WHERE team_id = ? ORDER BY agent_id ASC").all(teamId).map((row2) => ({
19516
+ agentId: row2.agent_id,
19517
+ teamId: row2.team_id,
19518
+ position: row2.position_x === null || row2.position_y === null ? null : { x: row2.position_x, y: row2.position_y },
19519
+ display: row2.display_json ? JSON.parse(row2.display_json) : null
19520
19520
  }));
19521
19521
  }
19522
19522
  function requireTeamPolicy(db, teamId) {
@@ -19536,7 +19536,7 @@ function requireRevision(teamPolicy, expected) {
19536
19536
  }
19537
19537
  function validateEdges(db, teamId, policyEdges) {
19538
19538
  const members2 = new Set(
19539
- db.raw.query("SELECT id FROM agents WHERE team_id = ?").all(teamId).map((row) => row.id)
19539
+ db.raw.query("SELECT id FROM agents WHERE team_id = ?").all(teamId).map((row2) => row2.id)
19540
19540
  );
19541
19541
  const keys2 = /* @__PURE__ */ new Set();
19542
19542
  for (const edge of policyEdges) {
@@ -19835,8 +19835,8 @@ function insert2(db, g2, paths2) {
19835
19835
  };
19836
19836
  }
19837
19837
  function get3(db, id, paths2) {
19838
- const row = db.raw.query("SELECT * FROM teams WHERE id = ?").get(id);
19839
- return row ? toTeam(row, paths2) : null;
19838
+ const row2 = db.raw.query("SELECT * FROM teams WHERE id = ?").get(id);
19839
+ return row2 ? toTeam(row2, paths2) : null;
19840
19840
  }
19841
19841
  function list2(db, paths2) {
19842
19842
  return db.raw.query("SELECT * FROM teams ORDER BY created_at ASC").all().map((r) => toTeam(r, paths2));
@@ -19851,10 +19851,10 @@ function setTelegramTopicNameFormat(db, id, format) {
19851
19851
  db.raw.run("UPDATE teams SET telegram_topic_name_format = ? WHERE id = ?", [format, id]);
19852
19852
  }
19853
19853
  function getTelegramIconColor(db, id) {
19854
- const row = db.raw.query(
19854
+ const row2 = db.raw.query(
19855
19855
  "SELECT telegram_icon_color FROM teams WHERE id = ?"
19856
19856
  ).get(id);
19857
- return row?.telegram_icon_color ?? null;
19857
+ return row2?.telegram_icon_color ?? null;
19858
19858
  }
19859
19859
  function setTelegramIconColor(db, id, color) {
19860
19860
  db.raw.run("UPDATE teams SET telegram_icon_color = ? WHERE id = ?", [color, id]);
@@ -20060,21 +20060,21 @@ __export(agentLessonProposals_exports, {
20060
20060
  updatePending: () => updatePending
20061
20061
  });
20062
20062
  import { randomUUID as randomUUID2 } from "crypto";
20063
- function toProposal(row) {
20063
+ function toProposal(row2) {
20064
20064
  return {
20065
- id: row.id,
20066
- reviewId: row.review_id,
20067
- agentId: row.agent_id,
20068
- scope: row.scope,
20069
- text: row.text,
20070
- evidence: JSON.parse(row.evidence_json),
20071
- status: row.status,
20072
- version: row.version,
20073
- decidedAt: row.decided_at,
20074
- revokedAt: row.revoked_at,
20075
- appliedKey: row.applied_key,
20076
- createdAt: row.created_at,
20077
- updatedAt: row.updated_at
20065
+ id: row2.id,
20066
+ reviewId: row2.review_id,
20067
+ agentId: row2.agent_id,
20068
+ scope: row2.scope,
20069
+ text: row2.text,
20070
+ evidence: JSON.parse(row2.evidence_json),
20071
+ status: row2.status,
20072
+ version: row2.version,
20073
+ decidedAt: row2.decided_at,
20074
+ revokedAt: row2.revoked_at,
20075
+ appliedKey: row2.applied_key,
20076
+ createdAt: row2.created_at,
20077
+ updatedAt: row2.updated_at
20078
20078
  };
20079
20079
  }
20080
20080
  function insert3(db, input) {
@@ -20100,8 +20100,8 @@ function insert3(db, input) {
20100
20100
  return proposal;
20101
20101
  }
20102
20102
  function get4(db, id) {
20103
- const row = db.raw.query("SELECT * FROM agent_lesson_proposals WHERE id = ?").get(id);
20104
- return row ? toProposal(row) : null;
20103
+ const row2 = db.raw.query("SELECT * FROM agent_lesson_proposals WHERE id = ?").get(id);
20104
+ return row2 ? toProposal(row2) : null;
20105
20105
  }
20106
20106
  function listForReview(db, reviewId) {
20107
20107
  return db.raw.query(
@@ -20190,8 +20190,8 @@ function insert4(db, p) {
20190
20190
  return { ...p, createdAt: now, updatedAt: now };
20191
20191
  }
20192
20192
  function get5(db, id) {
20193
- const row = db.raw.query("SELECT * FROM profiles WHERE id = ?").get(id);
20194
- return row ? toProfile(row) : null;
20193
+ const row2 = db.raw.query("SELECT * FROM profiles WHERE id = ?").get(id);
20194
+ return row2 ? toProfile(row2) : null;
20195
20195
  }
20196
20196
  function list3(db) {
20197
20197
  return db.raw.query("SELECT * FROM profiles ORDER BY created_at ASC").all().map(toProfile);
@@ -20263,16 +20263,16 @@ __export(profileCommunicationDefaults_exports, {
20263
20263
  set: () => set
20264
20264
  });
20265
20265
  function get6(db, profileId) {
20266
- const row = db.raw.query(
20266
+ const row2 = db.raw.query(
20267
20267
  `SELECT user_input, user_output, outside_team_input, outside_team_output, peer_default
20268
20268
  FROM profile_communication_defaults WHERE profile_id = ?`
20269
20269
  ).get(profileId);
20270
- return row ? {
20271
- userInput: row.user_input === 1,
20272
- userOutput: row.user_output === 1,
20273
- outsideTeamInput: row.outside_team_input === 1,
20274
- outsideTeamOutput: row.outside_team_output === 1,
20275
- peerDefault: row.peer_default
20270
+ return row2 ? {
20271
+ userInput: row2.user_input === 1,
20272
+ userOutput: row2.user_output === 1,
20273
+ outsideTeamInput: row2.outside_team_input === 1,
20274
+ outsideTeamOutput: row2.outside_team_output === 1,
20275
+ peerDefault: row2.peer_default
20276
20276
  } : null;
20277
20277
  }
20278
20278
  function set(db, profileId, value) {
@@ -20351,10 +20351,10 @@ function list4(db, provider) {
20351
20351
  }
20352
20352
  function listAll(db) {
20353
20353
  const out = {};
20354
- for (const row of db.raw.query("SELECT * FROM provider_models ORDER BY provider ASC, added_at ASC").all()) {
20355
- const bucket = out[row.provider] ?? [];
20356
- bucket.push(row.model);
20357
- out[row.provider] = bucket;
20354
+ for (const row2 of db.raw.query("SELECT * FROM provider_models ORDER BY provider ASC, added_at ASC").all()) {
20355
+ const bucket = out[row2.provider] ?? [];
20356
+ bucket.push(row2.model);
20357
+ out[row2.provider] = bucket;
20358
20358
  }
20359
20359
  return out;
20360
20360
  }
@@ -20385,8 +20385,8 @@ __export(providerState_exports, {
20385
20385
  setEnabled: () => setEnabled
20386
20386
  });
20387
20387
  function isEnabled(db, providerId) {
20388
- const row = db.raw.query("SELECT * FROM provider_state WHERE provider_id = ?").get(providerId);
20389
- return row?.enabled === 1;
20388
+ const row2 = db.raw.query("SELECT * FROM provider_state WHERE provider_id = ?").get(providerId);
20389
+ return row2?.enabled === 1;
20390
20390
  }
20391
20391
  function setEnabled(db, providerId, enabled) {
20392
20392
  db.raw.run(
@@ -20797,8 +20797,8 @@ var sources = [
20797
20797
  )
20798
20798
  }
20799
20799
  ];
20800
- function normalize(row) {
20801
- const { acknowledged_at, ...item } = row;
20800
+ function normalize(row2) {
20801
+ const { acknowledged_at, ...item } = row2;
20802
20802
  return { ...item, key: `${item.kind}:${item.sourceId}`, acknowledgedAt: acknowledged_at };
20803
20803
  }
20804
20804
  function parseAttentionKey(key3) {
@@ -21022,7 +21022,7 @@ function schemaObjects(db) {
21022
21022
  ).all();
21023
21023
  }
21024
21024
  function schemaPayload(rows) {
21025
- return rows.map((row) => [row.type, row.name, row.tbl_name, normalizeSql(row.sql)].join("\0")).join("\n");
21025
+ return rows.map((row2) => [row2.type, row2.name, row2.tbl_name, normalizeSql(row2.sql)].join("\0")).join("\n");
21026
21026
  }
21027
21027
  function expectedSchema(files) {
21028
21028
  if (canonicalSchemaObjects !== null) return canonicalSchemaObjects;
@@ -21041,7 +21041,7 @@ function assertMigrationCompatibility(db) {
21041
21041
  const expectedVersions = files.map((file) => file.version);
21042
21042
  let appliedVersions;
21043
21043
  try {
21044
- appliedVersions = db.raw.query("SELECT version FROM schema_migrations ORDER BY version").all().map((row) => row.version);
21044
+ appliedVersions = db.raw.query("SELECT version FROM schema_migrations ORDER BY version").all().map((row2) => row2.version);
21045
21045
  } catch {
21046
21046
  throw new IncompatibleDatabaseError();
21047
21047
  }
@@ -21049,10 +21049,10 @@ function assertMigrationCompatibility(db) {
21049
21049
  const expectedObjects = expectedSchema(files);
21050
21050
  if (appliedVersions.length === 0) {
21051
21051
  const migrationTable = actualObjects.filter(
21052
- (row) => row.type === "table" && row.name === "schema_migrations"
21052
+ (row2) => row2.type === "table" && row2.name === "schema_migrations"
21053
21053
  );
21054
21054
  const expectedMigrationTable = expectedObjects.filter(
21055
- (row) => row.type === "table" && row.name === "schema_migrations"
21055
+ (row2) => row2.type === "table" && row2.name === "schema_migrations"
21056
21056
  );
21057
21057
  if (actualObjects.length !== 1 || migrationTable.length !== 1 || schemaPayload(migrationTable) !== schemaPayload(expectedMigrationTable)) {
21058
21058
  throw new IncompatibleDatabaseError();
@@ -21065,7 +21065,7 @@ function assertMigrationCompatibility(db) {
21065
21065
  }
21066
21066
  function runMigrations(db) {
21067
21067
  const existingObjects = schemaObjects(db);
21068
- if (existingObjects.length > 0 && !existingObjects.some((row) => row.type === "table" && row.name === "schema_migrations")) {
21068
+ if (existingObjects.length > 0 && !existingObjects.some((row2) => row2.type === "table" && row2.name === "schema_migrations")) {
21069
21069
  throw new IncompatibleDatabaseError();
21070
21070
  }
21071
21071
  db.raw.exec(schemaMigrationsSql);
@@ -21138,44 +21138,44 @@ __export(teamTemplates_exports, {
21138
21138
  updateCanonicalMetadata: () => updateCanonicalMetadata
21139
21139
  });
21140
21140
  import { randomUUID as randomUUID4 } from "crypto";
21141
- function toTemplate(row) {
21141
+ function toTemplate(row2) {
21142
21142
  return {
21143
- id: row.id,
21144
- name: row.name,
21145
- userMd: row.user_md,
21146
- currentRevision: row.current_revision,
21147
- deletedAt: row.deleted_at,
21148
- createdAt: row.created_at,
21149
- updatedAt: row.updated_at
21143
+ id: row2.id,
21144
+ name: row2.name,
21145
+ userMd: row2.user_md,
21146
+ currentRevision: row2.current_revision,
21147
+ deletedAt: row2.deleted_at,
21148
+ createdAt: row2.created_at,
21149
+ updatedAt: row2.updated_at
21150
21150
  };
21151
21151
  }
21152
- function toSlot(row) {
21152
+ function toSlot(row2) {
21153
21153
  return {
21154
- templateId: row.template_id,
21155
- slotId: row.slot_id,
21156
- position: row.position,
21157
- profileId: row.profile_id,
21158
- agentName: row.agent_name,
21159
- modelOverride: row.model_override,
21160
- reasoningLevel: row.reasoning_level,
21161
- layoutPosition: row.position_x === null || row.position_y === null ? null : { x: row.position_x, y: row.position_y },
21162
- display: row.display_json ? JSON.parse(row.display_json) : null,
21163
- tombstonedAt: row.tombstoned_at
21164
- };
21165
- }
21166
- function toEdge(row) {
21154
+ templateId: row2.template_id,
21155
+ slotId: row2.slot_id,
21156
+ position: row2.position,
21157
+ profileId: row2.profile_id,
21158
+ agentName: row2.agent_name,
21159
+ modelOverride: row2.model_override,
21160
+ reasoningLevel: row2.reasoning_level,
21161
+ layoutPosition: row2.position_x === null || row2.position_y === null ? null : { x: row2.position_x, y: row2.position_y },
21162
+ display: row2.display_json ? JSON.parse(row2.display_json) : null,
21163
+ tombstonedAt: row2.tombstoned_at
21164
+ };
21165
+ }
21166
+ function toEdge(row2) {
21167
21167
  return {
21168
- templateId: row.template_id,
21169
- sourceKind: row.source_kind,
21170
- sourceId: row.source_id || null,
21171
- targetKind: row.target_kind,
21172
- targetId: row.target_id || null,
21173
- posture: row.posture
21168
+ templateId: row2.template_id,
21169
+ sourceKind: row2.source_kind,
21170
+ sourceId: row2.source_id || null,
21171
+ targetKind: row2.target_kind,
21172
+ targetId: row2.target_id || null,
21173
+ posture: row2.posture
21174
21174
  };
21175
21175
  }
21176
21176
  function get7(db, id) {
21177
- const row = db.raw.query("SELECT * FROM team_templates WHERE id = ?").get(id);
21178
- return row ? toTemplate(row) : null;
21177
+ const row2 = db.raw.query("SELECT * FROM team_templates WHERE id = ?").get(id);
21178
+ return row2 ? toTemplate(row2) : null;
21179
21179
  }
21180
21180
  function list5(db) {
21181
21181
  return db.raw.query("SELECT * FROM team_templates ORDER BY created_at ASC").all().map(toTemplate);
@@ -21658,26 +21658,26 @@ __export(agentReviews_exports, {
21658
21658
  setSource: () => setSource
21659
21659
  });
21660
21660
  import { randomUUID as randomUUID5 } from "crypto";
21661
- function toReview(row) {
21661
+ function toReview(row2) {
21662
21662
  return {
21663
- id: row.id,
21664
- agentId: row.agent_id,
21665
- status: row.status,
21666
- trigger: row.trigger_kind,
21667
- sourceSessionId: row.source_session_id,
21668
- sourceStartOrdinal: row.source_start_ordinal,
21669
- sourceEndOrdinal: row.source_end_ordinal,
21670
- inputCharacters: row.input_characters,
21671
- turnsReviewed: row.turns_reviewed,
21672
- proposalCount: row.proposal_count,
21673
- attemptCount: row.attempt_count,
21674
- nextAttemptAt: row.next_attempt_at,
21675
- leaseExpiresAt: row.lease_expires_at,
21676
- startedAt: row.started_at,
21677
- finishedAt: row.finished_at,
21678
- lastError: row.last_error,
21679
- createdAt: row.created_at,
21680
- updatedAt: row.updated_at
21663
+ id: row2.id,
21664
+ agentId: row2.agent_id,
21665
+ status: row2.status,
21666
+ trigger: row2.trigger_kind,
21667
+ sourceSessionId: row2.source_session_id,
21668
+ sourceStartOrdinal: row2.source_start_ordinal,
21669
+ sourceEndOrdinal: row2.source_end_ordinal,
21670
+ inputCharacters: row2.input_characters,
21671
+ turnsReviewed: row2.turns_reviewed,
21672
+ proposalCount: row2.proposal_count,
21673
+ attemptCount: row2.attempt_count,
21674
+ nextAttemptAt: row2.next_attempt_at,
21675
+ leaseExpiresAt: row2.lease_expires_at,
21676
+ startedAt: row2.started_at,
21677
+ finishedAt: row2.finished_at,
21678
+ lastError: row2.last_error,
21679
+ createdAt: row2.created_at,
21680
+ updatedAt: row2.updated_at
21681
21681
  };
21682
21682
  }
21683
21683
  function insert5(db, agentId, trigger, now) {
@@ -21694,15 +21694,15 @@ function insert5(db, agentId, trigger, now) {
21694
21694
  return review;
21695
21695
  }
21696
21696
  function get8(db, id) {
21697
- const row = db.raw.query("SELECT * FROM agent_reviews WHERE id = ?").get(id);
21698
- return row ? toReview(row) : null;
21697
+ const row2 = db.raw.query("SELECT * FROM agent_reviews WHERE id = ?").get(id);
21698
+ return row2 ? toReview(row2) : null;
21699
21699
  }
21700
21700
  function getOpenForAgent(db, agentId) {
21701
- const row = db.raw.query(
21701
+ const row2 = db.raw.query(
21702
21702
  `SELECT * FROM agent_reviews WHERE agent_id = ?
21703
21703
  AND status IN ('pending','running','retrying') LIMIT 1`
21704
21704
  ).get(agentId);
21705
- return row ? toReview(row) : null;
21705
+ return row2 ? toReview(row2) : null;
21706
21706
  }
21707
21707
  function enqueueManual(db, agentId, now = Date.now()) {
21708
21708
  return db.raw.transaction(
@@ -21762,11 +21762,11 @@ function defer(db, id, nextAttemptAt = Date.now() + 1e3) {
21762
21762
  );
21763
21763
  }
21764
21764
  function getLatestCompleted(db, agentId) {
21765
- const row = db.raw.query(
21765
+ const row2 = db.raw.query(
21766
21766
  `SELECT * FROM agent_reviews WHERE agent_id = ? AND status = 'completed'
21767
21767
  ORDER BY finished_at DESC LIMIT 1`
21768
21768
  ).get(agentId);
21769
- return row ? toReview(row) : null;
21769
+ return row2 ? toReview(row2) : null;
21770
21770
  }
21771
21771
  function setSource(db, id, source) {
21772
21772
  db.raw.run(
@@ -21844,40 +21844,40 @@ function endpoint(kind, id, teamId) {
21844
21844
  if (kind === "agent") return { kind, id };
21845
21845
  return { kind, teamId: teamId ?? "__missing__" };
21846
21846
  }
21847
- function toApproval(row) {
21847
+ function toApproval(row2) {
21848
21848
  return {
21849
- id: row.id,
21850
- attemptKind: row.attempt_kind,
21851
- attemptId: row.attempt_id,
21852
- operation: row.operation,
21853
- source: endpoint(row.source_kind, row.source_id, row.source_team_id),
21854
- target: endpoint(row.target_kind, row.target_id, row.target_team_id),
21855
- sourceTeamId: row.source_team_id,
21856
- targetTeamId: row.target_team_id,
21857
- channel: row.channel,
21858
- origin: row.origin,
21859
- requester: row.requester,
21860
- policyRefs: JSON.parse(row.policy_refs_json),
21861
- requiredEdgeIds: JSON.parse(row.required_edge_ids_json),
21862
- payloadKind: row.payload_kind,
21863
- status: row.status,
21864
- expiresAt: row.expires_at,
21865
- decidedAt: row.decided_at,
21866
- decidedBy: row.decided_by,
21867
- decisionReason: row.decision_reason,
21868
- deliveryError: row.delivery_error,
21869
- createdAt: row.created_at,
21870
- updatedAt: row.updated_at
21871
- };
21872
- }
21873
- function event(row) {
21849
+ id: row2.id,
21850
+ attemptKind: row2.attempt_kind,
21851
+ attemptId: row2.attempt_id,
21852
+ operation: row2.operation,
21853
+ source: endpoint(row2.source_kind, row2.source_id, row2.source_team_id),
21854
+ target: endpoint(row2.target_kind, row2.target_id, row2.target_team_id),
21855
+ sourceTeamId: row2.source_team_id,
21856
+ targetTeamId: row2.target_team_id,
21857
+ channel: row2.channel,
21858
+ origin: row2.origin,
21859
+ requester: row2.requester,
21860
+ policyRefs: JSON.parse(row2.policy_refs_json),
21861
+ requiredEdgeIds: JSON.parse(row2.required_edge_ids_json),
21862
+ payloadKind: row2.payload_kind,
21863
+ status: row2.status,
21864
+ expiresAt: row2.expires_at,
21865
+ decidedAt: row2.decided_at,
21866
+ decidedBy: row2.decided_by,
21867
+ decisionReason: row2.decision_reason,
21868
+ deliveryError: row2.delivery_error,
21869
+ createdAt: row2.created_at,
21870
+ updatedAt: row2.updated_at
21871
+ };
21872
+ }
21873
+ function event(row2) {
21874
21874
  return {
21875
- id: row.id,
21876
- approvalId: row.approval_id,
21877
- event: row.event,
21878
- actor: row.actor,
21879
- detail: row.detail,
21880
- createdAt: row.created_at
21875
+ id: row2.id,
21876
+ approvalId: row2.approval_id,
21877
+ event: row2.event,
21878
+ actor: row2.actor,
21879
+ detail: row2.detail,
21880
+ createdAt: row2.created_at
21881
21881
  };
21882
21882
  }
21883
21883
  function raw(db, id) {
@@ -21971,16 +21971,16 @@ function request(db, input, operation, authorization, payloadKind, payload, opti
21971
21971
  return toApproval(raced);
21972
21972
  }
21973
21973
  }
21974
- function expireOne(db, row, now) {
21975
- if (row.status !== "pending" || row.expires_at > now) return false;
21974
+ function expireOne(db, row2, now) {
21975
+ if (row2.status !== "pending" || row2.expires_at > now) return false;
21976
21976
  const changed = db.raw.run(
21977
21977
  `UPDATE communication_approvals
21978
21978
  SET status = 'expired', decided_at = ?, decided_by = 'system',
21979
21979
  decision_reason = 'approval expired', updated_at = ?
21980
21980
  WHERE id = ? AND status = 'pending' AND expires_at <= ?`,
21981
- [now, now, row.id, now]
21981
+ [now, now, row2.id, now]
21982
21982
  ).changes;
21983
- if (changed) appendEvent(db, row.id, "expired", "system", "approval expired", now);
21983
+ if (changed) appendEvent(db, row2.id, "expired", "system", "approval expired", now);
21984
21984
  return changed > 0;
21985
21985
  }
21986
21986
  function expirePending(db, now = Date.now()) {
@@ -21988,29 +21988,29 @@ function expirePending(db, now = Date.now()) {
21988
21988
  const rows = db.raw.query(
21989
21989
  "SELECT * FROM communication_approvals WHERE status = 'pending' AND expires_at <= ?"
21990
21990
  ).all(now);
21991
- for (const row of rows) expireOne(db, row, now);
21991
+ for (const row2 of rows) expireOne(db, row2, now);
21992
21992
  return rows.length;
21993
21993
  })();
21994
21994
  }
21995
21995
  function get9(db, id, includePayload = false) {
21996
21996
  expirePending(db);
21997
- const row = raw(db, id);
21998
- if (!row) return null;
21999
- const approval = toApproval(row);
21997
+ const row2 = raw(db, id);
21998
+ if (!row2) return null;
21999
+ const approval = toApproval(row2);
22000
22000
  if (!includePayload) return approval;
22001
- return detailFromRow(db, row);
22001
+ return detailFromRow(db, row2);
22002
22002
  }
22003
22003
  function getByAttempt(db, attemptKind, attemptId, includePayload = false) {
22004
22004
  expirePending(db);
22005
- const row = rawByAttempt(db, attemptKind, attemptId);
22006
- if (!row) return null;
22007
- return includePayload ? detailFromRow(db, row) : toApproval(row);
22005
+ const row2 = rawByAttempt(db, attemptKind, attemptId);
22006
+ if (!row2) return null;
22007
+ return includePayload ? detailFromRow(db, row2) : toApproval(row2);
22008
22008
  }
22009
- function detailFromRow(db, row) {
22009
+ function detailFromRow(db, row2) {
22010
22010
  const events = db.raw.query(
22011
22011
  "SELECT * FROM communication_approval_events WHERE approval_id = ? ORDER BY created_at, rowid"
22012
- ).all(row.id).map(event);
22013
- return { ...toApproval(row), payload: JSON.parse(row.payload_json), events };
22012
+ ).all(row2.id).map(event);
22013
+ return { ...toApproval(row2), payload: JSON.parse(row2.payload_json), events };
22014
22014
  }
22015
22015
  function list6(db, filters = {}) {
22016
22016
  expirePending(db);
@@ -22032,8 +22032,8 @@ function list6(db, filters = {}) {
22032
22032
  function decide(db, id, decision, actor, reason, now = Date.now()) {
22033
22033
  expirePending(db, now);
22034
22034
  return db.raw.transaction(() => {
22035
- const row = raw(db, id);
22036
- if (!row) throw new Error(`approval_not_found: ${id}`);
22035
+ const row2 = raw(db, id);
22036
+ if (!row2) throw new Error(`approval_not_found: ${id}`);
22037
22037
  const current = raw(db, id);
22038
22038
  if (current.status !== "pending")
22039
22039
  throw new Error(`approval_state_conflict: current ${current.status}`);
@@ -22773,6 +22773,42 @@ var SERVICES = [
22773
22773
  description: "Numeric id of the forum-enabled supergroup the bot is admin in."
22774
22774
  }
22775
22775
  ]
22776
+ },
22777
+ {
22778
+ id: "publication",
22779
+ displayName: "Code host publication",
22780
+ category: "integration",
22781
+ hint: "Where an accepted change is committed and opened as a pull request",
22782
+ fields: [
22783
+ {
22784
+ envVar: "PUBLICATION_HOST",
22785
+ kind: "config",
22786
+ label: "Host",
22787
+ placeholder: "github",
22788
+ description: 'The only supported host today. "local" points at a bare repository path and opens no pull request.'
22789
+ },
22790
+ {
22791
+ envVar: "PUBLICATION_REPOSITORY",
22792
+ kind: "config",
22793
+ label: "Repository",
22794
+ placeholder: "owner/name",
22795
+ description: "For github: owner/name. For local: an absolute path to a bare repository. The Team repository's own origin is never used."
22796
+ },
22797
+ {
22798
+ envVar: "PUBLICATION_BASE_BRANCH",
22799
+ kind: "config",
22800
+ label: "Base branch",
22801
+ placeholder: "main",
22802
+ description: "The branch a publication is based on and its pull request targets."
22803
+ },
22804
+ {
22805
+ envVar: "GITHUB_TOKEN",
22806
+ kind: "secret",
22807
+ label: "GitHub token",
22808
+ placeholder: "ghp_...",
22809
+ description: "Needs contents:write and pull_requests:write on that repository. Used only for one push and one pull request."
22810
+ }
22811
+ ]
22776
22812
  }
22777
22813
  ];
22778
22814
  var FIELD_INDEX = (() => {
@@ -22812,8 +22848,8 @@ function isConfigKey(key3) {
22812
22848
  function openConfig(db) {
22813
22849
  return {
22814
22850
  get(key3) {
22815
- const row = db.raw.query("SELECT * FROM config WHERE key = ?").get(key3);
22816
- return row?.value;
22851
+ const row2 = db.raw.query("SELECT * FROM config WHERE key = ?").get(key3);
22852
+ return row2?.value;
22817
22853
  },
22818
22854
  set(key3, value) {
22819
22855
  if (!isConfigKey(key3)) {
@@ -22895,17 +22931,17 @@ function insert6(db, input) {
22895
22931
  now
22896
22932
  ]
22897
22933
  );
22898
- const row = get10(db, id);
22899
- if (!row) throw new Error("mcp server insert failed");
22900
- return row;
22934
+ const row2 = get10(db, id);
22935
+ if (!row2) throw new Error("mcp server insert failed");
22936
+ return row2;
22901
22937
  }
22902
22938
  function get10(db, id) {
22903
- const row = db.raw.query("SELECT * FROM mcp_servers WHERE id = ?").get(id);
22904
- return row ? toServer(row) : null;
22939
+ const row2 = db.raw.query("SELECT * FROM mcp_servers WHERE id = ?").get(id);
22940
+ return row2 ? toServer(row2) : null;
22905
22941
  }
22906
22942
  function getByName(db, name) {
22907
- const row = db.raw.query("SELECT * FROM mcp_servers WHERE name = ?").get(name);
22908
- return row ? toServer(row) : null;
22943
+ const row2 = db.raw.query("SELECT * FROM mcp_servers WHERE name = ?").get(name);
22944
+ return row2 ? toServer(row2) : null;
22909
22945
  }
22910
22946
  function list7(db) {
22911
22947
  return db.raw.query("SELECT * FROM mcp_servers ORDER BY created_at ASC").all().map(toServer);
@@ -23008,8 +23044,8 @@ function send(db, input) {
23008
23044
  };
23009
23045
  }
23010
23046
  function get11(db, id) {
23011
- const row = db.raw.query("SELECT * FROM messages WHERE id = ?").get(id);
23012
- return row ? toMessage(row) : null;
23047
+ const row2 = db.raw.query("SELECT * FROM messages WHERE id = ?").get(id);
23048
+ return row2 ? toMessage(row2) : null;
23013
23049
  }
23014
23050
  function listInbox(db, agentId, opts) {
23015
23051
  const sql = opts?.unreadOnly ? "SELECT * FROM messages WHERE to_agent_id = ? AND read_at IS NULL AND policy_claimed_at IS NULL AND policy_disposition = 'deliverable' ORDER BY created_at ASC" : "SELECT * FROM messages WHERE to_agent_id = ? AND policy_disposition = 'deliverable' ORDER BY created_at ASC";
@@ -23124,9 +23160,9 @@ function openSecrets(db, password) {
23124
23160
  function listAll3() {
23125
23161
  return db.raw.query("SELECT * FROM secrets ORDER BY key ASC").all();
23126
23162
  }
23127
- function tryDecrypt(row) {
23163
+ function tryDecrypt(row2) {
23128
23164
  try {
23129
- const envelope = JSON.parse(row.envelope);
23165
+ const envelope = JSON.parse(row2.envelope);
23130
23166
  return decrypt(envelope, password);
23131
23167
  } catch {
23132
23168
  return void 0;
@@ -23134,9 +23170,9 @@ function openSecrets(db, password) {
23134
23170
  }
23135
23171
  return {
23136
23172
  get(key3) {
23137
- const row = getRow(key3);
23138
- if (!row) return void 0;
23139
- return tryDecrypt(row);
23173
+ const row2 = getRow(key3);
23174
+ if (!row2) return void 0;
23175
+ return tryDecrypt(row2);
23140
23176
  },
23141
23177
  set(key3, value) {
23142
23178
  const envelope = JSON.stringify(encrypt(value, password));
@@ -23188,8 +23224,8 @@ function toMeta(r) {
23188
23224
  };
23189
23225
  }
23190
23226
  function get12(db, name) {
23191
- const row = db.raw.query("SELECT * FROM skill_meta WHERE name = ?").get(name);
23192
- return row ? toMeta(row) : null;
23227
+ const row2 = db.raw.query("SELECT * FROM skill_meta WHERE name = ?").get(name);
23228
+ return row2 ? toMeta(row2) : null;
23193
23229
  }
23194
23230
  function listAll2(db) {
23195
23231
  return db.raw.query("SELECT * FROM skill_meta ORDER BY name ASC").all().map(toMeta);
@@ -23234,8 +23270,8 @@ function list8(db) {
23234
23270
  return db.raw.query("SELECT * FROM telegram_allowed_users ORDER BY added_at ASC").all().map(toUser);
23235
23271
  }
23236
23272
  function get13(db, userId) {
23237
- const row = db.raw.query("SELECT * FROM telegram_allowed_users WHERE user_id = ?").get(userId);
23238
- return row ? toUser(row) : null;
23273
+ const row2 = db.raw.query("SELECT * FROM telegram_allowed_users WHERE user_id = ?").get(userId);
23274
+ return row2 ? toUser(row2) : null;
23239
23275
  }
23240
23276
  function isAllowed(db, userId) {
23241
23277
  return get13(db, userId) !== null;
@@ -23308,30 +23344,30 @@ function status(db) {
23308
23344
  const owner = db.raw.query(
23309
23345
  "SELECT user_id FROM telegram_allowed_users WHERE role = 'owner' ORDER BY added_at LIMIT 1"
23310
23346
  ).get();
23311
- const row = db.raw.query(
23347
+ const row2 = db.raw.query(
23312
23348
  "SELECT digest, expires_at, created_at FROM telegram_pairing_challenge WHERE singleton = 1"
23313
23349
  ).get();
23314
- const active = row !== null && row.expires_at > Date.now();
23315
- if (row && !active) cancel2(db);
23350
+ const active = row2 !== null && row2.expires_at > Date.now();
23351
+ if (row2 && !active) cancel2(db);
23316
23352
  return {
23317
23353
  paired: owner !== null,
23318
23354
  challengeActive: active,
23319
- challengeExpiresAt: active ? row?.expires_at ?? null : null,
23355
+ challengeExpiresAt: active ? row2?.expires_at ?? null : null,
23320
23356
  ownerUserId: owner?.user_id ?? null
23321
23357
  };
23322
23358
  }
23323
23359
  function consume(db, input) {
23324
23360
  return db.raw.transaction(() => {
23325
23361
  if (status(db).paired) return false;
23326
- const row = db.raw.query(
23362
+ const row2 = db.raw.query(
23327
23363
  "SELECT digest, expires_at, created_at FROM telegram_pairing_challenge WHERE singleton = 1"
23328
23364
  ).get();
23329
- if (!row || row.expires_at <= Date.now()) {
23365
+ if (!row2 || row2.expires_at <= Date.now()) {
23330
23366
  cancel2(db);
23331
23367
  return false;
23332
23368
  }
23333
23369
  const supplied = digest(input.code);
23334
- const expected = Buffer.from(row.digest, "hex");
23370
+ const expected = Buffer.from(row2.digest, "hex");
23335
23371
  if (supplied.length !== expected.length || !timingSafeEqual(supplied, expected)) return false;
23336
23372
  add(db, { ...input, role: "owner" });
23337
23373
  cancel2(db);
@@ -23355,22 +23391,22 @@ __export(triggerDispatches_exports, {
23355
23391
  succeed: () => succeed
23356
23392
  });
23357
23393
  import { randomUUID as randomUUID9 } from "crypto";
23358
- function toDispatch(row) {
23394
+ function toDispatch(row2) {
23359
23395
  return {
23360
- id: row.id,
23361
- triggerId: row.trigger_id,
23362
- agentId: row.agent_id,
23363
- conversationId: row.conversation_id,
23364
- scheduledAt: row.scheduled_at,
23365
- status: row.status,
23366
- attemptCount: row.attempt_count,
23367
- nextAttemptAt: row.next_attempt_at,
23368
- leaseExpiresAt: row.lease_expires_at,
23369
- startedAt: row.started_at,
23370
- finishedAt: row.finished_at,
23371
- lastError: row.last_error,
23372
- createdAt: row.created_at,
23373
- updatedAt: row.updated_at
23396
+ id: row2.id,
23397
+ triggerId: row2.trigger_id,
23398
+ agentId: row2.agent_id,
23399
+ conversationId: row2.conversation_id,
23400
+ scheduledAt: row2.scheduled_at,
23401
+ status: row2.status,
23402
+ attemptCount: row2.attempt_count,
23403
+ nextAttemptAt: row2.next_attempt_at,
23404
+ leaseExpiresAt: row2.lease_expires_at,
23405
+ startedAt: row2.started_at,
23406
+ finishedAt: row2.finished_at,
23407
+ lastError: row2.last_error,
23408
+ createdAt: row2.created_at,
23409
+ updatedAt: row2.updated_at
23374
23410
  };
23375
23411
  }
23376
23412
  function materialize(db, input) {
@@ -23392,15 +23428,15 @@ function materialize(db, input) {
23392
23428
  now
23393
23429
  ]
23394
23430
  );
23395
- const row = db.raw.query(
23431
+ const row2 = db.raw.query(
23396
23432
  "SELECT * FROM trigger_dispatches WHERE trigger_id = ? AND scheduled_at = ?"
23397
23433
  ).get(input.triggerId, input.scheduledAt);
23398
- if (!row) throw new Error("trigger dispatch materialization failed");
23399
- return toDispatch(row);
23434
+ if (!row2) throw new Error("trigger dispatch materialization failed");
23435
+ return toDispatch(row2);
23400
23436
  }
23401
23437
  function get14(db, id) {
23402
- const row = db.raw.query("SELECT * FROM trigger_dispatches WHERE id = ?").get(id);
23403
- return row ? toDispatch(row) : null;
23438
+ const row2 = db.raw.query("SELECT * FROM trigger_dispatches WHERE id = ?").get(id);
23439
+ return row2 ? toDispatch(row2) : null;
23404
23440
  }
23405
23441
  function listClaimable2(db, now = Date.now()) {
23406
23442
  return db.raw.query(
@@ -23431,8 +23467,8 @@ function claim2(db, id, options = {}) {
23431
23467
  [leaseExpiresAt, now, now, id, now, now]
23432
23468
  );
23433
23469
  if (Number(result.changes) !== 1) return null;
23434
- const row = db.raw.query("SELECT * FROM trigger_dispatches WHERE id = ?").get(id);
23435
- return row ? toDispatch(row) : null;
23470
+ const row2 = db.raw.query("SELECT * FROM trigger_dispatches WHERE id = ?").get(id);
23471
+ return row2 ? toDispatch(row2) : null;
23436
23472
  })();
23437
23473
  }
23438
23474
  function succeed(db, id, now = Date.now()) {
@@ -23541,8 +23577,8 @@ function insert7(db, input) {
23541
23577
  };
23542
23578
  }
23543
23579
  function get15(db, id) {
23544
- const row = db.raw.query("SELECT * FROM agent_triggers WHERE id = ?").get(id);
23545
- return row ? toTrigger(row) : null;
23580
+ const row2 = db.raw.query("SELECT * FROM agent_triggers WHERE id = ?").get(id);
23581
+ return row2 ? toTrigger(row2) : null;
23546
23582
  }
23547
23583
  function listForAgent3(db, agentId) {
23548
23584
  return db.raw.query(
@@ -23643,25 +23679,25 @@ function list9(db, opts) {
23643
23679
  return db.raw.query(sql).all().map(toToken);
23644
23680
  }
23645
23681
  function get16(db, id) {
23646
- const row = db.raw.query("SELECT * FROM web_tokens WHERE id = ?").get(id);
23647
- return row ? toToken(row) : null;
23682
+ const row2 = db.raw.query("SELECT * FROM web_tokens WHERE id = ?").get(id);
23683
+ return row2 ? toToken(row2) : null;
23648
23684
  }
23649
23685
  function findActiveByToken(db, token) {
23650
23686
  const tokenHash = hashToken(token);
23651
- const row = db.raw.query(
23687
+ const row2 = db.raw.query(
23652
23688
  `SELECT * FROM web_tokens
23653
23689
  WHERE token_hash = ? AND revoked_at IS NULL
23654
23690
  AND (expires_at IS NULL OR expires_at > ?)`
23655
23691
  ).get(tokenHash, Date.now());
23656
- return row ? toToken(row) : null;
23692
+ return row2 ? toToken(row2) : null;
23657
23693
  }
23658
23694
  function rejectionReason(db, token, now = Date.now()) {
23659
- const row = db.raw.query(
23695
+ const row2 = db.raw.query(
23660
23696
  "SELECT expires_at, revoked_at FROM web_tokens WHERE token_hash = ?"
23661
23697
  ).get(hashToken(token));
23662
- if (!row) return "invalid";
23663
- if (row.revoked_at !== null) return "revoked";
23664
- if (row.expires_at !== null && row.expires_at <= now) return "expired";
23698
+ if (!row2) return "invalid";
23699
+ if (row2.revoked_at !== null) return "revoked";
23700
+ if (row2.expires_at !== null && row2.expires_at <= now) return "expired";
23665
23701
  return "invalid";
23666
23702
  }
23667
23703
  function markUsed(db, id, when = Date.now()) {
@@ -23681,17 +23717,17 @@ var SESSION_ABSOLUTE_MS = 7 * 24 * 60 * 60 * 1e3;
23681
23717
  function hash(value) {
23682
23718
  return createHash4("sha256").update(value).digest("hex");
23683
23719
  }
23684
- function toSession(row, currentId) {
23720
+ function toSession(row2, currentId) {
23685
23721
  return {
23686
- id: row.id,
23687
- deviceTokenId: row.device_token_id,
23688
- deviceLabel: row.device_label,
23689
- createdAt: row.created_at,
23690
- lastSeenAt: row.last_seen_at,
23691
- idleExpiresAt: row.idle_expires_at,
23692
- absoluteExpiresAt: row.absolute_expires_at,
23693
- revokedAt: row.revoked_at,
23694
- current: row.id === currentId
23722
+ id: row2.id,
23723
+ deviceTokenId: row2.device_token_id,
23724
+ deviceLabel: row2.device_label,
23725
+ createdAt: row2.created_at,
23726
+ lastSeenAt: row2.last_seen_at,
23727
+ idleExpiresAt: row2.idle_expires_at,
23728
+ absoluteExpiresAt: row2.absolute_expires_at,
23729
+ revokedAt: row2.revoked_at,
23730
+ current: row2.id === currentId
23695
23731
  };
23696
23732
  }
23697
23733
  function create3(db, deviceTokenId, now = Date.now()) {
@@ -23734,15 +23770,15 @@ function authenticate(db, cookieValue, now = Date.now()) {
23734
23770
  const id = cookieValue.slice(0, separator);
23735
23771
  const secret = cookieValue.slice(separator + 1);
23736
23772
  if (!secret) return null;
23737
- const row = db.raw.query(
23773
+ const row2 = db.raw.query(
23738
23774
  `SELECT s.*, t.label AS device_label
23739
23775
  FROM web_sessions s JOIN web_tokens t ON t.id = s.device_token_id
23740
23776
  WHERE s.id = ? AND s.secret_hash = ? AND s.revoked_at IS NULL
23741
23777
  AND s.idle_expires_at > ? AND s.absolute_expires_at > ?
23742
23778
  AND t.kind = 'device' AND t.revoked_at IS NULL AND t.expires_at > ?`
23743
23779
  ).get(id, hash(secret), now, now, now);
23744
- if (!row) return null;
23745
- const idleExpiresAt = Math.min(now + SESSION_IDLE_MS, row.absolute_expires_at);
23780
+ if (!row2) return null;
23781
+ const idleExpiresAt = Math.min(now + SESSION_IDLE_MS, row2.absolute_expires_at);
23746
23782
  db.raw.run("UPDATE web_sessions SET last_seen_at = ?, idle_expires_at = ? WHERE id = ?", [
23747
23783
  now,
23748
23784
  idleExpiresAt,
@@ -23750,9 +23786,9 @@ function authenticate(db, cookieValue, now = Date.now()) {
23750
23786
  ]);
23751
23787
  return {
23752
23788
  id,
23753
- deviceTokenId: row.device_token_id,
23754
- deviceLabel: row.device_label,
23755
- csrfHash: row.csrf_hash
23789
+ deviceTokenId: row2.device_token_id,
23790
+ deviceLabel: row2.device_label,
23791
+ csrfHash: row2.csrf_hash
23756
23792
  };
23757
23793
  }
23758
23794
  function csrfMatches(session, csrf) {
@@ -23764,7 +23800,7 @@ function list10(db, opts = {}) {
23764
23800
  `SELECT s.*, t.label AS device_label FROM web_sessions s
23765
23801
  JOIN web_tokens t ON t.id = s.device_token_id
23766
23802
  ${where} ORDER BY s.created_at DESC`
23767
- ).all().map((row) => toSession(row, opts.currentId));
23803
+ ).all().map((row2) => toSession(row2, opts.currentId));
23768
23804
  }
23769
23805
  function revoke3(db, id, now = Date.now()) {
23770
23806
  return db.raw.run("UPDATE web_sessions SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL", [
@@ -24985,15 +25021,15 @@ function saveCodingCommand(db, receipt) {
24985
25021
  pruneCodingCommands(db, receipt.teamId);
24986
25022
  }
24987
25023
  function getCodingCommand(db, id) {
24988
- const row = db.raw.query(
25024
+ const row2 = db.raw.query(
24989
25025
  "SELECT receipt_json FROM coding_commands WHERE id = ?"
24990
25026
  ).get(id);
24991
- return row ? JSON.parse(row.receipt_json) : null;
25027
+ return row2 ? JSON.parse(row2.receipt_json) : null;
24992
25028
  }
24993
25029
  function interruptCodingCommands(db, turnId) {
24994
25030
  const rows = db.raw.query("SELECT receipt_json FROM coding_commands").all();
24995
- for (const row of rows) {
24996
- const receipt = JSON.parse(row.receipt_json);
25031
+ for (const row2 of rows) {
25032
+ const receipt = JSON.parse(row2.receipt_json);
24997
25033
  if (turnId && receipt.turnId !== turnId) continue;
24998
25034
  if (!turnId) receipt.environment.inputFingerprint = null;
24999
25035
  if (receipt.state === "running") {
@@ -25024,15 +25060,15 @@ var receiptFields = `id, source_kind sourceKind, source_id sourceId, agent_id ag
25024
25060
  function publicDestination(binding) {
25025
25061
  return { id: binding.id, chatId: binding.chatId, topicId: binding.topicId };
25026
25062
  }
25027
- function decode(row) {
25028
- const { destinationJson, ...receipt } = row;
25063
+ function decode(row2) {
25064
+ const { destinationJson, ...receipt } = row2;
25029
25065
  return { ...receipt, destination: publicDestination(JSON.parse(destinationJson)) };
25030
25066
  }
25031
25067
  function settings(db) {
25032
- const row = db.raw.query(
25068
+ const row2 = db.raw.query(
25033
25069
  `SELECT ${settingsFields} FROM notification_settings WHERE singleton = 1`
25034
25070
  ).get();
25035
- if (!row)
25071
+ if (!row2)
25036
25072
  return {
25037
25073
  revision: 0,
25038
25074
  enabled: false,
@@ -25045,28 +25081,28 @@ function settings(db) {
25045
25081
  updatedAt: 0
25046
25082
  };
25047
25083
  return {
25048
- revision: row.revision,
25049
- enabled: row.enabled === 1,
25050
- restorePaused: row.restorePaused === 1,
25051
- kinds: JSON.parse(row.kindsJson),
25052
- timezone: row.timezone,
25053
- quietHours: row.quietJson === null ? null : JSON.parse(row.quietJson),
25054
- destination: row.destinationJson === null ? null : publicDestination(JSON.parse(row.destinationJson)),
25055
- eligibleAfter: row.eligibleAfter,
25056
- updatedAt: row.updatedAt
25084
+ revision: row2.revision,
25085
+ enabled: row2.enabled === 1,
25086
+ restorePaused: row2.restorePaused === 1,
25087
+ kinds: JSON.parse(row2.kindsJson),
25088
+ timezone: row2.timezone,
25089
+ quietHours: row2.quietJson === null ? null : JSON.parse(row2.quietJson),
25090
+ destination: row2.destinationJson === null ? null : publicDestination(JSON.parse(row2.destinationJson)),
25091
+ eligibleAfter: row2.eligibleAfter,
25092
+ updatedAt: row2.updatedAt
25057
25093
  };
25058
25094
  }
25059
25095
  function destinationBinding(db) {
25060
- const row = db.raw.query(
25096
+ const row2 = db.raw.query(
25061
25097
  "SELECT destination_json value FROM notification_settings WHERE singleton = 1"
25062
25098
  ).get();
25063
- return row?.value ? JSON.parse(row.value) : null;
25099
+ return row2?.value ? JSON.parse(row2.value) : null;
25064
25100
  }
25065
25101
  function eligibilityCutoffs(db) {
25066
- const row = db.raw.query(
25102
+ const row2 = db.raw.query(
25067
25103
  "SELECT kind_cutoffs_json value FROM notification_settings WHERE singleton=1"
25068
25104
  ).get();
25069
- return row ? JSON.parse(row.value) : {};
25105
+ return row2 ? JSON.parse(row2.value) : {};
25070
25106
  }
25071
25107
  function hasRestoredHistory(db) {
25072
25108
  return db.raw.query(
@@ -25125,14 +25161,14 @@ function saveSettings(db, expectedRevision, next, binding, now = Date.now()) {
25125
25161
  })();
25126
25162
  }
25127
25163
  function get17(db, id) {
25128
- const row = db.raw.query(`SELECT ${receiptFields} FROM notification_receipts WHERE id=?`).get(id);
25129
- return row ? decode(row) : null;
25164
+ const row2 = db.raw.query(`SELECT ${receiptFields} FROM notification_receipts WHERE id=?`).get(id);
25165
+ return row2 ? decode(row2) : null;
25130
25166
  }
25131
25167
  function receiptBinding(db, id) {
25132
- const row = db.raw.query(
25168
+ const row2 = db.raw.query(
25133
25169
  "SELECT destination_json value FROM notification_receipts WHERE id=?"
25134
25170
  ).get(id);
25135
- return row ? JSON.parse(row.value) : null;
25171
+ return row2 ? JSON.parse(row2.value) : null;
25136
25172
  }
25137
25173
  function admit(db, item, binding, now = Date.now()) {
25138
25174
  return db.raw.transaction(() => {
@@ -25170,10 +25206,10 @@ function list11(db, options = {}) {
25170
25206
  let after = "";
25171
25207
  const params = [];
25172
25208
  if (options.cursor) {
25173
- const row = get17(db, options.cursor);
25174
- if (!row) throw new Error("notification_cursor_invalid");
25209
+ const row2 = get17(db, options.cursor);
25210
+ if (!row2) throw new Error("notification_cursor_invalid");
25175
25211
  after = ` AND (created_at ${comparison} ? OR (created_at = ? AND id ${comparison} ?))`;
25176
- params.push(row.createdAt, row.createdAt, row.id);
25212
+ params.push(row2.createdAt, row2.createdAt, row2.id);
25177
25213
  }
25178
25214
  params.push(limit + 1);
25179
25215
  const rows = db.raw.query(`SELECT ${receiptFields} FROM notification_receipts
@@ -25234,8 +25270,202 @@ function recoverInterrupted(db, now = Date.now()) {
25234
25270
  );
25235
25271
  }
25236
25272
 
25273
+ // ../daemon/src/core/repos/publications.ts
25274
+ import { randomUUID as randomUUID19 } from "crypto";
25275
+ var PUBLICATION_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
25276
+ var PublicationError = class extends Error {
25277
+ constructor(code, message) {
25278
+ super(message);
25279
+ this.code = code;
25280
+ }
25281
+ code;
25282
+ };
25283
+ var COLUMNS = `id, team_id, packet_id, snapshot_id, host, repository, base_branch, head_branch,
25284
+ base_oid, commit_message, notify_agent_id, state, refusal_reason, refusal_detail, commit_oid,
25285
+ signed, pull_request_number, pull_request_url, error, created_at, finished_at`;
25286
+ function toRecord(row2) {
25287
+ return {
25288
+ id: row2.id,
25289
+ teamId: row2.team_id,
25290
+ packetId: row2.packet_id,
25291
+ snapshotId: row2.snapshot_id,
25292
+ host: row2.host,
25293
+ repository: row2.repository,
25294
+ baseBranch: row2.base_branch,
25295
+ headBranch: row2.head_branch,
25296
+ baseOid: row2.base_oid,
25297
+ commitMessage: row2.commit_message,
25298
+ notifyAgentId: row2.notify_agent_id,
25299
+ state: row2.state,
25300
+ refusalReason: row2.refusal_reason,
25301
+ refusalDetail: row2.refusal_detail,
25302
+ commitOid: row2.commit_oid,
25303
+ // Always false. Read from the row rather than assumed, so a future migration that stores 1 would
25304
+ // surface here instead of being silently reported as unsigned.
25305
+ signed: row2.signed === 1,
25306
+ pullRequestNumber: row2.pull_request_number,
25307
+ pullRequestUrl: row2.pull_request_url,
25308
+ error: row2.error,
25309
+ createdAt: row2.created_at,
25310
+ finishedAt: row2.finished_at
25311
+ };
25312
+ }
25313
+ function createPublication(db, input) {
25314
+ const now = input.now ?? Date.now();
25315
+ const id = randomUUID19();
25316
+ return inTx(db, () => {
25317
+ const published = db.raw.query(
25318
+ "SELECT id FROM publications WHERE packet_id = ? AND state = 'published'"
25319
+ ).get(input.packetId);
25320
+ if (published) {
25321
+ throw new PublicationError(
25322
+ "already_published",
25323
+ "this packet already has a published revision; publishing it again would duplicate the work"
25324
+ );
25325
+ }
25326
+ db.raw.run(
25327
+ `INSERT INTO publications (
25328
+ id, team_id, packet_id, snapshot_id, host, repository, base_branch, head_branch, base_oid,
25329
+ commit_message, notify_agent_id, state, signed, created_at, updated_at
25330
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending', 0, ?, ?)`,
25331
+ [
25332
+ id,
25333
+ input.teamId,
25334
+ input.packetId,
25335
+ input.snapshotId,
25336
+ input.host,
25337
+ input.repository,
25338
+ input.baseBranch,
25339
+ input.headBranch,
25340
+ input.baseOid,
25341
+ input.commitMessage,
25342
+ input.notifyAgentId ?? null,
25343
+ now,
25344
+ now
25345
+ ]
25346
+ );
25347
+ const created = getPublication(db, id);
25348
+ if (!created)
25349
+ throw new PublicationError("publication_not_found", "the publication could not be read back");
25350
+ return created;
25351
+ });
25352
+ }
25353
+ function getPublication(db, id) {
25354
+ const row2 = db.raw.query(`SELECT ${COLUMNS} FROM publications WHERE id = ?`).get(id);
25355
+ return row2 ? toRecord(row2) : null;
25356
+ }
25357
+ function listPublications(db, teamId, limit = 50) {
25358
+ return db.raw.query(
25359
+ `SELECT ${COLUMNS} FROM publications WHERE team_id = ? ORDER BY created_at DESC, id DESC LIMIT ?`
25360
+ ).all(teamId, limit).map(toRecord);
25361
+ }
25362
+ function claimPublication(db, input) {
25363
+ const now = input.now ?? Date.now();
25364
+ return inTx(db, () => {
25365
+ const result = db.raw.run(
25366
+ `UPDATE publications
25367
+ SET state = 'publishing', claimed_by = ?, lease_expires_at = ?, updated_at = ?
25368
+ WHERE id = ? AND state = 'pending'
25369
+ AND NOT EXISTS (
25370
+ SELECT 1 FROM publications p2
25371
+ WHERE p2.packet_id = publications.packet_id AND p2.state = 'published'
25372
+ )`,
25373
+ [input.leaseOwner, now + input.leaseMs, now, input.id]
25374
+ );
25375
+ if (Number(result.changes) === 0) return null;
25376
+ return getPublication(db, input.id);
25377
+ });
25378
+ }
25379
+ function refusePublication(db, input) {
25380
+ const now = input.now ?? Date.now();
25381
+ const record3 = inTx(db, () => {
25382
+ const result = db.raw.run(
25383
+ `UPDATE publications
25384
+ SET state = 'refused', refusal_reason = ?, refusal_detail = ?, lease_expires_at = NULL,
25385
+ claimed_by = NULL, finished_at = ?, updated_at = ?
25386
+ WHERE id = ? AND state IN ('pending', 'publishing')`,
25387
+ [input.reason, input.detail, now, now, input.id]
25388
+ );
25389
+ if (Number(result.changes) === 0) {
25390
+ throw new PublicationError(
25391
+ "publication_conflict",
25392
+ "a publication that already left the machine cannot be refused"
25393
+ );
25394
+ }
25395
+ return row(db, input.id);
25396
+ });
25397
+ return record3;
25398
+ }
25399
+ function settlePublicationPublished(db, input) {
25400
+ const now = input.now ?? Date.now();
25401
+ inTx(db, () => {
25402
+ const result = db.raw.run(
25403
+ `UPDATE publications
25404
+ SET state = 'published', commit_oid = ?, pull_request_number = ?, pull_request_url = ?,
25405
+ lease_expires_at = NULL, claimed_by = NULL, finished_at = ?, updated_at = ?
25406
+ WHERE id = ? AND state = 'publishing'`,
25407
+ [input.commitOid, input.pullRequestNumber, input.pullRequestUrl, now, now, input.id]
25408
+ );
25409
+ if (Number(result.changes) === 0) {
25410
+ throw new PublicationError("publication_conflict", "the publication was not being published");
25411
+ }
25412
+ });
25413
+ return row(db, input.id);
25414
+ }
25415
+ function settlePublicationUncertain(db, input) {
25416
+ return settleUnsent(
25417
+ db,
25418
+ input.id,
25419
+ "uncertain",
25420
+ input.error || "the attempt was interrupted before its outcome was recorded",
25421
+ input.now
25422
+ );
25423
+ }
25424
+ function settleUnsent(db, id, state3, error2, now = Date.now()) {
25425
+ inTx(db, () => {
25426
+ const result = db.raw.run(
25427
+ `UPDATE publications
25428
+ SET state = ?, error = ?, lease_expires_at = NULL, claimed_by = NULL,
25429
+ finished_at = ?, updated_at = ?
25430
+ WHERE id = ? AND state = 'publishing'`,
25431
+ [state3, error2, now, now, id]
25432
+ );
25433
+ if (Number(result.changes) === 0) {
25434
+ throw new PublicationError("publication_conflict", `the publication was not being published`);
25435
+ }
25436
+ });
25437
+ return row(db, id);
25438
+ }
25439
+ function recoverExpiredPublications(db, now = Date.now()) {
25440
+ const expired = db.raw.query(
25441
+ "SELECT id FROM publications WHERE state = 'publishing' AND lease_expires_at <= ?"
25442
+ ).all(now);
25443
+ const recovered = [];
25444
+ for (const { id } of expired) {
25445
+ settlePublicationUncertain(db, {
25446
+ id,
25447
+ error: "the publishing process did not finish; whether the branch reached the host is unknown",
25448
+ now
25449
+ });
25450
+ recovered.push(id);
25451
+ }
25452
+ return recovered;
25453
+ }
25454
+ function row(db, id) {
25455
+ const record3 = getPublication(db, id);
25456
+ if (!record3) throw new PublicationError("publication_not_found", "the publication is gone");
25457
+ return record3;
25458
+ }
25459
+ function notePublicationError(db, id, error2, now = Date.now()) {
25460
+ db.raw.run("UPDATE publications SET error = ?, updated_at = ? WHERE id = ?", [
25461
+ error2.slice(0, 400),
25462
+ now,
25463
+ id
25464
+ ]);
25465
+ }
25466
+
25237
25467
  // ../daemon/src/core/repos/questions.ts
25238
- import { createHash as createHash6, randomUUID as randomUUID19 } from "crypto";
25468
+ import { createHash as createHash6, randomUUID as randomUUID20 } from "crypto";
25239
25469
 
25240
25470
  // ../daemon/src/lib/question-input.ts
25241
25471
  var QUESTION_LIMITS = Object.freeze({
@@ -25336,8 +25566,8 @@ var fields = `id, agent_id AS agentId, team_id AS teamId, conversation_id AS con
25336
25566
  created_at AS createdAt, expires_at AS expiresAt, settled_at AS settledAt, delivered_at AS deliveredAt, answer_json AS answerJson,
25337
25567
  response_request_id AS responseRequestId, no_answer_reason AS noAnswerReason, continuation,
25338
25568
  consumed_at AS consumedAt, delivery_approval_id AS deliveryApprovalId, answer_approval_id AS answerApprovalId`;
25339
- function decode2(row) {
25340
- const { questionJson, answerJson, ...item } = row;
25569
+ function decode2(row2) {
25570
+ const { questionJson, answerJson, ...item } = row2;
25341
25571
  return {
25342
25572
  ...item,
25343
25573
  question: parseQuestionInput(JSON.parse(questionJson)),
@@ -25345,10 +25575,10 @@ function decode2(row) {
25345
25575
  };
25346
25576
  }
25347
25577
  function get18(db, agentId, id) {
25348
- const row = db.raw.query(
25578
+ const row2 = db.raw.query(
25349
25579
  `SELECT ${fields} FROM agent_questions WHERE agent_id = ? AND id = ?`
25350
25580
  ).get(agentId, id);
25351
- return row ? decode2(row) : null;
25581
+ return row2 ? decode2(row2) : null;
25352
25582
  }
25353
25583
  function list12(db, agentId, limit = 20, conversationId) {
25354
25584
  if (!Number.isInteger(limit) || limit < 1 || limit > 100)
@@ -25381,7 +25611,7 @@ function create4(db, input, now = Date.now()) {
25381
25611
  COALESCE(SUM(status = 'pending'), 0) AS pending, COALESCE(SUM(turn_id = ?), 0) AS turn FROM agent_questions`).get(input.turnId);
25382
25612
  if (!count3 || count3.total >= QUESTION_LIMITS.recordsPerHome || count3.pending >= QUESTION_LIMITS.pendingPerHome || count3.turn >= QUESTION_LIMITS.perTurn)
25383
25613
  throw new Error("Question capacity reached");
25384
- const id = randomUUID19();
25614
+ const id = randomUUID20();
25385
25615
  db.raw.run(
25386
25616
  `INSERT INTO agent_questions (id, agent_id, team_id, conversation_id, turn_id, tool_call_id,
25387
25617
  question_json, binding_json, status, created_at, expires_at, continuation) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending', ?, ?, 'waiting')`,
@@ -25493,10 +25723,10 @@ function retireClosedApprovals(db, now) {
25493
25723
  WHERE q.status != 'pending' AND a.status = 'pending'
25494
25724
  AND a.payload_kind IN ('question_delivery', 'question_answer')
25495
25725
  `).all();
25496
- for (const row of rows)
25726
+ for (const row2 of rows)
25497
25727
  decide(
25498
25728
  db,
25499
- row.id,
25729
+ row2.id,
25500
25730
  "cancel",
25501
25731
  "system",
25502
25732
  "Originating question is closed",
@@ -25507,13 +25737,13 @@ var digest2 = (value) => createHash6("sha256").update(JSON.stringify(value)).dig
25507
25737
  function approvalSnapshot(db, agentId, id) {
25508
25738
  const question = get18(db, agentId, id);
25509
25739
  if (!question) return null;
25510
- const row = db.raw.query(
25740
+ const row2 = db.raw.query(
25511
25741
  "SELECT binding_json, proposal_json FROM agent_questions WHERE id = ?"
25512
25742
  ).get(id);
25513
- if (!row || Buffer.byteLength(row.binding_json) > 16384 || row.proposal_json && Buffer.byteLength(row.proposal_json) > 32768)
25743
+ if (!row2 || Buffer.byteLength(row2.binding_json) > 16384 || row2.proposal_json && Buffer.byteLength(row2.proposal_json) > 32768)
25514
25744
  throw new Error("Question binding unavailable");
25515
- const proposal = row.proposal_json ? parseQuestionResponse(
25516
- JSON.parse(row.proposal_json),
25745
+ const proposal = row2.proposal_json ? parseQuestionResponse(
25746
+ JSON.parse(row2.proposal_json),
25517
25747
  question.question,
25518
25748
  question.conversationId
25519
25749
  ) : null;
@@ -25525,7 +25755,7 @@ function approvalSnapshot(db, agentId, id) {
25525
25755
  turnId: question.turnId,
25526
25756
  toolCallId: question.toolCallId,
25527
25757
  question: question.question,
25528
- binding: JSON.parse(row.binding_json)
25758
+ binding: JSON.parse(row2.binding_json)
25529
25759
  });
25530
25760
  return {
25531
25761
  question,
@@ -25582,7 +25812,7 @@ function ownsApproval(db, capturedId, providedId) {
25582
25812
  }
25583
25813
 
25584
25814
  // ../daemon/src/core/repos/review-packets.ts
25585
- import { randomUUID as randomUUID20 } from "crypto";
25815
+ import { randomUUID as randomUUID21 } from "crypto";
25586
25816
  var REVIEW_PACKET_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
25587
25817
  var REVIEW_LIMITS = {
25588
25818
  summary: 2e3,
@@ -25612,7 +25842,7 @@ function assertLength(value, max, field) {
25612
25842
  }
25613
25843
  function createReviewPacket(db, input) {
25614
25844
  const now = input.now ?? Date.now();
25615
- const id = randomUUID20();
25845
+ const id = randomUUID21();
25616
25846
  if (input.summary) assertLength(input.summary, REVIEW_LIMITS.summary, "summary");
25617
25847
  db.raw.run(
25618
25848
  `INSERT INTO review_packets (
@@ -25639,16 +25869,16 @@ function createReviewPacket(db, input) {
25639
25869
  return created;
25640
25870
  }
25641
25871
  function getReviewPacket(db, id, now = Date.now()) {
25642
- const row = db.raw.query(
25872
+ const row2 = db.raw.query(
25643
25873
  `SELECT ${PACKET_COLUMNS} FROM review_packets WHERE id = ? AND expires_at > ?`
25644
25874
  ).get(id, now);
25645
- return row ? toPacket(row) : null;
25875
+ return row2 ? toPacket(row2) : null;
25646
25876
  }
25647
25877
  function getTeamReviewPacket(db, teamId, id, now = Date.now()) {
25648
- const row = db.raw.query(
25878
+ const row2 = db.raw.query(
25649
25879
  `SELECT ${PACKET_COLUMNS} FROM review_packets WHERE id = ? AND team_id = ? AND expires_at > ?`
25650
25880
  ).get(id, teamId, now);
25651
- return row ? toPacket(row) : null;
25881
+ return row2 ? toPacket(row2) : null;
25652
25882
  }
25653
25883
  function listReviewPackets(db, teamId, limit = 50, now = Date.now()) {
25654
25884
  return db.raw.query(
@@ -25691,7 +25921,7 @@ function addReviewFinding(db, input) {
25691
25921
  `a packet holds at most ${REVIEW_LIMITS.findings} findings`
25692
25922
  );
25693
25923
  }
25694
- const id = randomUUID20();
25924
+ const id = randomUUID21();
25695
25925
  db.raw.run(
25696
25926
  `INSERT INTO review_findings (
25697
25927
  id, packet_id, author_kind, author_agent_id, path, line_start, line_end, severity, note,
@@ -25712,14 +25942,14 @@ function addReviewFinding(db, input) {
25712
25942
  input.now ?? Date.now()
25713
25943
  ]
25714
25944
  );
25715
- const row = getReviewFinding(db, id);
25716
- if (!row) throw new ReviewPacketError("finding_not_found", "the finding could not be read back");
25717
- return row;
25945
+ const row2 = getReviewFinding(db, id);
25946
+ if (!row2) throw new ReviewPacketError("finding_not_found", "the finding could not be read back");
25947
+ return row2;
25718
25948
  });
25719
25949
  }
25720
25950
  function getReviewFinding(db, id) {
25721
- const row = db.raw.query(`SELECT ${FINDING_COLUMNS} FROM review_findings WHERE id = ?`).get(id);
25722
- return row ? toFinding(row) : null;
25951
+ const row2 = db.raw.query(`SELECT ${FINDING_COLUMNS} FROM review_findings WHERE id = ?`).get(id);
25952
+ return row2 ? toFinding(row2) : null;
25723
25953
  }
25724
25954
  function listReviewFindings(db, packetId) {
25725
25955
  return db.raw.query(
@@ -25760,7 +25990,7 @@ function resolveReviewFinding(db, input) {
25760
25990
  }
25761
25991
  function recordReviewConclusion(db, input) {
25762
25992
  if (input.note) assertLength(input.note, REVIEW_LIMITS.note, "conclusion note");
25763
- const id = randomUUID20();
25993
+ const id = randomUUID21();
25764
25994
  db.raw.run(
25765
25995
  `INSERT INTO review_conclusions (
25766
25996
  id, packet_id, reviewer_kind, reviewer_agent_id, conclusion, note, snapshot_id, created_at
@@ -25781,12 +26011,14 @@ function recordReviewConclusion(db, input) {
25781
26011
  input.now ?? Date.now()
25782
26012
  ]
25783
26013
  );
25784
- const row = db.raw.query(
26014
+ const row2 = db.raw.query(
25785
26015
  `SELECT ${CONCLUSION_COLUMNS} FROM review_conclusions
25786
26016
  WHERE packet_id = ? AND reviewer_kind = ? AND reviewer_agent_id IS ?`
25787
26017
  ).get(input.packetId, input.reviewerKind, input.reviewerAgentId ?? null);
25788
- if (!row) throw new ReviewPacketError("packet_not_found", "the conclusion could not be read back");
25789
- return toConclusion(row);
26018
+ if (!row2) throw new ReviewPacketError("packet_not_found", "the conclusion could not be read back");
26019
+ const packet = getReviewPacket(db, input.packetId);
26020
+ if (packet?.state === "open") setReviewPacketState(db, input.packetId, "reviewed");
26021
+ return toConclusion(row2);
25790
26022
  }
25791
26023
  function listReviewConclusions(db, packetId) {
25792
26024
  return db.raw.query(
@@ -25801,7 +26033,7 @@ function claimReviewAttempt(db, input) {
25801
26033
  const next = (db.raw.query(
25802
26034
  "SELECT COALESCE(MAX(attempt_number), 0) AS n FROM review_attempts WHERE packet_id = ?"
25803
26035
  ).get(input.packetId)?.n ?? 0) + 1;
25804
- const id = randomUUID20();
26036
+ const id = randomUUID21();
25805
26037
  db.raw.run(
25806
26038
  `INSERT INTO review_attempts (
25807
26039
  id, packet_id, attempt_number, supersedes_attempt_id, state, lease_owner, lease_expires_at, created_at
@@ -25824,8 +26056,8 @@ function claimReviewAttempt(db, input) {
25824
26056
  });
25825
26057
  }
25826
26058
  function getReviewAttempt(db, id) {
25827
- const row = db.raw.query(`SELECT ${ATTEMPT_COLUMNS} FROM review_attempts WHERE id = ?`).get(id);
25828
- return row ? toAttempt(row) : null;
26059
+ const row2 = db.raw.query(`SELECT ${ATTEMPT_COLUMNS} FROM review_attempts WHERE id = ?`).get(id);
26060
+ return row2 ? toAttempt(row2) : null;
25829
26061
  }
25830
26062
  function listReviewAttempts(db, packetId) {
25831
26063
  return db.raw.query(
@@ -25836,11 +26068,11 @@ function finishReviewAttempt(db, input) {
25836
26068
  if (input.error != null) assertLength(input.error, REVIEW_LIMITS.summary, "error");
25837
26069
  const now = input.now ?? Date.now();
25838
26070
  return inTx(db, () => {
25839
- const row = db.raw.query(
26071
+ const row2 = db.raw.query(
25840
26072
  `SELECT ${ATTEMPT_COLUMNS} FROM review_attempts WHERE id = ? AND lease_owner = ?`
25841
26073
  ).get(input.attemptId, input.leaseOwner);
25842
- if (!row) return false;
25843
- const attempt = toAttempt(row);
26074
+ if (!row2) return false;
26075
+ const attempt = toAttempt(row2);
25844
26076
  if (attempt.finishedAt !== null) return false;
25845
26077
  db.raw.run(
25846
26078
  `UPDATE review_attempts
@@ -25877,24 +26109,24 @@ var PACKET_COLUMNS = "id, team_id, requester_kind, requester_agent_id, reviewer_
25877
26109
  var FINDING_COLUMNS = "id, packet_id, author_kind, author_agent_id, path, line_start, line_end, severity, note, snapshot_id, state, resolution_kind, resolution_note, resolved_at, resolved_by_kind, resolved_by_agent_id, created_at";
25878
26110
  var CONCLUSION_COLUMNS = "id, packet_id, reviewer_kind, reviewer_agent_id, conclusion, note, snapshot_id, created_at";
25879
26111
  var ATTEMPT_COLUMNS = "id, packet_id, attempt_number, supersedes_attempt_id, state, lease_owner, lease_expires_at, started_at, finished_at, error, created_at";
25880
- function toPacket(row) {
26112
+ function toPacket(row2) {
25881
26113
  return {
25882
- id: row.id,
25883
- teamId: row.team_id,
25884
- requesterKind: row.requester_kind,
25885
- requesterAgentId: row.requester_agent_id,
25886
- reviewerAgentId: row.reviewer_agent_id,
25887
- snapshotId: row.snapshot_id,
25888
- snapshotComplete: row.snapshot_complete === 1,
25889
- head: row.head,
25890
- baseOid: row.base_oid,
25891
- summary: row.summary,
25892
- state: row.state,
25893
- exportedAt: row.exported_at,
25894
- exportRevision: row.export_revision,
25895
- reported: parseReported(row.reported_json),
25896
- createdAt: row.created_at,
25897
- expiresAt: row.expires_at
26114
+ id: row2.id,
26115
+ teamId: row2.team_id,
26116
+ requesterKind: row2.requester_kind,
26117
+ requesterAgentId: row2.requester_agent_id,
26118
+ reviewerAgentId: row2.reviewer_agent_id,
26119
+ snapshotId: row2.snapshot_id,
26120
+ snapshotComplete: row2.snapshot_complete === 1,
26121
+ head: row2.head,
26122
+ baseOid: row2.base_oid,
26123
+ summary: row2.summary,
26124
+ state: row2.state,
26125
+ exportedAt: row2.exported_at,
26126
+ exportRevision: row2.export_revision,
26127
+ reported: parseReported(row2.reported_json),
26128
+ createdAt: row2.created_at,
26129
+ expiresAt: row2.expires_at
25898
26130
  };
25899
26131
  }
25900
26132
  function parseReported(json) {
@@ -25934,57 +26166,57 @@ function recordReportedState(db, input) {
25934
26166
  ]);
25935
26167
  return next;
25936
26168
  }
25937
- function toFinding(row) {
26169
+ function toFinding(row2) {
25938
26170
  return {
25939
- id: row.id,
25940
- packetId: row.packet_id,
25941
- authorKind: row.author_kind,
25942
- authorAgentId: row.author_agent_id,
25943
- path: row.path,
25944
- lineStart: row.line_start,
25945
- lineEnd: row.line_end,
25946
- severity: row.severity,
25947
- note: row.note,
25948
- snapshotId: row.snapshot_id,
25949
- state: row.state,
25950
- resolutionKind: row.resolution_kind,
25951
- resolutionNote: row.resolution_note,
25952
- resolvedAt: row.resolved_at,
25953
- resolvedByKind: row.resolved_by_kind,
25954
- resolvedByAgentId: row.resolved_by_agent_id,
25955
- createdAt: row.created_at
25956
- };
25957
- }
25958
- function toConclusion(row) {
26171
+ id: row2.id,
26172
+ packetId: row2.packet_id,
26173
+ authorKind: row2.author_kind,
26174
+ authorAgentId: row2.author_agent_id,
26175
+ path: row2.path,
26176
+ lineStart: row2.line_start,
26177
+ lineEnd: row2.line_end,
26178
+ severity: row2.severity,
26179
+ note: row2.note,
26180
+ snapshotId: row2.snapshot_id,
26181
+ state: row2.state,
26182
+ resolutionKind: row2.resolution_kind,
26183
+ resolutionNote: row2.resolution_note,
26184
+ resolvedAt: row2.resolved_at,
26185
+ resolvedByKind: row2.resolved_by_kind,
26186
+ resolvedByAgentId: row2.resolved_by_agent_id,
26187
+ createdAt: row2.created_at
26188
+ };
26189
+ }
26190
+ function toConclusion(row2) {
25959
26191
  return {
25960
- id: row.id,
25961
- packetId: row.packet_id,
25962
- reviewerKind: row.reviewer_kind,
25963
- reviewerAgentId: row.reviewer_agent_id,
25964
- conclusion: row.conclusion,
25965
- note: row.note,
25966
- snapshotId: row.snapshot_id,
25967
- createdAt: row.created_at
26192
+ id: row2.id,
26193
+ packetId: row2.packet_id,
26194
+ reviewerKind: row2.reviewer_kind,
26195
+ reviewerAgentId: row2.reviewer_agent_id,
26196
+ conclusion: row2.conclusion,
26197
+ note: row2.note,
26198
+ snapshotId: row2.snapshot_id,
26199
+ createdAt: row2.created_at
25968
26200
  };
25969
26201
  }
25970
- function toAttempt(row) {
26202
+ function toAttempt(row2) {
25971
26203
  return {
25972
- id: row.id,
25973
- packetId: row.packet_id,
25974
- attemptNumber: row.attempt_number,
25975
- supersedesAttemptId: row.supersedes_attempt_id,
25976
- state: row.state,
25977
- leaseOwner: row.lease_owner,
25978
- leaseExpiresAt: row.lease_expires_at,
25979
- startedAt: row.started_at,
25980
- finishedAt: row.finished_at,
25981
- error: row.error,
25982
- createdAt: row.created_at
26204
+ id: row2.id,
26205
+ packetId: row2.packet_id,
26206
+ attemptNumber: row2.attempt_number,
26207
+ supersedesAttemptId: row2.supersedes_attempt_id,
26208
+ state: row2.state,
26209
+ leaseOwner: row2.lease_owner,
26210
+ leaseExpiresAt: row2.lease_expires_at,
26211
+ startedAt: row2.started_at,
26212
+ finishedAt: row2.finished_at,
26213
+ error: row2.error,
26214
+ createdAt: row2.created_at
25983
26215
  };
25984
26216
  }
25985
26217
 
25986
26218
  // ../daemon/src/core/repos/user-queue.ts
25987
- import { createHash as createHash7, randomUUID as randomUUID21 } from "crypto";
26219
+ import { createHash as createHash7, randomUUID as randomUUID22 } from "crypto";
25988
26220
  var QUEUE_LIMITS = Object.freeze({
25989
26221
  perAgent: 20,
25990
26222
  perHome: 100,
@@ -26039,10 +26271,10 @@ function normalize2(message, attachments2) {
26039
26271
  return { message, files, total };
26040
26272
  }
26041
26273
  function control(db, agentId) {
26042
- const row = db.raw.query(
26274
+ const row2 = db.raw.query(
26043
26275
  "SELECT paused, revision, reason FROM user_queue_controls WHERE agent_id = ?"
26044
26276
  ).get(agentId);
26045
- return row ? { ...row, paused: row.paused === 1 } : { paused: false, revision: 0, reason: null };
26277
+ return row2 ? { ...row2, paused: row2.paused === 1 } : { paused: false, revision: 0, reason: null };
26046
26278
  }
26047
26279
  function ensureControl(db, agentId) {
26048
26280
  db.raw.run("INSERT INTO user_queue_controls (agent_id) VALUES (?) ON CONFLICT DO NOTHING", [
@@ -26054,18 +26286,18 @@ function attachments(db, id) {
26054
26286
  `SELECT id, name, mime_type AS mimeType, byte_length AS byteLength, sha256 FROM user_queue_attachments WHERE item_id = ? ORDER BY ordinal`
26055
26287
  ).all(id);
26056
26288
  }
26057
- function hydrate(db, row) {
26289
+ function hydrate(db, row2) {
26058
26290
  return {
26059
- ...row,
26060
- payloadRetained: row.payloadRetained === 1,
26061
- attachments: attachments(db, row.id)
26291
+ ...row2,
26292
+ payloadRetained: row2.payloadRetained === 1,
26293
+ attachments: attachments(db, row2.id)
26062
26294
  };
26063
26295
  }
26064
26296
  function get19(db, agentId, id) {
26065
- const row = db.raw.query(
26297
+ const row2 = db.raw.query(
26066
26298
  `SELECT ${fields2} FROM user_queue_items WHERE agent_id = ? AND id = ?`
26067
26299
  ).get(agentId, id);
26068
- return row ? hydrate(db, row) : null;
26300
+ return row2 ? hydrate(db, row2) : null;
26069
26301
  }
26070
26302
  function list13(db, agentId, options = {}) {
26071
26303
  const { all = false, limit = 20, offset = 0 } = options;
@@ -26077,7 +26309,7 @@ function list13(db, agentId, options = {}) {
26077
26309
  ).all(agentId, limit, offset);
26078
26310
  const total = db.raw.query(`SELECT count(*) n FROM user_queue_items WHERE ${where}`).get(agentId)?.n ?? 0;
26079
26311
  return {
26080
- items: rows.map((row) => hydrate(db, row)),
26312
+ items: rows.map((row2) => hydrate(db, row2)),
26081
26313
  control: control(db, agentId),
26082
26314
  total,
26083
26315
  limit,
@@ -26172,7 +26404,7 @@ function accept(db, input, replacement) {
26172
26404
  db.raw.run(
26173
26405
  `INSERT INTO user_queue_attachments (id,item_id,ordinal,name,mime_type,byte_length,sha256,bytes) VALUES (?,?,?,?,?,?,?,?)`,
26174
26406
  [
26175
- randomUUID21(),
26407
+ randomUUID22(),
26176
26408
  input.id,
26177
26409
  ordinal,
26178
26410
  file.name,
@@ -26192,10 +26424,10 @@ function readInput(db, agentId, id) {
26192
26424
  const item = get19(db, agentId, id);
26193
26425
  if (!item?.payloadRetained || item.text === null)
26194
26426
  throw new Error("Queue input no longer retained");
26195
- const row = db.raw.query(
26427
+ const row2 = db.raw.query(
26196
26428
  "SELECT provenance_json, input_digest FROM user_queue_items WHERE id = ?"
26197
26429
  ).get(id);
26198
- if (!row) throw new Error("Queue input unavailable");
26430
+ if (!row2) throw new Error("Queue input unavailable");
26199
26431
  const retainedSize = db.raw.query(
26200
26432
  "SELECT count(*) n, coalesce(sum(length(bytes)),0) bytes FROM user_queue_attachments WHERE item_id = ?"
26201
26433
  ).get(id);
@@ -26213,7 +26445,7 @@ function readInput(db, agentId, id) {
26213
26445
  };
26214
26446
  });
26215
26447
  const normalized = normalize2(item.text, restored);
26216
- const provenance = JSON.parse(row.provenance_json);
26448
+ const provenance = JSON.parse(row2.provenance_json);
26217
26449
  const actualDigest = hash2(
26218
26450
  JSON.stringify({
26219
26451
  agentId: item.agentId,
@@ -26226,9 +26458,9 @@ function readInput(db, agentId, id) {
26226
26458
  replaces: item.supersedesId
26227
26459
  })
26228
26460
  );
26229
- if (actualDigest !== row.input_digest)
26461
+ if (actualDigest !== row2.input_digest)
26230
26462
  throw new Error("Queue input binding is missing or corrupt");
26231
- return { item, attachments: restored, provenance, digest: row.input_digest };
26463
+ return { item, attachments: restored, provenance, digest: row2.input_digest };
26232
26464
  }
26233
26465
  function setPaused(db, agentId, paused, expectedRevision, reason = null) {
26234
26466
  if (typeof paused !== "boolean" || !Number.isSafeInteger(expectedRevision) || expectedRevision < 0 || reason !== null && (typeof reason !== "string" || reason.length > 500))
@@ -26324,11 +26556,11 @@ function recoverInterrupted3(db) {
26324
26556
  const agents = db.raw.query(
26325
26557
  `SELECT DISTINCT agent_id FROM user_queue_items WHERE ${interrupted}`
26326
26558
  ).all();
26327
- for (const row of agents) {
26328
- ensureControl(db, row.agent_id);
26559
+ for (const row2 of agents) {
26560
+ ensureControl(db, row2.agent_id);
26329
26561
  db.raw.run(
26330
26562
  "UPDATE user_queue_controls SET paused = 1, revision = revision + 1, reason = 'interrupted' WHERE agent_id = ?",
26331
- [row.agent_id]
26563
+ [row2.agent_id]
26332
26564
  );
26333
26565
  }
26334
26566
  return Number(
@@ -26371,36 +26603,36 @@ function pruneTerminalInput(db, now = Date.now()) {
26371
26603
  })();
26372
26604
  }
26373
26605
  function findAttempt(db, source, attemptId) {
26374
- const row = db.raw.query(
26606
+ const row2 = db.raw.query(
26375
26607
  `SELECT ${fields2} FROM user_queue_items WHERE source = ? AND attempt_id = ?`
26376
26608
  ).get(source, attemptId);
26377
- return row ? hydrate(db, row) : null;
26609
+ return row2 ? hydrate(db, row2) : null;
26378
26610
  }
26379
26611
  function agentsWithOpenItems(db) {
26380
26612
  return db.raw.query(
26381
26613
  `SELECT DISTINCT agent_id FROM user_queue_items WHERE status IN (${openStates})`
26382
- ).all().map((row) => row.agent_id);
26614
+ ).all().map((row2) => row2.agent_id);
26383
26615
  }
26384
26616
  function validateInput(message, attachments2) {
26385
26617
  normalize2(message, attachments2);
26386
26618
  }
26387
26619
  function readProvenance(db, agentId, id) {
26388
- const row = db.raw.query(
26620
+ const row2 = db.raw.query(
26389
26621
  "SELECT provenance_json FROM user_queue_items WHERE agent_id = ? AND id = ? AND length(provenance_json) <= 16384"
26390
26622
  ).get(agentId, id);
26391
- if (!row?.provenance_json) throw new Error("Queue provenance unavailable");
26392
- return JSON.parse(row.provenance_json);
26623
+ if (!row2?.provenance_json) throw new Error("Queue provenance unavailable");
26624
+ return JSON.parse(row2.provenance_json);
26393
26625
  }
26394
26626
  function approvalReference(db, agentId, id) {
26395
- const row = db.raw.query(
26627
+ const row2 = db.raw.query(
26396
26628
  "SELECT input_digest FROM user_queue_items WHERE id = ? AND agent_id = ?"
26397
26629
  ).get(id, agentId);
26398
- if (!row) throw new QueueConflictError("Queue approval input unavailable");
26399
- return { agentId, itemId: id, inputDigest: row.input_digest };
26630
+ if (!row2) throw new QueueConflictError("Queue approval input unavailable");
26631
+ return { agentId, itemId: id, inputDigest: row2.input_digest };
26400
26632
  }
26401
26633
 
26402
26634
  // ../daemon/src/core/repos/verification-requests.ts
26403
- import { randomUUID as randomUUID22 } from "crypto";
26635
+ import { randomUUID as randomUUID23 } from "crypto";
26404
26636
  var VERIFICATION_REQUEST_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
26405
26637
  var VERIFICATION_MAX_CHECKS = 8;
26406
26638
  var VERIFICATION_LIMITS = {
@@ -26422,61 +26654,61 @@ var REQUEST_COLUMNS = "id, team_id, requester_kind, requester_agent_id, recipien
26422
26654
  var CHECK_COLUMNS = "request_id, ordinal, command, cwd, purpose, timeout_ms";
26423
26655
  var OUTCOME_COLUMNS = "attempt_id, ordinal, state, command_id, exit_code, started_at, finished_at";
26424
26656
  var ATTEMPT_COLUMNS2 = "id, request_id, attempt_number, supersedes_attempt_id, state, lease_owner, lease_expires_at, started_at, finished_at, error, observed_writes_json, created_at";
26425
- function toRequest(row) {
26657
+ function toRequest(row2) {
26426
26658
  return {
26427
- id: row.id,
26428
- teamId: row.team_id,
26429
- requesterKind: row.requester_kind === "agent" ? "agent" : "operator",
26430
- requesterAgentId: row.requester_agent_id,
26431
- recipientAgentId: row.recipient_agent_id,
26432
- messageId: row.message_id,
26433
- sourceSessionId: row.source_session_id,
26434
- snapshotId: row.snapshot_id,
26435
- snapshotComplete: row.snapshot_complete === 1,
26436
- head: row.head,
26437
- baseOid: row.base_oid,
26438
- environment: JSON.parse(row.environment_json),
26439
- summary: row.summary,
26440
- state: row.state,
26441
- createdAt: row.created_at,
26442
- expiresAt: row.expires_at
26443
- };
26444
- }
26445
- function toCheck(row) {
26659
+ id: row2.id,
26660
+ teamId: row2.team_id,
26661
+ requesterKind: row2.requester_kind === "agent" ? "agent" : "operator",
26662
+ requesterAgentId: row2.requester_agent_id,
26663
+ recipientAgentId: row2.recipient_agent_id,
26664
+ messageId: row2.message_id,
26665
+ sourceSessionId: row2.source_session_id,
26666
+ snapshotId: row2.snapshot_id,
26667
+ snapshotComplete: row2.snapshot_complete === 1,
26668
+ head: row2.head,
26669
+ baseOid: row2.base_oid,
26670
+ environment: JSON.parse(row2.environment_json),
26671
+ summary: row2.summary,
26672
+ state: row2.state,
26673
+ createdAt: row2.created_at,
26674
+ expiresAt: row2.expires_at
26675
+ };
26676
+ }
26677
+ function toCheck(row2) {
26446
26678
  return {
26447
- requestId: row.request_id,
26448
- ordinal: row.ordinal,
26449
- command: row.command,
26450
- cwd: row.cwd,
26451
- purpose: row.purpose,
26452
- timeoutMs: row.timeout_ms
26679
+ requestId: row2.request_id,
26680
+ ordinal: row2.ordinal,
26681
+ command: row2.command,
26682
+ cwd: row2.cwd,
26683
+ purpose: row2.purpose,
26684
+ timeoutMs: row2.timeout_ms
26453
26685
  };
26454
26686
  }
26455
- function toOutcome(row) {
26687
+ function toOutcome(row2) {
26456
26688
  return {
26457
- attemptId: row.attempt_id,
26458
- ordinal: row.ordinal,
26459
- state: row.state,
26460
- commandId: row.command_id,
26461
- exitCode: row.exit_code,
26462
- startedAt: row.started_at,
26463
- finishedAt: row.finished_at
26689
+ attemptId: row2.attempt_id,
26690
+ ordinal: row2.ordinal,
26691
+ state: row2.state,
26692
+ commandId: row2.command_id,
26693
+ exitCode: row2.exit_code,
26694
+ startedAt: row2.started_at,
26695
+ finishedAt: row2.finished_at
26464
26696
  };
26465
26697
  }
26466
- function toAttempt2(row) {
26698
+ function toAttempt2(row2) {
26467
26699
  return {
26468
- id: row.id,
26469
- requestId: row.request_id,
26470
- attemptNumber: row.attempt_number,
26471
- supersedesAttemptId: row.supersedes_attempt_id,
26472
- state: row.state,
26473
- leaseOwner: row.lease_owner,
26474
- leaseExpiresAt: row.lease_expires_at,
26475
- startedAt: row.started_at,
26476
- finishedAt: row.finished_at,
26477
- error: row.error,
26478
- observedWrites: parseObservedWrites(row.observed_writes_json),
26479
- createdAt: row.created_at
26700
+ id: row2.id,
26701
+ requestId: row2.request_id,
26702
+ attemptNumber: row2.attempt_number,
26703
+ supersedesAttemptId: row2.supersedes_attempt_id,
26704
+ state: row2.state,
26705
+ leaseOwner: row2.lease_owner,
26706
+ leaseExpiresAt: row2.lease_expires_at,
26707
+ startedAt: row2.started_at,
26708
+ finishedAt: row2.finished_at,
26709
+ error: row2.error,
26710
+ observedWrites: parseObservedWrites(row2.observed_writes_json),
26711
+ createdAt: row2.created_at
26480
26712
  };
26481
26713
  }
26482
26714
  function parseObservedWrites(json) {
@@ -26492,7 +26724,7 @@ var VerificationRequestError = class extends Error {
26492
26724
  };
26493
26725
  function createVerificationRequest(db, input) {
26494
26726
  const now = input.now ?? Date.now();
26495
- const id = input.id ?? randomUUID22();
26727
+ const id = input.id ?? randomUUID23();
26496
26728
  if (input.checks.length < 1)
26497
26729
  throw new VerificationRequestError("a request needs at least one check");
26498
26730
  if (input.checks.length > VERIFICATION_MAX_CHECKS) {
@@ -26553,17 +26785,17 @@ function createVerificationRequest(db, input) {
26553
26785
  });
26554
26786
  }
26555
26787
  function getVerificationRequest(db, teamId, id, now = Date.now()) {
26556
- const row = db.raw.query(
26788
+ const row2 = db.raw.query(
26557
26789
  `SELECT ${REQUEST_COLUMNS} FROM verification_requests
26558
26790
  WHERE team_id = ? AND id = ? AND expires_at > ?`
26559
26791
  ).get(teamId, id, now);
26560
- return row ? toRequest(row) : null;
26792
+ return row2 ? toRequest(row2) : null;
26561
26793
  }
26562
26794
  function getVerificationRequestById(db, id, now = Date.now()) {
26563
- const row = db.raw.query(
26795
+ const row2 = db.raw.query(
26564
26796
  `SELECT ${REQUEST_COLUMNS} FROM verification_requests WHERE id = ? AND expires_at > ?`
26565
26797
  ).get(id, now);
26566
- return row ? toRequest(row) : null;
26798
+ return row2 ? toRequest(row2) : null;
26567
26799
  }
26568
26800
  function listVerificationRequests(db, teamId, limit = 50, now = Date.now()) {
26569
26801
  return db.raw.query(
@@ -26594,11 +26826,11 @@ function claimVerificationAttempt(db, input) {
26594
26826
  if (!input.leaseOwner) throw new VerificationRequestError("a claim requires an owner");
26595
26827
  if (input.leaseMs <= 0) throw new VerificationRequestError("a claim requires a positive lease");
26596
26828
  return inTx(db, () => {
26597
- const row = db.raw.query(
26829
+ const row2 = db.raw.query(
26598
26830
  `SELECT ${REQUEST_COLUMNS} FROM verification_requests WHERE id = ? AND expires_at > ?`
26599
26831
  ).get(input.requestId, now);
26600
- if (!row) return null;
26601
- const request2 = toRequest(row);
26832
+ if (!row2) return null;
26833
+ const request2 = toRequest(row2);
26602
26834
  const terminal = VERIFICATION_TERMINAL_REQUEST_STATES.includes(request2.state);
26603
26835
  if (!terminal && request2.state !== "pending") return null;
26604
26836
  if (terminal && !input.rerun) return null;
@@ -26610,7 +26842,7 @@ function claimVerificationAttempt(db, input) {
26610
26842
  `SELECT id, attempt_number FROM verification_attempts WHERE request_id = ?
26611
26843
  ORDER BY attempt_number DESC LIMIT 1`
26612
26844
  ).get(input.requestId);
26613
- const attemptId = randomUUID22();
26845
+ const attemptId = randomUUID23();
26614
26846
  db.raw.run(
26615
26847
  `INSERT INTO verification_attempts
26616
26848
  (id, request_id, attempt_number, supersedes_attempt_id, state, lease_owner,
@@ -26643,11 +26875,11 @@ function finishVerificationAttempt(db, input) {
26643
26875
  const now = input.now ?? Date.now();
26644
26876
  if (input.error != null) assertLength2(input.error, VERIFICATION_LIMITS.error, "error");
26645
26877
  return inTx(db, () => {
26646
- const row = db.raw.query(
26878
+ const row2 = db.raw.query(
26647
26879
  `SELECT ${ATTEMPT_COLUMNS2} FROM verification_attempts WHERE id = ? AND lease_owner = ?`
26648
26880
  ).get(input.attemptId, input.leaseOwner);
26649
- if (!row) return false;
26650
- const attempt = toAttempt2(row);
26881
+ if (!row2) return false;
26882
+ const attempt = toAttempt2(row2);
26651
26883
  if (attempt.finishedAt !== null) return false;
26652
26884
  db.raw.run(
26653
26885
  `UPDATE verification_attempts
@@ -26713,22 +26945,22 @@ function recoverInterruptedVerificationAttempts(db, daemonIdentity, now = Date.n
26713
26945
  `SELECT id, request_id, lease_owner FROM verification_attempts WHERE finished_at IS NULL`
26714
26946
  ).all();
26715
26947
  const recovered = [];
26716
- for (const row of rows) {
26717
- if (row.lease_owner === daemonIdentity) continue;
26948
+ for (const row2 of rows) {
26949
+ if (row2.lease_owner === daemonIdentity) continue;
26718
26950
  db.raw.run(
26719
26951
  `UPDATE verification_attempts
26720
26952
  SET state = 'uncertain', finished_at = ?, lease_owner = NULL, lease_expires_at = NULL,
26721
26953
  error = 'execution was interrupted before it reported an outcome'
26722
26954
  WHERE id = ?`,
26723
- [now, row.id]
26955
+ [now, row2.id]
26724
26956
  );
26725
26957
  db.raw.run(
26726
26958
  `UPDATE verification_check_outcomes SET state = 'unknown', finished_at = ?
26727
26959
  WHERE attempt_id = ? AND state = 'not_executed'`,
26728
- [now, row.id]
26960
+ [now, row2.id]
26729
26961
  );
26730
- setRequestState(db, row.request_id, "uncertain");
26731
- recovered.push(row.request_id);
26962
+ setRequestState(db, row2.request_id, "uncertain");
26963
+ recovered.push(row2.request_id);
26732
26964
  }
26733
26965
  return recovered;
26734
26966
  });
@@ -26749,13 +26981,13 @@ function validateCheck(check) {
26749
26981
  throw new VerificationRequestError("timeout is outside its bounded contract");
26750
26982
  }
26751
26983
  }
26752
- function validateEnvironment(environment) {
26753
- if (!environment.image)
26984
+ function validateEnvironment(environment2) {
26985
+ if (!environment2.image)
26754
26986
  throw new VerificationRequestError("the admitted environment has no image");
26755
- if (environment.sandbox !== "off" && environment.sandbox !== "docker") {
26987
+ if (environment2.sandbox !== "off" && environment2.sandbox !== "docker") {
26756
26988
  throw new VerificationRequestError("the admitted environment has an unknown shell backend");
26757
26989
  }
26758
- if (environment.env && Object.keys(environment.env).length > 32) {
26990
+ if (environment2.env && Object.keys(environment2.env).length > 32) {
26759
26991
  throw new VerificationRequestError("the admitted environment carries too many variables");
26760
26992
  }
26761
26993
  }
@@ -26862,14 +27094,14 @@ function reconcilePrivateResults(db, options = {}) {
26862
27094
  }
26863
27095
 
26864
27096
  // ../daemon/src/lib/coding-environment/lifecycle.ts
26865
- import { randomUUID as randomUUID26 } from "crypto";
27097
+ import { randomUUID as randomUUID27 } from "crypto";
26866
27098
 
26867
27099
  // ../daemon/src/lib/coding-environment/resources.ts
26868
- import { randomUUID as randomUUID24 } from "crypto";
27100
+ import { randomUUID as randomUUID25 } from "crypto";
26869
27101
 
26870
27102
  // ../daemon/src/runtime/shell/docker.ts
26871
27103
  import { spawn } from "child_process";
26872
- import { randomUUID as randomUUID23 } from "crypto";
27104
+ import { randomUUID as randomUUID24 } from "crypto";
26873
27105
  import { closeSync as closeSync2, constants as constants2, mkdtempSync as mkdtempSync2, openSync as openSync2, rmSync as rmSync9, writeFileSync as writeFileSync6 } from "fs";
26874
27106
  import { access, lstat, realpath, stat } from "fs/promises";
26875
27107
  import { tmpdir as tmpdir2 } from "os";
@@ -27359,7 +27591,7 @@ function createPreparedDockerBashOperations(runtime, lifecycle) {
27359
27591
  }
27360
27592
  await assertDockerExecutableIdentity(runtime.dockerPath, runtime.executableIdentity);
27361
27593
  if (signal?.aborted) throw new Error("aborted");
27362
- const containerName = lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID23().replaceAll("-", "")}`;
27594
+ const containerName = lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID24().replaceAll("-", "")}`;
27363
27595
  const spec = buildDockerRunSpec({
27364
27596
  image: runtime.image,
27365
27597
  resolvedImage: runtime.imageId,
@@ -27408,7 +27640,7 @@ async function preflightProtectedDockerEngine(input) {
27408
27640
  }
27409
27641
  async function proveProtectedContainerCreation(engine, workspace, readOnlyMounts, lifecycle, signal) {
27410
27642
  if (signal?.aborted) throw new Error("aborted");
27411
- const containerName = lifecycle?.name("preflight") ?? `bazilion-preflight-${process.pid}-${randomUUID23().replaceAll("-", "")}`;
27643
+ const containerName = lifecycle?.name("preflight") ?? `bazilion-preflight-${process.pid}-${randomUUID24().replaceAll("-", "")}`;
27412
27644
  const dockerClientEnv = { DOCKER_HOST: engine.endpoint };
27413
27645
  const spec = buildDockerRunSpec({
27414
27646
  image: engine.image,
@@ -27740,7 +27972,7 @@ function createDockerBashOperations(options) {
27740
27972
  const dockerClientEnv = await resolveLocalDockerClientEnv(dockerPath, hostEnv);
27741
27973
  const resolvedImage = await inspectSandboxImage(dockerPath, image, dockerClientEnv);
27742
27974
  if (signal?.aborted) throw new Error("aborted");
27743
- const containerName = options.lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID23().replaceAll("-", "")}`;
27975
+ const containerName = options.lifecycle?.name("bash") ?? `bazilion-bash-${process.pid}-${randomUUID24().replaceAll("-", "")}`;
27744
27976
  const spec = buildDockerRunSpec({
27745
27977
  image,
27746
27978
  env,
@@ -28396,7 +28628,7 @@ var WorkspaceResources = class {
28396
28628
  }
28397
28629
  register(lease, resource) {
28398
28630
  return inTx(this.db, () => {
28399
- const id = randomUUID24();
28631
+ const id = randomUUID25();
28400
28632
  lease.attach({ id, kind: resource.kind });
28401
28633
  this.db.raw.run(
28402
28634
  "INSERT INTO workspace_resources (id, writer_id, kind, identity_json) VALUES (?, ?, ?, ?)",
@@ -28406,13 +28638,13 @@ var WorkspaceResources = class {
28406
28638
  });
28407
28639
  }
28408
28640
  async cleanupResource(id, observedNormalExit = false) {
28409
- const row = this.db.raw.query(`SELECT r.*, w.recovery_mode FROM workspace_resources r
28641
+ const row2 = this.db.raw.query(`SELECT r.*, w.recovery_mode FROM workspace_resources r
28410
28642
  JOIN workspace_writers w ON w.id = r.writer_id WHERE r.id = ?`).get(id);
28411
- if (!row) return false;
28412
- if (row.recovery_mode === "restored") return false;
28413
- if (row.cleanup_confirmed) return true;
28414
- const identity2 = JSON.parse(row.identity_json);
28415
- const confirmed = row.kind === "worker" ? await terminateWorkerProcess(identity2, observedNormalExit) : await terminateRecordedContainer(identity2, row.creation_acknowledged === 1);
28643
+ if (!row2) return false;
28644
+ if (row2.recovery_mode === "restored") return false;
28645
+ if (row2.cleanup_confirmed) return true;
28646
+ const identity2 = JSON.parse(row2.identity_json);
28647
+ const confirmed = row2.kind === "worker" ? await terminateWorkerProcess(identity2, observedNormalExit) : await terminateRecordedContainer(identity2, row2.creation_acknowledged === 1);
28416
28648
  if (confirmed)
28417
28649
  this.db.raw.run("UPDATE workspace_resources SET cleanup_confirmed = 1 WHERE id = ?", [id]);
28418
28650
  return confirmed;
@@ -28423,18 +28655,18 @@ var WorkspaceResources = class {
28423
28655
  "SELECT * FROM workspace_resources WHERE writer_id = ? ORDER BY CASE kind WHEN 'worker' THEN 0 ELSE 1 END"
28424
28656
  ).all(writer.id);
28425
28657
  if (writer.resources.some(
28426
- (resource) => !rows.some((row) => row.id === resource.id && row.kind === resource.kind)
28658
+ (resource) => !rows.some((row2) => row2.id === resource.id && row2.kind === resource.kind)
28427
28659
  ))
28428
28660
  return false;
28429
- for (const row of rows) {
28430
- if (!await this.cleanupResource(row.id)) return false;
28661
+ for (const row2 of rows) {
28662
+ if (!await this.cleanupResource(row2.id)) return false;
28431
28663
  }
28432
28664
  return true;
28433
28665
  }
28434
28666
  };
28435
28667
 
28436
28668
  // ../daemon/src/lib/coding-environment/workspace.ts
28437
- import { randomUUID as randomUUID25 } from "crypto";
28669
+ import { randomUUID as randomUUID26 } from "crypto";
28438
28670
  import { realpathSync as realpathSync3 } from "fs";
28439
28671
  import { isAbsolute as isAbsolute3, relative as relative2 } from "path";
28440
28672
  var WorkspaceBusyError = class extends Error {
@@ -28462,15 +28694,15 @@ function workspaceIdentity(registeredRoot) {
28462
28694
  directory.close();
28463
28695
  }
28464
28696
  }
28465
- function view(row) {
28697
+ function view(row2) {
28466
28698
  return {
28467
- id: row.id,
28468
- teamId: row.team_id,
28469
- root: row.root_path,
28470
- rootIdentity: row.root_identity,
28471
- kind: row.kind,
28472
- resources: JSON.parse(row.resources_json),
28473
- ...row.recovery_mode === "restored" ? { restored: true } : {}
28699
+ id: row2.id,
28700
+ teamId: row2.team_id,
28701
+ root: row2.root_path,
28702
+ rootIdentity: row2.root_identity,
28703
+ kind: row2.kind,
28704
+ resources: JSON.parse(row2.resources_json),
28705
+ ...row2.recovery_mode === "restored" ? { restored: true } : {}
28474
28706
  };
28475
28707
  }
28476
28708
  var WorkspaceCoordinator = class {
@@ -28478,7 +28710,7 @@ var WorkspaceCoordinator = class {
28478
28710
  this.db = db;
28479
28711
  }
28480
28712
  db;
28481
- identity = randomUUID25();
28713
+ identity = randomUUID26();
28482
28714
  leases = /* @__PURE__ */ new Set();
28483
28715
  issued = /* @__PURE__ */ new WeakSet();
28484
28716
  claim(teamId, registeredRoot, kind) {
@@ -28486,13 +28718,13 @@ var WorkspaceCoordinator = class {
28486
28718
  return inTx(this.db, () => {
28487
28719
  const exclusive = true;
28488
28720
  const rows = this.db.raw.query("SELECT * FROM workspace_writers").all();
28489
- for (const row of rows) {
28490
- if (!(row.recovery_mode === "restored" && row.team_id === teamId) && !overlappingWorkspaceRoots(row.root_path, root.root) && row.root_identity !== root.rootIdentity)
28721
+ for (const row2 of rows) {
28722
+ if (!(row2.recovery_mode === "restored" && row2.team_id === teamId) && !overlappingWorkspaceRoots(row2.root_path, root.root) && row2.root_identity !== root.rootIdentity)
28491
28723
  continue;
28492
- const recovery = row.daemon_identity !== this.identity || row.state === "recovery";
28493
- if (recovery || exclusive || row.exclusive === 1) throw new WorkspaceBusyError(recovery);
28724
+ const recovery = row2.daemon_identity !== this.identity || row2.state === "recovery";
28725
+ if (recovery || exclusive || row2.exclusive === 1) throw new WorkspaceBusyError(recovery);
28494
28726
  }
28495
- const id = randomUUID25();
28727
+ const id = randomUUID26();
28496
28728
  this.db.raw.run(
28497
28729
  `INSERT INTO workspace_writers
28498
28730
  (id, team_id, root_path, root_identity, daemon_identity, kind, exclusive, state, created_at)
@@ -28527,21 +28759,21 @@ var WorkspaceCoordinator = class {
28527
28759
  }
28528
28760
  /** The recovery host must terminate/reap each recorded resource before acknowledging it. */
28529
28761
  async recover(writerId, teardown) {
28530
- const row = this.db.raw.query("SELECT * FROM workspace_writers WHERE id = ?").get(writerId);
28531
- if (!row) return true;
28532
- if (row.recovery_mode === "restored") return false;
28533
- if (this.leases.has(writerId) || row.daemon_identity === this.identity && row.state === "active")
28762
+ const row2 = this.db.raw.query("SELECT * FROM workspace_writers WHERE id = ?").get(writerId);
28763
+ if (!row2) return true;
28764
+ if (row2.recovery_mode === "restored") return false;
28765
+ if (this.leases.has(writerId) || row2.daemon_identity === this.identity && row2.state === "active")
28534
28766
  throw new WorkspaceBusyError();
28535
28767
  this.db.raw.run("UPDATE workspace_writers SET state = 'recovery' WHERE id = ?", [writerId]);
28536
- if (!await teardown(view(row))) return false;
28768
+ if (!await teardown(view(row2))) return false;
28537
28769
  this.db.raw.run("DELETE FROM workspace_writers WHERE id = ? AND state = 'recovery'", [writerId]);
28538
28770
  return true;
28539
28771
  }
28540
28772
  attach(id, resource) {
28541
28773
  if (!this.leases.has(id)) throw new Error("Workspace lease is no longer active");
28542
- const row = this.db.raw.query("SELECT * FROM workspace_writers WHERE id = ?").get(id);
28543
- if (row?.state !== "active") throw new Error("Workspace lease requires recovery");
28544
- const resources2 = JSON.parse(row.resources_json);
28774
+ const row2 = this.db.raw.query("SELECT * FROM workspace_writers WHERE id = ?").get(id);
28775
+ if (row2?.state !== "active") throw new Error("Workspace lease requires recovery");
28776
+ const resources2 = JSON.parse(row2.resources_json);
28545
28777
  if (resources2.some((item) => item.kind === resource.kind && item.id === resource.id)) return;
28546
28778
  resources2.push(resource);
28547
28779
  this.db.raw.run("UPDATE workspace_writers SET resources_json = ? WHERE id = ?", [
@@ -28611,7 +28843,7 @@ var WorkspaceLifecycle = class {
28611
28843
  const prefix = `bazilion-${lease.writer.id}-`;
28612
28844
  const records2 = /* @__PURE__ */ new Map();
28613
28845
  return {
28614
- name: (kind) => `${prefix}${kind}-${randomUUID26()}`,
28846
+ name: (kind) => `${prefix}${kind}-${randomUUID27()}`,
28615
28847
  beforeCreate: async (identity2) => {
28616
28848
  if (!identity2.containerName.startsWith(prefix) || !/^bazilion-[a-z0-9-]{1,160}$/.test(identity2.containerName) || records2.has(identity2.containerName))
28617
28849
  throw new Error("Invalid turn container identity");
@@ -28646,7 +28878,7 @@ var WorkspaceLifecycle = class {
28646
28878
  };
28647
28879
 
28648
28880
  // ../daemon/src/lib/conversation-target.ts
28649
- import { randomUUID as randomUUID28 } from "crypto";
28881
+ import { randomUUID as randomUUID29 } from "crypto";
28650
28882
 
28651
28883
  // ../daemon/src/core/repos/conversations.ts
28652
28884
  var columns = "id, agent_id AS agentId, title, title_revision AS titleRevision, created_at AS createdAt, updated_at AS updatedAt";
@@ -28681,11 +28913,11 @@ function get20(db, agentId, id) {
28681
28913
  ).get(agentId, id);
28682
28914
  }
28683
28915
  function filename(db, agentId, id) {
28684
- const row = db.raw.query(
28916
+ const row2 = db.raw.query(
28685
28917
  "SELECT filename FROM agent_conversations WHERE agent_id = ? AND id = ?"
28686
28918
  ).get(agentId, id);
28687
- if (!row) throw new Error("Conversation not found");
28688
- return row.filename;
28919
+ if (!row2) throw new Error("Conversation not found");
28920
+ return row2.filename;
28689
28921
  }
28690
28922
  function list14(db, agentId, limit = 20, offset = 0) {
28691
28923
  if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100 || !Number.isSafeInteger(offset) || offset < 0)
@@ -28768,7 +29000,7 @@ function rename(db, agentId, id, value, expectedRevision) {
28768
29000
  }
28769
29001
 
28770
29002
  // ../daemon/src/lib/conversation-file.ts
28771
- import { randomUUID as randomUUID27 } from "crypto";
29003
+ import { randomUUID as randomUUID28 } from "crypto";
28772
29004
  import {
28773
29005
  closeSync as closeSync4,
28774
29006
  constants as constants4,
@@ -28818,7 +29050,7 @@ function readCanonicalSessionFile(directory, filename2, sessionId, minimumEntryO
28818
29050
  const header = entries[0]?.entry;
28819
29051
  if (header?.type !== "session" || header.id !== sessionId)
28820
29052
  throw new Error("Result source session does not match the active Agent session");
28821
- return entries.filter((row, index) => index === 0 || row.offset >= minimumEntryOffset).map((row) => row.entry);
29053
+ return entries.filter((row2, index) => index === 0 || row2.offset >= minimumEntryOffset).map((row2) => row2.entry);
28822
29054
  } finally {
28823
29055
  closeSync3(fd);
28824
29056
  }
@@ -28833,7 +29065,7 @@ function createConversationFile(paths2, agentId, conversationId, cwd) {
28833
29065
  if (realpathSync5(directory) !== directory) throw new Error("Conversation escaped its Agent");
28834
29066
  const filename2 = `${conversationId}.jsonl`;
28835
29067
  const destination = join16(directory, filename2);
28836
- const staging = join16(directory, `.conversation-${randomUUID27()}.tmp`);
29068
+ const staging = join16(directory, `.conversation-${randomUUID28()}.tmp`);
28837
29069
  const header = SessionManager.inMemory(cwd, { id: conversationId }).getHeader();
28838
29070
  const fd = openSync4(staging, constants4.O_WRONLY | constants4.O_CREAT | constants4.O_EXCL, 384);
28839
29071
  try {
@@ -28871,7 +29103,7 @@ function resolveConversationTarget(db, paths2, agentId, pinnedId) {
28871
29103
  db,
28872
29104
  agentId,
28873
29105
  {
28874
- requestId: randomUUID28(),
29106
+ requestId: randomUUID29(),
28875
29107
  expectedSelection: { conversationId: null, revision: 0 }
28876
29108
  },
28877
29109
  (newId) => createConversationFile(paths2, agentId, newId, agent.team.path)
@@ -28938,22 +29170,22 @@ async function runAgentLifecycleMutation(agentId, mutation) {
28938
29170
  }
28939
29171
 
28940
29172
  // ../daemon/src/lib/agent-loop-guard.ts
28941
- import { randomUUID as randomUUID29 } from "crypto";
29173
+ import { randomUUID as randomUUID30 } from "crypto";
28942
29174
  var DEFAULT_MAX_HOPS = 8;
28943
- function toEvent(row) {
29175
+ function toEvent(row2) {
28944
29176
  return {
28945
- id: row.id,
28946
- causalChainId: row.causal_chain_id,
28947
- parentMessageId: row.parent_message_id,
28948
- fromAgentId: row.from_agent_id,
28949
- toAgentId: row.to_agent_id,
28950
- sourceTeamId: row.source_team_id,
28951
- targetTeamId: row.target_team_id,
28952
- attemptedHop: row.attempted_hop,
28953
- maxHops: row.max_hops,
28954
- reason: row.reason,
28955
- origin: row.origin,
28956
- createdAt: row.created_at
29177
+ id: row2.id,
29178
+ causalChainId: row2.causal_chain_id,
29179
+ parentMessageId: row2.parent_message_id,
29180
+ fromAgentId: row2.from_agent_id,
29181
+ toAgentId: row2.to_agent_id,
29182
+ sourceTeamId: row2.source_team_id,
29183
+ targetTeamId: row2.target_team_id,
29184
+ attemptedHop: row2.attempted_hop,
29185
+ maxHops: row2.max_hops,
29186
+ reason: row2.reason,
29187
+ origin: row2.origin,
29188
+ createdAt: row2.created_at
28957
29189
  };
28958
29190
  }
28959
29191
  function agentLoopMaxHops(db, env = process.env) {
@@ -28990,8 +29222,8 @@ function enforceMessageCausality(db, input) {
28990
29222
  const target = agents_exports.get(db, input.to);
28991
29223
  if (!source || !target) return null;
28992
29224
  const event2 = {
28993
- id: randomUUID29(),
28994
- causalChainId: input.causality.causalChainId ?? input.causality.parentMessageId ?? randomUUID29(),
29225
+ id: randomUUID30(),
29226
+ causalChainId: input.causality.causalChainId ?? input.causality.parentMessageId ?? randomUUID30(),
28995
29227
  parentMessageId: input.causality.parentMessageId,
28996
29228
  fromAgentId: input.from,
28997
29229
  toAgentId: input.to,
@@ -30384,8 +30616,8 @@ function assertRepositoryContext(value, teamId) {
30384
30616
  throw new Error("Invalid repository context report");
30385
30617
  const instructions = value.instructions;
30386
30618
  const commands = value.commands;
30387
- const git = value.git;
30388
- if (!keys(instructions, ["state", "issues", "files"]) || !keys(commands, ["state", "issues", "sources", "candidates"]) || !keys(git, [
30619
+ const git2 = value.git;
30620
+ if (!keys(instructions, ["state", "issues", "files"]) || !keys(commands, ["state", "issues", "sources", "candidates"]) || !keys(git2, [
30389
30621
  "state",
30390
30622
  "root",
30391
30623
  "branch",
@@ -30416,7 +30648,7 @@ function assertRepositoryContext(value, teamId) {
30416
30648
  "kind",
30417
30649
  "packageManager"
30418
30650
  ]) && string(candidate.source) && digest3(candidate.sha256) && string(candidate.location) && string(candidate.cwd) && string(candidate.command) && ["script", "excerpt"].includes(String(candidate.kind)) && [null, "npm", "pnpm", "yarn"].includes(candidate.packageManager)
30419
- ) || !["available", "unavailable", "not_repository"].includes(String(git.state)) || ![null, "branch", "detached", "unborn"].includes(git.headState) || ![git.root, git.branch, git.head].every((value2) => value2 === null || string(value2)) || ![git.staged, git.unstaged, git.untracked, git.conflicted].every(count2) || !list15(git.issues, 128, issue))
30651
+ ) || !["available", "unavailable", "not_repository"].includes(String(git2.state)) || ![null, "branch", "detached", "unborn"].includes(git2.headState) || ![git2.root, git2.branch, git2.head].every((value2) => value2 === null || string(value2)) || ![git2.staged, git2.unstaged, git2.untracked, git2.conflicted].every(count2) || !list15(git2.issues, 128, issue))
30420
30652
  throw new Error("Invalid repository context report");
30421
30653
  const report2 = value;
30422
30654
  if (report2.instructions.files.reduce((bytes, file) => bytes + Buffer.byteLength(file.content), 0) > 128 * 1024 || report2.instructions.state === "complete" && (report2.rootIdentity === null || report2.instructions.issues.length > 0))
@@ -30764,11 +30996,26 @@ async function createBazilionPiRuntime(options) {
30764
30996
  }
30765
30997
  return runtime;
30766
30998
  }
30999
+ var OPENAI_COMPATIBLE_VERSION_SEGMENT = { fireworks: "/v1" };
31000
+ function fallbackBaseUrl(providerName, baseUrl) {
31001
+ const segment = OPENAI_COMPATIBLE_VERSION_SEGMENT[providerName];
31002
+ if (!segment || !baseUrl) return baseUrl;
31003
+ let url2;
31004
+ try {
31005
+ url2 = new URL(baseUrl);
31006
+ } catch {
31007
+ return baseUrl;
31008
+ }
31009
+ const path = url2.pathname.replace(/\/+$/, "");
31010
+ if (path.endsWith(segment)) return baseUrl;
31011
+ url2.pathname = `${path}${segment}`;
31012
+ return url2.toString();
31013
+ }
30767
31014
  function resolvePiModel(runtime, providerName, modelId, baseUrl) {
30768
31015
  const known = runtime.getModel(piProviderName(providerName), modelId);
30769
31016
  if (known) return baseUrl ? { ...known, baseUrl } : known;
30770
31017
  if (!baseUrl) throw new UnknownModelError(providerName, modelId);
30771
- return fallbackPiModel(providerName, modelId, baseUrl);
31018
+ return fallbackPiModel(providerName, modelId, fallbackBaseUrl(providerName, baseUrl));
30772
31019
  }
30773
31020
 
30774
31021
  // ../daemon/src/runtime/providers/pi-adapter.ts
@@ -31107,7 +31354,12 @@ function loadProviderConfigFromEnv(env = process.env, oauth) {
31107
31354
  if (env.OPENROUTER_API_KEY) config2.openrouter = { apiKey: env.OPENROUTER_API_KEY };
31108
31355
  if (env.AI_GATEWAY_API_KEY) config2.vercelAiGateway = { apiKey: env.AI_GATEWAY_API_KEY };
31109
31356
  if (env.DEEPSEEK_API_KEY) config2.deepseek = { apiKey: env.DEEPSEEK_API_KEY };
31110
- if (env.FIREWORKS_API_KEY) config2.fireworks = { apiKey: env.FIREWORKS_API_KEY };
31357
+ if (env.FIREWORKS_API_KEY) {
31358
+ config2.fireworks = {
31359
+ apiKey: env.FIREWORKS_API_KEY,
31360
+ baseURL: env.FIREWORKS_BASE_URL ?? providerBaseUrl("fireworks", env)
31361
+ };
31362
+ }
31111
31363
  if (env.TOGETHER_API_KEY) config2.together = { apiKey: env.TOGETHER_API_KEY };
31112
31364
  if (env.BASETEN_API_KEY) config2.baseten = { apiKey: env.BASETEN_API_KEY };
31113
31365
  if (env.MOONSHOT_API_KEY) config2.moonshotai = { apiKey: env.MOONSHOT_API_KEY };
@@ -36194,7 +36446,7 @@ function createBrowserHost(config2) {
36194
36446
  }
36195
36447
 
36196
36448
  // ../daemon/src/lib/coding-environment/agent-host.ts
36197
- import { createHash as createHash10, randomUUID as randomUUID32 } from "crypto";
36449
+ import { createHash as createHash10, randomUUID as randomUUID33 } from "crypto";
36198
36450
 
36199
36451
  // ../daemon/src/core/repos/coding-command-logs.ts
36200
36452
  var CODING_LOG_BYTES = 2 * 1024 * 1024;
@@ -36213,38 +36465,38 @@ function headBytes(value, limit) {
36213
36465
  function mayDisclose(view2, audience) {
36214
36466
  return audience === "producer" || view2.releasedAt !== null;
36215
36467
  }
36216
- var COLUMNS = `command_id, team_id, agent_id, turn_id, tool_call_id, state, text,
36468
+ var COLUMNS2 = `command_id, team_id, agent_id, turn_id, tool_call_id, state, text,
36217
36469
  byte_length, observed_bytes, redacted, truncated, created_at, expires_at, released_at, retired_at`;
36218
- function expiryDue(row, now) {
36219
- return row.state === "retained" && row.expires_at <= now;
36470
+ function expiryDue(row2, now) {
36471
+ return row2.state === "retained" && row2.expires_at <= now;
36220
36472
  }
36221
- function liveText(row, now) {
36222
- return row.state === "retained" && !expiryDue(row, now) ? row.text : null;
36473
+ function liveText(row2, now) {
36474
+ return row2.state === "retained" && !expiryDue(row2, now) ? row2.text : null;
36223
36475
  }
36224
- function availabilityOf(row, now) {
36225
- if (row.state === "deleted") return "deleted";
36226
- if (row.state === "expired" || expiryDue(row, now)) return "expired";
36227
- return row.truncated === 1 ? "truncated" : "available";
36476
+ function availabilityOf(row2, now) {
36477
+ if (row2.state === "deleted") return "deleted";
36478
+ if (row2.state === "expired" || expiryDue(row2, now)) return "expired";
36479
+ return row2.truncated === 1 ? "truncated" : "available";
36228
36480
  }
36229
- function toView(row, now) {
36481
+ function toView(row2, now) {
36230
36482
  return {
36231
- commandId: row.command_id,
36232
- teamId: row.team_id,
36233
- agentId: row.agent_id,
36234
- turnId: row.turn_id,
36235
- toolCallId: row.tool_call_id,
36236
- availability: availabilityOf(row, now),
36237
- byteLength: row.byte_length,
36238
- observedBytes: row.observed_bytes,
36239
- redacted: row.redacted === 1,
36240
- createdAt: row.created_at,
36241
- expiresAt: row.expires_at,
36242
- releasedAt: row.released_at,
36243
- retiredAt: row.retired_at
36483
+ commandId: row2.command_id,
36484
+ teamId: row2.team_id,
36485
+ agentId: row2.agent_id,
36486
+ turnId: row2.turn_id,
36487
+ toolCallId: row2.tool_call_id,
36488
+ availability: availabilityOf(row2, now),
36489
+ byteLength: row2.byte_length,
36490
+ observedBytes: row2.observed_bytes,
36491
+ redacted: row2.redacted === 1,
36492
+ createdAt: row2.created_at,
36493
+ expiresAt: row2.expires_at,
36494
+ releasedAt: row2.released_at,
36495
+ retiredAt: row2.retired_at
36244
36496
  };
36245
36497
  }
36246
36498
  function rowFor(db, commandId) {
36247
- return db.raw.query(`SELECT ${COLUMNS} FROM coding_command_logs WHERE command_id = ?`).get(commandId) ?? null;
36499
+ return db.raw.query(`SELECT ${COLUMNS2} FROM coding_command_logs WHERE command_id = ?`).get(commandId) ?? null;
36248
36500
  }
36249
36501
  function unavailableLog(commandId) {
36250
36502
  return {
@@ -36264,8 +36516,8 @@ function unavailableLog(commandId) {
36264
36516
  };
36265
36517
  }
36266
36518
  function getCodingCommandLog(db, commandId, now = Date.now()) {
36267
- const row = rowFor(db, commandId);
36268
- return row ? toView(row, now) : unavailableLog(commandId);
36519
+ const row2 = rowFor(db, commandId);
36520
+ return row2 ? toView(row2, now) : unavailableLog(commandId);
36269
36521
  }
36270
36522
  function saveCodingCommandLog(db, input) {
36271
36523
  const now = input.now ?? Date.now();
@@ -36274,7 +36526,7 @@ function saveCodingCommandLog(db, input) {
36274
36526
  const observed = Math.max(input.observedBytes, byteLength);
36275
36527
  const truncated = retained.truncated || input.truncated || !input.redacted && input.observedBytes > byteLength;
36276
36528
  db.raw.run(
36277
- `INSERT INTO coding_command_logs (${COLUMNS})
36529
+ `INSERT INTO coding_command_logs (${COLUMNS2})
36278
36530
  VALUES (?, ?, ?, ?, ?, 'retained', ?, ?, ?, ?, ?, ?, ?, NULL, NULL)
36279
36531
  ON CONFLICT(command_id) DO UPDATE SET
36280
36532
  state = 'retained',
@@ -36324,10 +36576,10 @@ function releaseCodingCommandLog(db, commandId, now = Date.now()) {
36324
36576
  function readCodingCommandLog(db, commandId, options, now = Date.now()) {
36325
36577
  const view2 = getCodingCommandLog(db, commandId, now);
36326
36578
  if (!mayDisclose(view2, options.audience)) return null;
36327
- const row = rowFor(db, commandId);
36579
+ const row2 = rowFor(db, commandId);
36328
36580
  const limit = Math.min(Math.max(options.limit ?? CODING_LOG_PAGE_BYTES, 1), CODING_LOG_BYTES);
36329
- const text3 = row ? liveText(row, now) : null;
36330
- if (!row || text3 === null) {
36581
+ const text3 = row2 ? liveText(row2, now) : null;
36582
+ if (!row2 || text3 === null) {
36331
36583
  return {
36332
36584
  commandId,
36333
36585
  availability: view2.availability,
@@ -36354,14 +36606,14 @@ function readCodingCommandLog(db, commandId, options, now = Date.now()) {
36354
36606
  function searchCodingCommandLog(db, commandId, needle, options, now = Date.now()) {
36355
36607
  const view2 = getCodingCommandLog(db, commandId, now);
36356
36608
  if (!mayDisclose(view2, options.audience)) return null;
36357
- const row = rowFor(db, commandId);
36609
+ const row2 = rowFor(db, commandId);
36358
36610
  const empty = {
36359
36611
  commandId,
36360
36612
  availability: view2.availability,
36361
36613
  matches: [],
36362
36614
  bounded: false
36363
36615
  };
36364
- const text3 = row ? liveText(row, now) : null;
36616
+ const text3 = row2 ? liveText(row2, now) : null;
36365
36617
  if (text3 === null || !needle) return empty;
36366
36618
  const scanned = Buffer.byteLength(text3) > CODING_LOG_SEARCH_SCAN_BYTES;
36367
36619
  const haystack = scanned ? headBytes(text3, CODING_LOG_SEARCH_SCAN_BYTES) : text3;
@@ -36414,7 +36666,7 @@ function pruneCodingCommandLogs(db, now = Date.now(), budgetBytes = CODING_LOG_H
36414
36666
  }
36415
36667
 
36416
36668
  // ../daemon/src/lib/communication.ts
36417
- import { randomUUID as randomUUID31 } from "crypto";
36669
+ import { randomUUID as randomUUID32 } from "crypto";
36418
36670
 
36419
36671
  // ../daemon/src/lib/question-approval.ts
36420
36672
  function questionApprovalReference(snapshot, kind) {
@@ -36509,7 +36761,7 @@ function questionVisible(db, item) {
36509
36761
  }
36510
36762
 
36511
36763
  // ../daemon/src/core/repos/results.ts
36512
- import { createHash as createHash9, randomUUID as randomUUID30 } from "crypto";
36764
+ import { createHash as createHash9, randomUUID as randomUUID31 } from "crypto";
36513
36765
  var MAX_RESULT_BYTES = 25 * 1024 * 1024;
36514
36766
  var MAX_RETAINED_RESULT_BYTES = 1024 * 1024 * 1024;
36515
36767
  var columns2 = `id, team_id AS teamId, agent_id AS agentId, source_kind AS sourceKind,
@@ -36572,7 +36824,7 @@ function publish(db, input) {
36572
36824
  "Result storage is full (1 GiB). Delete saved results before delivering more files."
36573
36825
  );
36574
36826
  }
36575
- const id = randomUUID30();
36827
+ const id = randomUUID31();
36576
36828
  db.raw.run(
36577
36829
  `INSERT INTO agent_results
36578
36830
  (id, team_id, agent_id, source_kind, session_id, tool_call_id, review_packet_id, review_revision,
@@ -36640,12 +36892,12 @@ function listReleased(db, opts = {}) {
36640
36892
  return { results, total, limit, offset };
36641
36893
  }
36642
36894
  function readCaptured(db, id) {
36643
- const row = db.raw.query(
36895
+ const row2 = db.raw.query(
36644
36896
  "SELECT bytes, byte_length, sha256 FROM agent_results WHERE id = ? AND deleted_at IS NULL"
36645
36897
  ).get(id);
36646
- if (!row) throw new Error("Captured result is unavailable");
36647
- const bytes = Buffer.from(row.bytes);
36648
- if (bytes.byteLength !== row.byte_length || createHash9("sha256").update(bytes).digest("hex") !== row.sha256) {
36898
+ if (!row2) throw new Error("Captured result is unavailable");
36899
+ const bytes = Buffer.from(row2.bytes);
36900
+ if (bytes.byteLength !== row2.byte_length || createHash9("sha256").update(bytes).digest("hex") !== row2.sha256) {
36649
36901
  throw new Error("Captured result failed integrity verification");
36650
36902
  }
36651
36903
  return bytes;
@@ -36892,7 +37144,7 @@ function isUserFacingFrame(frame) {
36892
37144
  }
36893
37145
  function sendAgentMessage(db, input) {
36894
37146
  const attemptKind = input.attemptKind ?? "agent_tool";
36895
- const attemptId = input.attemptId ?? randomUUID31();
37147
+ const attemptId = input.attemptId ?? randomUUID32();
36896
37148
  const outcome = db.raw.transaction(
36897
37149
  () => {
36898
37150
  const causality = resolveMessageCausality(db, input);
@@ -37221,29 +37473,29 @@ function claimDeliverableInbox(db, agentId, onAllowed, conversationId) {
37221
37473
 
37222
37474
  // ../daemon/src/core/repos/source-snapshots.ts
37223
37475
  var SOURCE_SNAPSHOT_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
37224
- var COLUMNS2 = "snapshot_id, team_id, captured_by, agent_id, turn_id, tool_call_id, complete, head, base_oid, entry_count, captured_content_bytes, manifest_json, created_at, expires_at";
37225
- function toRecord(row) {
37476
+ var COLUMNS3 = "snapshot_id, team_id, captured_by, agent_id, turn_id, tool_call_id, complete, head, base_oid, entry_count, captured_content_bytes, manifest_json, created_at, expires_at";
37477
+ function toRecord2(row2) {
37226
37478
  return {
37227
- snapshotId: row.snapshot_id,
37228
- teamId: row.team_id,
37229
- capturedBy: row.captured_by === "agent" ? "agent" : "operator",
37230
- agentId: row.agent_id,
37231
- turnId: row.turn_id,
37232
- toolCallId: row.tool_call_id,
37233
- complete: row.complete === 1,
37234
- head: row.head,
37235
- baseOid: row.base_oid,
37236
- entryCount: row.entry_count,
37237
- capturedContentBytes: row.captured_content_bytes,
37238
- manifestJson: row.manifest_json,
37239
- createdAt: row.created_at,
37240
- expiresAt: row.expires_at
37479
+ snapshotId: row2.snapshot_id,
37480
+ teamId: row2.team_id,
37481
+ capturedBy: row2.captured_by === "agent" ? "agent" : "operator",
37482
+ agentId: row2.agent_id,
37483
+ turnId: row2.turn_id,
37484
+ toolCallId: row2.tool_call_id,
37485
+ complete: row2.complete === 1,
37486
+ head: row2.head,
37487
+ baseOid: row2.base_oid,
37488
+ entryCount: row2.entry_count,
37489
+ capturedContentBytes: row2.captured_content_bytes,
37490
+ manifestJson: row2.manifest_json,
37491
+ createdAt: row2.created_at,
37492
+ expiresAt: row2.expires_at
37241
37493
  };
37242
37494
  }
37243
37495
  function saveSourceSnapshot(db, input) {
37244
37496
  const now = input.now ?? Date.now();
37245
37497
  db.raw.run(
37246
- `INSERT INTO source_snapshots (${COLUMNS2})
37498
+ `INSERT INTO source_snapshots (${COLUMNS3})
37247
37499
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
37248
37500
  ON CONFLICT(snapshot_id, team_id) DO NOTHING`,
37249
37501
  [
@@ -37266,11 +37518,11 @@ function saveSourceSnapshot(db, input) {
37266
37518
  pruneSourceSnapshots(db, now);
37267
37519
  }
37268
37520
  function getSourceSnapshot(db, teamId, snapshotId, now = Date.now()) {
37269
- const row = db.raw.query(
37270
- `SELECT ${COLUMNS2} FROM source_snapshots
37521
+ const row2 = db.raw.query(
37522
+ `SELECT ${COLUMNS3} FROM source_snapshots
37271
37523
  WHERE team_id = ? AND snapshot_id = ? AND expires_at > ?`
37272
37524
  ).get(teamId, snapshotId, now);
37273
- return row ? toRecord(row) : null;
37525
+ return row2 ? toRecord2(row2) : null;
37274
37526
  }
37275
37527
  function pruneSourceSnapshots(db, now = Date.now()) {
37276
37528
  const result = db.raw.run("DELETE FROM source_snapshots WHERE expires_at <= ?", [now]);
@@ -37278,10 +37530,10 @@ function pruneSourceSnapshots(db, now = Date.now()) {
37278
37530
  }
37279
37531
  function listSourceSnapshots(db, teamId, limit = 50, now = Date.now()) {
37280
37532
  return db.raw.query(
37281
- `SELECT ${COLUMNS2} FROM source_snapshots
37533
+ `SELECT ${COLUMNS3} FROM source_snapshots
37282
37534
  WHERE team_id = ? AND expires_at > ?
37283
37535
  ORDER BY created_at DESC, snapshot_id LIMIT ?`
37284
- ).all(teamId, now, limit).map(toRecord);
37536
+ ).all(teamId, now, limit).map(toRecord2);
37285
37537
  }
37286
37538
 
37287
37539
  // ../daemon/src/lib/git/capture.ts
@@ -37307,13 +37559,13 @@ async function captureRepositoryGit(root, budgetMs = INSPECTION_BUDGET_MS) {
37307
37559
  const marker = root.entry(".git");
37308
37560
  if (!marker?.isDirectory() || marker.isSymbolicLink())
37309
37561
  throw new ContextReadError("unsupported_git_metadata");
37310
- const git = root.directory(".git");
37311
- if (git.entry("commondir") || git.entry("gitdir")) {
37562
+ const git2 = root.directory(".git");
37563
+ if (git2.entry("commondir") || git2.entry("gitdir")) {
37312
37564
  throw new ContextReadError("unsupported_git_metadata");
37313
37565
  }
37314
- const info = git.entry("info");
37566
+ const info = git2.entry("info");
37315
37567
  if (info) {
37316
- const dir = git.directory("info");
37568
+ const dir = git2.directory("info");
37317
37569
  if (dir.entry("sparse-checkout")) throw new ContextReadError("unsupported_git_metadata");
37318
37570
  }
37319
37571
  const scratch = mkdtempSync4(join25(tmpdir4(), "bazilion-context-git-"));
@@ -37367,7 +37619,7 @@ async function captureRepositoryGit(root, budgetMs = INSPECTION_BUDGET_MS) {
37367
37619
  ...args
37368
37620
  ];
37369
37621
  const runGit = (args) => rawGit(inspectionArgs(args));
37370
- const capturedConfig = git.read("config", METADATA_READ);
37622
+ const capturedConfig = git2.read("config", METADATA_READ);
37371
37623
  const configLines = ["[core]", "repositoryformatversion = 0", "bare = false", "filemode = true"];
37372
37624
  if (capturedConfig) {
37373
37625
  bytes += capturedConfig.length;
@@ -37422,7 +37674,7 @@ objectformat = ${value}`
37422
37674
  }
37423
37675
  }
37424
37676
  if (info) {
37425
- const exclude = git.directory("info").read("exclude", METADATA_READ);
37677
+ const exclude = git2.directory("info").read("exclude", METADATA_READ);
37426
37678
  if (exclude) {
37427
37679
  bytes += exclude.length;
37428
37680
  mkdirSync9(join25(scratch, "info"), { mode: 448 });
@@ -37450,7 +37702,7 @@ objectformat = ${value}`
37450
37702
  }
37451
37703
  };
37452
37704
  for (const name of ["HEAD", "index", "packed-refs", "shallow"]) {
37453
- const content = git.read(name, Math.min(METADATA_READ_LARGE, METADATA_BYTES - bytes));
37705
+ const content = git2.read(name, Math.min(METADATA_READ_LARGE, METADATA_BYTES - bytes));
37454
37706
  if (content) {
37455
37707
  count3++;
37456
37708
  bytes += content.length;
@@ -37459,13 +37711,13 @@ objectformat = ${value}`
37459
37711
  }
37460
37712
  for (const name of ["refs", "objects"]) {
37461
37713
  mkdirSync9(join25(scratch, name), { mode: 448 });
37462
- if (git.entry(name)) copy(git.directory(name), join25(scratch, name), 0);
37714
+ if (git2.entry(name)) copy(git2.directory(name), join25(scratch, name), 0);
37463
37715
  }
37464
- if (git.list().some((name) => name.startsWith("sharedindex.")))
37716
+ if (git2.list().some((name) => name.startsWith("sharedindex.")))
37465
37717
  throw new ContextReadError("unsupported_git_metadata");
37466
37718
  writeFileSync12(join25(scratch, "config"), `${configLines.join("\n")}
37467
37719
  `, { mode: 384 });
37468
- const validate2 = () => git.validate();
37720
+ const validate2 = () => git2.validate();
37469
37721
  validate2();
37470
37722
  return { root, runGit, validate: validate2, cleanup };
37471
37723
  } catch (error2) {
@@ -37492,6 +37744,23 @@ var REVIEW_LIMITS2 = {
37492
37744
  patchBytes: 256 * 1024
37493
37745
  };
37494
37746
 
37747
+ // ../../packages/api-types/src/publication.ts
37748
+ var PUBLICATION_LIMITS = {
37749
+ repository: 200,
37750
+ branch: 200,
37751
+ commitMessage: 2e3,
37752
+ refusalDetail: 400,
37753
+ error: 400,
37754
+ /** Branches that are never published to, whatever the host says. */
37755
+ protectedBranches: ["main", "master", "trunk", "develop", "release"]
37756
+ };
37757
+
37758
+ // ../../packages/api-types/src/verification.ts
37759
+ var VERIFICATION_OUTCOME_LIMITS = [
37760
+ "Facts above are executor-owned. A non-zero exit is a result about the commands that ran, never proof about later code, and this is not an approval to publish, merge or deploy.",
37761
+ "Declared output paths are not enforced, so a change they do not cover appears above rather than being prevented."
37762
+ ];
37763
+
37495
37764
  // ../../packages/api-types/src/index.ts
37496
37765
  var PROFILE_FILES = [
37497
37766
  "profile.json",
@@ -38676,15 +38945,15 @@ function createCodingHost(input) {
38676
38945
  throw new Error("Command contains protected credential material");
38677
38946
  starting = true;
38678
38947
  try {
38679
- const environment = await snapshot(command.cwd);
38948
+ const environment2 = await snapshot(command.cwd);
38680
38949
  const receipt = {
38681
- id: randomUUID32(),
38950
+ id: randomUUID33(),
38682
38951
  agentId: input.agentId,
38683
38952
  teamId: input.teamId,
38684
38953
  turnId: input.turnId,
38685
38954
  toolCallId: raw2.toolCallId,
38686
38955
  input: command,
38687
- environment,
38956
+ environment: environment2,
38688
38957
  startedAt: Date.now(),
38689
38958
  finishedAt: null,
38690
38959
  state: "running",
@@ -39013,7 +39282,7 @@ function createDbMessagingHost(db, opts = {}) {
39013
39282
  }
39014
39283
 
39015
39284
  // ../daemon/src/lib/question-service.ts
39016
- import { randomUUID as randomUUID34 } from "crypto";
39285
+ import { randomUUID as randomUUID35 } from "crypto";
39017
39286
 
39018
39287
  // ../daemon/src/lib/question-consumption.ts
39019
39288
  import { isDeepStrictEqual } from "util";
@@ -39069,8 +39338,8 @@ function key(db, create7) {
39069
39338
  db.raw.run("INSERT OR IGNORE INTO question_receipt_key (singleton, key) VALUES (1, ?)", [
39070
39339
  randomBytes5(32)
39071
39340
  ]);
39072
- const row = db.raw.query("SELECT key FROM question_receipt_key WHERE singleton = 1").get();
39073
- return row ? Buffer.from(row.key) : null;
39341
+ const row2 = db.raw.query("SELECT key FROM question_receipt_key WHERE singleton = 1").get();
39342
+ return row2 ? Buffer.from(row2.key) : null;
39074
39343
  }
39075
39344
  function signQuestionReceipt(db, agentId, result) {
39076
39345
  const item = get18(db, agentId, result.questionId);
@@ -39541,7 +39810,7 @@ function parseTelegramQuestionReply(db, authToken, update3) {
39541
39810
  }
39542
39811
 
39543
39812
  // ../daemon/src/lib/attachments.ts
39544
- import { randomUUID as randomUUID33 } from "crypto";
39813
+ import { randomUUID as randomUUID34 } from "crypto";
39545
39814
  import { closeSync as closeSync9, constants as constants10, fstatSync as fstatSync7, openSync as openSync9, writeFileSync as writeFileSync13 } from "fs";
39546
39815
  import { join as join26, posix } from "path";
39547
39816
  var MAX_FILE_BYTES = 25 * 1024 * 1024;
@@ -39568,7 +39837,7 @@ function saveInputFiles(agentDir, files, options = {}) {
39568
39837
  lines.push(`[attachment "${label}" skipped: too large (${fmtBytes(buf.byteLength)} > 25 MB)]`);
39569
39838
  continue;
39570
39839
  }
39571
- const filename2 = `${randomUUID33().slice(0, 8)}-${safeName(label)}`;
39840
+ const filename2 = `${randomUUID34().slice(0, 8)}-${safeName(label)}`;
39572
39841
  const path = join26(dir, filename2);
39573
39842
  let fd;
39574
39843
  try {
@@ -39598,13 +39867,13 @@ var CodingEnvironmentRevisionError = class extends Error {
39598
39867
  }
39599
39868
  };
39600
39869
  function getCodingEnvironment(db, teamId) {
39601
- const row = db.raw.query("SELECT * FROM team_coding_environments WHERE team_id = ?").get(teamId);
39602
- if (!row) return null;
39870
+ const row2 = db.raw.query("SELECT * FROM team_coding_environments WHERE team_id = ?").get(teamId);
39871
+ if (!row2) return null;
39603
39872
  return {
39604
- teamId: row.team_id,
39605
- revision: row.revision,
39606
- config: validateCodingEnvironmentConfig(JSON.parse(row.config_json)),
39607
- updatedAt: row.updated_at
39873
+ teamId: row2.team_id,
39874
+ revision: row2.revision,
39875
+ config: validateCodingEnvironmentConfig(JSON.parse(row2.config_json)),
39876
+ updatedAt: row2.updated_at
39608
39877
  };
39609
39878
  }
39610
39879
  function putCodingEnvironment(db, teamId, expectedRevision, input) {
@@ -39629,14 +39898,14 @@ function putCodingEnvironment(db, teamId, expectedRevision, input) {
39629
39898
  // ../daemon/src/lib/coding-environment/resolve.ts
39630
39899
  function resolveTeamCodingEnvironment(db, teamId, env) {
39631
39900
  const fallback = resolveShellSecurityConfig(env).sandboxImage;
39632
- const environment = getCodingEnvironment(db, teamId);
39633
- if (!environment) return { image: fallback };
39901
+ const environment2 = getCodingEnvironment(db, teamId);
39902
+ if (!environment2) return { image: fallback };
39634
39903
  return {
39635
- image: environment.config.image,
39904
+ image: environment2.config.image,
39636
39905
  coding: validateDockerCodingSelection({
39637
- revision: environment.revision,
39638
- cwd: environment.config.cwd,
39639
- env: environment.config.env
39906
+ revision: environment2.revision,
39907
+ cwd: environment2.config.cwd,
39908
+ env: environment2.config.env
39640
39909
  })
39641
39910
  };
39642
39911
  }
@@ -40441,7 +40710,7 @@ var QuestionService = class {
40441
40710
  turn.conversation.id
40442
40711
  ).length;
40443
40712
  this.#attached.add(turn);
40444
- const turnId = randomUUID34();
40713
+ const turnId = randomUUID35();
40445
40714
  const listeners = /* @__PURE__ */ new Set();
40446
40715
  if (onQuestion) listeners.add(onQuestion);
40447
40716
  this.#turns.set(turnId, {
@@ -42485,7 +42754,7 @@ function renderTable(token) {
42485
42754
  const widths = [];
42486
42755
  for (let c = 0; c < cols; c++) {
42487
42756
  let w2 = headers[c]?.length ?? 0;
42488
- for (const row of rows) w2 = Math.max(w2, row[c]?.length ?? 0);
42757
+ for (const row2 of rows) w2 = Math.max(w2, row2[c]?.length ?? 0);
42489
42758
  widths[c] = w2;
42490
42759
  }
42491
42760
  const fmt = (cells) => cells.map((cell, c) => c === cols - 1 ? cell : cell.padEnd(widths[c] ?? 0)).join(" ").trimEnd();
@@ -43008,15 +43277,15 @@ function captureVerificationRequest(db, paths2, intent, env = process.env) {
43008
43277
  "the captured change has incomplete coverage, so a result could not be tied to it"
43009
43278
  );
43010
43279
  }
43011
- const environment = admittedEnvironment(db, team.id, env);
43012
- if (!environment) {
43280
+ const environment2 = admittedEnvironment(db, team.id, env);
43281
+ if (!environment2) {
43013
43282
  return blocked2(
43014
43283
  "environment_unavailable",
43015
43284
  "the Team has no usable admitted environment to freeze with the request"
43016
43285
  );
43017
43286
  }
43018
43287
  if (intent.writablePaths && intent.writablePaths.length > 0) {
43019
- const bounded3 = [];
43288
+ const bounded4 = [];
43020
43289
  for (const path of intent.writablePaths) {
43021
43290
  if (typeof path !== "string" || path.length === 0 || path.length > 1e3) {
43022
43291
  return blocked2("unsupported", "declared writable paths are outside their bounded contract");
@@ -43031,12 +43300,22 @@ function captureVerificationRequest(db, paths2, intent, env = process.env) {
43031
43300
  `declared writable path must be inside the workspace: ${path}`
43032
43301
  );
43033
43302
  }
43034
- bounded3.push(parts.join("/"));
43303
+ bounded4.push(parts.join("/"));
43035
43304
  }
43036
- if (bounded3.length > 16) {
43305
+ if (bounded4.length > 16) {
43037
43306
  return blocked2("unsupported", "too many declared writable paths");
43038
43307
  }
43039
- environment.writablePaths = bounded3;
43308
+ environment2.writablePaths = bounded4;
43309
+ }
43310
+ for (const check of intent.checks) {
43311
+ try {
43312
+ codingRelativePath(check.cwd);
43313
+ } catch {
43314
+ return blocked2(
43315
+ "unsupported",
43316
+ `a check working directory must be a path inside the workspace: ${String(check.cwd)}`
43317
+ );
43318
+ }
43040
43319
  }
43041
43320
  try {
43042
43321
  const request2 = createVerificationRequest(db, {
@@ -43050,7 +43329,7 @@ function captureVerificationRequest(db, paths2, intent, env = process.env) {
43050
43329
  snapshotComplete: snapshot.complete,
43051
43330
  head: snapshot.head,
43052
43331
  baseOid: snapshot.baseOid,
43053
- environment,
43332
+ environment: environment2,
43054
43333
  summary: intent.summary ?? null,
43055
43334
  checks: intent.checks
43056
43335
  });
@@ -43546,7 +43825,7 @@ function bound(value) {
43546
43825
  }
43547
43826
 
43548
43827
  // ../daemon/src/lib/review/dispatch.ts
43549
- import { randomUUID as randomUUID35 } from "crypto";
43828
+ import { randomUUID as randomUUID36 } from "crypto";
43550
43829
 
43551
43830
  // ../daemon/src/lib/review/preparation.ts
43552
43831
  async function prepareChangeReviewTurn(input) {
@@ -43765,6 +44044,25 @@ async function readRevisionPatch(db, paths2, packet, path) {
43765
44044
  }
43766
44045
  return { path, patch: change.patch, truncated: change.patchTruncated, reason: null };
43767
44046
  }
44047
+ async function readRevisionContentAvailability(db, paths2, packet) {
44048
+ let comparison = null;
44049
+ try {
44050
+ const applicability = await readSnapshotApplicability(
44051
+ db,
44052
+ paths2,
44053
+ packet.teamId,
44054
+ packet.snapshotId
44055
+ );
44056
+ comparison = applicability.comparison;
44057
+ } catch {
44058
+ comparison = null;
44059
+ }
44060
+ if (comparison === "identical") return { contentAvailable: true, contentUnavailableReason: null };
44061
+ return {
44062
+ contentAvailable: false,
44063
+ contentUnavailableReason: comparison === "changed" ? "the working tree changed after the capture, so the reviewed revision\u2019s content is no longer reproducible" : "the reviewed revision could not be compared with the working tree"
44064
+ };
44065
+ }
43768
44066
 
43769
44067
  // ../daemon/src/lib/review/reviewer-capability.ts
43770
44068
  function createReviewCapabilityHost(input) {
@@ -43778,17 +44076,15 @@ function createReviewCapabilityHost(input) {
43778
44076
  contentUnavailableReason: revision4.reason
43779
44077
  };
43780
44078
  }
43781
- const applicability = await readSnapshotApplicability(
44079
+ const { contentAvailable, contentUnavailableReason } = await readRevisionContentAvailability(
43782
44080
  input.db,
43783
44081
  input.paths,
43784
- packet.teamId,
43785
- packet.snapshotId
43786
- ).catch(() => null);
43787
- const contentAvailable = applicability?.comparison === "identical";
44082
+ packet
44083
+ );
43788
44084
  return {
43789
44085
  changes: revision4.changes,
43790
44086
  contentAvailable,
43791
- contentUnavailableReason: contentAvailable ? null : applicability?.comparison === "changed" ? "the working tree changed after the capture, so the reviewed revision\u2019s content is no longer reproducible" : "the reviewed revision could not be compared with the working tree"
44087
+ contentUnavailableReason
43792
44088
  };
43793
44089
  }
43794
44090
  return {
@@ -43892,7 +44188,7 @@ function refused(message) {
43892
44188
  }
43893
44189
 
43894
44190
  // ../daemon/src/lib/review/dispatch.ts
43895
- var REVIEW_DISPATCH_OWNER = randomUUID35();
44191
+ var REVIEW_DISPATCH_OWNER = randomUUID36();
43896
44192
  var REVIEW_LEASE_MS = 10 * 60 * 1e3;
43897
44193
  var dispatchRegistry = () => {
43898
44194
  const global2 = globalThis;
@@ -44080,10 +44376,10 @@ function buildReviewDigest(input, options = {}) {
44080
44376
  }
44081
44377
  selected.reverse();
44082
44378
  const firstUserIndex = selected.findIndex((entry) => entry.role === "user");
44083
- const bounded3 = firstUserIndex >= 0 ? selected.slice(firstUserIndex) : selected;
44084
- characters = bounded3.reduce((total, entry) => total + entry.text.length, 0);
44085
- const first = bounded3[0];
44086
- const last = bounded3.at(-1);
44379
+ const bounded4 = firstUserIndex >= 0 ? selected.slice(firstUserIndex) : selected;
44380
+ characters = bounded4.reduce((total, entry) => total + entry.text.length, 0);
44381
+ const first = bounded4[0];
44382
+ const last = bounded4.at(-1);
44087
44383
  if (!first || !last) return null;
44088
44384
  return {
44089
44385
  sessionId: last.sessionId,
@@ -44091,7 +44387,7 @@ function buildReviewDigest(input, options = {}) {
44091
44387
  endOrdinal: last.ordinal,
44092
44388
  inputCharacters: characters,
44093
44389
  turnsReviewed: userTurns,
44094
- entries: bounded3
44390
+ entries: bounded4
44095
44391
  };
44096
44392
  }
44097
44393
 
@@ -44333,9 +44629,9 @@ async function dispatchClaimableReviews(now = Date.now()) {
44333
44629
  }
44334
44630
 
44335
44631
  // ../daemon/src/lib/verification/admission.ts
44336
- import { randomUUID as randomUUID36 } from "crypto";
44632
+ import { randomUUID as randomUUID37 } from "crypto";
44337
44633
  var VERIFICATION_LEASE_MS = 10 * 60 * 1e3;
44338
- var VERIFICATION_DISPATCH_OWNER = randomUUID36();
44634
+ var VERIFICATION_DISPATCH_OWNER = randomUUID37();
44339
44635
  async function admitVerificationRequest(db, paths2, requestId2, now = Date.now()) {
44340
44636
  const request2 = getVerificationRequestById(db, requestId2, now);
44341
44637
  if (!request2) return { kind: "deferred", requestId: requestId2, reason: "unknown_or_expired" };
@@ -44473,7 +44769,7 @@ function safeTeam3(db, paths2, teamId) {
44473
44769
  }
44474
44770
 
44475
44771
  // ../daemon/src/lib/verification/executor.ts
44476
- import { randomUUID as randomUUID37 } from "crypto";
44772
+ import { randomUUID as randomUUID38 } from "crypto";
44477
44773
  import { existsSync as existsSync17 } from "fs";
44478
44774
  import { join as join28, posix as posix2, relative as relative8, sep as sep7 } from "path";
44479
44775
  import { createLocalBashOperations as createLocalBashOperations3 } from "@earendil-works/pi-coding-agent";
@@ -44504,14 +44800,14 @@ function createProtectedCheckExecutor(input) {
44504
44800
  }
44505
44801
  const container = buildContainerOperations(input, env, config2.envAllowlist, absoluteCwd);
44506
44802
  if ("blocked" in container) return blocked3("environment_unavailable", container.blocked);
44507
- const commandId = randomUUID37();
44803
+ const commandId = randomUUID38();
44508
44804
  const startedAt = Date.now();
44509
44805
  const receipt = {
44510
44806
  id: commandId,
44511
44807
  agentId: input.request.recipientAgentId,
44512
44808
  teamId: input.request.teamId,
44513
44809
  turnId: input.attemptId,
44514
- toolCallId: `verification:${input.attemptId}:${randomUUID37()}`,
44810
+ toolCallId: `verification:${input.attemptId}:${randomUUID38()}`,
44515
44811
  input: {
44516
44812
  command,
44517
44813
  cwd: relative9,
@@ -44804,12 +45100,7 @@ function renderResult2(input) {
44804
45100
  }
44805
45101
  }
44806
45102
  if (attempt.error) lines.push("", `Limitation: ${attempt.error}`);
44807
- lines.push(
44808
- "",
44809
- "Facts above are executor-owned. A non-zero exit is a result about the commands that ran, never",
44810
- "proof about later code, and this is not an approval to publish, merge or deploy. Declared output",
44811
- "paths are not enforced, so a change they do not cover appears above rather than being prevented."
44812
- );
45103
+ lines.push("", VERIFICATION_OUTCOME_LIMITS[0], VERIFICATION_OUTCOME_LIMITS[1]);
44813
45104
  const payload = lines.join("\n");
44814
45105
  return payload.length > MAX_RESULT_CHARACTERS2 ? `${payload.slice(0, MAX_RESULT_CHARACTERS2)}
44815
45106
  [result truncated]` : payload;
@@ -45009,7 +45300,7 @@ async function fingerprintWorkspace(root) {
45009
45300
  let children;
45010
45301
  try {
45011
45302
  children = await readdir(join29(root, dir), { withFileTypes: true }).then(
45012
- (rows) => rows.map((row) => row.name)
45303
+ (rows) => rows.map((row2) => row2.name)
45013
45304
  );
45014
45305
  } catch {
45015
45306
  continue;
@@ -45246,7 +45537,7 @@ async function dispatchPendingVerifications(now = Date.now()) {
45246
45537
  ORDER BY created_at LIMIT 20`
45247
45538
  ).all(now);
45248
45539
  void paths2;
45249
- await Promise.allSettled(pending.map((row) => dispatchVerificationRequest(row.id)));
45540
+ await Promise.allSettled(pending.map((row2) => dispatchVerificationRequest(row2.id)));
45250
45541
  }
45251
45542
  function currentSecrets() {
45252
45543
  const { db, authToken } = getCtx();
@@ -45653,6 +45944,7 @@ async function tick() {
45653
45944
  for (const agentId of recipients) {
45654
45945
  work.push(fireInboxWake(agentId));
45655
45946
  }
45947
+ recoverExpiredPublications(ctx.db, now);
45656
45948
  work.push(dispatchClaimableReviews(now));
45657
45949
  work.push(dispatchPendingVerifications(now));
45658
45950
  for (const packet of dispatchableReviews()) {
@@ -45723,6 +46015,7 @@ function bootstrap(paths2) {
45723
46015
  interruptCodingCommands(db);
45724
46016
  recoverInterruptedVerificationAttempts(db, VERIFICATION_DISPATCH_OWNER);
45725
46017
  recoverInterruptedReviewAttempts(db, Date.now());
46018
+ recoverExpiredPublications(db);
45726
46019
  reconcileApprovalHolds(db);
45727
46020
  recoverInterruptedResultDeliveries(db);
45728
46021
  reconcilePrivateResults(db);
@@ -45890,7 +46183,7 @@ async function authMiddleware(c, next) {
45890
46183
  }
45891
46184
 
45892
46185
  // ../daemon/src/routes/agents.ts
45893
- import { randomUUID as randomUUID39 } from "crypto";
46186
+ import { randomUUID as randomUUID40 } from "crypto";
45894
46187
  import { existsSync as existsSync19, readFileSync as readFileSync12 } from "fs";
45895
46188
  import { join as join30 } from "path";
45896
46189
  import { Hono } from "hono";
@@ -47215,7 +47508,7 @@ async function notifyTelegramQueueStatus(db, agentId, itemId) {
47215
47508
  }
47216
47509
 
47217
47510
  // ../daemon/src/lib/user-queue-admission.ts
47218
- import { randomUUID as randomUUID38 } from "crypto";
47511
+ import { randomUUID as randomUUID39 } from "crypto";
47219
47512
  async function enqueueTelegramInput(binding, message, attachments2, context = getCtx()) {
47220
47513
  validateInput(message, attachments2);
47221
47514
  const { db, paths: paths2, authToken } = context;
@@ -47234,7 +47527,7 @@ async function enqueueTelegramInput(binding, message, attachments2, context = ge
47234
47527
  const existing = findAttempt(db, "telegram", binding.authorization.attemptId);
47235
47528
  return db.raw.transaction(() => {
47236
47529
  const item = accept(db, {
47237
- id: existing?.id ?? randomUUID38(),
47530
+ id: existing?.id ?? randomUUID39(),
47238
47531
  agentId,
47239
47532
  teamId: existing?.teamId ?? agent.team.id,
47240
47533
  conversationId,
@@ -49054,7 +49347,7 @@ agentsRouter.post("/:id/chat", async (c) => {
49054
49347
  if (!message && attachments2.length === 0) {
49055
49348
  return c.json({ error: "message or an attachment is required" }, 400);
49056
49349
  }
49057
- const requestAttemptId = c.req.header("x-request-id") ?? randomUUID39();
49350
+ const requestAttemptId = c.req.header("x-request-id") ?? randomUUID40();
49058
49351
  let preparedTurn;
49059
49352
  try {
49060
49353
  preparedTurn = await prepareAgentTurn({
@@ -51412,13 +51705,13 @@ function assertSnapshotIntegrity(path) {
51412
51705
  try {
51413
51706
  const rows = snapshot.prepare("PRAGMA integrity_check").all();
51414
51707
  if (rows.length !== 1 || rows[0]?.integrity_check !== "ok") {
51415
- const detail3 = rows.map((row) => row.integrity_check).join("; ") || "no result";
51708
+ const detail3 = rows.map((row2) => row2.integrity_check).join("; ") || "no result";
51416
51709
  throw new Error(`SQLite snapshot failed integrity_check: ${detail3}`);
51417
51710
  }
51418
- for (const row of snapshot.prepare("SELECT id, bytes, byte_length, sha256 FROM agent_results WHERE deleted_at IS NULL").iterate()) {
51419
- const bytes = row.bytes;
51420
- if (!(bytes instanceof Uint8Array) || bytes.byteLength !== row.byte_length || createHash17("sha256").update(bytes).digest("hex") !== row.sha256) {
51421
- throw new Error(`Result snapshot integrity verification failed: ${row.id}`);
51711
+ for (const row2 of snapshot.prepare("SELECT id, bytes, byte_length, sha256 FROM agent_results WHERE deleted_at IS NULL").iterate()) {
51712
+ const bytes = row2.bytes;
51713
+ if (!(bytes instanceof Uint8Array) || bytes.byteLength !== row2.byte_length || createHash17("sha256").update(bytes).digest("hex") !== row2.sha256) {
51714
+ throw new Error(`Result snapshot integrity verification failed: ${row2.id}`);
51422
51715
  }
51423
51716
  }
51424
51717
  const foreignKeyErrors = snapshot.prepare("PRAGMA foreign_key_check").all();
@@ -51485,7 +51778,7 @@ function createBackupArchive(paths2, snapshot) {
51485
51778
  }
51486
51779
 
51487
51780
  // ../daemon/src/lib/daemon-liveness.ts
51488
- import { createHash as createHash18, randomUUID as randomUUID40 } from "crypto";
51781
+ import { createHash as createHash18, randomUUID as randomUUID41 } from "crypto";
51489
51782
  import {
51490
51783
  chmodSync as chmodSync2,
51491
51784
  closeSync as closeSync10,
@@ -51655,7 +51948,7 @@ function acquireDaemonLiveness(paths2) {
51655
51948
  mkdirSync11(dirname6(resolve7(paths2.home)), { recursive: true });
51656
51949
  const path = daemonLivenessPath(paths2.home);
51657
51950
  mkdirSync11(dirname6(path), { recursive: true });
51658
- const instanceId = randomUUID40();
51951
+ const instanceId = randomUUID41();
51659
51952
  const startedAt = Date.now();
51660
51953
  let fd = null;
51661
51954
  let reclaimClaim = null;
@@ -52170,7 +52463,7 @@ import { bodyLimit } from "hono/body-limit";
52170
52463
  import { HTTPException } from "hono/http-exception";
52171
52464
 
52172
52465
  // ../daemon/src/lib/notification-control.ts
52173
- import { randomUUID as randomUUID41 } from "crypto";
52466
+ import { randomUUID as randomUUID42 } from "crypto";
52174
52467
 
52175
52468
  // ../daemon/src/lib/notification-authorization.ts
52176
52469
  function authorizeAttentionNotification(db, item, captured) {
@@ -52335,7 +52628,7 @@ var NotificationControl = class {
52335
52628
  );
52336
52629
  for (const item of items) byKind[item.kind]++;
52337
52630
  const value = {
52338
- id: randomUUID41(),
52631
+ id: randomUUID42(),
52339
52632
  settingsRevision: revision4,
52340
52633
  destinationId: binding.id,
52341
52634
  kinds,
@@ -52553,7 +52846,7 @@ var NotificationDispatcher = class {
52553
52846
  const known = new Set(
52554
52847
  this.db.raw.query(
52555
52848
  "SELECT source_kind || ':' || source_id key FROM notification_receipts WHERE destination_id=?"
52556
- ).all(binding.id).map((row) => row.key)
52849
+ ).all(binding.id).map((row2) => row2.key)
52557
52850
  );
52558
52851
  let admitted = 0;
52559
52852
  const cutoffs = eligibilityCutoffs(this.db);
@@ -53245,7 +53538,7 @@ async function parseImportInput(request2) {
53245
53538
  }
53246
53539
 
53247
53540
  // ../daemon/src/routes/team-templates.ts
53248
- import { randomUUID as randomUUID42 } from "crypto";
53541
+ import { randomUUID as randomUUID43 } from "crypto";
53249
53542
  import { Hono as Hono17 } from "hono";
53250
53543
  var teamTemplatesRouter = new Hono17();
53251
53544
  teamTemplatesRouter.get("/", (c) => {
@@ -53285,7 +53578,7 @@ teamTemplatesRouter.post("/import", async (c) => {
53285
53578
  if (!profiles_exports.get(db, parsed.profileId)) {
53286
53579
  throw new Error(`profile not found: ${parsed.profileId}`);
53287
53580
  }
53288
- const slotId = randomUUID42();
53581
+ const slotId = randomUUID43();
53289
53582
  keyToSlot.set(clientKey, slotId);
53290
53583
  return { ...parsed, slotId };
53291
53584
  });
@@ -53577,7 +53870,7 @@ function canonicalError(c, error2) {
53577
53870
  }
53578
53871
 
53579
53872
  // ../daemon/src/routes/teams.ts
53580
- import { join as join37 } from "path";
53873
+ import { join as join39 } from "path";
53581
53874
  import { Hono as Hono18 } from "hono";
53582
53875
 
53583
53876
  // ../daemon/src/lib/coding-environment/management.ts
@@ -53733,6 +54026,604 @@ function lineRange(request2, _captured) {
53733
54026
  return { start, end };
53734
54027
  }
53735
54028
 
54029
+ // ../daemon/src/lib/publication/config.ts
54030
+ var PUBLICATION_CONFIG = {
54031
+ host: "PUBLICATION_HOST",
54032
+ repository: "PUBLICATION_REPOSITORY",
54033
+ baseBranch: "PUBLICATION_BASE_BRANCH"
54034
+ };
54035
+ var PUBLICATION_CREDENTIAL_KEY = "GITHUB_TOKEN";
54036
+ var HOSTS = ["github", "local"];
54037
+ function resolvePublicationTarget(db, authToken) {
54038
+ const config2 = openConfig(db);
54039
+ const configured = config2.get(PUBLICATION_CONFIG.host)?.trim().toLowerCase() ?? "";
54040
+ if (!configured) {
54041
+ return {
54042
+ ok: false,
54043
+ reason: "host_not_configured",
54044
+ detail: `no publication host is configured (set ${PUBLICATION_CONFIG.host}); nothing was sent`
54045
+ };
54046
+ }
54047
+ if (!HOSTS.includes(configured)) {
54048
+ return {
54049
+ ok: false,
54050
+ reason: "host_not_configured",
54051
+ detail: `the configured publication host is not supported by this build: ${configured}`
54052
+ };
54053
+ }
54054
+ const repository = config2.get(PUBLICATION_CONFIG.repository)?.trim() ?? "";
54055
+ if (!repository) {
54056
+ return {
54057
+ ok: false,
54058
+ reason: "host_not_configured",
54059
+ detail: `no repository is configured (set ${PUBLICATION_CONFIG.repository}); nothing was sent`
54060
+ };
54061
+ }
54062
+ const baseBranch = config2.get(PUBLICATION_CONFIG.baseBranch)?.trim() || "main";
54063
+ const credential = openSecrets(db, authToken).get(PUBLICATION_CREDENTIAL_KEY)?.trim() ?? "";
54064
+ if (!credential) {
54065
+ return {
54066
+ ok: false,
54067
+ reason: "credential_missing",
54068
+ detail: `no credential is stored for ${configured} (set ${PUBLICATION_CREDENTIAL_KEY}); nothing was sent`
54069
+ };
54070
+ }
54071
+ return {
54072
+ ok: true,
54073
+ target: { host: configured, repository, baseBranch, credential }
54074
+ };
54075
+ }
54076
+
54077
+ // ../daemon/src/lib/publication/revision-content.ts
54078
+ import { createHash as createHash19 } from "crypto";
54079
+ import { readFileSync as readFileSync15 } from "fs";
54080
+ import { join as join36 } from "path";
54081
+ function readReviewedRevisionFiles(db, paths2, packet) {
54082
+ const record3 = getSourceSnapshot(db, packet.teamId, packet.snapshotId);
54083
+ if (!record3) {
54084
+ return {
54085
+ ok: false,
54086
+ reason: "revision_unavailable",
54087
+ detail: "the reviewed revision is no longer retained, so its content cannot be committed"
54088
+ };
54089
+ }
54090
+ if (!record3.complete) {
54091
+ return {
54092
+ ok: false,
54093
+ reason: "revision_unavailable",
54094
+ detail: "the reviewed revision has incomplete coverage, so publishing it would commit a partial change"
54095
+ };
54096
+ }
54097
+ let snapshot;
54098
+ try {
54099
+ snapshot = JSON.parse(record3.manifestJson);
54100
+ } catch {
54101
+ return {
54102
+ ok: false,
54103
+ reason: "revision_unavailable",
54104
+ detail: "the reviewed revision manifest could not be read"
54105
+ };
54106
+ }
54107
+ const files = [];
54108
+ const removed = [];
54109
+ for (const entry of snapshot.entries) {
54110
+ if (entry.kind === "deleted") {
54111
+ removed.push(entry.path);
54112
+ continue;
54113
+ }
54114
+ if (entry.kind !== "file") {
54115
+ return {
54116
+ ok: false,
54117
+ reason: "revision_not_reproducible",
54118
+ detail: `the reviewed revision records ${entry.path} as ${entry.kind}, so its content cannot be committed`
54119
+ };
54120
+ }
54121
+ if (!entry.digest) {
54122
+ return {
54123
+ ok: false,
54124
+ reason: "revision_not_reproducible",
54125
+ detail: `the reviewed revision captured no content for ${entry.path}`
54126
+ };
54127
+ }
54128
+ let content;
54129
+ try {
54130
+ content = readFileSync15(join36(paths2.teamDir(packet.teamId), entry.path));
54131
+ } catch {
54132
+ return {
54133
+ ok: false,
54134
+ reason: "revision_not_reproducible",
54135
+ detail: `the reviewed content for ${entry.path} can no longer be read`
54136
+ };
54137
+ }
54138
+ const digest4 = createHash19("sha256").update(content).digest("hex");
54139
+ if (digest4 !== entry.digest) {
54140
+ return {
54141
+ ok: false,
54142
+ reason: "revision_not_reproducible",
54143
+ detail: `the content of ${entry.path} no longer matches the reviewed revision, so committing it would publish a different change`
54144
+ };
54145
+ }
54146
+ files.push({ path: entry.path, content });
54147
+ }
54148
+ if (files.length === 0 && removed.length === 0) {
54149
+ return {
54150
+ ok: false,
54151
+ reason: "revision_unavailable",
54152
+ detail: "the reviewed revision records no changed content to publish"
54153
+ };
54154
+ }
54155
+ return { ok: true, files, removed };
54156
+ }
54157
+
54158
+ // ../daemon/src/lib/publication/capture.ts
54159
+ function defaultHeadBranch(packetId) {
54160
+ return `bazilion/review-${packetId.slice(0, 8)}`;
54161
+ }
54162
+ function validateHeadBranch(branch) {
54163
+ if (branch.length === 0 || branch.length > PUBLICATION_LIMITS.branch) {
54164
+ return { ok: false, detail: "the branch name is empty or too long" };
54165
+ }
54166
+ if (!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(branch)) {
54167
+ return {
54168
+ ok: false,
54169
+ detail: `the branch name has characters this build will not publish: ${branch}`
54170
+ };
54171
+ }
54172
+ if (branch.includes("..") || branch.includes("//") || branch.endsWith("/") || branch.endsWith(".lock")) {
54173
+ return { ok: false, detail: `the branch name is not a valid ref: ${branch}` };
54174
+ }
54175
+ const protectedName = PUBLICATION_LIMITS.protectedBranches.find(
54176
+ (name) => name === branch || branch.endsWith(`/${name}`)
54177
+ );
54178
+ if (protectedName) {
54179
+ return {
54180
+ ok: false,
54181
+ detail: `this build never publishes to ${branch}: it is the protected branch ${protectedName}`
54182
+ };
54183
+ }
54184
+ return { ok: true };
54185
+ }
54186
+ async function capturePublication(db, paths2, authToken, intent) {
54187
+ const packet = getReviewPacket(db, intent.packetId);
54188
+ if (!packet || packet.teamId !== intent.teamId) {
54189
+ return refused2("packet_unknown", "the review packet is unknown in this Team");
54190
+ }
54191
+ if (packet.state !== "reviewed") {
54192
+ return refused2(
54193
+ "packet_not_reviewed",
54194
+ `the packet is ${packet.state}: publishing is a decision about a reviewed revision, not a promise about one`
54195
+ );
54196
+ }
54197
+ const conclusions = listReviewConclusions(db, packet.id);
54198
+ if (conclusions.length === 0) {
54199
+ return refused2(
54200
+ "missing_reviewer_conclusion",
54201
+ "the packet has no recorded conclusion, so there is nothing reviewed to publish"
54202
+ );
54203
+ }
54204
+ const target = resolvePublicationTarget(db, authToken);
54205
+ if (!target.ok) return refused2(target.reason, target.detail);
54206
+ const headBranch = (intent.headBranch ?? "").trim() || defaultHeadBranch(packet.id);
54207
+ const branch = validateHeadBranch(headBranch);
54208
+ if (!branch.ok) return refused2("branch_protected", branch.detail);
54209
+ const files = readReviewedRevisionFiles(db, paths2, packet);
54210
+ if (!files.ok) {
54211
+ if (files.reason === "revision_not_reproducible") {
54212
+ return refused2("revision_not_reproducible", files.detail);
54213
+ }
54214
+ return refused2("revision_unavailable", files.detail);
54215
+ }
54216
+ if (files.files.length === 0 && files.removed.length === 0) {
54217
+ return refused2("nothing_to_publish", "the reviewed revision holds no change to publish");
54218
+ }
54219
+ const commitMessage = (intent.commitMessage ?? "").trim() || `${conclusionTitle(conclusions[0]?.conclusion ?? "reviewed")}: ${packet.summary?.trim() || "reviewed change"}`;
54220
+ try {
54221
+ const publication = createPublication(db, {
54222
+ teamId: intent.teamId,
54223
+ packetId: packet.id,
54224
+ snapshotId: packet.snapshotId,
54225
+ host: target.target.host,
54226
+ repository: target.target.repository,
54227
+ baseBranch: target.target.baseBranch,
54228
+ headBranch,
54229
+ baseOid: packet.baseOid,
54230
+ commitMessage: bounded3(commitMessage, PUBLICATION_LIMITS.commitMessage),
54231
+ notifyAgentId: packet.requesterKind === "agent" ? packet.requesterAgentId : null
54232
+ });
54233
+ return { kind: "captured", publication };
54234
+ } catch (error2) {
54235
+ if (error2 instanceof PublicationError) {
54236
+ return refused2(error2.code, error2.message);
54237
+ }
54238
+ throw error2;
54239
+ }
54240
+ }
54241
+ function conclusionTitle(conclusion) {
54242
+ return conclusion === "changes_requested" ? "Reviewed change with requested changes" : conclusion === "recommended" ? "Reviewed change" : "Reviewed change (inconclusive review)";
54243
+ }
54244
+ function bounded3(value, max) {
54245
+ return value.length <= max ? value : `${value.slice(0, max - 1)}\u2026`;
54246
+ }
54247
+ function refused2(reason, detail3) {
54248
+ return { kind: "refused", reason, detail: bounded3(detail3, PUBLICATION_LIMITS.refusalDetail) };
54249
+ }
54250
+
54251
+ // ../daemon/src/lib/publication/git-publish.ts
54252
+ import { execFile as execFile2 } from "child_process";
54253
+ import { mkdirSync as mkdirSync12, mkdtempSync as mkdtempSync7, rmSync as rmSync18, writeFileSync as writeFileSync17 } from "fs";
54254
+ import { dirname as dirname7, join as join37 } from "path";
54255
+ import { promisify } from "util";
54256
+ var execFileAsync = promisify(execFile2);
54257
+ var COMMAND_BUDGET_MS = 6e4;
54258
+ var MAX_OUTPUT = 64 * 1024;
54259
+ var AUTHOR_NAME = "Bazilion";
54260
+ var AUTHOR_EMAIL = "bazilion@localhost";
54261
+ async function publishRevisionCommit(input) {
54262
+ const scratch = mkdtempSync7(join37(input.scratchParentDir ?? "/tmp", "bazilion-publish-"));
54263
+ const gitDir = join37(scratch, "repo");
54264
+ const gitEnv = environment(scratch, input.remoteUrl, input.credential);
54265
+ const run = (args, cwd = scratch) => git(["-C", gitDir, ...args], cwd, gitEnv);
54266
+ try {
54267
+ await git(
54268
+ [
54269
+ "-c",
54270
+ "init.templateDir=",
54271
+ "clone",
54272
+ "--no-checkout",
54273
+ "--no-hardlinks",
54274
+ "--quiet",
54275
+ input.teamDir,
54276
+ gitDir
54277
+ ],
54278
+ scratch,
54279
+ gitEnv
54280
+ );
54281
+ try {
54282
+ await run(["rev-parse", "--verify", "--quiet", `${input.baseOid}^{commit}`]);
54283
+ } catch {
54284
+ return {
54285
+ ok: false,
54286
+ reason: "base_unknown",
54287
+ detail: "the pinned base commit is not present in the Team repository"
54288
+ };
54289
+ }
54290
+ const existing = await remoteHeads(input, gitEnv);
54291
+ if (existing.includes(input.headBranch)) {
54292
+ return {
54293
+ ok: false,
54294
+ reason: "head_branch_exists",
54295
+ detail: `the remote already has a branch named ${input.headBranch}; publishing over it is not something this build will do`
54296
+ };
54297
+ }
54298
+ await run(["checkout", "--quiet", "--detach", input.baseOid]);
54299
+ for (const file of input.files) {
54300
+ const target = join37(gitDir, file.path);
54301
+ mkdirSync12(dirname7(target), { recursive: true });
54302
+ writeFileSync17(target, file.content);
54303
+ }
54304
+ for (const path of input.removed) {
54305
+ await run(["rm", "--quiet", "--ignore-unmatch", "--", path]);
54306
+ }
54307
+ await run(["add", "--all", "--", "."]);
54308
+ await run([
54309
+ "-c",
54310
+ "commit.gpgsign=false",
54311
+ "-c",
54312
+ `user.name=${AUTHOR_NAME}`,
54313
+ "-c",
54314
+ `user.email=${AUTHOR_EMAIL}`,
54315
+ "commit",
54316
+ "--quiet",
54317
+ "--no-verify",
54318
+ "-m",
54319
+ input.commitMessage
54320
+ ]);
54321
+ const commitOid = await run(["rev-parse", "HEAD"]);
54322
+ try {
54323
+ await run(["push", "--quiet", input.remoteUrl, `HEAD:refs/heads/${input.headBranch}`]);
54324
+ } catch (error2) {
54325
+ return {
54326
+ ok: false,
54327
+ reason: "push_rejected",
54328
+ detail: `the push was refused: ${summarize(error2)}`
54329
+ };
54330
+ }
54331
+ return { ok: true, commitOid };
54332
+ } catch (error2) {
54333
+ return { ok: false, reason: "commit_failed", detail: summarize(error2) };
54334
+ } finally {
54335
+ rmSync18(scratch, { recursive: true, force: true });
54336
+ }
54337
+ }
54338
+ async function remoteHeads(input, env) {
54339
+ const output = await git(["ls-remote", "--heads", input.remoteUrl], process.cwd(), env);
54340
+ return output.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).map((line) => line.split(/\s+/)[1] ?? "").filter((ref) => ref.startsWith("refs/heads/")).map((ref) => ref.slice("refs/heads/".length));
54341
+ }
54342
+ function environment(scratch, remoteUrl, credential) {
54343
+ const env = {
54344
+ PATH: process.env.PATH,
54345
+ HOME: scratch,
54346
+ GIT_CONFIG_NOSYSTEM: "1",
54347
+ GIT_CONFIG_GLOBAL: "/dev/null",
54348
+ // Never prompt: a missing credential must fail, not hang a daemon thread waiting for a terminal.
54349
+ GIT_TERMINAL_PROMPT: "0",
54350
+ GIT_ASKPASS: "",
54351
+ SSH_ASKPASS: "",
54352
+ GIT_LFS_SKIP_SMUDGE: "1"
54353
+ };
54354
+ const entries = [
54355
+ ["credential.helper", ""],
54356
+ ["core.hooksPath", "/dev/null"],
54357
+ ["core.autocrlf", "false"],
54358
+ ["gc.auto", "0"],
54359
+ ["http.followRedirects", "false"]
54360
+ ];
54361
+ if (/^https?:\/\//.test(remoteUrl)) {
54362
+ const basic = Buffer.from(`x-access-token:${credential}`, "utf8").toString("base64");
54363
+ entries.push(["http.extraheader", `Authorization: Basic ${basic}`]);
54364
+ }
54365
+ entries.forEach(([key3, value], index) => {
54366
+ env[`GIT_CONFIG_KEY_${index}`] = key3;
54367
+ env[`GIT_CONFIG_VALUE_${index}`] = value;
54368
+ });
54369
+ env.GIT_CONFIG_COUNT = String(entries.length);
54370
+ return env;
54371
+ }
54372
+ async function git(args, cwd, env) {
54373
+ try {
54374
+ const { stdout } = await execFileAsync("git", args, {
54375
+ cwd,
54376
+ env,
54377
+ timeout: COMMAND_BUDGET_MS,
54378
+ maxBuffer: MAX_OUTPUT,
54379
+ encoding: "utf8"
54380
+ });
54381
+ return stdout.trim();
54382
+ } catch (error2) {
54383
+ throw new Error(summarize(error2));
54384
+ }
54385
+ }
54386
+ function summarize(error2) {
54387
+ const stderr = typeof error2 === "object" && error2 !== null && "stderr" in error2 ? String(error2.stderr ?? "") : "";
54388
+ const message = stderr.trim() || (error2 instanceof Error ? error2.message : String(error2)) || "unknown failure";
54389
+ return message.length > 300 ? `${message.slice(0, 300)}\u2026` : message;
54390
+ }
54391
+
54392
+ // ../daemon/src/lib/publication/host/github.ts
54393
+ var API = "https://api.github.com";
54394
+ var REQUEST_TIMEOUT_MS = 3e4;
54395
+ function createGitHubAdapter(input) {
54396
+ const apiBase = input.apiBaseUrl ?? API;
54397
+ const doFetch = input.fetchImpl ?? fetch;
54398
+ const headers = {
54399
+ accept: "application/vnd.github+json",
54400
+ authorization: `Bearer ${input.credential}`,
54401
+ "content-type": "application/json",
54402
+ "user-agent": "bazilion",
54403
+ "x-github-api-version": "2022-11-28"
54404
+ };
54405
+ return {
54406
+ remoteUrl(target) {
54407
+ if (!/^[A-Za-z0-9][A-Za-z0-9._-]*\/[A-Za-z0-9][A-Za-z0-9._-]*$/.test(target.repository)) {
54408
+ return {
54409
+ ok: false,
54410
+ reason: "origin_not_configured",
54411
+ detail: `the configured repository is not a GitHub owner/name: ${target.repository}`
54412
+ };
54413
+ }
54414
+ return { ok: true, url: `https://github.com/${target.repository}.git` };
54415
+ },
54416
+ async openPullRequest(target) {
54417
+ let response;
54418
+ try {
54419
+ response = await doFetch(`${apiBase}/repos/${target.repository}/pulls`, {
54420
+ method: "POST",
54421
+ headers,
54422
+ body: JSON.stringify({
54423
+ title: target.title,
54424
+ head: target.headBranch,
54425
+ base: target.baseBranch,
54426
+ body: target.body
54427
+ }),
54428
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
54429
+ });
54430
+ } catch {
54431
+ return {
54432
+ ok: false,
54433
+ reason: "host_unavailable",
54434
+ detail: "the host could not be reached, so whether the branch has a pull request is unknown"
54435
+ };
54436
+ }
54437
+ if (!response.ok) {
54438
+ const text3 = await safeText(response);
54439
+ return {
54440
+ ok: false,
54441
+ reason: "host_refused",
54442
+ detail: `the host refused the pull request (${response.status}): ${text3}`
54443
+ };
54444
+ }
54445
+ const body = await response.json().catch(() => null);
54446
+ const outcome = {
54447
+ pullRequestNumber: typeof body?.number === "number" ? body.number : null,
54448
+ pullRequestUrl: typeof body?.html_url === "string" ? body.html_url : null
54449
+ };
54450
+ return { ok: true, outcome };
54451
+ }
54452
+ };
54453
+ }
54454
+ async function safeText(response) {
54455
+ try {
54456
+ const text3 = await response.text();
54457
+ return text3.replace(/\s+/g, " ").slice(0, 200);
54458
+ } catch {
54459
+ return "no response body";
54460
+ }
54461
+ }
54462
+
54463
+ // ../daemon/src/lib/publication/host/local.ts
54464
+ function createLocalAdapter(input) {
54465
+ return {
54466
+ remoteUrl(target) {
54467
+ if (!target.repository.startsWith("/")) {
54468
+ return {
54469
+ ok: false,
54470
+ reason: "origin_not_configured",
54471
+ detail: `a local publication needs an absolute repository path, got: ${target.repository}`
54472
+ };
54473
+ }
54474
+ void input.credentialPresent;
54475
+ return { ok: true, url: target.repository };
54476
+ },
54477
+ async openPullRequest() {
54478
+ return {
54479
+ ok: true,
54480
+ outcome: { pullRequestNumber: null, pullRequestUrl: null }
54481
+ };
54482
+ }
54483
+ };
54484
+ }
54485
+
54486
+ // ../daemon/src/lib/publication/execute.ts
54487
+ var PUBLICATION_LEASE_MS = 2 * 60 * 1e3;
54488
+ var PUBLICATION_OWNER = `publication-${process.pid}`;
54489
+ async function executePublication(db, paths2, authToken, publicationId, opts = {}) {
54490
+ const claimed = claimPublication(db, {
54491
+ id: publicationId,
54492
+ leaseOwner: PUBLICATION_OWNER,
54493
+ leaseMs: opts.leaseMs ?? PUBLICATION_LEASE_MS,
54494
+ ...opts.now !== void 0 ? { now: opts.now } : {}
54495
+ });
54496
+ if (!claimed) return "not_claimed";
54497
+ const refuse = (reason, detail3) => {
54498
+ refusePublication(db, {
54499
+ id: claimed.id,
54500
+ reason,
54501
+ detail: detail3.slice(0, 400),
54502
+ ...opts.now !== void 0 ? { now: opts.now } : {}
54503
+ });
54504
+ return "refused";
54505
+ };
54506
+ const packet = getReviewPacket(db, claimed.packetId);
54507
+ if (!packet) return refuse("packet_unknown", "the review packet is gone");
54508
+ const files = readReviewedRevisionFiles(db, paths2, packet);
54509
+ if (!files.ok) return refuse(files.reason, files.detail);
54510
+ const resolved = resolvePublicationTarget(db, authToken);
54511
+ if (!resolved.ok) return refuse(resolved.reason, resolved.detail);
54512
+ const adapter = opts.adapter ?? adapterFor(resolved.target.host, resolved.target.credential);
54513
+ const hostTarget = {
54514
+ host: resolved.target.host,
54515
+ repository: resolved.target.repository,
54516
+ baseBranch: claimed.baseBranch,
54517
+ headBranch: claimed.headBranch,
54518
+ commitMessage: claimed.commitMessage,
54519
+ title: claimed.commitMessage,
54520
+ body: publicationBody(claimed, packet.summary)
54521
+ };
54522
+ const remote = adapter.remoteUrl(hostTarget);
54523
+ if (!remote.ok) return refuse(remote.reason, remote.detail);
54524
+ const pushed = await publishRevisionCommit({
54525
+ teamDir: paths2.teamDir(claimed.teamId),
54526
+ baseOid: claimed.baseOid,
54527
+ headBranch: claimed.headBranch,
54528
+ commitMessage: claimed.commitMessage,
54529
+ files: files.files,
54530
+ removed: files.removed,
54531
+ remoteUrl: remote.url,
54532
+ credential: resolved.target.credential,
54533
+ ...opts.scratchParentDir ? { scratchParentDir: opts.scratchParentDir } : {}
54534
+ });
54535
+ if (!pushed.ok) {
54536
+ return refuse(pushed.reason, pushed.detail);
54537
+ }
54538
+ const opened = await adapter.openPullRequest(hostTarget);
54539
+ const settled = settlePublicationPublished(db, {
54540
+ id: claimed.id,
54541
+ commitOid: pushed.commitOid,
54542
+ pullRequestNumber: opened.ok ? opened.outcome.pullRequestNumber : null,
54543
+ pullRequestUrl: opened.ok ? opened.outcome.pullRequestUrl : null,
54544
+ ...opts.now !== void 0 ? { now: opts.now } : {}
54545
+ });
54546
+ if (!opened.ok) {
54547
+ noteBranchWithoutPullRequest(db, settled, opened.detail);
54548
+ }
54549
+ notifyOutcome(db, settled, opened.ok ? null : opened.detail);
54550
+ return "published";
54551
+ }
54552
+ function adapterFor(host2, credential) {
54553
+ return host2 === "github" ? createGitHubAdapter({ credential }) : createLocalAdapter({ credentialPresent: credential.length > 0 });
54554
+ }
54555
+ function publicationBody(publication, summary) {
54556
+ return [
54557
+ `Reviewed revision ${publication.snapshotId.slice(0, 12)} (base ${publication.baseOid.slice(0, 12)}).`,
54558
+ summary ? `
54559
+ ${summary}` : "",
54560
+ "",
54561
+ "Published by Bazilion from a reviewed packet. The commit is unsigned.",
54562
+ "Nothing was merged or deployed."
54563
+ ].join("\n").trim();
54564
+ }
54565
+ function noteBranchWithoutPullRequest(db, publication, detail3) {
54566
+ notePublicationError(
54567
+ db,
54568
+ publication.id,
54569
+ `the branch was published, but no pull request was opened: ${detail3}`
54570
+ );
54571
+ }
54572
+ function notifyOutcome(db, publication, detail3) {
54573
+ const to = publication.notifyAgentId;
54574
+ if (!to) return;
54575
+ const packet = getReviewPacket(db, publication.packetId);
54576
+ const from = packet?.reviewerAgentId;
54577
+ if (!from) return;
54578
+ const lines = [
54579
+ `Publication of ${publication.packetId}: ${publication.state}.`,
54580
+ `branch ${publication.headBranch}`,
54581
+ publication.commitOid ? `commit ${publication.commitOid}` : "",
54582
+ publication.pullRequestUrl ? `pull request ${publication.pullRequestUrl}` : "no pull request was opened",
54583
+ "The commit is unsigned, and nothing was merged or deployed.",
54584
+ detail3 ?? ""
54585
+ ].filter((line) => line.length > 0);
54586
+ try {
54587
+ sendAgentMessage(db, {
54588
+ from,
54589
+ to,
54590
+ payload: lines.join("\n"),
54591
+ origin: "publication_result",
54592
+ attemptKind: "publication_result",
54593
+ attemptId: publication.id
54594
+ });
54595
+ } catch {
54596
+ }
54597
+ }
54598
+
54599
+ // ../daemon/src/lib/publication/report.ts
54600
+ function buildPublicationReport(publication) {
54601
+ const facts = {
54602
+ // Any non-refused row got this far only after every path's digest matched the capture.
54603
+ contentFromReviewedRevision: publication.state !== "refused",
54604
+ nothingSent: publication.state === "refused",
54605
+ pullRequestOpened: publication.pullRequestUrl !== null && publication.pullRequestNumber !== null,
54606
+ unsigned: !publication.signed
54607
+ };
54608
+ return { publication, facts, guidance: guidanceFor(publication) };
54609
+ }
54610
+ function guidanceFor(publication) {
54611
+ switch (publication.state) {
54612
+ case "pending":
54613
+ return "Nothing has been sent. Publishing commits the reviewed revision to a new branch and opens a pull request; it never merges or deploys.";
54614
+ case "publishing":
54615
+ return "An attempt is in progress. Until it settles, whether the branch reached the host is unknown.";
54616
+ case "published":
54617
+ return publication.pullRequestUrl ? "The branch is on the host and a pull request is open. Nothing was merged and nothing was deployed; those stay yours to report." : "The branch is on the host, but no pull request came back. Nothing was merged and nothing was deployed.";
54618
+ case "refused":
54619
+ return "Nothing was sent: no commit, no push, no pull request. Fix the reason below and publish again; the review itself is unchanged.";
54620
+ case "failed":
54621
+ return "The attempt ended without publishing. Nothing is known to be on the host, but check before retrying if the failure happened late.";
54622
+ case "uncertain":
54623
+ return "Whether the branch reached the host is unknown, so this is never retried automatically. Check the host first: a branch that is already there will make a retry refuse.";
54624
+ }
54625
+ }
54626
+
53736
54627
  // ../daemon/src/lib/review/export.ts
53737
54628
  var MAX_PATCH_BYTES = 2e5;
53738
54629
  async function buildReviewExport(db, paths2, teamId, packetId) {
@@ -53990,11 +54881,11 @@ function renderExportDocument(exported) {
53990
54881
  }
53991
54882
 
53992
54883
  // ../daemon/src/lib/review/file-link.ts
53993
- import { execFile as execFile2 } from "child_process";
54884
+ import { execFile as execFile3 } from "child_process";
53994
54885
  import { hostname } from "os";
53995
- import { isAbsolute as isAbsolute10, join as join36 } from "path";
53996
- import { promisify } from "util";
53997
- var execFileAsync = promisify(execFile2);
54886
+ import { isAbsolute as isAbsolute10, join as join38 } from "path";
54887
+ import { promisify as promisify2 } from "util";
54888
+ var execFileAsync2 = promisify2(execFile3);
53998
54889
  var EDITOR_TEMPLATE_ENV = "BAZILION_REVIEW_EDITOR";
53999
54890
  var EDITOR_MAP_ENV = "BAZILION_REVIEW_EDITOR_MAP";
54000
54891
  function buildFileLink(input) {
@@ -54005,7 +54896,7 @@ function buildFileLink(input) {
54005
54896
  const known = revision4.ok && revision4.changes.some((change) => change.path === input.path);
54006
54897
  const line = input.line !== null && input.line >= 1 ? input.line : null;
54007
54898
  const copyTarget = line === null ? input.path : `${input.path}:${line}`;
54008
- const hostPath = known ? join36(team.path, input.path) : null;
54899
+ const hostPath = known ? join38(team.path, input.path) : null;
54009
54900
  const template = env[EDITOR_TEMPLATE_ENV]?.trim();
54010
54901
  const mapped = hostPath ? mapHostPath(hostPath, env[EDITOR_MAP_ENV]) : null;
54011
54902
  if (!known) {
@@ -54059,7 +54950,7 @@ async function openFileLink(link) {
54059
54950
  const [command, ...args] = argv;
54060
54951
  if (!command) return { opened: false, detail: "the configured editor command is empty" };
54061
54952
  try {
54062
- await execFileAsync(command, args, { timeout: 1e4 });
54953
+ await execFileAsync2(command, args, { timeout: 1e4 });
54063
54954
  return { opened: true, detail: `ran ${command} on ${link.hostPath} (daemon host)` };
54064
54955
  } catch (error2) {
54065
54956
  return {
@@ -54256,6 +55147,7 @@ teamsRouter.post("/:id/reviews/:packetId/findings", async (c) => {
54256
55147
  return c.json({ error: "The path is outside the reviewed scope", code: "invalid_path" }, 400);
54257
55148
  }
54258
55149
  try {
55150
+ const availability = await readRevisionContentAvailability(db, paths2, packet);
54259
55151
  const finding = addReviewFinding(db, {
54260
55152
  packetId,
54261
55153
  authorKind: "operator",
@@ -54265,7 +55157,8 @@ teamsRouter.post("/:id/reviews/:packetId/findings", async (c) => {
54265
55157
  lineStart: readLine(body.lineStart),
54266
55158
  lineEnd: readLine(body.lineEnd),
54267
55159
  // The finding is about the revision this packet captured — not about whatever is on disk now.
54268
- snapshotId: packet.snapshotId
55160
+ snapshotId: packet.snapshotId,
55161
+ state: availability.contentAvailable ? "open" : "unverified"
54269
55162
  });
54270
55163
  const report2 = await readReviewPacketReport(db, paths2, packet.teamId, packetId);
54271
55164
  return c.json({ finding, report: report2 }, 201);
@@ -54590,14 +55483,14 @@ teamsRouter.put("/:id/coding-environment", async (c) => {
54590
55483
  return c.json({ error: "Invalid coding environment request" }, 400);
54591
55484
  const request2 = body;
54592
55485
  try {
54593
- const environment = await configureTeamCodingEnvironment(
55486
+ const environment2 = await configureTeamCodingEnvironment(
54594
55487
  db,
54595
55488
  team,
54596
55489
  request2.expectedRevision,
54597
55490
  request2.config
54598
55491
  );
54599
55492
  c.header("Cache-Control", "no-store");
54600
- return c.json(environment);
55493
+ return c.json(environment2);
54601
55494
  } catch (error2) {
54602
55495
  if (error2 instanceof WorkspaceBusyError)
54603
55496
  return c.json({ error: error2.message, code: error2.message }, 409);
@@ -54677,12 +55570,12 @@ teamsRouter.get("/:id/policy/blocks", (c) => {
54677
55570
  WHERE ${filters.join(" AND ")}
54678
55571
  ORDER BY created_at DESC, id DESC LIMIT ?`
54679
55572
  ).all(...params);
54680
- const page = rows.slice(0, limit).map((row) => ({
54681
- ...row,
54682
- policyRefs: JSON.parse(String(row.policy_refs_json)),
54683
- componentOutcomes: JSON.parse(String(row.component_outcomes_json)),
54684
- matchedEdgeIds: JSON.parse(String(row.matched_edge_ids_json)),
54685
- requiredEdgeIds: JSON.parse(String(row.required_edge_ids_json)),
55573
+ const page = rows.slice(0, limit).map((row2) => ({
55574
+ ...row2,
55575
+ policyRefs: JSON.parse(String(row2.policy_refs_json)),
55576
+ componentOutcomes: JSON.parse(String(row2.component_outcomes_json)),
55577
+ matchedEdgeIds: JSON.parse(String(row2.matched_edge_ids_json)),
55578
+ requiredEdgeIds: JSON.parse(String(row2.required_edge_ids_json)),
54686
55579
  policy_refs_json: void 0,
54687
55580
  component_outcomes_json: void 0,
54688
55581
  matched_edge_ids_json: void 0,
@@ -54886,7 +55779,7 @@ async function openMemory(rawId) {
54886
55779
  const { db, paths: paths2 } = getCtx();
54887
55780
  const team = teams_exports.get(db, rawId, paths2);
54888
55781
  if (!team) throw new TeamMemoryNotFoundError(`team not found: ${rawId}`);
54889
- const mem = qmdBackend(join37(team.path, "memory"));
55782
+ const mem = qmdBackend(join39(team.path, "memory"));
54890
55783
  await mem.init();
54891
55784
  return { mem, team };
54892
55785
  }
@@ -55054,6 +55947,93 @@ teamsRouter.post("/:id/verifications/:requestId/cancel", async (c) => {
55054
55947
  async function report(db, paths2, record3) {
55055
55948
  return readVerificationReport(db, paths2, record3.teamId, record3.id);
55056
55949
  }
55950
+ teamsRouter.get("/:id/publications", async (c) => {
55951
+ const { db, paths: paths2 } = getCtx();
55952
+ c.header("Cache-Control", "no-store");
55953
+ try {
55954
+ const team = requireTeam(db, paths2, c.req.param("id"));
55955
+ return c.json({ publications: listPublications(db, team.id).map(toWirePublication) });
55956
+ } catch (error2) {
55957
+ return reviewFailure(c, error2);
55958
+ }
55959
+ });
55960
+ teamsRouter.post("/:id/publications", async (c) => {
55961
+ const { db, paths: paths2, authToken } = getCtx();
55962
+ c.header("Cache-Control", "no-store");
55963
+ const body = await c.req.json().catch(() => null);
55964
+ if (!body || typeof body !== "object" || Array.isArray(body)) {
55965
+ return c.json({ error: "Invalid publication request" }, 400);
55966
+ }
55967
+ const input = body;
55968
+ if (typeof input.packetId !== "string") {
55969
+ return c.json({ error: "Invalid publication request" }, 400);
55970
+ }
55971
+ if (input.headBranch !== void 0 && typeof input.headBranch !== "string") {
55972
+ return c.json({ error: "Invalid publication request" }, 400);
55973
+ }
55974
+ if (input.commitMessage !== void 0 && typeof input.commitMessage !== "string") {
55975
+ return c.json({ error: "Invalid publication request" }, 400);
55976
+ }
55977
+ try {
55978
+ const team = requireTeam(db, paths2, c.req.param("id"));
55979
+ const captured = await capturePublication(db, paths2, authToken, {
55980
+ teamId: team.id,
55981
+ packetId: input.packetId,
55982
+ ...typeof input.headBranch === "string" ? { headBranch: input.headBranch } : {},
55983
+ ...typeof input.commitMessage === "string" ? { commitMessage: input.commitMessage } : {}
55984
+ });
55985
+ if (captured.kind === "refused") {
55986
+ return c.json({ blocked: { reason: captured.reason, detail: captured.detail } }, 409);
55987
+ }
55988
+ await executePublication(db, paths2, authToken, captured.publication.id);
55989
+ const settled = getPublication(db, captured.publication.id);
55990
+ if (!settled) return c.json({ error: "Publication not found" }, 404);
55991
+ return c.json({ report: buildPublicationReport(settled) }, 201);
55992
+ } catch (error2) {
55993
+ if (error2 instanceof PublicationError) {
55994
+ return c.json({ blocked: { reason: error2.code, detail: error2.message } }, 409);
55995
+ }
55996
+ return reviewFailure(c, error2);
55997
+ }
55998
+ });
55999
+ teamsRouter.get("/:id/publications/:publicationId", async (c) => {
56000
+ const { db, paths: paths2 } = getCtx();
56001
+ c.header("Cache-Control", "no-store");
56002
+ try {
56003
+ const team = requireTeam(db, paths2, c.req.param("id"));
56004
+ const publication = getPublication(db, c.req.param("publicationId"));
56005
+ if (!publication || publication.teamId !== team.id) {
56006
+ return c.json({ error: "Publication not found" }, 404);
56007
+ }
56008
+ return c.json({ report: buildPublicationReport(publication) });
56009
+ } catch (error2) {
56010
+ return reviewFailure(c, error2);
56011
+ }
56012
+ });
56013
+ function toWirePublication(record3) {
56014
+ return {
56015
+ id: record3.id,
56016
+ teamId: record3.teamId,
56017
+ packetId: record3.packetId,
56018
+ snapshotId: record3.snapshotId,
56019
+ host: record3.host,
56020
+ repository: record3.repository,
56021
+ baseBranch: record3.baseBranch,
56022
+ headBranch: record3.headBranch,
56023
+ baseOid: record3.baseOid,
56024
+ commitMessage: record3.commitMessage,
56025
+ state: record3.state,
56026
+ signed: record3.signed,
56027
+ commitOid: record3.commitOid,
56028
+ pullRequestNumber: record3.pullRequestNumber,
56029
+ pullRequestUrl: record3.pullRequestUrl,
56030
+ refusalReason: record3.refusalReason,
56031
+ refusalDetail: record3.refusalDetail,
56032
+ error: record3.error,
56033
+ createdAt: record3.createdAt,
56034
+ finishedAt: record3.finishedAt
56035
+ };
56036
+ }
55057
56037
 
55058
56038
  // ../daemon/src/routes/telegram.ts
55059
56039
  import { Hono as Hono19 } from "hono";