@signetai/connector-claude-code 0.185.4 → 0.185.5

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 (2) hide show
  1. package/dist/index.js +485 -25
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { dirname as dirname5, isAbsolute, join as join3, relative, sep } from "n
11
11
  import { createRequire } from "node:module";
12
12
  import { dirname, join } from "node:path";
13
13
  import { fileURLToPath } from "node:url";
14
+ import { createHash } from "node:crypto";
14
15
  import { createRequire as createRequire2 } from "node:module";
15
16
  import { homedir as homedir4 } from "node:os";
16
17
  import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
@@ -10542,6 +10543,224 @@ function up116(db) {
10542
10543
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
10543
10544
  `);
10544
10545
  }
10546
+ function hasTable4(db, table) {
10547
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
10548
+ }
10549
+ function addColumnIfMissing25(db, table, column, definition) {
10550
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
10551
+ if (columns.some((row) => row.name === column))
10552
+ return;
10553
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
10554
+ }
10555
+ function tableColumns(db, table) {
10556
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
10557
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
10558
+ }
10559
+ function hashTranscript(content) {
10560
+ return createHash("sha256").update(content, "utf8").digest("hex");
10561
+ }
10562
+ function backfillTranscriptHashes(db) {
10563
+ const columns = tableColumns(db, "session_transcripts");
10564
+ if (!columns.has("content_hash") || !columns.has("content"))
10565
+ return;
10566
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
10567
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
10568
+ for (const row of rows) {
10569
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
10570
+ continue;
10571
+ update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
10572
+ }
10573
+ }
10574
+ var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
10575
+ function summaryJobTimestamp(job) {
10576
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
10577
+ }
10578
+ function laterTimestamp(current, candidate) {
10579
+ if (current === null)
10580
+ return candidate;
10581
+ if (candidate === null)
10582
+ return current;
10583
+ const currentMillis = Date.parse(current);
10584
+ const candidateMillis = Date.parse(candidate);
10585
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
10586
+ return candidateMillis > currentMillis ? candidate : current;
10587
+ }
10588
+ return candidate > current ? candidate : current;
10589
+ }
10590
+ function isCompletionBoundary(job, columns) {
10591
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
10592
+ }
10593
+ function mergeTranscriptContent(current, next) {
10594
+ if (current.length === 0)
10595
+ return next;
10596
+ if (next.length === 0 || current === next || current.includes(next))
10597
+ return current;
10598
+ if (next.includes(current))
10599
+ return next;
10600
+ return `${current}
10601
+ ${next}`;
10602
+ }
10603
+ function backfillTranscriptsFromSummaryJobs(db) {
10604
+ if (!hasTable4(db, "summary_jobs"))
10605
+ return;
10606
+ const summaryColumns = tableColumns(db, "summary_jobs");
10607
+ if (!summaryColumns.has("transcript"))
10608
+ return;
10609
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
10610
+ const jobs = db.prepare(`SELECT ${[
10611
+ "id",
10612
+ "session_key",
10613
+ "transcript",
10614
+ "harness",
10615
+ "project",
10616
+ "agent_id",
10617
+ "trigger",
10618
+ "boundary_reason",
10619
+ "captured_at",
10620
+ "ended_at",
10621
+ "completed_at",
10622
+ "created_at"
10623
+ ].map(select).join(", ")} FROM summary_jobs`).all();
10624
+ const candidates = new Map;
10625
+ for (const job of jobs) {
10626
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
10627
+ continue;
10628
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
10629
+ const sessionKey = typeof job.session_key === "string" && job.session_key.trim().length > 0 ? job.session_key : `legacy-summary-job:${job.id ?? hashTranscript(`${summaryJobTimestamp(job)}\x00${job.transcript}`)}`;
10630
+ const key = `${agentId}\x00${sessionKey}`;
10631
+ const current = candidates.get(key);
10632
+ const timestamp = summaryJobTimestamp(job);
10633
+ const boundary = isCompletionBoundary(job, summaryColumns);
10634
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
10635
+ if (!current) {
10636
+ candidates.set(key, {
10637
+ sessionKey,
10638
+ job: { ...job, agent_id: agentId },
10639
+ content: job.transcript,
10640
+ createdAt,
10641
+ completedAt: boundary ? timestamp : null
10642
+ });
10643
+ continue;
10644
+ }
10645
+ const currentTimestamp = summaryJobTimestamp(current.job);
10646
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
10647
+ candidates.set(key, {
10648
+ sessionKey,
10649
+ job: preferred,
10650
+ content: mergeTranscriptContent(current.content, job.transcript),
10651
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
10652
+ completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
10653
+ });
10654
+ }
10655
+ const transcriptColumns = tableColumns(db, "session_transcripts");
10656
+ const hasUpdated = transcriptColumns.has("updated_at");
10657
+ const hasCompleted = transcriptColumns.has("completed_at");
10658
+ const hasHash = transcriptColumns.has("content_hash");
10659
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
10660
+ if (hasUpdated)
10661
+ insertColumns.push("updated_at");
10662
+ if (hasCompleted)
10663
+ insertColumns.push("completed_at");
10664
+ if (hasHash)
10665
+ insertColumns.push("content_hash");
10666
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
10667
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
10668
+ for (const candidate of candidates.values()) {
10669
+ const job = candidate.job;
10670
+ const agentId = job.agent_id ?? "default";
10671
+ const existingRow = existing.get(agentId, candidate.sessionKey);
10672
+ if (existingRow != null) {
10673
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
10674
+ const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
10675
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
10676
+ const assignments = ["content = ?"];
10677
+ const values2 = [mergedContent];
10678
+ if (hasUpdated && mergedContent !== previousContent) {
10679
+ assignments.push("updated_at = ?");
10680
+ values2.push(candidate.createdAt);
10681
+ }
10682
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
10683
+ assignments.push("completed_at = ?");
10684
+ values2.push(completedAt);
10685
+ }
10686
+ if (hasHash) {
10687
+ assignments.push("content_hash = ?");
10688
+ values2.push(hashTranscript(mergedContent));
10689
+ }
10690
+ values2.push(agentId, candidate.sessionKey);
10691
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
10692
+ continue;
10693
+ }
10694
+ const values = [
10695
+ candidate.sessionKey,
10696
+ candidate.content,
10697
+ job.harness ?? null,
10698
+ job.project ?? null,
10699
+ agentId,
10700
+ candidate.createdAt
10701
+ ];
10702
+ if (hasUpdated)
10703
+ values.push(candidate.createdAt);
10704
+ if (hasCompleted)
10705
+ values.push(candidate.completedAt);
10706
+ if (hasHash)
10707
+ values.push(hashTranscript(candidate.content));
10708
+ insert.run(...values);
10709
+ }
10710
+ }
10711
+ function up117(db) {
10712
+ if (!hasTable4(db, "session_transcripts"))
10713
+ return;
10714
+ addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
10715
+ addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
10716
+ backfillTranscriptHashes(db);
10717
+ if (hasTable4(db, "transcript_capture_jobs")) {
10718
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
10719
+ if (captureColumns.some((row) => row.name === "summary_status")) {
10720
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
10721
+ }
10722
+ }
10723
+ if (hasTable4(db, "summary_jobs")) {
10724
+ backfillTranscriptsFromSummaryJobs(db);
10725
+ backfillTranscriptHashes(db);
10726
+ const summaryColumns = tableColumns(db, "summary_jobs");
10727
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
10728
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
10729
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
10730
+ const boundaryParts = [
10731
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
10732
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
10733
+ ].filter((part) => part !== null);
10734
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
10735
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
10736
+ if (completionTimestamp !== "NULL") {
10737
+ db.exec(`
10738
+ UPDATE session_transcripts
10739
+ SET completed_at = COALESCE(
10740
+ completed_at,
10741
+ (
10742
+ SELECT ${completionTimestamp}
10743
+ FROM summary_jobs AS sj
10744
+ WHERE ${agentPredicate}
10745
+ AND sj.session_key = session_transcripts.session_key
10746
+ AND ${boundaryPredicate}
10747
+ )
10748
+ )
10749
+ WHERE completed_at IS NULL;
10750
+ `);
10751
+ }
10752
+ db.exec("DELETE FROM summary_jobs");
10753
+ }
10754
+ const completionIndexColumns = ["agent_id", "completed_at"];
10755
+ if (tableColumns(db, "session_transcripts").has("updated_at"))
10756
+ completionIndexColumns.push("updated_at");
10757
+ db.exec(`
10758
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
10759
+ ON session_transcripts(${completionIndexColumns.join(", ")});
10760
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
10761
+ ON session_transcripts(agent_id, content_hash);
10762
+ `);
10763
+ }
10545
10764
  var MIGRATIONS = [
10546
10765
  {
10547
10766
  version: 1,
@@ -11481,6 +11700,17 @@ var MIGRATIONS = [
11481
11700
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
11482
11701
  ]
11483
11702
  }
11703
+ },
11704
+ {
11705
+ version: 117,
11706
+ name: "retire-summary-worker",
11707
+ up: up117,
11708
+ artifacts: {
11709
+ columns: [
11710
+ { table: "session_transcripts", column: "completed_at" },
11711
+ { table: "session_transcripts", column: "content_hash" }
11712
+ ]
11713
+ }
11484
11714
  }
11485
11715
  ];
11486
11716
  var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
@@ -11818,6 +12048,7 @@ function resolveSignetMcpCommand() {
11818
12048
  import { createRequire as createRequire3 } from "node:module";
11819
12049
  import { dirname as dirname2, join as join2 } from "node:path";
11820
12050
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12051
+ import { createHash as createHash2 } from "node:crypto";
11821
12052
  import { homedir as homedir2 } from "os";
11822
12053
  import { join as join22 } from "path";
11823
12054
  import { createRequire as createRequire22 } from "node:module";
@@ -18773,7 +19004,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
18773
19004
  return true;
18774
19005
  return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
18775
19006
  }
18776
- function up117(db) {
19007
+ function up118(db) {
18777
19008
  db.exec(`
18778
19009
  CREATE TABLE IF NOT EXISTS schema_migrations (
18779
19010
  version INTEGER PRIMARY KEY,
@@ -18866,27 +19097,27 @@ function hasColumn22(db, table, column) {
18866
19097
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
18867
19098
  return rows.some((r) => r.name === column);
18868
19099
  }
18869
- function addColumnIfMissing25(db, table, column, definition) {
19100
+ function addColumnIfMissing26(db, table, column, definition) {
18870
19101
  if (!hasColumn22(db, table, column)) {
18871
19102
  db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
18872
19103
  }
18873
19104
  }
18874
19105
  function up210(db) {
18875
- addColumnIfMissing25(db, "memories", "content_hash", "TEXT");
18876
- addColumnIfMissing25(db, "memories", "normalized_content", "TEXT");
18877
- addColumnIfMissing25(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
18878
- addColumnIfMissing25(db, "memories", "deleted_at", "TEXT");
18879
- addColumnIfMissing25(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
18880
- addColumnIfMissing25(db, "memories", "embedding_model", "TEXT");
18881
- addColumnIfMissing25(db, "memories", "extraction_model", "TEXT");
18882
- addColumnIfMissing25(db, "memories", "update_count", "INTEGER DEFAULT 0");
18883
- addColumnIfMissing25(db, "memories", "who", "TEXT");
18884
- addColumnIfMissing25(db, "memories", "why", "TEXT");
18885
- addColumnIfMissing25(db, "memories", "project", "TEXT");
18886
- addColumnIfMissing25(db, "memories", "pinned", "INTEGER DEFAULT 0");
18887
- addColumnIfMissing25(db, "memories", "importance", "REAL DEFAULT 0.5");
18888
- addColumnIfMissing25(db, "memories", "last_accessed", "TEXT");
18889
- addColumnIfMissing25(db, "memories", "access_count", "INTEGER DEFAULT 0");
19106
+ addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
19107
+ addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
19108
+ addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
19109
+ addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
19110
+ addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
19111
+ addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
19112
+ addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
19113
+ addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
19114
+ addColumnIfMissing26(db, "memories", "who", "TEXT");
19115
+ addColumnIfMissing26(db, "memories", "why", "TEXT");
19116
+ addColumnIfMissing26(db, "memories", "project", "TEXT");
19117
+ addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
19118
+ addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
19119
+ addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
19120
+ addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
18890
19121
  db.exec(`
18891
19122
  CREATE TABLE IF NOT EXISTS memory_history (
18892
19123
  id TEXT PRIMARY KEY,
@@ -18982,7 +19213,7 @@ function up210(db) {
18982
19213
  ON memory_entity_mentions(entity_id);
18983
19214
  `);
18984
19215
  }
18985
- function addColumnIfMissing26(db, table, column, definition) {
19216
+ function addColumnIfMissing27(db, table, column, definition) {
18986
19217
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
18987
19218
  if (rows.some((r) => r.name === column))
18988
19219
  return false;
@@ -18990,8 +19221,8 @@ function addColumnIfMissing26(db, table, column, definition) {
18990
19221
  return true;
18991
19222
  }
18992
19223
  function up310(db) {
18993
- addColumnIfMissing26(db, "memories", "why", "TEXT");
18994
- addColumnIfMissing26(db, "memories", "project", "TEXT");
19224
+ addColumnIfMissing27(db, "memories", "why", "TEXT");
19225
+ addColumnIfMissing27(db, "memories", "project", "TEXT");
18995
19226
  db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
18996
19227
  db.exec(`
18997
19228
  UPDATE memories
@@ -19196,7 +19427,7 @@ function up1010(db) {
19196
19427
  )
19197
19428
  `);
19198
19429
  }
19199
- function up118(db) {
19430
+ function up119(db) {
19200
19431
  db.exec(`
19201
19432
  CREATE TABLE IF NOT EXISTS session_scores (
19202
19433
  id TEXT PRIMARY KEY,
@@ -20417,7 +20648,7 @@ function up492(db) {
20417
20648
  );
20418
20649
  `);
20419
20650
  }
20420
- function hasTable4(db, name) {
20651
+ function hasTable5(db, name) {
20421
20652
  return db.prepare(`SELECT name
20422
20653
  FROM sqlite_master
20423
20654
  WHERE type = 'table' AND name = ?
@@ -20447,7 +20678,7 @@ function up502(db) {
20447
20678
  CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
20448
20679
  ON entity_dependency_history(created_at DESC);
20449
20680
  `);
20450
- if (!hasTable4(db, "entity_dependencies"))
20681
+ if (!hasTable5(db, "entity_dependencies"))
20451
20682
  return;
20452
20683
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
20453
20684
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
@@ -22349,11 +22580,229 @@ function up1162(db) {
22349
22580
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
22350
22581
  `);
22351
22582
  }
22583
+ function hasTable42(db, table) {
22584
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
22585
+ }
22586
+ function addColumnIfMissing252(db, table, column, definition) {
22587
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
22588
+ if (columns.some((row) => row.name === column))
22589
+ return;
22590
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
22591
+ }
22592
+ function tableColumns2(db, table) {
22593
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
22594
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
22595
+ }
22596
+ function hashTranscript2(content) {
22597
+ return createHash2("sha256").update(content, "utf8").digest("hex");
22598
+ }
22599
+ function backfillTranscriptHashes2(db) {
22600
+ const columns = tableColumns2(db, "session_transcripts");
22601
+ if (!columns.has("content_hash") || !columns.has("content"))
22602
+ return;
22603
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
22604
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
22605
+ for (const row of rows) {
22606
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
22607
+ continue;
22608
+ update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
22609
+ }
22610
+ }
22611
+ var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
22612
+ function summaryJobTimestamp2(job) {
22613
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
22614
+ }
22615
+ function laterTimestamp2(current, candidate) {
22616
+ if (current === null)
22617
+ return candidate;
22618
+ if (candidate === null)
22619
+ return current;
22620
+ const currentMillis = Date.parse(current);
22621
+ const candidateMillis = Date.parse(candidate);
22622
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
22623
+ return candidateMillis > currentMillis ? candidate : current;
22624
+ }
22625
+ return candidate > current ? candidate : current;
22626
+ }
22627
+ function isCompletionBoundary2(job, columns) {
22628
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
22629
+ }
22630
+ function mergeTranscriptContent2(current, next) {
22631
+ if (current.length === 0)
22632
+ return next;
22633
+ if (next.length === 0 || current === next || current.includes(next))
22634
+ return current;
22635
+ if (next.includes(current))
22636
+ return next;
22637
+ return `${current}
22638
+ ${next}`;
22639
+ }
22640
+ function backfillTranscriptsFromSummaryJobs2(db) {
22641
+ if (!hasTable42(db, "summary_jobs"))
22642
+ return;
22643
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22644
+ if (!summaryColumns.has("transcript"))
22645
+ return;
22646
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
22647
+ const jobs = db.prepare(`SELECT ${[
22648
+ "id",
22649
+ "session_key",
22650
+ "transcript",
22651
+ "harness",
22652
+ "project",
22653
+ "agent_id",
22654
+ "trigger",
22655
+ "boundary_reason",
22656
+ "captured_at",
22657
+ "ended_at",
22658
+ "completed_at",
22659
+ "created_at"
22660
+ ].map(select).join(", ")} FROM summary_jobs`).all();
22661
+ const candidates = new Map;
22662
+ for (const job of jobs) {
22663
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
22664
+ continue;
22665
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
22666
+ const sessionKey = typeof job.session_key === "string" && job.session_key.trim().length > 0 ? job.session_key : `legacy-summary-job:${job.id ?? hashTranscript2(`${summaryJobTimestamp2(job)}\x00${job.transcript}`)}`;
22667
+ const key = `${agentId}\x00${sessionKey}`;
22668
+ const current = candidates.get(key);
22669
+ const timestamp = summaryJobTimestamp2(job);
22670
+ const boundary = isCompletionBoundary2(job, summaryColumns);
22671
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
22672
+ if (!current) {
22673
+ candidates.set(key, {
22674
+ sessionKey,
22675
+ job: { ...job, agent_id: agentId },
22676
+ content: job.transcript,
22677
+ createdAt,
22678
+ completedAt: boundary ? timestamp : null
22679
+ });
22680
+ continue;
22681
+ }
22682
+ const currentTimestamp = summaryJobTimestamp2(current.job);
22683
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
22684
+ candidates.set(key, {
22685
+ sessionKey,
22686
+ job: preferred,
22687
+ content: mergeTranscriptContent2(current.content, job.transcript),
22688
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
22689
+ completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
22690
+ });
22691
+ }
22692
+ const transcriptColumns = tableColumns2(db, "session_transcripts");
22693
+ const hasUpdated = transcriptColumns.has("updated_at");
22694
+ const hasCompleted = transcriptColumns.has("completed_at");
22695
+ const hasHash = transcriptColumns.has("content_hash");
22696
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
22697
+ if (hasUpdated)
22698
+ insertColumns.push("updated_at");
22699
+ if (hasCompleted)
22700
+ insertColumns.push("completed_at");
22701
+ if (hasHash)
22702
+ insertColumns.push("content_hash");
22703
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
22704
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
22705
+ for (const candidate of candidates.values()) {
22706
+ const job = candidate.job;
22707
+ const agentId = job.agent_id ?? "default";
22708
+ const existingRow = existing.get(agentId, candidate.sessionKey);
22709
+ if (existingRow != null) {
22710
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
22711
+ const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
22712
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
22713
+ const assignments = ["content = ?"];
22714
+ const values2 = [mergedContent];
22715
+ if (hasUpdated && mergedContent !== previousContent) {
22716
+ assignments.push("updated_at = ?");
22717
+ values2.push(candidate.createdAt);
22718
+ }
22719
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
22720
+ assignments.push("completed_at = ?");
22721
+ values2.push(completedAt);
22722
+ }
22723
+ if (hasHash) {
22724
+ assignments.push("content_hash = ?");
22725
+ values2.push(hashTranscript2(mergedContent));
22726
+ }
22727
+ values2.push(agentId, candidate.sessionKey);
22728
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
22729
+ continue;
22730
+ }
22731
+ const values = [
22732
+ candidate.sessionKey,
22733
+ candidate.content,
22734
+ job.harness ?? null,
22735
+ job.project ?? null,
22736
+ agentId,
22737
+ candidate.createdAt
22738
+ ];
22739
+ if (hasUpdated)
22740
+ values.push(candidate.createdAt);
22741
+ if (hasCompleted)
22742
+ values.push(candidate.completedAt);
22743
+ if (hasHash)
22744
+ values.push(hashTranscript2(candidate.content));
22745
+ insert.run(...values);
22746
+ }
22747
+ }
22748
+ function up1172(db) {
22749
+ if (!hasTable42(db, "session_transcripts"))
22750
+ return;
22751
+ addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
22752
+ addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
22753
+ backfillTranscriptHashes2(db);
22754
+ if (hasTable42(db, "transcript_capture_jobs")) {
22755
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
22756
+ if (captureColumns.some((row) => row.name === "summary_status")) {
22757
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
22758
+ }
22759
+ }
22760
+ if (hasTable42(db, "summary_jobs")) {
22761
+ backfillTranscriptsFromSummaryJobs2(db);
22762
+ backfillTranscriptHashes2(db);
22763
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22764
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
22765
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
22766
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
22767
+ const boundaryParts = [
22768
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
22769
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
22770
+ ].filter((part) => part !== null);
22771
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
22772
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
22773
+ if (completionTimestamp !== "NULL") {
22774
+ db.exec(`
22775
+ UPDATE session_transcripts
22776
+ SET completed_at = COALESCE(
22777
+ completed_at,
22778
+ (
22779
+ SELECT ${completionTimestamp}
22780
+ FROM summary_jobs AS sj
22781
+ WHERE ${agentPredicate}
22782
+ AND sj.session_key = session_transcripts.session_key
22783
+ AND ${boundaryPredicate}
22784
+ )
22785
+ )
22786
+ WHERE completed_at IS NULL;
22787
+ `);
22788
+ }
22789
+ db.exec("DELETE FROM summary_jobs");
22790
+ }
22791
+ const completionIndexColumns = ["agent_id", "completed_at"];
22792
+ if (tableColumns2(db, "session_transcripts").has("updated_at"))
22793
+ completionIndexColumns.push("updated_at");
22794
+ db.exec(`
22795
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
22796
+ ON session_transcripts(${completionIndexColumns.join(", ")});
22797
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
22798
+ ON session_transcripts(agent_id, content_hash);
22799
+ `);
22800
+ }
22352
22801
  var MIGRATIONS2 = [
22353
22802
  {
22354
22803
  version: 1,
22355
22804
  name: "baseline",
22356
- up: up117,
22805
+ up: up118,
22357
22806
  artifacts: { tables: ["memories", "conversations", "embeddings"] }
22358
22807
  },
22359
22808
  {
@@ -22419,7 +22868,7 @@ var MIGRATIONS2 = [
22419
22868
  {
22420
22869
  version: 11,
22421
22870
  name: "session-scores",
22422
- up: up118,
22871
+ up: up119,
22423
22872
  artifacts: { tables: ["session_scores"] }
22424
22873
  },
22425
22874
  {
@@ -23288,6 +23737,17 @@ var MIGRATIONS2 = [
23288
23737
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
23289
23738
  ]
23290
23739
  }
23740
+ },
23741
+ {
23742
+ version: 117,
23743
+ name: "retire-summary-worker",
23744
+ up: up1172,
23745
+ artifacts: {
23746
+ columns: [
23747
+ { table: "session_transcripts", column: "completed_at" },
23748
+ { table: "session_transcripts", column: "content_hash" }
23749
+ ]
23750
+ }
23291
23751
  }
23292
23752
  ];
23293
23753
  var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signetai/connector-claude-code",
3
- "version": "0.185.4",
3
+ "version": "0.185.5",
4
4
  "description": "Signet connector for Claude Code (Anthropic CLI)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -24,8 +24,8 @@
24
24
  "typecheck": "tsc --noEmit"
25
25
  },
26
26
  "dependencies": {
27
- "@signetai/connector-base": "0.185.4",
28
- "@signetai/core": "0.185.4"
27
+ "@signetai/connector-base": "0.185.5",
28
+ "@signetai/core": "0.185.5"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/node": "^22.0.0",