@buildautomaton/cli 0.1.96 → 0.1.97

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -23770,6 +23770,7 @@ import os from "node:os";
23770
23770
  var INDEX_WORK_YIELD_EVERY, INDEX_DIR, INDEX_HASH_LEN;
23771
23771
  var init_constants = __esm({
23772
23772
  "../bridge/src/files/index/constants.ts"() {
23773
+ "use strict";
23773
23774
  INDEX_WORK_YIELD_EVERY = 128;
23774
23775
  INDEX_DIR = path3.join(os.homedir(), ".buildautomaton");
23775
23776
  INDEX_HASH_LEN = 16;
@@ -24235,6 +24236,7 @@ function maybeLogCodeNavCacheWorkerError(message) {
24235
24236
  var diagnosticSink, lastDiagnosticKey;
24236
24237
  var init_code_nav_cache_log = __esm({
24237
24238
  "../bridge/src/sqlite/code-nav-cache/code-nav-cache-log.ts"() {
24239
+ "use strict";
24238
24240
  init_log();
24239
24241
  init_sqlite_errors();
24240
24242
  init_sqlite_lock_path();
@@ -30370,7 +30372,7 @@ var {
30370
30372
  } = import_index.default;
30371
30373
 
30372
30374
  // src/cli-version.ts
30373
- var CLI_VERSION = "0.1.96".length > 0 ? "0.1.96" : "0.0.0-dev";
30375
+ var CLI_VERSION = "0.1.97".length > 0 ? "0.1.97" : "0.0.0-dev";
30374
30376
 
30375
30377
  // src/cli/defaults.ts
30376
30378
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
@@ -34963,7 +34965,7 @@ var coerce = {
34963
34965
  };
34964
34966
  var NEVER = INVALID;
34965
34967
 
34966
- // ../types/src/work-items.ts
34968
+ // ../core/src/work-items.ts
34967
34969
  var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
34968
34970
  var WorkItemProgressSchema = external_exports.object({
34969
34971
  remainingCriteria: external_exports.array(external_exports.string()).default([]),
@@ -35004,7 +35006,7 @@ var WorkItemSchema = external_exports.object({
35004
35006
  assignedToUserId: external_exports.string().optional()
35005
35007
  });
35006
35008
 
35007
- // ../types/src/user-profiles.ts
35009
+ // ../core/src/user-profiles.ts
35008
35010
  var UserWorkspaceProfileSchema = external_exports.object({
35009
35011
  id: external_exports.string(),
35010
35012
  workspaceId: external_exports.string(),
@@ -35015,7 +35017,7 @@ var UserWorkspaceProfileSchema = external_exports.object({
35015
35017
  learnings: external_exports.array(external_exports.string())
35016
35018
  });
35017
35019
 
35018
- // ../types/src/runtime.ts
35020
+ // ../core/src/runtime.ts
35019
35021
  var WorkspaceOwnerInfoSchema = external_exports.object({
35020
35022
  ownerId: external_exports.string(),
35021
35023
  ownerName: external_exports.string().optional(),
@@ -35030,7 +35032,7 @@ var WorkspaceRuntimeEntrySchema = external_exports.object({
35030
35032
  isOwner: external_exports.boolean().optional()
35031
35033
  });
35032
35034
 
35033
- // ../types/src/agent.ts
35035
+ // ../core/src/agent.ts
35034
35036
  var ProjectContextSchema = external_exports.object({
35035
35037
  projectId: external_exports.string(),
35036
35038
  context: external_exports.record(external_exports.unknown()).default({}),
@@ -35056,7 +35058,7 @@ var WebSocketMessageSchema = external_exports.object({
35056
35058
  error: external_exports.string().optional()
35057
35059
  });
35058
35060
 
35059
- // ../types/src/integrations/link-detection/linear.ts
35061
+ // ../core/src/integrations/link-detection/linear.ts
35060
35062
  function detectLinearLink(url2) {
35061
35063
  const linearMatch = url2.match(
35062
35064
  /https?:\/\/(?:app\.)?linear\.app\/([^/]+)\/issue\/([A-Z]+-\d+)/i
@@ -35073,7 +35075,7 @@ function detectLinearLink(url2) {
35073
35075
  return null;
35074
35076
  }
35075
35077
 
35076
- // ../types/src/integrations/link-detection/github.ts
35078
+ // ../core/src/integrations/link-detection/github.ts
35077
35079
  function detectGitHubLink(url2) {
35078
35080
  const githubIssueMatch = url2.match(
35079
35081
  /https?:\/\/github\.com\/([^/]+)\/([^/]+)\/issues\/(\d+)/i
@@ -35104,7 +35106,7 @@ function detectGitHubLink(url2) {
35104
35106
  return null;
35105
35107
  }
35106
35108
 
35107
- // ../types/src/integrations/link-detection/jira.ts
35109
+ // ../core/src/integrations/link-detection/jira.ts
35108
35110
  function detectJIRALink(url2) {
35109
35111
  const jiraMatch = url2.match(
35110
35112
  /https?:\/\/([^/]+)\.atlassian\.net\/(?:browse|jira\/software\/projects\/[^/]+\/issues)\/([A-Z]+-\d+)/i
@@ -35121,7 +35123,7 @@ function detectJIRALink(url2) {
35121
35123
  return null;
35122
35124
  }
35123
35125
 
35124
- // ../types/src/integrations/link-detection/notion.ts
35126
+ // ../core/src/integrations/link-detection/notion.ts
35125
35127
  function formatNotionPageId(hex3) {
35126
35128
  if (hex3.length !== 32) return hex3;
35127
35129
  return `${hex3.slice(0, 8)}-${hex3.slice(8, 12)}-${hex3.slice(12, 16)}-${hex3.slice(16, 20)}-${hex3.slice(20, 32)}`;
@@ -35153,48 +35155,7 @@ function detectNotionLink(url2) {
35153
35155
  return null;
35154
35156
  }
35155
35157
 
35156
- // ../types/src/integrations/link-detection/slack.ts
35157
- function detectSlackLink(url2) {
35158
- const archiveThreadMatch = url2.match(
35159
- /https?:\/\/(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/p(\d+)(?:\?.*)?$/i
35160
- );
35161
- if (archiveThreadMatch) {
35162
- return {
35163
- url: url2,
35164
- integrationType: "slack",
35165
- resourceType: "thread",
35166
- resourceId: `${archiveThreadMatch[2]}-${archiveThreadMatch[3]}`,
35167
- isChannel: false
35168
- };
35169
- }
35170
- const appThreadMatch = url2.match(
35171
- /https?:\/\/app\.slack\.com\/client\/([^/]+)\/([A-Z0-9]+)\/thread\/[A-Z0-9]+-(\d+)/i
35172
- );
35173
- if (appThreadMatch) {
35174
- return {
35175
- url: url2,
35176
- integrationType: "slack",
35177
- resourceType: "thread",
35178
- resourceId: `${appThreadMatch[2]}-${appThreadMatch[3]}`,
35179
- isChannel: false
35180
- };
35181
- }
35182
- const channelOnlyMatch = url2.match(
35183
- /https?:\/\/(?:app\.)?(?:([^./]+)\.)?slack\.com\/archives\/([A-Z0-9]+)\/?(\?.*)?$/i
35184
- );
35185
- if (channelOnlyMatch && !url2.includes("/p")) {
35186
- return {
35187
- url: url2,
35188
- integrationType: "slack",
35189
- resourceType: "channel",
35190
- resourceId: channelOnlyMatch[2],
35191
- isChannel: true
35192
- };
35193
- }
35194
- return null;
35195
- }
35196
-
35197
- // ../types/src/integrations/link-detection/zoom.ts
35158
+ // ../core/src/integrations/link-detection/zoom.ts
35198
35159
  function detectZoomLink(url2) {
35199
35160
  try {
35200
35161
  const u = new URL(url2);
@@ -35218,7 +35179,7 @@ function detectZoomLink(url2) {
35218
35179
  return null;
35219
35180
  }
35220
35181
 
35221
- // ../types/src/integrations/link-detection/asana.ts
35182
+ // ../core/src/integrations/link-detection/asana.ts
35222
35183
  var ASANA_TASK_GID = /\d{10,}/;
35223
35184
  function parseAsanaTaskGid(segment) {
35224
35185
  const trimmed2 = segment.trim();
@@ -35270,9 +35231,9 @@ function detectAsanaLink(url2) {
35270
35231
  return null;
35271
35232
  }
35272
35233
 
35273
- // ../types/src/integrations/link-detection/index.ts
35234
+ // ../core/src/integrations/link-detection/index.ts
35274
35235
  function detectIntegrationLink(url2) {
35275
- return detectLinearLink(url2) || detectGitHubLink(url2) || detectJIRALink(url2) || detectNotionLink(url2) || detectSlackLink(url2) || detectZoomLink(url2) || detectAsanaLink(url2);
35236
+ return detectLinearLink(url2) || detectGitHubLink(url2) || detectJIRALink(url2) || detectNotionLink(url2) || detectZoomLink(url2) || detectAsanaLink(url2);
35276
35237
  }
35277
35238
  function extractIntegrationLinks(text) {
35278
35239
  const urlRegex = /https?:\/\/[^\s<>"{}|\\^`[\]]+/gi;
@@ -35285,10 +35246,10 @@ function extractIntegrationLinks(text) {
35285
35246
  return links;
35286
35247
  }
35287
35248
  function extractFetchableIntegrationLinks(text) {
35288
- return extractIntegrationLinks(text).filter((link) => !(link.integrationType === "slack" && link.isChannel));
35249
+ return extractIntegrationLinks(text);
35289
35250
  }
35290
35251
 
35291
- // ../types/src/checkpoints.ts
35252
+ // ../core/src/checkpoints.ts
35292
35253
  var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
35293
35254
  var CheckpointSummarySchema = external_exports.object({
35294
35255
  id: external_exports.string(),
@@ -35300,11 +35261,11 @@ var CheckpointSummarySchema = external_exports.object({
35300
35261
  updatedAt: external_exports.string()
35301
35262
  });
35302
35263
 
35303
- // ../types/src/threads.ts
35264
+ // ../core/src/threads.ts
35304
35265
  var ThreadMetaSchema = external_exports.object({
35305
35266
  threadId: external_exports.string(),
35306
35267
  workspaceId: external_exports.string(),
35307
- /** External source (e.g. slack, discord); null if internal-only */
35268
+ /** External source (e.g. discord); null if internal-only */
35308
35269
  externalSource: external_exports.string().nullable(),
35309
35270
  /** Id in the external system (e.g. channel_id + thread_ts) */
35310
35271
  externalId: external_exports.string().nullable(),
@@ -35329,15 +35290,15 @@ var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
35329
35290
  threadId: external_exports.string()
35330
35291
  });
35331
35292
 
35332
- // ../types/src/content-items.ts
35333
- var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
35293
+ // ../core/src/content-items.ts
35294
+ var ContentSourceSchema = external_exports.enum(["notion", "doc", "other"]);
35334
35295
  var ContentItemMetaSchema = external_exports.object({
35335
35296
  contentId: external_exports.string(),
35336
35297
  workspaceId: external_exports.string(),
35337
35298
  source: ContentSourceSchema,
35338
35299
  /** Id in the external system (e.g. Notion page id, doc url) */
35339
35300
  externalId: external_exports.string(),
35340
- /** If source is slack_thread, points to Thread DO id */
35301
+ /** Optional linked thread DO id */
35341
35302
  threadId: external_exports.string().nullable(),
35342
35303
  title: external_exports.string().optional(),
35343
35304
  createdAt: external_exports.string(),
@@ -35352,7 +35313,7 @@ var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
35352
35313
  contentId: external_exports.string()
35353
35314
  });
35354
35315
 
35355
- // ../types/src/stories.ts
35316
+ // ../core/src/stories.ts
35356
35317
  var StoryMetaSchema = external_exports.object({
35357
35318
  storyId: external_exports.string(),
35358
35319
  workspaceId: external_exports.string(),
@@ -35376,7 +35337,7 @@ var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
35376
35337
  storyId: external_exports.string()
35377
35338
  });
35378
35339
 
35379
- // ../types/src/sessions.ts
35340
+ // ../core/src/sessions.ts
35380
35341
  var SessionMetaSchema = external_exports.object({
35381
35342
  sessionId: external_exports.string(),
35382
35343
  workspaceId: external_exports.string(),
@@ -35430,104 +35391,7 @@ function isUserEndedSessionTurnErrorText(errorText) {
35430
35391
  return LEGACY_USER_ENDED_SESSION_TURN_ERRORS.includes(raw);
35431
35392
  }
35432
35393
 
35433
- // ../types/src/session-kind.ts
35434
- var SESSION_KINDS = ["regular", "planned"];
35435
- var SESSION_KIND_SET = new Set(SESSION_KINDS);
35436
-
35437
- // ../types/src/diff/line-diff.ts
35438
- function normalizeDiffLineText(line) {
35439
- return line.replace(/\r$/, "").replace(/\s*\\s*$/, "");
35440
- }
35441
- function normalizePatchContent(patch) {
35442
- return patch.replace(/^\n+/, "").replace(/\n+$/, "");
35443
- }
35444
- function splitTextIntoDiffLines(text) {
35445
- if (text.length === 0) return [];
35446
- const lines = text.split("\n").map((line) => normalizeDiffLineText(line));
35447
- if (text.endsWith("\n") && lines.at(-1) === "") {
35448
- lines.pop();
35449
- }
35450
- return lines;
35451
- }
35452
- function createEofNewlineDiffLine(change) {
35453
- return {
35454
- type: change === "added" ? "add" : "remove",
35455
- line: "",
35456
- oldLineNo: null,
35457
- newLineNo: null,
35458
- eofNewlineChange: change
35459
- };
35460
- }
35461
- function hasSameLogicalLines(left, right) {
35462
- return left.length === right.length && left.every((line, index) => line === right[index]);
35463
- }
35464
- function detectEofNewlineChange(oldText, newText, oldLines, newLines) {
35465
- if (!hasSameLogicalLines(oldLines, newLines) || oldLines.length === 0) return null;
35466
- if (!oldText.endsWith("\n") && newText.endsWith("\n")) return "added";
35467
- if (oldText.endsWith("\n") && !newText.endsWith("\n")) return "removed";
35468
- return null;
35469
- }
35470
- function computeLineDiff(oldText, newText) {
35471
- const oldLines = splitTextIntoDiffLines(oldText);
35472
- const newLines = splitTextIntoDiffLines(newText);
35473
- const m = oldLines.length;
35474
- const n = newLines.length;
35475
- const dp = Array(m + 1);
35476
- for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
35477
- for (let i2 = 1; i2 <= m; i2++) {
35478
- for (let j2 = 1; j2 <= n; j2++) {
35479
- if (oldLines[i2 - 1] === newLines[j2 - 1]) {
35480
- dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
35481
- } else {
35482
- dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
35483
- }
35484
- }
35485
- }
35486
- const result = [];
35487
- let i = m;
35488
- let j = n;
35489
- while (i > 0 || j > 0) {
35490
- if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
35491
- result.unshift({ type: "context", line: oldLines[i - 1] });
35492
- i--;
35493
- j--;
35494
- } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
35495
- result.unshift({ type: "add", line: newLines[j - 1] });
35496
- j--;
35497
- } else {
35498
- result.unshift({ type: "remove", line: oldLines[i - 1] });
35499
- i--;
35500
- }
35501
- }
35502
- const eofNewlineChange = detectEofNewlineChange(oldText, newText, oldLines, newLines);
35503
- if (eofNewlineChange) result.push(createEofNewlineDiffLine(eofNewlineChange));
35504
- return result;
35505
- }
35506
- function editSnippetToUnifiedDiff(filePath, oldText, newText) {
35507
- const lines = computeLineDiff(oldText, newText);
35508
- const out = [`--- ${filePath}`, `+++ ${filePath}`];
35509
- for (const d of lines) {
35510
- if (d.eofNewlineChange) {
35511
- const previous = out.at(-1);
35512
- if (previous?.startsWith(" ")) {
35513
- const line = previous.slice(1);
35514
- out.pop();
35515
- if (d.eofNewlineChange === "added") {
35516
- out.push(`-${line}`, "\", `+${line}`);
35517
- } else {
35518
- out.push(`-${line}`, `+${line}`, "\");
35519
- }
35520
- continue;
35521
- }
35522
- }
35523
- if (d.type === "add") out.push(`+${d.line}`);
35524
- else if (d.type === "remove") out.push(`-${d.line}`);
35525
- else out.push(` ${d.line}`);
35526
- }
35527
- return out.join("\n");
35528
- }
35529
-
35530
- // ../types/src/artifacts.ts
35394
+ // ../core/src/artifacts.ts
35531
35395
  var ArtifactMetaSchema = external_exports.object({
35532
35396
  artifactId: external_exports.string(),
35533
35397
  workspaceId: external_exports.string(),
@@ -35542,7 +35406,7 @@ var ArtifactMetaSchema = external_exports.object({
35542
35406
  updatedAt: external_exports.string()
35543
35407
  });
35544
35408
 
35545
- // ../types/src/templates.ts
35409
+ // ../core/src/templates.ts
35546
35410
  var TemplateMetaSchema = external_exports.object({
35547
35411
  templateId: external_exports.string(),
35548
35412
  workspaceId: external_exports.string(),
@@ -35553,7 +35417,7 @@ var TemplateMetaSchema = external_exports.object({
35553
35417
  updatedAt: external_exports.string()
35554
35418
  });
35555
35419
 
35556
- // ../types/src/git-repos.ts
35420
+ // ../core/src/git-repos.ts
35557
35421
  var GitRepoMetaSchema = external_exports.object({
35558
35422
  /** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
35559
35423
  repoId: external_exports.string(),
@@ -35566,7 +35430,7 @@ var GitRepoMetaSchema = external_exports.object({
35566
35430
  updatedAt: external_exports.string()
35567
35431
  });
35568
35432
 
35569
- // ../types/src/mcp/bridge-mcp-constants.ts
35433
+ // ../core/src/mcp/bridge-mcp-constants.ts
35570
35434
  var GET_INTEGRATION_CONTENT_TOOL = "get_integration_content";
35571
35435
  var LIST_PARENT_SESSION_PROMPTS_TOOL = "list_parent_session_prompts";
35572
35436
  var GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL = "get_parent_session_turn_transcript";
@@ -35576,12 +35440,12 @@ var BRIDGE_MCP_TOOL_LABELS = {
35576
35440
  [GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL]: "Read parent session transcript"
35577
35441
  };
35578
35442
 
35579
- // ../types/src/prompts/server.ts
35443
+ // ../core/src/prompts/server.ts
35580
35444
  function isRunnableBridgePromptTurnServerState(state) {
35581
35445
  return state === "queued" || state === "requeued" || state === "requeued_with_revert";
35582
35446
  }
35583
35447
 
35584
- // ../types/src/claude-code-permission-mode.ts
35448
+ // ../core/src/claude-code-permission-mode.ts
35585
35449
  var CLAUDE_CODE_PERMISSION_MODES = [
35586
35450
  "default",
35587
35451
  "acceptEdits",
@@ -35595,7 +35459,7 @@ function isClaudeCodePermissionMode(value) {
35595
35459
  return MODE_SET.has(value);
35596
35460
  }
35597
35461
 
35598
- // ../types/src/codex-permission-mode.ts
35462
+ // ../core/src/codex-permission-mode.ts
35599
35463
  function isCodexPermissionMode(value) {
35600
35464
  return value.trim() !== "";
35601
35465
  }
@@ -35605,7 +35469,7 @@ function normalizeCodexPermissionModeInput(raw) {
35605
35469
  return isCodexPermissionMode(t) ? t : null;
35606
35470
  }
35607
35471
 
35608
- // ../types/src/cli-permission-mode.ts
35472
+ // ../core/src/cli-permission-mode.ts
35609
35473
  var CLI_PERMISSION_MODE_DEFAULT = "default";
35610
35474
  var CLI_PERMISSION_MODE_DANGEROUS = "dangerous";
35611
35475
  function normalizeCliPermissionModeInput(raw) {
@@ -35616,7 +35480,7 @@ function normalizeCliPermissionModeInput(raw) {
35616
35480
  return CLI_PERMISSION_MODE_DEFAULT;
35617
35481
  }
35618
35482
 
35619
- // ../types/src/acp-permission-auto-approve.ts
35483
+ // ../core/src/acp-permission-auto-approve.ts
35620
35484
  function isRejectKind(kind) {
35621
35485
  return kind === "reject_once" || kind === "reject_always";
35622
35486
  }
@@ -35673,7 +35537,7 @@ function buildCliAutoApprovedPermissionRpcResult(requestParams) {
35673
35537
  };
35674
35538
  }
35675
35539
 
35676
- // ../types/src/agent-config.ts
35540
+ // ../core/src/agent-config.ts
35677
35541
  var AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY = "claude_permission_mode";
35678
35542
  var AGENT_CONFIG_CLI_PERMISSION_MODE_KEY = "cli_permission_mode";
35679
35543
  var AGENT_CONFIG_CODEX_PERMISSION_MODE_KEY = "codex_permission_mode";
@@ -35701,11 +35565,104 @@ function getAgentModelFromAgentConfig(config2) {
35701
35565
  return t !== "" ? t : null;
35702
35566
  }
35703
35567
 
35704
- // ../types/src/overview/heatmap/constants.ts
35568
+ // ../core/src/diff/line-diff.ts
35569
+ function normalizeDiffLineText(line) {
35570
+ return line.replace(/\r$/, "").replace(/\s*\\s*$/, "");
35571
+ }
35572
+ function normalizePatchContent(patch) {
35573
+ return patch.replace(/^\n+/, "").replace(/\n+$/, "");
35574
+ }
35575
+ function splitTextIntoDiffLines(text) {
35576
+ if (text.length === 0) return [];
35577
+ const lines = text.split("\n").map((line) => normalizeDiffLineText(line));
35578
+ if (text.endsWith("\n") && lines.at(-1) === "") {
35579
+ lines.pop();
35580
+ }
35581
+ return lines;
35582
+ }
35583
+ function createEofNewlineDiffLine(change) {
35584
+ return {
35585
+ type: change === "added" ? "add" : "remove",
35586
+ line: "",
35587
+ oldLineNo: null,
35588
+ newLineNo: null,
35589
+ eofNewlineChange: change
35590
+ };
35591
+ }
35592
+ function hasSameLogicalLines(left, right) {
35593
+ return left.length === right.length && left.every((line, index) => line === right[index]);
35594
+ }
35595
+ function detectEofNewlineChange(oldText, newText, oldLines, newLines) {
35596
+ if (!hasSameLogicalLines(oldLines, newLines) || oldLines.length === 0) return null;
35597
+ if (!oldText.endsWith("\n") && newText.endsWith("\n")) return "added";
35598
+ if (oldText.endsWith("\n") && !newText.endsWith("\n")) return "removed";
35599
+ return null;
35600
+ }
35601
+ function computeLineDiff(oldText, newText) {
35602
+ const oldLines = splitTextIntoDiffLines(oldText);
35603
+ const newLines = splitTextIntoDiffLines(newText);
35604
+ const m = oldLines.length;
35605
+ const n = newLines.length;
35606
+ const dp = Array(m + 1);
35607
+ for (let i2 = 0; i2 <= m; i2++) dp[i2] = Array(n + 1).fill(0);
35608
+ for (let i2 = 1; i2 <= m; i2++) {
35609
+ for (let j2 = 1; j2 <= n; j2++) {
35610
+ if (oldLines[i2 - 1] === newLines[j2 - 1]) {
35611
+ dp[i2][j2] = dp[i2 - 1][j2 - 1] + 1;
35612
+ } else {
35613
+ dp[i2][j2] = Math.max(dp[i2 - 1][j2], dp[i2][j2 - 1]);
35614
+ }
35615
+ }
35616
+ }
35617
+ const result = [];
35618
+ let i = m;
35619
+ let j = n;
35620
+ while (i > 0 || j > 0) {
35621
+ if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
35622
+ result.unshift({ type: "context", line: oldLines[i - 1] });
35623
+ i--;
35624
+ j--;
35625
+ } else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
35626
+ result.unshift({ type: "add", line: newLines[j - 1] });
35627
+ j--;
35628
+ } else {
35629
+ result.unshift({ type: "remove", line: oldLines[i - 1] });
35630
+ i--;
35631
+ }
35632
+ }
35633
+ const eofNewlineChange = detectEofNewlineChange(oldText, newText, oldLines, newLines);
35634
+ if (eofNewlineChange) result.push(createEofNewlineDiffLine(eofNewlineChange));
35635
+ return result;
35636
+ }
35637
+ function editSnippetToUnifiedDiff(filePath, oldText, newText) {
35638
+ const lines = computeLineDiff(oldText, newText);
35639
+ const out = [`--- ${filePath}`, `+++ ${filePath}`];
35640
+ for (const d of lines) {
35641
+ if (d.eofNewlineChange) {
35642
+ const previous = out.at(-1);
35643
+ if (previous?.startsWith(" ")) {
35644
+ const line = previous.slice(1);
35645
+ out.pop();
35646
+ if (d.eofNewlineChange === "added") {
35647
+ out.push(`-${line}`, "\", `+${line}`);
35648
+ } else {
35649
+ out.push(`-${line}`, `+${line}`, "\");
35650
+ }
35651
+ continue;
35652
+ }
35653
+ }
35654
+ if (d.type === "add") out.push(`+${d.line}`);
35655
+ else if (d.type === "remove") out.push(`-${d.line}`);
35656
+ else out.push(` ${d.line}`);
35657
+ }
35658
+ return out.join("\n");
35659
+ }
35660
+
35661
+ // ../core/src/overview/heatmap/constants.ts
35705
35662
  var HOUR_MS = 36e5;
35706
35663
  var DAY_MS = 24 * HOUR_MS;
35707
35664
 
35708
- // ../types/src/hosts/skus.ts
35665
+ // ../core/src/hosts/skus.ts
35709
35666
  function defineHostSku(params) {
35710
35667
  return structuredClone(params);
35711
35668
  }
@@ -35739,7 +35696,7 @@ var HOST_SKUS_BY_ID = {
35739
35696
  [FLY_DEFAULT_HOST_SKU.id]: FLY_DEFAULT_HOST_SKU
35740
35697
  };
35741
35698
 
35742
- // ../types/src/bridges/agents/types.ts
35699
+ // ../core/src/bridges/agents/types.ts
35743
35700
  var INSTALLABLE_BRIDGE_AGENTS = [
35744
35701
  { value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
35745
35702
  { value: "codex-acp", label: "Codex", tokenLabel: "OpenAI API key", tokenEnvVar: "OPENAI_API_KEY" },
@@ -35747,12 +35704,12 @@ var INSTALLABLE_BRIDGE_AGENTS = [
35747
35704
  { value: "opencode", label: "OpenCode agent", tokenLabel: "Provider API key", tokenEnvVar: "OPENCODE_API_KEY" }
35748
35705
  ];
35749
35706
 
35750
- // ../types/src/agent-subscriptions.ts
35707
+ // ../core/src/agent-subscriptions.ts
35751
35708
  var AGENT_SUBSCRIPTION_TYPES = INSTALLABLE_BRIDGE_AGENTS.map(
35752
35709
  (a) => a.value
35753
35710
  );
35754
35711
 
35755
- // ../types/src/role-payment-model.ts
35712
+ // ../core/src/role-payment-model.ts
35756
35713
  var ROLE_FIXED_AMOUNT_USD_MAX = 5e4;
35757
35714
  var ROLE_PER_SESSION_USD_MIN = 0;
35758
35715
  var ROLE_PER_SESSION_USD_MAX = 200;
@@ -35777,14 +35734,14 @@ var RolePaymentModelWireSchema = external_exports.discriminatedUnion("type", [
35777
35734
  })
35778
35735
  ]);
35779
35736
 
35780
- // ../types/src/role-period-days.ts
35737
+ // ../core/src/role-period-days.ts
35781
35738
  var ROLE_PERIOD_MIN_DAYS = 1;
35782
35739
  var ROLE_PERIOD_DAYS_PER_WEEK = 5;
35783
35740
  var ROLE_PERIOD_WEEKS_PER_MONTH = 4;
35784
35741
  var ROLE_PERIOD_DAYS_PER_MONTH = ROLE_PERIOD_DAYS_PER_WEEK * ROLE_PERIOD_WEEKS_PER_MONTH;
35785
35742
  var ROLE_PERIOD_MAX_DAYS = ROLE_PERIOD_DAYS_PER_MONTH * 6;
35786
35743
 
35787
- // ../types/src/role-length.ts
35744
+ // ../core/src/role-length.ts
35788
35745
  var ROLE_LENGTH_MAX_SESSIONS_MIN = 1;
35789
35746
  var ROLE_LENGTH_MAX_SESSIONS_MAX = 50;
35790
35747
  var ROLE_LENGTH_SESSIONS_UNLIMITED_STOP = ROLE_LENGTH_MAX_SESSIONS_MAX + 8;
@@ -35799,7 +35756,7 @@ var RoleLengthWireSchema = external_exports.discriminatedUnion("type", [
35799
35756
  external_exports.object({ type: external_exports.literal("session_count"), max_sessions: MaxSessionsSchema })
35800
35757
  ]);
35801
35758
 
35802
- // ../types/src/role-access-restrictions.ts
35759
+ // ../core/src/role-access-restrictions.ts
35803
35760
  var EMPTY_ROLE_ACCESS_RESTRICTIONS = {
35804
35761
  sessionsOwnAndExplicitOnly: false,
35805
35762
  bridgesOwnAndExplicitOnly: false,
@@ -35817,7 +35774,7 @@ function roleAccessRestrictionsToWire(restrictions) {
35817
35774
  };
35818
35775
  }
35819
35776
 
35820
- // ../types/src/role-details.ts
35777
+ // ../core/src/role-details.ts
35821
35778
  var InitialPeriodDaysSchema = external_exports.number().int().min(ROLE_PERIOD_MIN_DAYS).max(ROLE_PERIOD_MAX_DAYS);
35822
35779
  var AgentSubscriptionIdsSchema = external_exports.array(external_exports.string().min(1)).default([]);
35823
35780
  var BoolFalseSchema = external_exports.boolean().default(false);
@@ -39755,7 +39712,31 @@ function createBridgeOnRequest(opts) {
39755
39712
  }
39756
39713
 
39757
39714
  // ../bridge/src/agents/acp/hooks/bridge-on-session-update/constants.ts
39758
- var PATH_SNAPSHOT_DEBOUNCE_MS = 500;
39715
+ var PATH_SNAPSHOT_DEBOUNCE_MS = 150;
39716
+
39717
+ // ../bridge/src/agents/acp/hooks/bridge-on-session-update/pair-path-snapshot-changes.ts
39718
+ function isDeleted(c) {
39719
+ return c.newText === "" && c.oldText.length > 0;
39720
+ }
39721
+ function isAdded(c) {
39722
+ return c.oldText === "" && c.newText.length > 0 && !c.movedFromPath;
39723
+ }
39724
+ function pairPathSnapshotChanges(changes) {
39725
+ const out = changes.map((c) => ({ ...c }));
39726
+ const deleted = out.filter(isDeleted);
39727
+ const usedDeleted = /* @__PURE__ */ new Set();
39728
+ for (const add of out) {
39729
+ if (!isAdded(add)) continue;
39730
+ const match = deleted.find(
39731
+ (d) => !usedDeleted.has(d.displayPath) && d.oldText === add.newText && d.displayPath !== add.displayPath
39732
+ );
39733
+ if (!match) continue;
39734
+ add.movedFromPath = match.displayPath;
39735
+ add.oldText = match.oldText;
39736
+ usedDeleted.add(match.displayPath);
39737
+ }
39738
+ return out.filter((c) => !(isDeleted(c) && usedDeleted.has(c.displayPath))).map(({ displayPath: _d, ...payload }) => payload);
39739
+ }
39759
39740
 
39760
39741
  // ../bridge/src/agents/acp/hooks/bridge-on-session-update/tool-key.ts
39761
39742
  function getToolCallId(params) {
@@ -39847,26 +39828,31 @@ var PathSnapshotTracker = class {
39847
39828
  if (!beforeMap || beforeMap.size === 0) return;
39848
39829
  this.beforeByToolKey.delete(toolKey);
39849
39830
  if (!send || !runId || !sessionId) return;
39831
+ const pending2 = [];
39850
39832
  for (const [displayPath, oldText] of beforeMap) {
39851
39833
  const newText = readUtf8WorkspaceFile(sessionParentPath, displayPath);
39852
39834
  if (oldText === newText) continue;
39853
39835
  const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
39854
39836
  const dirFlags = getSessionFileChangeDirectoryFlags(sessionParentPath, displayPath);
39837
+ pending2.push({
39838
+ type: "session_file_change",
39839
+ sessionId,
39840
+ runId,
39841
+ path: displayPath,
39842
+ displayPath,
39843
+ oldText,
39844
+ newText,
39845
+ patchContent,
39846
+ isDirectory: dirFlags.isDirectory,
39847
+ directoryRemoved: dirFlags.directoryRemoved
39848
+ });
39849
+ }
39850
+ for (const payload of pairPathSnapshotChanges(pending2)) {
39855
39851
  try {
39856
- send({
39857
- type: "session_file_change",
39858
- sessionId,
39859
- runId,
39860
- path: displayPath,
39861
- oldText,
39862
- newText,
39863
- patchContent,
39864
- isDirectory: dirFlags.isDirectory,
39865
- directoryRemoved: dirFlags.directoryRemoved
39866
- });
39867
- sentPaths.add(displayPath);
39852
+ send(payload);
39853
+ sentPaths.add(payload.path);
39868
39854
  } catch (err) {
39869
- log2(`[Bridge service] Session file change failed for ${displayPath}: ${errorMessage(err)}`);
39855
+ log2(`[Bridge service] Session file change failed for ${payload.path}: ${errorMessage(err)}`);
39870
39856
  }
39871
39857
  }
39872
39858
  }
@@ -40971,16 +40957,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
40971
40957
  // ../bridge/src/agents/acp/prompts/report-post-turn-enrichment.ts
40972
40958
  function reportPostTurnEnrichment(options) {
40973
40959
  void (async () => {
40974
- const {
40975
- sessionId,
40976
- runId,
40977
- agentCwd,
40978
- result,
40979
- sendSessionUpdate,
40980
- log: log2
40981
- } = options;
40960
+ const { sessionId, runId, agentCwd, sendSessionUpdate, log: log2 } = options;
40982
40961
  await yieldToEventLoop();
40983
- if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
40962
+ if (sessionId && runId && sendSessionUpdate && agentCwd) {
40984
40963
  await collectTurnGitDiffFromPreTurnSnapshot({
40985
40964
  sessionId,
40986
40965
  runId,
@@ -43592,7 +43571,7 @@ function createBridgeHeartbeatController(params) {
43592
43571
  }
43593
43572
 
43594
43573
  // ../bridge/src/cli/cli-version.ts
43595
- var CLI_VERSION2 = "0.1.96".length > 0 ? "0.1.96" : "0.0.0-dev";
43574
+ var CLI_VERSION2 = "0.1.97".length > 0 ? "0.1.97" : "0.0.0-dev";
43596
43575
 
43597
43576
  // ../bridge/src/connection/identify/send-bridge-identify.ts
43598
43577
  function sendBridgeIdentify(ws, params) {
@@ -57054,7 +57033,7 @@ var SESSION_ID_SCHEMA2 = {
57054
57033
  var INTEGRATION_CONTENT_MCP_TOOL_DEFINITIONS = [
57055
57034
  {
57056
57035
  name: GET_INTEGRATION_CONTENT_TOOL2,
57057
- description: "Fetch the full content of a supported external integration link (Linear, GitHub, Jira, Notion, Slack thread, Zoom meeting, Asana). Requires sessionId and url. By default, links the URL as this session external ticket when the session has none yet. Pass associateAsSessionTicket: false to fetch content only (e.g. additional context links). Returns an error when the URL is unsupported, the integration is not connected, or content is temporarily unavailable (retry may succeed).",
57036
+ description: "Fetch the full content of a supported external integration link (Linear, GitHub, Jira, Notion, Zoom meeting, Asana). Requires sessionId and url. By default, links the URL as this session external ticket when the session has none yet. Pass associateAsSessionTicket: false to fetch content only (e.g. additional context links). Returns an error when the URL is unsupported, the integration is not connected, or content is temporarily unavailable (retry may succeed).",
57058
57037
  inputSchema: {
57059
57038
  type: "object",
57060
57039
  properties: {
@@ -57262,7 +57241,7 @@ async function enrichForkedSessionPromptForAgent(params) {
57262
57241
  function buildIntegrationContentAgentPromptNote(sessionId) {
57263
57242
  const sessionRef = sessionId.trim();
57264
57243
  return [
57265
- "The user message includes link(s) to external integration resources (Linear, GitHub, Jira, Notion, Slack thread, Zoom, or Asana).",
57244
+ "The user message includes link(s) to external integration resources (Linear, GitHub, Jira, Notion, Zoom, or Asana).",
57266
57245
  "Use the get_integration_content MCP tool on the buildautomaton-bridge server to fetch the full content of each link.",
57267
57246
  `When calling the tool, pass sessionId "${sessionRef}" and the URL as url.`,
57268
57247
  "By default the tool links the fetched URL as this session external ticket when the session has none yet. Pass associateAsSessionTicket: false when fetching additional links for context only (after the primary ticket is linked, or when you do not want association).",