@signetai/connector-codex 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 +487 -27
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/index.ts
2
2
  import { spawnSync } from "node:child_process";
3
- import { createHash } from "node:crypto";
3
+ import { createHash as createHash3 } from "node:crypto";
4
4
  import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, readdirSync, rmSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
5
5
  import { homedir } from "node:os";
6
6
  import { basename as basename3, dirname as dirname6, join as join4 } from "node:path";
@@ -12,6 +12,7 @@ import { dirname as dirname5, isAbsolute, join as join3, relative, sep } from "n
12
12
  import { createRequire } from "node:module";
13
13
  import { dirname, join } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
+ import { createHash } from "node:crypto";
15
16
  import { createRequire as createRequire2 } from "node:module";
16
17
  import { homedir as homedir4 } from "node:os";
17
18
  import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
@@ -10543,6 +10544,224 @@ function up116(db) {
10543
10544
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
10544
10545
  `);
10545
10546
  }
10547
+ function hasTable4(db, table) {
10548
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
10549
+ }
10550
+ function addColumnIfMissing25(db, table, column, definition) {
10551
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
10552
+ if (columns.some((row) => row.name === column))
10553
+ return;
10554
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
10555
+ }
10556
+ function tableColumns(db, table) {
10557
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
10558
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
10559
+ }
10560
+ function hashTranscript(content) {
10561
+ return createHash("sha256").update(content, "utf8").digest("hex");
10562
+ }
10563
+ function backfillTranscriptHashes(db) {
10564
+ const columns = tableColumns(db, "session_transcripts");
10565
+ if (!columns.has("content_hash") || !columns.has("content"))
10566
+ return;
10567
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
10568
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
10569
+ for (const row of rows) {
10570
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
10571
+ continue;
10572
+ update.run(hashTranscript(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
10573
+ }
10574
+ }
10575
+ var COMPLETION_BOUNDARY_REASONS = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
10576
+ function summaryJobTimestamp(job) {
10577
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
10578
+ }
10579
+ function laterTimestamp(current, candidate) {
10580
+ if (current === null)
10581
+ return candidate;
10582
+ if (candidate === null)
10583
+ return current;
10584
+ const currentMillis = Date.parse(current);
10585
+ const candidateMillis = Date.parse(candidate);
10586
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
10587
+ return candidateMillis > currentMillis ? candidate : current;
10588
+ }
10589
+ return candidate > current ? candidate : current;
10590
+ }
10591
+ function isCompletionBoundary(job, columns) {
10592
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS.has(job.boundary_reason ?? "");
10593
+ }
10594
+ function mergeTranscriptContent(current, next) {
10595
+ if (current.length === 0)
10596
+ return next;
10597
+ if (next.length === 0 || current === next || current.includes(next))
10598
+ return current;
10599
+ if (next.includes(current))
10600
+ return next;
10601
+ return `${current}
10602
+ ${next}`;
10603
+ }
10604
+ function backfillTranscriptsFromSummaryJobs(db) {
10605
+ if (!hasTable4(db, "summary_jobs"))
10606
+ return;
10607
+ const summaryColumns = tableColumns(db, "summary_jobs");
10608
+ if (!summaryColumns.has("transcript"))
10609
+ return;
10610
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
10611
+ const jobs = db.prepare(`SELECT ${[
10612
+ "id",
10613
+ "session_key",
10614
+ "transcript",
10615
+ "harness",
10616
+ "project",
10617
+ "agent_id",
10618
+ "trigger",
10619
+ "boundary_reason",
10620
+ "captured_at",
10621
+ "ended_at",
10622
+ "completed_at",
10623
+ "created_at"
10624
+ ].map(select).join(", ")} FROM summary_jobs`).all();
10625
+ const candidates = new Map;
10626
+ for (const job of jobs) {
10627
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
10628
+ continue;
10629
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
10630
+ 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}`)}`;
10631
+ const key = `${agentId}\x00${sessionKey}`;
10632
+ const current = candidates.get(key);
10633
+ const timestamp = summaryJobTimestamp(job);
10634
+ const boundary = isCompletionBoundary(job, summaryColumns);
10635
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
10636
+ if (!current) {
10637
+ candidates.set(key, {
10638
+ sessionKey,
10639
+ job: { ...job, agent_id: agentId },
10640
+ content: job.transcript,
10641
+ createdAt,
10642
+ completedAt: boundary ? timestamp : null
10643
+ });
10644
+ continue;
10645
+ }
10646
+ const currentTimestamp = summaryJobTimestamp(current.job);
10647
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
10648
+ candidates.set(key, {
10649
+ sessionKey,
10650
+ job: preferred,
10651
+ content: mergeTranscriptContent(current.content, job.transcript),
10652
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
10653
+ completedAt: laterTimestamp(current.completedAt, boundary ? timestamp : null)
10654
+ });
10655
+ }
10656
+ const transcriptColumns = tableColumns(db, "session_transcripts");
10657
+ const hasUpdated = transcriptColumns.has("updated_at");
10658
+ const hasCompleted = transcriptColumns.has("completed_at");
10659
+ const hasHash = transcriptColumns.has("content_hash");
10660
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
10661
+ if (hasUpdated)
10662
+ insertColumns.push("updated_at");
10663
+ if (hasCompleted)
10664
+ insertColumns.push("completed_at");
10665
+ if (hasHash)
10666
+ insertColumns.push("content_hash");
10667
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
10668
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
10669
+ for (const candidate of candidates.values()) {
10670
+ const job = candidate.job;
10671
+ const agentId = job.agent_id ?? "default";
10672
+ const existingRow = existing.get(agentId, candidate.sessionKey);
10673
+ if (existingRow != null) {
10674
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
10675
+ const mergedContent = mergeTranscriptContent(previousContent, candidate.content);
10676
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
10677
+ const assignments = ["content = ?"];
10678
+ const values2 = [mergedContent];
10679
+ if (hasUpdated && mergedContent !== previousContent) {
10680
+ assignments.push("updated_at = ?");
10681
+ values2.push(candidate.createdAt);
10682
+ }
10683
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
10684
+ assignments.push("completed_at = ?");
10685
+ values2.push(completedAt);
10686
+ }
10687
+ if (hasHash) {
10688
+ assignments.push("content_hash = ?");
10689
+ values2.push(hashTranscript(mergedContent));
10690
+ }
10691
+ values2.push(agentId, candidate.sessionKey);
10692
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
10693
+ continue;
10694
+ }
10695
+ const values = [
10696
+ candidate.sessionKey,
10697
+ candidate.content,
10698
+ job.harness ?? null,
10699
+ job.project ?? null,
10700
+ agentId,
10701
+ candidate.createdAt
10702
+ ];
10703
+ if (hasUpdated)
10704
+ values.push(candidate.createdAt);
10705
+ if (hasCompleted)
10706
+ values.push(candidate.completedAt);
10707
+ if (hasHash)
10708
+ values.push(hashTranscript(candidate.content));
10709
+ insert.run(...values);
10710
+ }
10711
+ }
10712
+ function up117(db) {
10713
+ if (!hasTable4(db, "session_transcripts"))
10714
+ return;
10715
+ addColumnIfMissing25(db, "session_transcripts", "completed_at", "TEXT");
10716
+ addColumnIfMissing25(db, "session_transcripts", "content_hash", "TEXT");
10717
+ backfillTranscriptHashes(db);
10718
+ if (hasTable4(db, "transcript_capture_jobs")) {
10719
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
10720
+ if (captureColumns.some((row) => row.name === "summary_status")) {
10721
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
10722
+ }
10723
+ }
10724
+ if (hasTable4(db, "summary_jobs")) {
10725
+ backfillTranscriptsFromSummaryJobs(db);
10726
+ backfillTranscriptHashes(db);
10727
+ const summaryColumns = tableColumns(db, "summary_jobs");
10728
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
10729
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
10730
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
10731
+ const boundaryParts = [
10732
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
10733
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
10734
+ ].filter((part) => part !== null);
10735
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
10736
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
10737
+ if (completionTimestamp !== "NULL") {
10738
+ db.exec(`
10739
+ UPDATE session_transcripts
10740
+ SET completed_at = COALESCE(
10741
+ completed_at,
10742
+ (
10743
+ SELECT ${completionTimestamp}
10744
+ FROM summary_jobs AS sj
10745
+ WHERE ${agentPredicate}
10746
+ AND sj.session_key = session_transcripts.session_key
10747
+ AND ${boundaryPredicate}
10748
+ )
10749
+ )
10750
+ WHERE completed_at IS NULL;
10751
+ `);
10752
+ }
10753
+ db.exec("DELETE FROM summary_jobs");
10754
+ }
10755
+ const completionIndexColumns = ["agent_id", "completed_at"];
10756
+ if (tableColumns(db, "session_transcripts").has("updated_at"))
10757
+ completionIndexColumns.push("updated_at");
10758
+ db.exec(`
10759
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
10760
+ ON session_transcripts(${completionIndexColumns.join(", ")});
10761
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
10762
+ ON session_transcripts(agent_id, content_hash);
10763
+ `);
10764
+ }
10546
10765
  var MIGRATIONS = [
10547
10766
  {
10548
10767
  version: 1,
@@ -11482,6 +11701,17 @@ var MIGRATIONS = [
11482
11701
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
11483
11702
  ]
11484
11703
  }
11704
+ },
11705
+ {
11706
+ version: 117,
11707
+ name: "retire-summary-worker",
11708
+ up: up117,
11709
+ artifacts: {
11710
+ columns: [
11711
+ { table: "session_transcripts", column: "completed_at" },
11712
+ { table: "session_transcripts", column: "content_hash" }
11713
+ ]
11714
+ }
11485
11715
  }
11486
11716
  ];
11487
11717
  var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
@@ -11909,6 +12139,7 @@ function resolveRemoteDaemonUrl() {
11909
12139
  import { createRequire as createRequire3 } from "node:module";
11910
12140
  import { dirname as dirname2, join as join2 } from "node:path";
11911
12141
  import { fileURLToPath as fileURLToPath2 } from "node:url";
12142
+ import { createHash as createHash2 } from "node:crypto";
11912
12143
  import { homedir as homedir2 } from "os";
11913
12144
  import { join as join22 } from "path";
11914
12145
  import { createRequire as createRequire22 } from "node:module";
@@ -18864,7 +19095,7 @@ function memoriesFtsNeedsTokenizerRepair2(sql) {
18864
19095
  return true;
18865
19096
  return !normalized.includes(`tokenize='${MEMORIES_FTS_TOKENIZER2}'`);
18866
19097
  }
18867
- function up117(db) {
19098
+ function up118(db) {
18868
19099
  db.exec(`
18869
19100
  CREATE TABLE IF NOT EXISTS schema_migrations (
18870
19101
  version INTEGER PRIMARY KEY,
@@ -18957,27 +19188,27 @@ function hasColumn22(db, table, column) {
18957
19188
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
18958
19189
  return rows.some((r) => r.name === column);
18959
19190
  }
18960
- function addColumnIfMissing25(db, table, column, definition) {
19191
+ function addColumnIfMissing26(db, table, column, definition) {
18961
19192
  if (!hasColumn22(db, table, column)) {
18962
19193
  db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
18963
19194
  }
18964
19195
  }
18965
19196
  function up210(db) {
18966
- addColumnIfMissing25(db, "memories", "content_hash", "TEXT");
18967
- addColumnIfMissing25(db, "memories", "normalized_content", "TEXT");
18968
- addColumnIfMissing25(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
18969
- addColumnIfMissing25(db, "memories", "deleted_at", "TEXT");
18970
- addColumnIfMissing25(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
18971
- addColumnIfMissing25(db, "memories", "embedding_model", "TEXT");
18972
- addColumnIfMissing25(db, "memories", "extraction_model", "TEXT");
18973
- addColumnIfMissing25(db, "memories", "update_count", "INTEGER DEFAULT 0");
18974
- addColumnIfMissing25(db, "memories", "who", "TEXT");
18975
- addColumnIfMissing25(db, "memories", "why", "TEXT");
18976
- addColumnIfMissing25(db, "memories", "project", "TEXT");
18977
- addColumnIfMissing25(db, "memories", "pinned", "INTEGER DEFAULT 0");
18978
- addColumnIfMissing25(db, "memories", "importance", "REAL DEFAULT 0.5");
18979
- addColumnIfMissing25(db, "memories", "last_accessed", "TEXT");
18980
- addColumnIfMissing25(db, "memories", "access_count", "INTEGER DEFAULT 0");
19197
+ addColumnIfMissing26(db, "memories", "content_hash", "TEXT");
19198
+ addColumnIfMissing26(db, "memories", "normalized_content", "TEXT");
19199
+ addColumnIfMissing26(db, "memories", "is_deleted", "INTEGER DEFAULT 0");
19200
+ addColumnIfMissing26(db, "memories", "deleted_at", "TEXT");
19201
+ addColumnIfMissing26(db, "memories", "extraction_status", "TEXT DEFAULT 'none'");
19202
+ addColumnIfMissing26(db, "memories", "embedding_model", "TEXT");
19203
+ addColumnIfMissing26(db, "memories", "extraction_model", "TEXT");
19204
+ addColumnIfMissing26(db, "memories", "update_count", "INTEGER DEFAULT 0");
19205
+ addColumnIfMissing26(db, "memories", "who", "TEXT");
19206
+ addColumnIfMissing26(db, "memories", "why", "TEXT");
19207
+ addColumnIfMissing26(db, "memories", "project", "TEXT");
19208
+ addColumnIfMissing26(db, "memories", "pinned", "INTEGER DEFAULT 0");
19209
+ addColumnIfMissing26(db, "memories", "importance", "REAL DEFAULT 0.5");
19210
+ addColumnIfMissing26(db, "memories", "last_accessed", "TEXT");
19211
+ addColumnIfMissing26(db, "memories", "access_count", "INTEGER DEFAULT 0");
18981
19212
  db.exec(`
18982
19213
  CREATE TABLE IF NOT EXISTS memory_history (
18983
19214
  id TEXT PRIMARY KEY,
@@ -19073,7 +19304,7 @@ function up210(db) {
19073
19304
  ON memory_entity_mentions(entity_id);
19074
19305
  `);
19075
19306
  }
19076
- function addColumnIfMissing26(db, table, column, definition) {
19307
+ function addColumnIfMissing27(db, table, column, definition) {
19077
19308
  const rows = db.prepare(`PRAGMA table_info(${table})`).all();
19078
19309
  if (rows.some((r) => r.name === column))
19079
19310
  return false;
@@ -19081,8 +19312,8 @@ function addColumnIfMissing26(db, table, column, definition) {
19081
19312
  return true;
19082
19313
  }
19083
19314
  function up310(db) {
19084
- addColumnIfMissing26(db, "memories", "why", "TEXT");
19085
- addColumnIfMissing26(db, "memories", "project", "TEXT");
19315
+ addColumnIfMissing27(db, "memories", "why", "TEXT");
19316
+ addColumnIfMissing27(db, "memories", "project", "TEXT");
19086
19317
  db.exec(`DROP INDEX IF EXISTS idx_memories_content_hash`);
19087
19318
  db.exec(`
19088
19319
  UPDATE memories
@@ -19287,7 +19518,7 @@ function up1010(db) {
19287
19518
  )
19288
19519
  `);
19289
19520
  }
19290
- function up118(db) {
19521
+ function up119(db) {
19291
19522
  db.exec(`
19292
19523
  CREATE TABLE IF NOT EXISTS session_scores (
19293
19524
  id TEXT PRIMARY KEY,
@@ -20508,7 +20739,7 @@ function up492(db) {
20508
20739
  );
20509
20740
  `);
20510
20741
  }
20511
- function hasTable4(db, name) {
20742
+ function hasTable5(db, name) {
20512
20743
  return db.prepare(`SELECT name
20513
20744
  FROM sqlite_master
20514
20745
  WHERE type = 'table' AND name = ?
@@ -20538,7 +20769,7 @@ function up502(db) {
20538
20769
  CREATE INDEX IF NOT EXISTS idx_entity_dependency_history_created
20539
20770
  ON entity_dependency_history(created_at DESC);
20540
20771
  `);
20541
- if (!hasTable4(db, "entity_dependencies"))
20772
+ if (!hasTable5(db, "entity_dependencies"))
20542
20773
  return;
20543
20774
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_insert");
20544
20775
  db.exec("DROP TRIGGER IF EXISTS trg_entity_dependencies_related_to_reason_update");
@@ -22440,11 +22671,229 @@ function up1162(db) {
22440
22671
  ON cross_agent_messages(delivery_path, delivery_state, delivery_lease_expires_at, delivery_updated_at);
22441
22672
  `);
22442
22673
  }
22674
+ function hasTable42(db, table) {
22675
+ return db.prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?").get(table) != null;
22676
+ }
22677
+ function addColumnIfMissing252(db, table, column, definition) {
22678
+ const columns = db.prepare(`PRAGMA table_info(${table})`).all();
22679
+ if (columns.some((row) => row.name === column))
22680
+ return;
22681
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
22682
+ }
22683
+ function tableColumns2(db, table) {
22684
+ const rows = db.prepare(`PRAGMA table_info(${table})`).all();
22685
+ return new Set(rows.map((row) => typeof row.name === "string" ? row.name : ""));
22686
+ }
22687
+ function hashTranscript2(content) {
22688
+ return createHash2("sha256").update(content, "utf8").digest("hex");
22689
+ }
22690
+ function backfillTranscriptHashes2(db) {
22691
+ const columns = tableColumns2(db, "session_transcripts");
22692
+ if (!columns.has("content_hash") || !columns.has("content"))
22693
+ return;
22694
+ const rows = db.prepare("SELECT session_key, agent_id, content FROM session_transcripts WHERE content_hash IS NULL").all();
22695
+ const update = db.prepare("UPDATE session_transcripts SET content_hash = ? WHERE agent_id = ? AND session_key = ? AND content_hash IS NULL");
22696
+ for (const row of rows) {
22697
+ if (typeof row.content !== "string" || typeof row.session_key !== "string")
22698
+ continue;
22699
+ update.run(hashTranscript2(row.content), typeof row.agent_id === "string" ? row.agent_id : "default", row.session_key);
22700
+ }
22701
+ }
22702
+ var COMPLETION_BOUNDARY_REASONS2 = new Set(["session_closed", "session_clear", "stale_session", "ttl_expired"]);
22703
+ function summaryJobTimestamp2(job) {
22704
+ return job.completed_at ?? job.ended_at ?? job.captured_at ?? job.created_at ?? new Date(0).toISOString();
22705
+ }
22706
+ function laterTimestamp2(current, candidate) {
22707
+ if (current === null)
22708
+ return candidate;
22709
+ if (candidate === null)
22710
+ return current;
22711
+ const currentMillis = Date.parse(current);
22712
+ const candidateMillis = Date.parse(candidate);
22713
+ if (Number.isFinite(currentMillis) && Number.isFinite(candidateMillis)) {
22714
+ return candidateMillis > currentMillis ? candidate : current;
22715
+ }
22716
+ return candidate > current ? candidate : current;
22717
+ }
22718
+ function isCompletionBoundary2(job, columns) {
22719
+ return columns.has("trigger") && job.trigger === "session_end" || columns.has("boundary_reason") && COMPLETION_BOUNDARY_REASONS2.has(job.boundary_reason ?? "");
22720
+ }
22721
+ function mergeTranscriptContent2(current, next) {
22722
+ if (current.length === 0)
22723
+ return next;
22724
+ if (next.length === 0 || current === next || current.includes(next))
22725
+ return current;
22726
+ if (next.includes(current))
22727
+ return next;
22728
+ return `${current}
22729
+ ${next}`;
22730
+ }
22731
+ function backfillTranscriptsFromSummaryJobs2(db) {
22732
+ if (!hasTable42(db, "summary_jobs"))
22733
+ return;
22734
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22735
+ if (!summaryColumns.has("transcript"))
22736
+ return;
22737
+ const select = (name) => summaryColumns.has(name) ? `"${name}" AS "${name}"` : `NULL AS "${name}"`;
22738
+ const jobs = db.prepare(`SELECT ${[
22739
+ "id",
22740
+ "session_key",
22741
+ "transcript",
22742
+ "harness",
22743
+ "project",
22744
+ "agent_id",
22745
+ "trigger",
22746
+ "boundary_reason",
22747
+ "captured_at",
22748
+ "ended_at",
22749
+ "completed_at",
22750
+ "created_at"
22751
+ ].map(select).join(", ")} FROM summary_jobs`).all();
22752
+ const candidates = new Map;
22753
+ for (const job of jobs) {
22754
+ if (typeof job.transcript !== "string" || job.transcript.trim().length === 0)
22755
+ continue;
22756
+ const agentId = typeof job.agent_id === "string" && job.agent_id.length > 0 ? job.agent_id : "default";
22757
+ 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}`)}`;
22758
+ const key = `${agentId}\x00${sessionKey}`;
22759
+ const current = candidates.get(key);
22760
+ const timestamp = summaryJobTimestamp2(job);
22761
+ const boundary = isCompletionBoundary2(job, summaryColumns);
22762
+ const createdAt = job.captured_at ?? job.created_at ?? job.ended_at ?? timestamp;
22763
+ if (!current) {
22764
+ candidates.set(key, {
22765
+ sessionKey,
22766
+ job: { ...job, agent_id: agentId },
22767
+ content: job.transcript,
22768
+ createdAt,
22769
+ completedAt: boundary ? timestamp : null
22770
+ });
22771
+ continue;
22772
+ }
22773
+ const currentTimestamp = summaryJobTimestamp2(current.job);
22774
+ const preferred = timestamp > currentTimestamp || timestamp === currentTimestamp && job.transcript.length > current.content.length ? { ...job, agent_id: agentId } : current.job;
22775
+ candidates.set(key, {
22776
+ sessionKey,
22777
+ job: preferred,
22778
+ content: mergeTranscriptContent2(current.content, job.transcript),
22779
+ createdAt: current.createdAt < createdAt ? current.createdAt : createdAt,
22780
+ completedAt: laterTimestamp2(current.completedAt, boundary ? timestamp : null)
22781
+ });
22782
+ }
22783
+ const transcriptColumns = tableColumns2(db, "session_transcripts");
22784
+ const hasUpdated = transcriptColumns.has("updated_at");
22785
+ const hasCompleted = transcriptColumns.has("completed_at");
22786
+ const hasHash = transcriptColumns.has("content_hash");
22787
+ const insertColumns = ["session_key", "content", "harness", "project", "agent_id", "created_at"];
22788
+ if (hasUpdated)
22789
+ insertColumns.push("updated_at");
22790
+ if (hasCompleted)
22791
+ insertColumns.push("completed_at");
22792
+ if (hasHash)
22793
+ insertColumns.push("content_hash");
22794
+ const insert = db.prepare(`INSERT OR IGNORE INTO session_transcripts (${insertColumns.join(", ")}) VALUES (${insertColumns.map(() => "?").join(", ")})`);
22795
+ const existing = db.prepare("SELECT content, completed_at FROM session_transcripts WHERE agent_id = ? AND session_key = ?");
22796
+ for (const candidate of candidates.values()) {
22797
+ const job = candidate.job;
22798
+ const agentId = job.agent_id ?? "default";
22799
+ const existingRow = existing.get(agentId, candidate.sessionKey);
22800
+ if (existingRow != null) {
22801
+ const previousContent = typeof existingRow.content === "string" ? existingRow.content : "";
22802
+ const mergedContent = mergeTranscriptContent2(previousContent, candidate.content);
22803
+ const completedAt = typeof existingRow.completed_at === "string" && existingRow.completed_at.length > 0 ? existingRow.completed_at : candidate.completedAt;
22804
+ const assignments = ["content = ?"];
22805
+ const values2 = [mergedContent];
22806
+ if (hasUpdated && mergedContent !== previousContent) {
22807
+ assignments.push("updated_at = ?");
22808
+ values2.push(candidate.createdAt);
22809
+ }
22810
+ if (hasCompleted && completedAt && !existingRow.completed_at) {
22811
+ assignments.push("completed_at = ?");
22812
+ values2.push(completedAt);
22813
+ }
22814
+ if (hasHash) {
22815
+ assignments.push("content_hash = ?");
22816
+ values2.push(hashTranscript2(mergedContent));
22817
+ }
22818
+ values2.push(agentId, candidate.sessionKey);
22819
+ db.prepare(`UPDATE session_transcripts SET ${assignments.join(", ")} WHERE agent_id = ? AND session_key = ?`).run(...values2);
22820
+ continue;
22821
+ }
22822
+ const values = [
22823
+ candidate.sessionKey,
22824
+ candidate.content,
22825
+ job.harness ?? null,
22826
+ job.project ?? null,
22827
+ agentId,
22828
+ candidate.createdAt
22829
+ ];
22830
+ if (hasUpdated)
22831
+ values.push(candidate.createdAt);
22832
+ if (hasCompleted)
22833
+ values.push(candidate.completedAt);
22834
+ if (hasHash)
22835
+ values.push(hashTranscript2(candidate.content));
22836
+ insert.run(...values);
22837
+ }
22838
+ }
22839
+ function up1172(db) {
22840
+ if (!hasTable42(db, "session_transcripts"))
22841
+ return;
22842
+ addColumnIfMissing252(db, "session_transcripts", "completed_at", "TEXT");
22843
+ addColumnIfMissing252(db, "session_transcripts", "content_hash", "TEXT");
22844
+ backfillTranscriptHashes2(db);
22845
+ if (hasTable42(db, "transcript_capture_jobs")) {
22846
+ const captureColumns = db.prepare("PRAGMA table_info(transcript_capture_jobs)").all();
22847
+ if (captureColumns.some((row) => row.name === "summary_status")) {
22848
+ db.exec("UPDATE transcript_capture_jobs SET summary_status = 'not_requested' WHERE summary_status IN ('pending', 'failed', 'skipped')");
22849
+ }
22850
+ }
22851
+ if (hasTable42(db, "summary_jobs")) {
22852
+ backfillTranscriptsFromSummaryJobs2(db);
22853
+ backfillTranscriptHashes2(db);
22854
+ const summaryColumns = tableColumns2(db, "summary_jobs");
22855
+ const timestampParts = ["completed_at", "ended_at", "captured_at", "created_at"].filter((column) => summaryColumns.has(column)).map((column) => `sj.${column}`);
22856
+ const timestampValue = timestampParts.length === 1 ? timestampParts[0] : `COALESCE(${timestampParts.join(", ")})`;
22857
+ const completionTimestamp = timestampValue ? `MAX(${timestampValue})` : "NULL";
22858
+ const boundaryParts = [
22859
+ summaryColumns.has("trigger") ? "sj.trigger = 'session_end'" : null,
22860
+ summaryColumns.has("boundary_reason") ? "sj.boundary_reason IN ('session_closed', 'session_clear', 'stale_session', 'ttl_expired')" : null
22861
+ ].filter((part) => part !== null);
22862
+ const boundaryPredicate = boundaryParts.length > 0 ? `(${boundaryParts.join(" OR ")})` : "1=1";
22863
+ const agentPredicate = summaryColumns.has("agent_id") ? "sj.agent_id = session_transcripts.agent_id" : "session_transcripts.agent_id = 'default'";
22864
+ if (completionTimestamp !== "NULL") {
22865
+ db.exec(`
22866
+ UPDATE session_transcripts
22867
+ SET completed_at = COALESCE(
22868
+ completed_at,
22869
+ (
22870
+ SELECT ${completionTimestamp}
22871
+ FROM summary_jobs AS sj
22872
+ WHERE ${agentPredicate}
22873
+ AND sj.session_key = session_transcripts.session_key
22874
+ AND ${boundaryPredicate}
22875
+ )
22876
+ )
22877
+ WHERE completed_at IS NULL;
22878
+ `);
22879
+ }
22880
+ db.exec("DELETE FROM summary_jobs");
22881
+ }
22882
+ const completionIndexColumns = ["agent_id", "completed_at"];
22883
+ if (tableColumns2(db, "session_transcripts").has("updated_at"))
22884
+ completionIndexColumns.push("updated_at");
22885
+ db.exec(`
22886
+ CREATE INDEX IF NOT EXISTS idx_st_agent_completed
22887
+ ON session_transcripts(${completionIndexColumns.join(", ")});
22888
+ CREATE INDEX IF NOT EXISTS idx_st_agent_hash
22889
+ ON session_transcripts(agent_id, content_hash);
22890
+ `);
22891
+ }
22443
22892
  var MIGRATIONS2 = [
22444
22893
  {
22445
22894
  version: 1,
22446
22895
  name: "baseline",
22447
- up: up117,
22896
+ up: up118,
22448
22897
  artifacts: { tables: ["memories", "conversations", "embeddings"] }
22449
22898
  },
22450
22899
  {
@@ -22510,7 +22959,7 @@ var MIGRATIONS2 = [
22510
22959
  {
22511
22960
  version: 11,
22512
22961
  name: "session-scores",
22513
- up: up118,
22962
+ up: up119,
22514
22963
  artifacts: { tables: ["session_scores"] }
22515
22964
  },
22516
22965
  {
@@ -23379,6 +23828,17 @@ var MIGRATIONS2 = [
23379
23828
  { table: "cross_agent_messages", column: "acp_target_agent_name" }
23380
23829
  ]
23381
23830
  }
23831
+ },
23832
+ {
23833
+ version: 117,
23834
+ name: "retire-summary-worker",
23835
+ up: up1172,
23836
+ artifacts: {
23837
+ columns: [
23838
+ { table: "session_transcripts", column: "completed_at" },
23839
+ { table: "session_transcripts", column: "content_hash" }
23840
+ ]
23841
+ }
23382
23842
  }
23383
23843
  ];
23384
23844
  var LATEST_SCHEMA_VERSION2 = MIGRATIONS2[MIGRATIONS2.length - 1]?.version ?? 0;
@@ -24001,7 +24461,7 @@ function codexHookHash(eventName, handler) {
24001
24461
  }
24002
24462
  ]
24003
24463
  };
24004
- return `sha256:${createHash("sha256").update(JSON.stringify(canonicalJson(identity))).digest("hex")}`;
24464
+ return `sha256:${createHash3("sha256").update(JSON.stringify(canonicalJson(identity))).digest("hex")}`;
24005
24465
  }
24006
24466
  function buildHookTrustEntries(hooksPath, file) {
24007
24467
  const entries = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signetai/connector-codex",
3
- "version": "0.185.4",
3
+ "version": "0.185.5",
4
4
  "description": "Signet connector for Codex 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",