@cleocode/core 2026.3.39 → 2026.3.41

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/index.js CHANGED
@@ -1774,7 +1774,7 @@ var init_sql = __esm({
1774
1774
  return new SQL([new StringChunk(str)]);
1775
1775
  }
1776
1776
  _sql.raw = raw;
1777
- function join105(chunks, separator) {
1777
+ function join103(chunks, separator) {
1778
1778
  const result = [];
1779
1779
  for (const [i, chunk] of chunks.entries()) {
1780
1780
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -1782,7 +1782,7 @@ var init_sql = __esm({
1782
1782
  }
1783
1783
  return new SQL(result);
1784
1784
  }
1785
- _sql.join = join105;
1785
+ _sql.join = join103;
1786
1786
  function identifier(value) {
1787
1787
  return new Name(value);
1788
1788
  }
@@ -6469,7 +6469,7 @@ var init_select2 = __esm({
6469
6469
  const baseTableName = this.tableName;
6470
6470
  const tableName = getTableLikeName(table);
6471
6471
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
6472
- if (typeof tableName === "string" && this.config.joins?.some((join105) => join105.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6472
+ if (typeof tableName === "string" && this.config.joins?.some((join103) => join103.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
6473
6473
  if (!this.isPartialSelect) {
6474
6474
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
6475
6475
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -7754,7 +7754,7 @@ var init_dialect = __esm({
7754
7754
  if (!joins2) return;
7755
7755
  const withEntries = Object.entries(joins2).filter(([_, v]) => v);
7756
7756
  if (!withEntries.length) return;
7757
- return sql.join(withEntries.map(([k, join105]) => {
7757
+ return sql.join(withEntries.map(([k, join103]) => {
7758
7758
  const relation = tableConfig.relations[k];
7759
7759
  const isSingle2 = is(relation, One3);
7760
7760
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -7765,7 +7765,7 @@ var init_dialect = __esm({
7765
7765
  table: targetTable,
7766
7766
  mode: isSingle2 ? "first" : "many",
7767
7767
  schema,
7768
- queryConfig: join105,
7768
+ queryConfig: join103,
7769
7769
  tableConfig: schema[relation.targetTableName],
7770
7770
  relationWhere: filter,
7771
7771
  isNested: true,
@@ -7779,7 +7779,7 @@ var init_dialect = __esm({
7779
7779
  key: k,
7780
7780
  selection: innerQuery.selection,
7781
7781
  isArray: !isSingle2,
7782
- isOptional: (relation.optional ?? false) || join105 !== true && !!join105.where
7782
+ isOptional: (relation.optional ?? false) || join103 !== true && !!join103.where
7783
7783
  });
7784
7784
  const jsonColumns = sql.join(innerQuery.selection.map((s) => {
7785
7785
  return sql`${sql.raw(this.escapeString(s.key))}, ${s.selection ? sql`${jsonb2}(${sql.identifier(s.key)})` : sql.identifier(s.key)}`;
@@ -8178,7 +8178,7 @@ var init_update = __esm({
8178
8178
  createJoin(joinType) {
8179
8179
  return ((table, on) => {
8180
8180
  const tableName = getTableLikeName(table);
8181
- if (typeof tableName === "string" && this.config.joins.some((join105) => join105.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8181
+ if (typeof tableName === "string" && this.config.joins.some((join103) => join103.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
8182
8182
  if (typeof on === "function") {
8183
8183
  const from = this.config.from ? is(table, SQLiteTable) ? table[Table.Symbol.Columns] : is(table, Subquery) ? table._.selectedFields : is(table, SQLiteViewBase) ? table[ViewBaseConfig].selectedFields : void 0 : void 0;
8184
8184
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -8884,6 +8884,7 @@ __export(tasks_schema_exports, {
8884
8884
  adrTaskLinks: () => adrTaskLinks,
8885
8885
  architectureDecisions: () => architectureDecisions,
8886
8886
  auditLog: () => auditLog,
8887
+ externalTaskLinks: () => externalTaskLinks,
8887
8888
  isValidStatus: () => isValidStatus,
8888
8889
  lifecycleEvidence: () => lifecycleEvidence,
8889
8890
  lifecycleGateResults: () => lifecycleGateResults,
@@ -8905,7 +8906,7 @@ __export(tasks_schema_exports, {
8905
8906
  warpChains: () => warpChains
8906
8907
  });
8907
8908
  import { sql as sql3 } from "drizzle-orm";
8908
- var TASK_PRIORITIES, TASK_TYPES, TASK_SIZES, LIFECYCLE_STAGE_NAMES, LIFECYCLE_GATE_RESULTS, LIFECYCLE_EVIDENCE_TYPES, TOKEN_USAGE_METHODS, TOKEN_USAGE_CONFIDENCE, TOKEN_USAGE_TRANSPORTS, tasks, taskDependencies, taskRelations, sessions, taskWorkHistory, lifecyclePipelines, lifecycleStages, lifecycleGateResults, lifecycleEvidence, lifecycleTransitions, manifestEntries, pipelineManifest, releaseManifests, schemaMeta, auditLog, tokenUsage, architectureDecisions, adrTaskLinks, adrRelations, statusRegistryTable;
8909
+ var TASK_PRIORITIES, TASK_TYPES, TASK_SIZES, LIFECYCLE_STAGE_NAMES, LIFECYCLE_GATE_RESULTS, LIFECYCLE_EVIDENCE_TYPES, TOKEN_USAGE_METHODS, TOKEN_USAGE_CONFIDENCE, TOKEN_USAGE_TRANSPORTS, tasks, taskDependencies, taskRelations, sessions, taskWorkHistory, lifecyclePipelines, lifecycleStages, lifecycleGateResults, lifecycleEvidence, lifecycleTransitions, manifestEntries, pipelineManifest, releaseManifests, schemaMeta, auditLog, tokenUsage, architectureDecisions, adrTaskLinks, adrRelations, externalTaskLinks, statusRegistryTable;
8909
8910
  var init_tasks_schema = __esm({
8910
8911
  "packages/core/src/store/tasks-schema.ts"() {
8911
8912
  "use strict";
@@ -9360,6 +9361,40 @@ var init_tasks_schema = __esm({
9360
9361
  },
9361
9362
  (table) => [primaryKey({ columns: [table.fromAdrId, table.toAdrId, table.relationType] })]
9362
9363
  );
9364
+ externalTaskLinks = sqliteTable(
9365
+ "external_task_links",
9366
+ {
9367
+ id: text("id").primaryKey(),
9368
+ taskId: text("task_id").notNull().references(() => tasks.id, { onDelete: "cascade" }),
9369
+ /** Provider identifier (e.g. 'linear', 'jira', 'github', 'gitlab'). */
9370
+ providerId: text("provider_id").notNull(),
9371
+ /** Provider-assigned identifier for the external task (opaque to CLEO). */
9372
+ externalId: text("external_id").notNull(),
9373
+ /** Optional URL to the external task (for human navigation). */
9374
+ externalUrl: text("external_url"),
9375
+ /** Title of the external task at the time of last sync. */
9376
+ externalTitle: text("external_title"),
9377
+ /** How this link was established. */
9378
+ linkType: text("link_type", {
9379
+ enum: ["created", "matched", "manual"]
9380
+ }).notNull(),
9381
+ /** Direction of the sync that created this link. */
9382
+ syncDirection: text("sync_direction", {
9383
+ enum: ["inbound", "outbound", "bidirectional"]
9384
+ }).notNull().default("inbound"),
9385
+ /** Arbitrary provider-specific metadata (JSON). */
9386
+ metadataJson: text("metadata_json").default("{}"),
9387
+ /** When the link was first established. */
9388
+ linkedAt: text("linked_at").notNull().default(sql3`(datetime('now'))`),
9389
+ /** When the external task was last synchronized. */
9390
+ lastSyncAt: text("last_sync_at")
9391
+ },
9392
+ (table) => [
9393
+ index("idx_ext_links_task_id").on(table.taskId),
9394
+ index("idx_ext_links_provider_external").on(table.providerId, table.externalId),
9395
+ index("idx_ext_links_provider_id").on(table.providerId)
9396
+ ]
9397
+ );
9363
9398
  statusRegistryTable = sqliteTable(
9364
9399
  "status_registry",
9365
9400
  {
@@ -12860,9 +12895,9 @@ async function readSequenceFromDb(cwd, accessor) {
12860
12895
  return isValidSequenceState(value) ? value : null;
12861
12896
  }
12862
12897
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
12863
- const { eq: eq7 } = await import("drizzle-orm");
12898
+ const { eq: eq8 } = await import("drizzle-orm");
12864
12899
  const db = await getDb3(cwd);
12865
- const rows = await db.select().from(schemaMeta).where(eq7(schemaMeta.key, SEQUENCE_META_KEY)).all();
12900
+ const rows = await db.select().from(schemaMeta).where(eq8(schemaMeta.key, SEQUENCE_META_KEY)).all();
12866
12901
  const raw = rows[0]?.value;
12867
12902
  if (!raw) return null;
12868
12903
  try {
@@ -14298,8 +14333,8 @@ function analyzeArchitecture(projectRoot, _projectContext) {
14298
14333
  for (const entry of entries) {
14299
14334
  const entryPath = join22(srcPath, entry);
14300
14335
  try {
14301
- const stat3 = statSync2(entryPath);
14302
- if (stat3.isDirectory()) {
14336
+ const stat2 = statSync2(entryPath);
14337
+ if (stat2.isDirectory()) {
14303
14338
  const purpose = LAYER_PURPOSE[entry.toLowerCase()] ?? `${entry} layer`;
14304
14339
  layers.push({ name: entry, path: `src/${entry}`, purpose });
14305
14340
  } else if (ENTRY_POINT_NAMES.has(entry)) {
@@ -14420,8 +14455,8 @@ function analyzeStructure(projectRoot) {
14420
14455
  if (EXCLUDED_DIRS.has(entry) || entry.startsWith(".")) continue;
14421
14456
  const entryPath = join23(projectRoot, entry);
14422
14457
  try {
14423
- const stat3 = statSync3(entryPath);
14424
- if (stat3.isDirectory()) {
14458
+ const stat2 = statSync3(entryPath);
14459
+ if (stat2.isDirectory()) {
14425
14460
  const fileCount = countFiles(entryPath);
14426
14461
  totalFiles += fileCount;
14427
14462
  const purpose = DIR_PURPOSE[entry.toLowerCase()] ?? "Project directory";
@@ -14464,8 +14499,8 @@ function countFiles(dir, depth = 0) {
14464
14499
  if (EXCLUDED_DIRS.has(entry) || entry.startsWith(".")) continue;
14465
14500
  const entryPath = join23(dir, entry);
14466
14501
  try {
14467
- const stat3 = statSync3(entryPath);
14468
- if (stat3.isDirectory()) {
14502
+ const stat2 = statSync3(entryPath);
14503
+ if (stat2.isDirectory()) {
14469
14504
  count2 += countFiles(entryPath, depth + 1);
14470
14505
  } else {
14471
14506
  count2++;
@@ -14905,8 +14940,8 @@ function walkSourceFiles(dir, projectRoot, callback, depth = 0) {
14905
14940
  if (EXCLUDED_DIRS2.has(entry) || entry.startsWith(".")) continue;
14906
14941
  const fullPath = join27(dir, entry);
14907
14942
  try {
14908
- const stat3 = statSync5(fullPath);
14909
- if (stat3.isDirectory()) {
14943
+ const stat2 = statSync5(fullPath);
14944
+ if (stat2.isDirectory()) {
14910
14945
  walkSourceFiles(fullPath, projectRoot, callback, depth + 1);
14911
14946
  } else {
14912
14947
  const ext = entry.slice(entry.lastIndexOf("."));
@@ -17148,19 +17183,19 @@ async function queryAudit(options) {
17148
17183
  try {
17149
17184
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
17150
17185
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
17151
- const { and: and5, eq: eq7, gte: gte3, or: or4 } = await import("drizzle-orm");
17186
+ const { and: and6, eq: eq8, gte: gte3, or: or4 } = await import("drizzle-orm");
17152
17187
  const db = await getDb3(process.cwd());
17153
17188
  const conditions = [];
17154
- if (options?.sessionId) conditions.push(eq7(auditLog2.sessionId, options.sessionId));
17155
- if (options?.domain) conditions.push(eq7(auditLog2.domain, options.domain));
17189
+ if (options?.sessionId) conditions.push(eq8(auditLog2.sessionId, options.sessionId));
17190
+ if (options?.domain) conditions.push(eq8(auditLog2.domain, options.domain));
17156
17191
  if (options?.operation)
17157
17192
  conditions.push(
17158
- or4(eq7(auditLog2.operation, options.operation), eq7(auditLog2.action, options.operation))
17193
+ or4(eq8(auditLog2.operation, options.operation), eq8(auditLog2.action, options.operation))
17159
17194
  );
17160
- if (options?.taskId) conditions.push(eq7(auditLog2.taskId, options.taskId));
17195
+ if (options?.taskId) conditions.push(eq8(auditLog2.taskId, options.taskId));
17161
17196
  if (options?.since) conditions.push(gte3(auditLog2.timestamp, options.since));
17162
17197
  const limit = options?.limit ?? 1e3;
17163
- const rows = await db.select().from(auditLog2).where(conditions.length > 0 ? and5(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
17198
+ const rows = await db.select().from(auditLog2).where(conditions.length > 0 ? and6(...conditions) : void 0).orderBy(auditLog2.timestamp).limit(limit);
17164
17199
  return rows.map((row) => ({
17165
17200
  timestamp: row.timestamp,
17166
17201
  sessionId: row.sessionId,
@@ -17966,8 +18001,8 @@ async function cleanProjectSchemas(projectRoot) {
17966
18001
  return { cleaned: false };
17967
18002
  }
17968
18003
  try {
17969
- const stat3 = statSync7(projectSchemasDir);
17970
- if (!stat3.isDirectory()) {
18004
+ const stat2 = statSync7(projectSchemasDir);
18005
+ if (!stat2.isDirectory()) {
17971
18006
  return { cleaned: false };
17972
18007
  }
17973
18008
  } catch {
@@ -19013,8 +19048,8 @@ function checkSqliteDb(projectRoot) {
19013
19048
  fix: "cleo init"
19014
19049
  };
19015
19050
  }
19016
- const stat3 = statSync8(dbPath);
19017
- if (stat3.size === 0) {
19051
+ const stat2 = statSync8(dbPath);
19052
+ if (stat2.size === 0) {
19018
19053
  return {
19019
19054
  id: "sqlite_db",
19020
19055
  category: "scaffold",
@@ -19028,8 +19063,8 @@ function checkSqliteDb(projectRoot) {
19028
19063
  id: "sqlite_db",
19029
19064
  category: "scaffold",
19030
19065
  status: "passed",
19031
- message: `tasks.db exists (${stat3.size} bytes)`,
19032
- details: { path: dbPath, exists: true, size: stat3.size },
19066
+ message: `tasks.db exists (${stat2.size} bytes)`,
19067
+ details: { path: dbPath, exists: true, size: stat2.size },
19033
19068
  fix: null
19034
19069
  };
19035
19070
  }
@@ -19081,8 +19116,8 @@ function checkBrainDb(projectRoot) {
19081
19116
  fix: "cleo init"
19082
19117
  };
19083
19118
  }
19084
- const stat3 = statSync8(dbPath);
19085
- if (stat3.size === 0) {
19119
+ const stat2 = statSync8(dbPath);
19120
+ if (stat2.size === 0) {
19086
19121
  return {
19087
19122
  id: "brain_db",
19088
19123
  category: "scaffold",
@@ -19096,8 +19131,8 @@ function checkBrainDb(projectRoot) {
19096
19131
  id: "brain_db",
19097
19132
  category: "scaffold",
19098
19133
  status: "passed",
19099
- message: `brain.db exists (${stat3.size} bytes)`,
19100
- details: { path: dbPath, exists: true, size: stat3.size },
19134
+ message: `brain.db exists (${stat2.size} bytes)`,
19135
+ details: { path: dbPath, exists: true, size: stat2.size },
19101
19136
  fix: null
19102
19137
  };
19103
19138
  }
@@ -19348,8 +19383,8 @@ function detectEnvMode() {
19348
19383
  const devKv = {};
19349
19384
  const devLines = devContent.trim().split("\n");
19350
19385
  for (let i = 1; i < devLines.length; i++) {
19351
- const eq7 = devLines[i].indexOf("=");
19352
- if (eq7 > 0) devKv[devLines[i].slice(0, eq7).trim()] = devLines[i].slice(eq7 + 1).trim();
19386
+ const eq8 = devLines[i].indexOf("=");
19387
+ if (eq8 > 0) devKv[devLines[i].slice(0, eq8).trim()] = devLines[i].slice(eq8 + 1).trim();
19353
19388
  }
19354
19389
  if (devKv["mode"] === "dev-ts" && devKv["source"]) {
19355
19390
  const devSource = devKv["source"].replace(/\\/g, "/");
@@ -20588,9 +20623,9 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
20588
20623
  const projectHash = generateProjectHash(projectPath);
20589
20624
  await nexusInit();
20590
20625
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20591
- const { eq: eq7 } = await import("drizzle-orm");
20626
+ const { eq: eq8 } = await import("drizzle-orm");
20592
20627
  const db = await getNexusDb2();
20593
- const existingRows = await db.select().from(projectRegistry).where(eq7(projectRegistry.projectHash, projectHash));
20628
+ const existingRows = await db.select().from(projectRegistry).where(eq8(projectRegistry.projectHash, projectHash));
20594
20629
  const existing = existingRows[0];
20595
20630
  if (existing?.permissions) {
20596
20631
  throw new CleoError(
@@ -20599,7 +20634,7 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
20599
20634
  );
20600
20635
  }
20601
20636
  if (!existing) {
20602
- const nameConflictRows = await db.select().from(projectRegistry).where(eq7(projectRegistry.name, projectName));
20637
+ const nameConflictRows = await db.select().from(projectRegistry).where(eq8(projectRegistry.name, projectName));
20603
20638
  if (nameConflictRows.length > 0) {
20604
20639
  throw new CleoError(
20605
20640
  6 /* VALIDATION_ERROR */,
@@ -20617,7 +20652,7 @@ async function nexusRegister(projectPath, name2, permissions = "read") {
20617
20652
  taskCount: meta.taskCount,
20618
20653
  labelsJson: JSON.stringify(meta.labels),
20619
20654
  lastSeen: now
20620
- }).where(eq7(projectRegistry.projectHash, projectHash));
20655
+ }).where(eq8(projectRegistry.projectHash, projectHash));
20621
20656
  } else {
20622
20657
  if (!projectId) {
20623
20658
  projectId = randomUUID3();
@@ -20655,9 +20690,9 @@ async function nexusUnregister(nameOrHash) {
20655
20690
  throw new CleoError(4 /* NOT_FOUND */, `Project not found in registry: ${nameOrHash}`);
20656
20691
  }
20657
20692
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20658
- const { eq: eq7 } = await import("drizzle-orm");
20693
+ const { eq: eq8 } = await import("drizzle-orm");
20659
20694
  const db = await getNexusDb2();
20660
- await db.delete(projectRegistry).where(eq7(projectRegistry.projectHash, project.hash));
20695
+ await db.delete(projectRegistry).where(eq8(projectRegistry.projectHash, project.hash));
20661
20696
  await writeNexusAudit({
20662
20697
  action: "unregister",
20663
20698
  projectHash: project.hash,
@@ -20679,9 +20714,9 @@ async function nexusList() {
20679
20714
  async function nexusGetProject(nameOrHash) {
20680
20715
  try {
20681
20716
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20682
- const { eq: eq7, or: or4 } = await import("drizzle-orm");
20717
+ const { eq: eq8, or: or4 } = await import("drizzle-orm");
20683
20718
  const db = await getNexusDb2();
20684
- const rows = await db.select().from(projectRegistry).where(or4(eq7(projectRegistry.projectHash, nameOrHash), eq7(projectRegistry.name, nameOrHash)));
20719
+ const rows = await db.select().from(projectRegistry).where(or4(eq8(projectRegistry.projectHash, nameOrHash), eq8(projectRegistry.name, nameOrHash)));
20685
20720
  const row = rows[0];
20686
20721
  if (!row) return null;
20687
20722
  return rowToProject(row);
@@ -20704,14 +20739,14 @@ async function nexusSync(nameOrHash) {
20704
20739
  const meta = await readProjectMeta(project.path);
20705
20740
  const now = (/* @__PURE__ */ new Date()).toISOString();
20706
20741
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20707
- const { eq: eq7 } = await import("drizzle-orm");
20742
+ const { eq: eq8 } = await import("drizzle-orm");
20708
20743
  const db = await getNexusDb2();
20709
20744
  await db.update(projectRegistry).set({
20710
20745
  taskCount: meta.taskCount,
20711
20746
  labelsJson: JSON.stringify(meta.labels),
20712
20747
  lastSync: now,
20713
20748
  lastSeen: now
20714
- }).where(eq7(projectRegistry.projectHash, project.hash));
20749
+ }).where(eq8(projectRegistry.projectHash, project.hash));
20715
20750
  await writeNexusAudit({
20716
20751
  action: "sync",
20717
20752
  projectHash: project.hash,
@@ -20725,7 +20760,7 @@ async function nexusSyncAll() {
20725
20760
  let synced = 0;
20726
20761
  let failed = 0;
20727
20762
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20728
- const { eq: eq7 } = await import("drizzle-orm");
20763
+ const { eq: eq8 } = await import("drizzle-orm");
20729
20764
  const db = await getNexusDb2();
20730
20765
  for (const project of projects) {
20731
20766
  try {
@@ -20736,7 +20771,7 @@ async function nexusSyncAll() {
20736
20771
  labelsJson: JSON.stringify(meta.labels),
20737
20772
  lastSync: now,
20738
20773
  lastSeen: now
20739
- }).where(eq7(projectRegistry.projectHash, project.hash));
20774
+ }).where(eq8(projectRegistry.projectHash, project.hash));
20740
20775
  synced++;
20741
20776
  } catch {
20742
20777
  failed++;
@@ -20756,9 +20791,9 @@ async function nexusSetPermission(nameOrHash, permission) {
20756
20791
  throw new CleoError(4 /* NOT_FOUND */, `Project not found in registry: ${nameOrHash}`);
20757
20792
  }
20758
20793
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20759
- const { eq: eq7 } = await import("drizzle-orm");
20794
+ const { eq: eq8 } = await import("drizzle-orm");
20760
20795
  const db = await getNexusDb2();
20761
- await db.update(projectRegistry).set({ permissions: permission }).where(eq7(projectRegistry.projectHash, project.hash));
20796
+ await db.update(projectRegistry).set({ permissions: permission }).where(eq8(projectRegistry.projectHash, project.hash));
20762
20797
  await writeNexusAudit({
20763
20798
  action: "set-permission",
20764
20799
  projectHash: project.hash,
@@ -20774,12 +20809,12 @@ async function nexusReconcile(projectRoot) {
20774
20809
  }
20775
20810
  await nexusInit();
20776
20811
  const { getNexusDb: getNexusDb2 } = await Promise.resolve().then(() => (init_nexus_sqlite(), nexus_sqlite_exports));
20777
- const { eq: eq7 } = await import("drizzle-orm");
20812
+ const { eq: eq8 } = await import("drizzle-orm");
20778
20813
  const db = await getNexusDb2();
20779
20814
  const projectId = await readProjectId(projectRoot);
20780
20815
  const currentHash = generateProjectHash(projectRoot);
20781
20816
  if (projectId) {
20782
- const hashRows2 = await db.select().from(projectRegistry).where(eq7(projectRegistry.projectHash, currentHash));
20817
+ const hashRows2 = await db.select().from(projectRegistry).where(eq8(projectRegistry.projectHash, currentHash));
20783
20818
  const hashMatch2 = hashRows2[0];
20784
20819
  if (hashMatch2 && hashMatch2.projectId !== projectId) {
20785
20820
  await writeNexusAudit({
@@ -20798,12 +20833,12 @@ async function nexusReconcile(projectRoot) {
20798
20833
  }
20799
20834
  }
20800
20835
  if (projectId) {
20801
- const idRows = await db.select().from(projectRegistry).where(eq7(projectRegistry.projectId, projectId));
20836
+ const idRows = await db.select().from(projectRegistry).where(eq8(projectRegistry.projectId, projectId));
20802
20837
  const existing = idRows[0];
20803
20838
  if (existing) {
20804
20839
  const now = (/* @__PURE__ */ new Date()).toISOString();
20805
20840
  if (existing.projectPath === projectRoot) {
20806
- await db.update(projectRegistry).set({ lastSeen: now }).where(eq7(projectRegistry.projectId, projectId));
20841
+ await db.update(projectRegistry).set({ lastSeen: now }).where(eq8(projectRegistry.projectId, projectId));
20807
20842
  await writeNexusAudit({
20808
20843
  action: "reconcile",
20809
20844
  projectHash: currentHash,
@@ -20819,7 +20854,7 @@ async function nexusReconcile(projectRoot) {
20819
20854
  projectPath: projectRoot,
20820
20855
  projectHash: currentHash,
20821
20856
  lastSeen: now
20822
- }).where(eq7(projectRegistry.projectId, projectId));
20857
+ }).where(eq8(projectRegistry.projectId, projectId));
20823
20858
  await writeNexusAudit({
20824
20859
  action: "reconcile",
20825
20860
  projectHash: currentHash,
@@ -20831,11 +20866,11 @@ async function nexusReconcile(projectRoot) {
20831
20866
  return { status: "path_updated", oldPath, newPath: projectRoot };
20832
20867
  }
20833
20868
  }
20834
- const hashRows = await db.select().from(projectRegistry).where(eq7(projectRegistry.projectHash, currentHash));
20869
+ const hashRows = await db.select().from(projectRegistry).where(eq8(projectRegistry.projectHash, currentHash));
20835
20870
  const hashMatch = hashRows[0];
20836
20871
  if (hashMatch) {
20837
20872
  const now = (/* @__PURE__ */ new Date()).toISOString();
20838
- await db.update(projectRegistry).set({ lastSeen: now }).where(eq7(projectRegistry.projectHash, currentHash));
20873
+ await db.update(projectRegistry).set({ lastSeen: now }).where(eq8(projectRegistry.projectHash, currentHash));
20839
20874
  await writeNexusAudit({
20840
20875
  action: "reconcile",
20841
20876
  projectHash: currentHash,
@@ -21437,7 +21472,7 @@ var init_update2 = __esm({
21437
21472
  // packages/core/src/sessions/assumptions.ts
21438
21473
  import { randomBytes as randomBytes5 } from "node:crypto";
21439
21474
  import { appendFileSync as appendFileSync7, existsSync as existsSync63, mkdirSync as mkdirSync13 } from "node:fs";
21440
- import { join as join68 } from "node:path";
21475
+ import { join as join67 } from "node:path";
21441
21476
  async function recordAssumption(projectRoot, params) {
21442
21477
  if (!params?.assumption) {
21443
21478
  throw new CleoError(2 /* INVALID_INPUT */, "assumption is required");
@@ -21459,11 +21494,11 @@ async function recordAssumption(projectRoot, params) {
21459
21494
  validatedAt: null,
21460
21495
  timestamp: now
21461
21496
  };
21462
- const auditDir = join68(projectRoot, ".cleo", "audit");
21497
+ const auditDir = join67(projectRoot, ".cleo", "audit");
21463
21498
  if (!existsSync63(auditDir)) {
21464
21499
  mkdirSync13(auditDir, { recursive: true });
21465
21500
  }
21466
- const assumptionsPath = join68(auditDir, "assumptions.jsonl");
21501
+ const assumptionsPath = join67(auditDir, "assumptions.jsonl");
21467
21502
  appendFileSync7(assumptionsPath, JSON.stringify(record) + "\n", "utf-8");
21468
21503
  return {
21469
21504
  id,
@@ -22915,11 +22950,11 @@ var init_sessions = __esm({
22915
22950
 
22916
22951
  // packages/core/src/hooks.ts
22917
22952
  import { existsSync as existsSync83 } from "node:fs";
22918
- import { chmod, copyFile as copyFile2, mkdir as mkdir15, readFile as readFile14 } from "node:fs/promises";
22919
- import { join as join87 } from "node:path";
22953
+ import { chmod, copyFile as copyFile2, mkdir as mkdir14, readFile as readFile14 } from "node:fs/promises";
22954
+ import { join as join86 } from "node:path";
22920
22955
  async function ensureGitHooks(projectRoot, opts) {
22921
- const gitDir = join87(projectRoot, ".git");
22922
- const gitHooksDir = join87(gitDir, "hooks");
22956
+ const gitDir = join86(projectRoot, ".git");
22957
+ const gitHooksDir = join86(gitDir, "hooks");
22923
22958
  if (!existsSync83(gitDir)) {
22924
22959
  return {
22925
22960
  action: "skipped",
@@ -22928,7 +22963,7 @@ async function ensureGitHooks(projectRoot, opts) {
22928
22963
  };
22929
22964
  }
22930
22965
  const packageRoot = getPackageRoot();
22931
- const sourceDir = join87(packageRoot, "templates", "git-hooks");
22966
+ const sourceDir = join86(packageRoot, "templates", "git-hooks");
22932
22967
  if (!existsSync83(sourceDir)) {
22933
22968
  return {
22934
22969
  action: "skipped",
@@ -22936,13 +22971,13 @@ async function ensureGitHooks(projectRoot, opts) {
22936
22971
  details: "templates/git-hooks/ not found in package root, skipping git hook installation"
22937
22972
  };
22938
22973
  }
22939
- await mkdir15(gitHooksDir, { recursive: true });
22974
+ await mkdir14(gitHooksDir, { recursive: true });
22940
22975
  const force = opts?.force ?? false;
22941
22976
  let installedCount = 0;
22942
22977
  const errors = [];
22943
22978
  for (const hook of MANAGED_HOOKS) {
22944
- const sourcePath = join87(sourceDir, hook);
22945
- const destPath = join87(gitHooksDir, hook);
22979
+ const sourcePath = join86(sourceDir, hook);
22980
+ const destPath = join86(gitHooksDir, hook);
22946
22981
  if (!existsSync83(sourcePath)) {
22947
22982
  continue;
22948
22983
  }
@@ -22980,13 +23015,13 @@ async function ensureGitHooks(projectRoot, opts) {
22980
23015
  };
22981
23016
  }
22982
23017
  async function checkGitHooks(projectRoot) {
22983
- const gitHooksDir = join87(projectRoot, ".git", "hooks");
23018
+ const gitHooksDir = join86(projectRoot, ".git", "hooks");
22984
23019
  const packageRoot = getPackageRoot();
22985
- const sourceDir = join87(packageRoot, "templates", "git-hooks");
23020
+ const sourceDir = join86(packageRoot, "templates", "git-hooks");
22986
23021
  const results = [];
22987
23022
  for (const hook of MANAGED_HOOKS) {
22988
- const sourcePath = join87(sourceDir, hook);
22989
- const installedPath = join87(gitHooksDir, hook);
23023
+ const sourcePath = join86(sourceDir, hook);
23024
+ const installedPath = join86(gitHooksDir, hook);
22990
23025
  const result = {
22991
23026
  hook,
22992
23027
  installed: false,
@@ -23069,14 +23104,6 @@ function taskToMarkdown(task) {
23069
23104
  const priority = task.priority === "critical" ? "!!!" : task.priority === "high" ? "!!" : "";
23070
23105
  return `- [${status}] **${task.id}** ${priority} ${task.title}`;
23071
23106
  }
23072
- function taskToTodoWrite(task) {
23073
- return {
23074
- id: task.id,
23075
- content: task.title,
23076
- status: task.status === "done" ? "completed" : task.status === "active" ? "in_progress" : "pending",
23077
- priority: task.priority === "critical" ? "high" : task.priority
23078
- };
23079
- }
23080
23107
  async function exportTasks(params) {
23081
23108
  const accessor = await getAccessor(params.cwd);
23082
23109
  const queryResult = await accessor.queryTasks({});
@@ -23140,13 +23167,8 @@ async function exportTasks(params) {
23140
23167
  content = lines.join("\n");
23141
23168
  break;
23142
23169
  }
23143
- case "todowrite": {
23144
- const items = tasks2.map(taskToTodoWrite);
23145
- content = JSON.stringify(items, null, 2);
23146
- break;
23147
- }
23148
23170
  default:
23149
- throw new Error(`Unknown format: ${format}. Valid: json, csv, tsv, markdown, todowrite`);
23171
+ throw new Error(`Unknown format: ${format}. Valid: json, csv, tsv, markdown`);
23150
23172
  }
23151
23173
  if (params.output) {
23152
23174
  await writeFile2(params.output, content);
@@ -23969,7 +23991,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
23969
23991
  return result;
23970
23992
  }
23971
23993
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
23972
- const { and: and5, eq: eq7 } = await import("drizzle-orm");
23994
+ const { and: and6, eq: eq8 } = await import("drizzle-orm");
23973
23995
  const db = await getDb3(projectRoot);
23974
23996
  const now = (/* @__PURE__ */ new Date()).toISOString();
23975
23997
  for (const filePath of matchingFiles) {
@@ -23979,7 +24001,7 @@ async function linkPipelineAdr(projectRoot, taskId) {
23979
24001
  const fm = record.frontmatter;
23980
24002
  const content = readFileSync5(filePath, "utf-8");
23981
24003
  const relativePath = `.cleo/adrs/${filename}`;
23982
- const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq7(architectureDecisions.id, record.id)).all();
24004
+ const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq8(architectureDecisions.id, record.id)).all();
23983
24005
  const rowBase = {
23984
24006
  id: record.id,
23985
24007
  title: record.title,
@@ -23999,19 +24021,19 @@ async function linkPipelineAdr(projectRoot, taskId) {
23999
24021
  updatedAt: now
24000
24022
  };
24001
24023
  if (existing.length > 0) {
24002
- await db.update(architectureDecisions).set(rowBase).where(eq7(architectureDecisions.id, record.id));
24024
+ await db.update(architectureDecisions).set(rowBase).where(eq8(architectureDecisions.id, record.id));
24003
24025
  } else {
24004
24026
  await db.insert(architectureDecisions).values({ ...rowBase, createdAt: now });
24005
24027
  }
24006
24028
  result.synced++;
24007
- await db.delete(adrTaskLinks).where(and5(eq7(adrTaskLinks.adrId, record.id), eq7(adrTaskLinks.taskId, taskId)));
24029
+ await db.delete(adrTaskLinks).where(and6(eq8(adrTaskLinks.adrId, record.id), eq8(adrTaskLinks.taskId, taskId)));
24008
24030
  await db.insert(adrTaskLinks).values({ adrId: record.id, taskId, linkType: "implements" });
24009
24031
  result.linked.push({ adrId: record.id, taskId });
24010
24032
  if (fm["Related ADRs"]) {
24011
24033
  const relatedIds = fm["Related ADRs"].split(",").map((r) => r.trim()).filter((r) => /^ADR-\d+$/.test(r));
24012
24034
  for (const toId of relatedIds) {
24013
24035
  try {
24014
- const targetExists = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq7(architectureDecisions.id, toId)).all();
24036
+ const targetExists = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq8(architectureDecisions.id, toId)).all();
24015
24037
  if (targetExists.length > 0) {
24016
24038
  await db.insert(adrRelations).values({ fromAdrId: record.id, toAdrId: toId, relationType: "related" }).onConflictDoNothing();
24017
24039
  }
@@ -24149,7 +24171,7 @@ async function syncAdrsToDb(projectRoot) {
24149
24171
  return result;
24150
24172
  }
24151
24173
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
24152
- const { eq: eq7 } = await import("drizzle-orm");
24174
+ const { eq: eq8 } = await import("drizzle-orm");
24153
24175
  const db = await getDb3(projectRoot);
24154
24176
  const now = (/* @__PURE__ */ new Date()).toISOString();
24155
24177
  const allFiles = collectAdrFiles(adrsDir);
@@ -24183,15 +24205,15 @@ async function syncAdrsToDb(projectRoot) {
24183
24205
  topics: fm.Topics ?? null,
24184
24206
  updatedAt: now
24185
24207
  };
24186
- const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq7(architectureDecisions.id, record.id)).all();
24208
+ const existing = await db.select({ id: architectureDecisions.id }).from(architectureDecisions).where(eq8(architectureDecisions.id, record.id)).all();
24187
24209
  if (existing.length > 0) {
24188
- await db.update(architectureDecisions).set(rowBase).where(eq7(architectureDecisions.id, record.id));
24210
+ await db.update(architectureDecisions).set(rowBase).where(eq8(architectureDecisions.id, record.id));
24189
24211
  result.updated++;
24190
24212
  } else {
24191
24213
  await db.insert(architectureDecisions).values({ ...rowBase, createdAt: now });
24192
24214
  result.inserted++;
24193
24215
  }
24194
- await db.delete(adrTaskLinks).where(eq7(adrTaskLinks.adrId, record.id));
24216
+ await db.delete(adrTaskLinks).where(eq8(adrTaskLinks.adrId, record.id));
24195
24217
  if (fm["Related Tasks"]) {
24196
24218
  for (const taskId of parseTaskIds2(fm["Related Tasks"])) {
24197
24219
  await db.insert(adrTaskLinks).values({ adrId: record.id, taskId, linkType: "related" });
@@ -25124,7 +25146,7 @@ function selectTasksForInjection(data, opts) {
25124
25146
  });
25125
25147
  return tasks2.slice(0, maxTasks);
25126
25148
  }
25127
- function formatForTodoWrite(tasks2) {
25149
+ function formatForInjection(tasks2) {
25128
25150
  return tasks2.map((t) => {
25129
25151
  let prefix = `[${t.id}]`;
25130
25152
  if (t.priority === "critical" || t.priority === "high") prefix += " [!]";
@@ -25143,7 +25165,7 @@ async function injectTasks(opts, accessor) {
25143
25165
  focus: focusMeta
25144
25166
  };
25145
25167
  const selectedTasks = selectTasksForInjection(data, opts);
25146
- const formatted = formatForTodoWrite(selectedTasks);
25168
+ const formatted = formatForInjection(selectedTasks);
25147
25169
  const phase = opts.phase ?? projectMeta?.currentPhase ?? null;
25148
25170
  return {
25149
25171
  tasks: formatted,
@@ -26289,12 +26311,12 @@ async function getEnforcementMode(cwd) {
26289
26311
  }
26290
26312
  async function getLifecycleStatus(epicId, cwd) {
26291
26313
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
26292
- const { eq: eq7 } = await import("drizzle-orm");
26314
+ const { eq: eq8 } = await import("drizzle-orm");
26293
26315
  const db = await getDb3(cwd);
26294
26316
  const pipelineResult = await db.select({
26295
26317
  pipeline: lifecyclePipelines,
26296
26318
  task: tasks
26297
- }).from(lifecyclePipelines).innerJoin(tasks, eq7(lifecyclePipelines.taskId, tasks.id)).where(eq7(lifecyclePipelines.taskId, epicId)).limit(1);
26319
+ }).from(lifecyclePipelines).innerJoin(tasks, eq8(lifecyclePipelines.taskId, tasks.id)).where(eq8(lifecyclePipelines.taskId, epicId)).limit(1);
26298
26320
  if (pipelineResult.length === 0) {
26299
26321
  return {
26300
26322
  epicId,
@@ -26307,7 +26329,7 @@ async function getLifecycleStatus(epicId, cwd) {
26307
26329
  }
26308
26330
  const task = pipelineResult[0].task;
26309
26331
  const pipelineId = `pipeline-${epicId}`;
26310
- const stageRows = await db.select().from(lifecycleStages).where(eq7(lifecycleStages.pipelineId, pipelineId)).orderBy(lifecycleStages.sequence);
26332
+ const stageRows = await db.select().from(lifecycleStages).where(eq8(lifecycleStages.pipelineId, pipelineId)).orderBy(lifecycleStages.sequence);
26311
26333
  const stageDataMap = /* @__PURE__ */ new Map();
26312
26334
  for (const row of stageRows) {
26313
26335
  let parsedChain;
@@ -26376,10 +26398,10 @@ async function getLifecycleStatus(epicId, cwd) {
26376
26398
  }
26377
26399
  async function getLifecycleHistory(epicId, cwd) {
26378
26400
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
26379
- const { eq: eq7 } = await import("drizzle-orm");
26401
+ const { eq: eq8 } = await import("drizzle-orm");
26380
26402
  const db = await getDb3(cwd);
26381
26403
  const pipelineId = `pipeline-${epicId}`;
26382
- const stages = await db.select().from(lifecycleStages).where(eq7(lifecycleStages.pipelineId, pipelineId));
26404
+ const stages = await db.select().from(lifecycleStages).where(eq8(lifecycleStages.pipelineId, pipelineId));
26383
26405
  if (stages.length === 0) {
26384
26406
  return { epicId, history: [] };
26385
26407
  }
@@ -26409,7 +26431,7 @@ async function getLifecycleHistory(epicId, cwd) {
26409
26431
  }
26410
26432
  const stageIds = stages.map((s) => s.id);
26411
26433
  if (stageIds.length > 0) {
26412
- const gateResults = await db.select().from(lifecycleGateResults).where(eq7(lifecycleGateResults.stageId, stageIds[0]));
26434
+ const gateResults = await db.select().from(lifecycleGateResults).where(eq8(lifecycleGateResults.stageId, stageIds[0]));
26413
26435
  for (const gate of gateResults) {
26414
26436
  const stageName = stageIdToName.get(gate.stageId);
26415
26437
  if (stageName) {
@@ -26422,7 +26444,7 @@ async function getLifecycleHistory(epicId, cwd) {
26422
26444
  }
26423
26445
  }
26424
26446
  for (let i = 1; i < stageIds.length; i++) {
26425
- const additionalGates = await db.select().from(lifecycleGateResults).where(eq7(lifecycleGateResults.stageId, stageIds[i]));
26447
+ const additionalGates = await db.select().from(lifecycleGateResults).where(eq8(lifecycleGateResults.stageId, stageIds[i]));
26426
26448
  for (const gate of additionalGates) {
26427
26449
  const stageName = stageIdToName.get(gate.stageId);
26428
26450
  if (stageName) {
@@ -26441,16 +26463,16 @@ async function getLifecycleHistory(epicId, cwd) {
26441
26463
  }
26442
26464
  async function getLifecycleGates(epicId, cwd) {
26443
26465
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
26444
- const { eq: eq7 } = await import("drizzle-orm");
26466
+ const { eq: eq8 } = await import("drizzle-orm");
26445
26467
  const db = await getDb3(cwd);
26446
26468
  const pipelineId = `pipeline-${epicId}`;
26447
- const stages = await db.select().from(lifecycleStages).where(eq7(lifecycleStages.pipelineId, pipelineId));
26469
+ const stages = await db.select().from(lifecycleStages).where(eq8(lifecycleStages.pipelineId, pipelineId));
26448
26470
  if (stages.length === 0) {
26449
26471
  return {};
26450
26472
  }
26451
26473
  const gates = {};
26452
26474
  for (const stage of stages) {
26453
- const gateRows = await db.select().from(lifecycleGateResults).where(eq7(lifecycleGateResults.stageId, stage.id));
26475
+ const gateRows = await db.select().from(lifecycleGateResults).where(eq8(lifecycleGateResults.stageId, stage.id));
26454
26476
  if (gateRows.length > 0) {
26455
26477
  gates[stage.stageName] = {};
26456
26478
  for (const gateRow of gateRows) {
@@ -26514,7 +26536,7 @@ async function checkStagePrerequisites(epicId, targetStage, cwd) {
26514
26536
  }
26515
26537
  async function ensureLifecycleContext(epicId, stageName, cwd, options) {
26516
26538
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
26517
- const { eq: eq7 } = await import("drizzle-orm");
26539
+ const { eq: eq8 } = await import("drizzle-orm");
26518
26540
  const db = await getDb3(cwd);
26519
26541
  const pipelineId = `pipeline-${epicId}`;
26520
26542
  const stageId = `stage-${epicId}-${stageName}`;
@@ -26522,7 +26544,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
26522
26544
  getNativeDb2().prepare(
26523
26545
  `INSERT OR IGNORE INTO tasks (id, title, status, priority, created_at) VALUES (?, ?, 'pending', 'medium', datetime('now'))`
26524
26546
  ).run(epicId, `Task ${epicId}`);
26525
- const existingPipeline = await db.select().from(lifecyclePipelines).where(eq7(lifecyclePipelines.id, pipelineId)).limit(1).all();
26547
+ const existingPipeline = await db.select().from(lifecyclePipelines).where(eq8(lifecyclePipelines.id, pipelineId)).limit(1).all();
26526
26548
  if (existingPipeline.length === 0) {
26527
26549
  await db.insert(lifecyclePipelines).values({
26528
26550
  id: pipelineId,
@@ -26532,7 +26554,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
26532
26554
  startedAt: options.now
26533
26555
  }).run();
26534
26556
  }
26535
- const existingStage = await db.select().from(lifecycleStages).where(eq7(lifecycleStages.id, stageId)).limit(1).all();
26557
+ const existingStage = await db.select().from(lifecycleStages).where(eq8(lifecycleStages.id, stageId)).limit(1).all();
26536
26558
  if (existingStage.length === 0) {
26537
26559
  const sequence = isValidStage(stageName) ? STAGE_ORDER[stageName] : 0;
26538
26560
  await db.insert(lifecycleStages).values({
@@ -26545,7 +26567,7 @@ async function ensureLifecycleContext(epicId, stageName, cwd, options) {
26545
26567
  }).run();
26546
26568
  }
26547
26569
  if (options.updateCurrentStage) {
26548
- await db.update(lifecyclePipelines).set({ currentStageId: stageId }).where(eq7(lifecyclePipelines.id, pipelineId)).run();
26570
+ await db.update(lifecyclePipelines).set({ currentStageId: stageId }).where(eq8(lifecyclePipelines.id, pipelineId)).run();
26549
26571
  }
26550
26572
  return { db, pipelineId, stageId };
26551
26573
  }
@@ -26560,7 +26582,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
26560
26582
  `Invalid status: ${status}. Valid: ${validStatuses.join(", ")}`
26561
26583
  );
26562
26584
  }
26563
- const { eq: eq7 } = await import("drizzle-orm");
26585
+ const { eq: eq8 } = await import("drizzle-orm");
26564
26586
  const now = (/* @__PURE__ */ new Date()).toISOString();
26565
26587
  const stageName = stage;
26566
26588
  const { db, stageId, pipelineId } = await ensureLifecycleContext(epicId, stage, cwd, {
@@ -26576,7 +26598,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
26576
26598
  status,
26577
26599
  related: artifact.related
26578
26600
  };
26579
- const existingStage = await db.select().from(lifecycleStages).where(eq7(lifecycleStages.id, stageId)).limit(1).all();
26601
+ const existingStage = await db.select().from(lifecycleStages).where(eq8(lifecycleStages.id, stageId)).limit(1).all();
26580
26602
  const sequence = STAGE_ORDER[stage];
26581
26603
  const stageValues = {
26582
26604
  status,
@@ -26603,7 +26625,7 @@ async function recordStageProgress(epicId, stage, status, notes, cwd) {
26603
26625
  provenanceChainJson: JSON.stringify(provenanceChain)
26604
26626
  }).run();
26605
26627
  } else {
26606
- await db.update(lifecycleStages).set(stageValues).where(eq7(lifecycleStages.id, stageId)).run();
26628
+ await db.update(lifecycleStages).set(stageValues).where(eq8(lifecycleStages.id, stageId)).run();
26607
26629
  }
26608
26630
  if (status === "completed") {
26609
26631
  await linkProvenance(epicId, stageName, artifact.absolutePath, cwd);
@@ -26623,7 +26645,7 @@ async function resetStage(epicId, stage, reason, cwd) {
26623
26645
  if (!PIPELINE_STAGES.includes(stage)) {
26624
26646
  throw new CleoError(2 /* INVALID_INPUT */, `Invalid stage: ${stage}`);
26625
26647
  }
26626
- const { eq: eq7 } = await import("drizzle-orm");
26648
+ const { eq: eq8 } = await import("drizzle-orm");
26627
26649
  const now = (/* @__PURE__ */ new Date()).toISOString();
26628
26650
  const { db, stageId } = await ensureLifecycleContext(epicId, stage, cwd, {
26629
26651
  now,
@@ -26636,11 +26658,11 @@ async function resetStage(epicId, stage, reason, cwd) {
26636
26658
  skippedAt: null,
26637
26659
  skipReason: null,
26638
26660
  notesJson: JSON.stringify([`Reset: ${reason}`])
26639
- }).where(eq7(lifecycleStages.id, stageId)).run();
26661
+ }).where(eq8(lifecycleStages.id, stageId)).run();
26640
26662
  return { epicId, stage, reason };
26641
26663
  }
26642
26664
  async function passGate(epicId, gateName, agent, notes, cwd) {
26643
- const { eq: eq7 } = await import("drizzle-orm");
26665
+ const { eq: eq8 } = await import("drizzle-orm");
26644
26666
  const now = (/* @__PURE__ */ new Date()).toISOString();
26645
26667
  const stageName = gateName.split("-")[0];
26646
26668
  const gateId = `gate-${epicId}-${stageName}-${gateName}`;
@@ -26649,7 +26671,7 @@ async function passGate(epicId, gateName, agent, notes, cwd) {
26649
26671
  stageStatusOnCreate: "in_progress",
26650
26672
  updateCurrentStage: true
26651
26673
  });
26652
- const existingGate = await db.select().from(lifecycleGateResults).where(eq7(lifecycleGateResults.id, gateId)).limit(1).all();
26674
+ const existingGate = await db.select().from(lifecycleGateResults).where(eq8(lifecycleGateResults.id, gateId)).limit(1).all();
26653
26675
  const gateValues = {
26654
26676
  id: gateId,
26655
26677
  stageId,
@@ -26661,14 +26683,14 @@ async function passGate(epicId, gateName, agent, notes, cwd) {
26661
26683
  reason: null
26662
26684
  };
26663
26685
  if (existingGate.length > 0) {
26664
- await db.update(lifecycleGateResults).set(gateValues).where(eq7(lifecycleGateResults.id, gateId)).run();
26686
+ await db.update(lifecycleGateResults).set(gateValues).where(eq8(lifecycleGateResults.id, gateId)).run();
26665
26687
  } else {
26666
26688
  await db.insert(lifecycleGateResults).values(gateValues).run();
26667
26689
  }
26668
26690
  return { epicId, gateName, timestamp: now };
26669
26691
  }
26670
26692
  async function failGate(epicId, gateName, reason, cwd) {
26671
- const { eq: eq7 } = await import("drizzle-orm");
26693
+ const { eq: eq8 } = await import("drizzle-orm");
26672
26694
  const now = (/* @__PURE__ */ new Date()).toISOString();
26673
26695
  const stageName = gateName.split("-")[0];
26674
26696
  const gateId = `gate-${epicId}-${stageName}-${gateName}`;
@@ -26677,7 +26699,7 @@ async function failGate(epicId, gateName, reason, cwd) {
26677
26699
  stageStatusOnCreate: "in_progress",
26678
26700
  updateCurrentStage: true
26679
26701
  });
26680
- const existingGate = await db.select().from(lifecycleGateResults).where(eq7(lifecycleGateResults.id, gateId)).limit(1).all();
26702
+ const existingGate = await db.select().from(lifecycleGateResults).where(eq8(lifecycleGateResults.id, gateId)).limit(1).all();
26681
26703
  const gateValues = {
26682
26704
  id: gateId,
26683
26705
  stageId,
@@ -26689,7 +26711,7 @@ async function failGate(epicId, gateName, reason, cwd) {
26689
26711
  reason: reason ?? null
26690
26712
  };
26691
26713
  if (existingGate.length > 0) {
26692
- await db.update(lifecycleGateResults).set(gateValues).where(eq7(lifecycleGateResults.id, gateId)).run();
26714
+ await db.update(lifecycleGateResults).set(gateValues).where(eq8(lifecycleGateResults.id, gateId)).run();
26693
26715
  } else {
26694
26716
  await db.insert(lifecycleGateResults).values(gateValues).run();
26695
26717
  }
@@ -27879,8 +27901,8 @@ function parseTokenMetrics(inputFile, cwd) {
27879
27901
  const raw = JSON.parse(readFileSync28(file, "utf-8"));
27880
27902
  if (raw.resourceMetrics) {
27881
27903
  const points = [];
27882
- for (const rm4 of raw.resourceMetrics ?? []) {
27883
- for (const sm of rm4.scopeMetrics ?? []) {
27904
+ for (const rm2 of raw.resourceMetrics ?? []) {
27905
+ for (const sm of rm2.scopeMetrics ?? []) {
27884
27906
  for (const metric of sm.metrics ?? []) {
27885
27907
  if (metric.name !== "claude_code.token.usage") continue;
27886
27908
  for (const dp of metric.sum?.dataPoints ?? []) {
@@ -31064,8 +31086,8 @@ function collectCleoFiles(cleoDir) {
31064
31086
  const fullPath = join59(dir, entry);
31065
31087
  const relPath = relative5(cleoDir, fullPath);
31066
31088
  try {
31067
- const stat3 = statSync15(fullPath);
31068
- if (stat3.isDirectory()) {
31089
+ const stat2 = statSync15(fullPath);
31090
+ if (stat2.isDirectory()) {
31069
31091
  walk(fullPath);
31070
31092
  } else {
31071
31093
  files.push(relPath.replaceAll("\\", "/"));
@@ -31301,17 +31323,17 @@ function scanLogDir(dir, includeMigration) {
31301
31323
  const isMigration = MIGRATION_LOG_PATTERN.test(name2);
31302
31324
  if (!cleoMatch && (!isMigration || !includeMigration)) continue;
31303
31325
  const filePath = join60(dir, name2);
31304
- let stat3;
31326
+ let stat2;
31305
31327
  try {
31306
- stat3 = statSync16(filePath);
31328
+ stat2 = statSync16(filePath);
31307
31329
  } catch {
31308
31330
  continue;
31309
31331
  }
31310
31332
  files.push({
31311
31333
  path: filePath,
31312
31334
  name: name2,
31313
- size: stat3.size,
31314
- mtime: stat3.mtime.toISOString(),
31335
+ size: stat2.size,
31336
+ mtime: stat2.mtime.toISOString(),
31315
31337
  date: cleoMatch ? cleoMatch[1] : null,
31316
31338
  isActive: false
31317
31339
  // set below
@@ -32501,53 +32523,109 @@ async function showPhase2(projectRoot, phaseId, accessor) {
32501
32523
  // packages/core/src/reconciliation/index.ts
32502
32524
  var reconciliation_exports = {};
32503
32525
  __export(reconciliation_exports, {
32504
- clearSyncState: () => clearSyncState,
32505
- readSyncState: () => readSyncState,
32526
+ createLink: () => createLink,
32527
+ getLinkByExternalId: () => getLinkByExternalId,
32528
+ getLinksByProvider: () => getLinksByProvider,
32529
+ getLinksByTaskId: () => getLinksByTaskId,
32506
32530
  reconcile: () => reconcile,
32507
- writeSyncState: () => writeSyncState
32531
+ removeLinksByProvider: () => removeLinksByProvider,
32532
+ touchLink: () => touchLink
32508
32533
  });
32509
32534
 
32510
- // packages/core/src/reconciliation/reconciliation-engine.ts
32511
- init_data_accessor();
32512
- init_add();
32513
- init_complete();
32514
- init_update2();
32515
-
32516
- // packages/core/src/reconciliation/sync-state.ts
32517
- init_paths();
32518
- init_atomic();
32519
- init_json2();
32520
- import { mkdir as mkdir13, rm as rm2 } from "node:fs/promises";
32521
- import { join as join62 } from "node:path";
32522
- function getSyncDir(cwd) {
32523
- return join62(getCleoDir(cwd), "sync");
32535
+ // packages/core/src/reconciliation/link-store.ts
32536
+ init_sqlite2();
32537
+ init_tasks_schema();
32538
+ import { randomUUID as randomUUID4 } from "node:crypto";
32539
+ import { and as and4, eq as eq6 } from "drizzle-orm";
32540
+ async function getLinksByProvider(providerId, cwd) {
32541
+ const db = await getDb(cwd);
32542
+ const rows = await db.select().from(externalTaskLinks).where(eq6(externalTaskLinks.providerId, providerId));
32543
+ return rows.map(rowToLink);
32524
32544
  }
32525
- function getStateFilePath(providerId, cwd) {
32526
- return join62(getSyncDir(cwd), `${providerId}-session.json`);
32545
+ async function getLinkByExternalId(providerId, externalId, cwd) {
32546
+ const db = await getDb(cwd);
32547
+ const rows = await db.select().from(externalTaskLinks).where(
32548
+ and4(
32549
+ eq6(externalTaskLinks.providerId, providerId),
32550
+ eq6(externalTaskLinks.externalId, externalId)
32551
+ )
32552
+ );
32553
+ return rows.length > 0 ? rowToLink(rows[0]) : null;
32527
32554
  }
32528
- async function readSyncState(providerId, cwd) {
32529
- const filePath = getStateFilePath(providerId, cwd);
32530
- try {
32531
- return await readJson(filePath);
32532
- } catch {
32533
- return null;
32555
+ async function getLinksByTaskId(taskId, cwd) {
32556
+ const db = await getDb(cwd);
32557
+ const rows = await db.select().from(externalTaskLinks).where(eq6(externalTaskLinks.taskId, taskId));
32558
+ return rows.map(rowToLink);
32559
+ }
32560
+ async function createLink(params, cwd) {
32561
+ const db = await getDb(cwd);
32562
+ const now = (/* @__PURE__ */ new Date()).toISOString();
32563
+ const id = randomUUID4();
32564
+ await db.insert(externalTaskLinks).values({
32565
+ id,
32566
+ taskId: params.taskId,
32567
+ providerId: params.providerId,
32568
+ externalId: params.externalId,
32569
+ externalUrl: params.externalUrl ?? null,
32570
+ externalTitle: params.externalTitle ?? null,
32571
+ linkType: params.linkType,
32572
+ syncDirection: params.syncDirection ?? "inbound",
32573
+ metadataJson: params.metadata ? JSON.stringify(params.metadata) : "{}",
32574
+ linkedAt: now,
32575
+ lastSyncAt: now
32576
+ });
32577
+ return {
32578
+ id,
32579
+ taskId: params.taskId,
32580
+ providerId: params.providerId,
32581
+ externalId: params.externalId,
32582
+ externalUrl: params.externalUrl ?? null,
32583
+ externalTitle: params.externalTitle ?? null,
32584
+ linkType: params.linkType,
32585
+ syncDirection: params.syncDirection ?? "inbound",
32586
+ metadata: params.metadata,
32587
+ linkedAt: now,
32588
+ lastSyncAt: now
32589
+ };
32590
+ }
32591
+ async function touchLink(linkId, updates, cwd) {
32592
+ const db = await getDb(cwd);
32593
+ const now = (/* @__PURE__ */ new Date()).toISOString();
32594
+ const values = { lastSyncAt: now };
32595
+ if (updates?.externalTitle !== void 0) {
32596
+ values.externalTitle = updates.externalTitle;
32597
+ }
32598
+ if (updates?.metadata !== void 0) {
32599
+ values.metadataJson = JSON.stringify(updates.metadata);
32534
32600
  }
32601
+ await db.update(externalTaskLinks).set(values).where(eq6(externalTaskLinks.id, linkId));
32535
32602
  }
32536
- async function writeSyncState(providerId, state, cwd) {
32537
- const syncDir = getSyncDir(cwd);
32538
- await mkdir13(syncDir, { recursive: true });
32539
- const filePath = getStateFilePath(providerId, cwd);
32540
- await atomicWriteJson(filePath, state);
32603
+ async function removeLinksByProvider(providerId, cwd) {
32604
+ const db = await getDb(cwd);
32605
+ const result = await db.delete(externalTaskLinks).where(eq6(externalTaskLinks.providerId, providerId));
32606
+ return Number(result.changes);
32541
32607
  }
32542
- async function clearSyncState(providerId, cwd) {
32543
- const filePath = getStateFilePath(providerId, cwd);
32544
- try {
32545
- await rm2(filePath);
32546
- } catch {
32547
- }
32608
+ function rowToLink(row) {
32609
+ return {
32610
+ id: row.id,
32611
+ taskId: row.taskId,
32612
+ providerId: row.providerId,
32613
+ externalId: row.externalId,
32614
+ externalUrl: row.externalUrl,
32615
+ externalTitle: row.externalTitle,
32616
+ linkType: row.linkType,
32617
+ syncDirection: row.syncDirection,
32618
+ metadata: row.metadataJson ? JSON.parse(row.metadataJson) : void 0,
32619
+ linkedAt: row.linkedAt,
32620
+ lastSyncAt: row.lastSyncAt
32621
+ };
32548
32622
  }
32549
32623
 
32550
32624
  // packages/core/src/reconciliation/reconciliation-engine.ts
32625
+ init_data_accessor();
32626
+ init_add();
32627
+ init_complete();
32628
+ init_update2();
32551
32629
  function buildTaskMap(tasks2) {
32552
32630
  const map = /* @__PURE__ */ new Map();
32553
32631
  for (const t of tasks2) {
@@ -32555,19 +32633,25 @@ function buildTaskMap(tasks2) {
32555
32633
  }
32556
32634
  return map;
32557
32635
  }
32558
- function computeActions(externalTasks, taskMap, injectedIds) {
32636
+ function buildLinkMap(links) {
32637
+ const map = /* @__PURE__ */ new Map();
32638
+ for (const link of links) {
32639
+ map.set(link.externalId, link);
32640
+ }
32641
+ return map;
32642
+ }
32643
+ function computeActions(externalTasks, taskMap, linkMap) {
32559
32644
  const actions = [];
32560
- const seenCleoIds = /* @__PURE__ */ new Set();
32561
32645
  for (const ext of externalTasks) {
32562
- if (ext.cleoTaskId) {
32563
- seenCleoIds.add(ext.cleoTaskId);
32564
- const cleoTask = taskMap.get(ext.cleoTaskId);
32646
+ const existingLink = linkMap.get(ext.externalId);
32647
+ if (existingLink) {
32648
+ const cleoTask = taskMap.get(existingLink.taskId);
32565
32649
  if (!cleoTask) {
32566
32650
  actions.push({
32567
32651
  type: "skip",
32568
- cleoTaskId: ext.cleoTaskId,
32652
+ cleoTaskId: existingLink.taskId,
32569
32653
  externalId: ext.externalId,
32570
- summary: `CLEO task ${ext.cleoTaskId} not found \u2014 skipping`,
32654
+ summary: `Linked CLEO task ${existingLink.taskId} no longer exists \u2014 skipping`,
32571
32655
  applied: false
32572
32656
  });
32573
32657
  continue;
@@ -32575,9 +32659,9 @@ function computeActions(externalTasks, taskMap, injectedIds) {
32575
32659
  if (cleoTask.status === "done" || cleoTask.status === "cancelled") {
32576
32660
  actions.push({
32577
32661
  type: "skip",
32578
- cleoTaskId: ext.cleoTaskId,
32662
+ cleoTaskId: cleoTask.id,
32579
32663
  externalId: ext.externalId,
32580
- summary: `CLEO task ${ext.cleoTaskId} already ${cleoTask.status}`,
32664
+ summary: `CLEO task ${cleoTask.id} already ${cleoTask.status}`,
32581
32665
  applied: false
32582
32666
  });
32583
32667
  continue;
@@ -32585,61 +32669,54 @@ function computeActions(externalTasks, taskMap, injectedIds) {
32585
32669
  if (ext.status === "completed") {
32586
32670
  actions.push({
32587
32671
  type: "complete",
32588
- cleoTaskId: ext.cleoTaskId,
32672
+ cleoTaskId: cleoTask.id,
32589
32673
  externalId: ext.externalId,
32590
- summary: `Complete ${ext.cleoTaskId} (${cleoTask.title})`,
32591
- applied: false
32674
+ summary: `Complete ${cleoTask.id} (${cleoTask.title})`,
32675
+ applied: false,
32676
+ linkId: existingLink.id
32592
32677
  });
32593
32678
  continue;
32594
32679
  }
32595
32680
  if (ext.status === "active" && (cleoTask.status === "pending" || cleoTask.status === "blocked")) {
32596
32681
  actions.push({
32597
32682
  type: "activate",
32598
- cleoTaskId: ext.cleoTaskId,
32683
+ cleoTaskId: cleoTask.id,
32599
32684
  externalId: ext.externalId,
32600
- summary: `Activate ${ext.cleoTaskId} (${cleoTask.title})`,
32601
- applied: false
32685
+ summary: `Activate ${cleoTask.id} (${cleoTask.title})`,
32686
+ applied: false,
32687
+ linkId: existingLink.id
32602
32688
  });
32603
32689
  continue;
32604
32690
  }
32605
- if (ext.status === "removed") {
32691
+ if (ext.title !== cleoTask.title) {
32606
32692
  actions.push({
32607
- type: "remove",
32608
- cleoTaskId: ext.cleoTaskId,
32693
+ type: "update",
32694
+ cleoTaskId: cleoTask.id,
32609
32695
  externalId: ext.externalId,
32610
- summary: `Task ${ext.cleoTaskId} removed from provider`,
32611
- applied: false
32696
+ summary: `Update ${cleoTask.id} title: "${cleoTask.title}" \u2192 "${ext.title}"`,
32697
+ applied: false,
32698
+ linkId: existingLink.id
32612
32699
  });
32613
32700
  continue;
32614
32701
  }
32615
32702
  actions.push({
32616
32703
  type: "skip",
32617
- cleoTaskId: ext.cleoTaskId,
32704
+ cleoTaskId: cleoTask.id,
32618
32705
  externalId: ext.externalId,
32619
- summary: `No change needed for ${ext.cleoTaskId}`,
32620
- applied: false
32621
- });
32622
- continue;
32623
- }
32624
- if (ext.status !== "removed") {
32625
- actions.push({
32626
- type: "create",
32627
- cleoTaskId: null,
32628
- externalId: ext.externalId,
32629
- summary: `Create new task: ${ext.title}`,
32630
- applied: false
32631
- });
32632
- }
32633
- }
32634
- for (const injectedId of injectedIds) {
32635
- if (!seenCleoIds.has(injectedId)) {
32636
- actions.push({
32637
- type: "remove",
32638
- cleoTaskId: injectedId,
32639
- externalId: `injected:${injectedId}`,
32640
- summary: `Injected task ${injectedId} no longer in provider`,
32641
- applied: false
32706
+ summary: `No change needed for ${cleoTask.id}`,
32707
+ applied: false,
32708
+ linkId: existingLink.id
32642
32709
  });
32710
+ } else {
32711
+ if (ext.status !== "removed") {
32712
+ actions.push({
32713
+ type: "create",
32714
+ cleoTaskId: null,
32715
+ externalId: ext.externalId,
32716
+ summary: `Create new task: ${ext.title}`,
32717
+ applied: false
32718
+ });
32719
+ }
32643
32720
  }
32644
32721
  }
32645
32722
  return actions;
@@ -32649,32 +32726,33 @@ async function reconcile(externalTasks, options, accessor) {
32649
32726
  const acc = accessor ?? await getAccessor(cwd);
32650
32727
  const { tasks: allTasks } = await acc.queryTasks({});
32651
32728
  const taskMap = buildTaskMap(allTasks);
32652
- const syncState = await readSyncState(providerId, cwd);
32653
- const injectedIds = new Set(syncState?.injectedTaskIds ?? []);
32654
- const actions = computeActions(externalTasks, taskMap, injectedIds);
32729
+ const existingLinks = await getLinksByProvider(providerId, cwd);
32730
+ const linkMap = buildLinkMap(existingLinks);
32731
+ const actions = computeActions(externalTasks, taskMap, linkMap);
32655
32732
  const summary = {
32733
+ created: 0,
32734
+ updated: 0,
32656
32735
  completed: 0,
32657
32736
  activated: 0,
32658
- created: 0,
32659
- removed: 0,
32660
32737
  skipped: 0,
32661
32738
  conflicts: 0,
32739
+ total: actions.length,
32662
32740
  applied: 0
32663
32741
  };
32664
32742
  for (const action of actions) {
32665
32743
  switch (action.type) {
32744
+ case "create":
32745
+ summary.created++;
32746
+ break;
32747
+ case "update":
32748
+ summary.updated++;
32749
+ break;
32666
32750
  case "complete":
32667
32751
  summary.completed++;
32668
32752
  break;
32669
32753
  case "activate":
32670
32754
  summary.activated++;
32671
32755
  break;
32672
- case "create":
32673
- summary.created++;
32674
- break;
32675
- case "remove":
32676
- summary.removed++;
32677
- break;
32678
32756
  case "skip":
32679
32757
  summary.skipped++;
32680
32758
  break;
@@ -32683,9 +32761,14 @@ async function reconcile(externalTasks, options, accessor) {
32683
32761
  break;
32684
32762
  }
32685
32763
  }
32764
+ let linksAffected = 0;
32686
32765
  if (!dryRun) {
32687
32766
  for (const action of actions) {
32688
32767
  if (action.type === "skip" || action.type === "conflict") {
32768
+ if (action.linkId) {
32769
+ const ext = externalTasks.find((e) => e.externalId === action.externalId);
32770
+ await touchLink(action.linkId, { externalTitle: ext?.title }, cwd);
32771
+ }
32689
32772
  continue;
32690
32773
  }
32691
32774
  try {
@@ -32694,11 +32777,15 @@ async function reconcile(externalTasks, options, accessor) {
32694
32777
  await completeTask(
32695
32778
  {
32696
32779
  taskId: action.cleoTaskId,
32697
- notes: `Completed via ${providerId} task sync`
32780
+ notes: `Completed via ${providerId} sync`
32698
32781
  },
32699
32782
  cwd,
32700
32783
  acc
32701
32784
  );
32785
+ if (action.linkId) {
32786
+ await touchLink(action.linkId, void 0, cwd);
32787
+ linksAffected++;
32788
+ }
32702
32789
  action.applied = true;
32703
32790
  summary.applied++;
32704
32791
  break;
@@ -32708,33 +32795,73 @@ async function reconcile(externalTasks, options, accessor) {
32708
32795
  {
32709
32796
  taskId: action.cleoTaskId,
32710
32797
  status: "active",
32711
- notes: `Activated during ${providerId} task sync`
32798
+ notes: `Activated via ${providerId} sync`
32712
32799
  },
32713
32800
  cwd,
32714
32801
  acc
32715
32802
  );
32803
+ if (action.linkId) {
32804
+ await touchLink(action.linkId, void 0, cwd);
32805
+ linksAffected++;
32806
+ }
32716
32807
  action.applied = true;
32717
32808
  summary.applied++;
32718
32809
  break;
32719
32810
  }
32720
- case "create": {
32811
+ case "update": {
32721
32812
  const ext = externalTasks.find((e) => e.externalId === action.externalId);
32722
32813
  if (!ext) break;
32723
- await addTask(
32814
+ await updateTask(
32724
32815
  {
32816
+ taskId: action.cleoTaskId,
32725
32817
  title: ext.title,
32726
- description: ext.description ?? `Created during ${providerId} task sync`,
32727
- labels: [...defaultLabels ?? [], ...ext.labels ?? [], "sync-created"],
32728
- ...defaultPhase ? { phase: defaultPhase, addPhase: true } : {}
32818
+ notes: `Updated via ${providerId} sync`
32729
32819
  },
32730
32820
  cwd,
32731
32821
  acc
32732
32822
  );
32823
+ if (action.linkId) {
32824
+ await touchLink(action.linkId, { externalTitle: ext.title }, cwd);
32825
+ linksAffected++;
32826
+ }
32733
32827
  action.applied = true;
32734
32828
  summary.applied++;
32735
32829
  break;
32736
32830
  }
32737
- case "remove": {
32831
+ case "create": {
32832
+ const ext = externalTasks.find((e) => e.externalId === action.externalId);
32833
+ if (!ext) break;
32834
+ const result = await addTask(
32835
+ {
32836
+ title: ext.title,
32837
+ description: ext.description ?? `Synced from ${providerId}`,
32838
+ priority: ext.priority,
32839
+ type: ext.type,
32840
+ labels: [...defaultLabels ?? [], ...ext.labels ?? [], `sync:${providerId}`],
32841
+ ...defaultPhase ? { phase: defaultPhase, addPhase: true } : {}
32842
+ },
32843
+ cwd,
32844
+ acc
32845
+ );
32846
+ const newTaskId = result.task.id;
32847
+ if (newTaskId) {
32848
+ const link = await createLink(
32849
+ {
32850
+ taskId: newTaskId,
32851
+ providerId,
32852
+ externalId: ext.externalId,
32853
+ externalUrl: ext.url,
32854
+ externalTitle: ext.title,
32855
+ linkType: "created",
32856
+ syncDirection: "inbound",
32857
+ metadata: ext.providerMeta
32858
+ },
32859
+ cwd
32860
+ );
32861
+ action.cleoTaskId = newTaskId;
32862
+ action.linkId = link.id;
32863
+ linksAffected++;
32864
+ }
32738
32865
  action.applied = true;
32739
32866
  summary.applied++;
32740
32867
  break;
@@ -32744,14 +32871,13 @@ async function reconcile(externalTasks, options, accessor) {
32744
32871
  action.error = err instanceof Error ? err.message : String(err);
32745
32872
  }
32746
32873
  }
32747
- await clearSyncState(providerId, cwd);
32748
32874
  }
32749
32875
  return {
32750
32876
  dryRun,
32751
32877
  providerId,
32752
32878
  actions,
32753
32879
  summary,
32754
- sessionCleared: !dryRun
32880
+ linksAffected
32755
32881
  };
32756
32882
  }
32757
32883
 
@@ -33358,15 +33484,15 @@ function describeChannel(channel) {
33358
33484
 
33359
33485
  // packages/core/src/release/ci.ts
33360
33486
  import { existsSync as existsSync59, mkdirSync as mkdirSync12, readFileSync as readFileSync42, writeFileSync as writeFileSync6 } from "node:fs";
33361
- import { dirname as dirname13, join as join64 } from "node:path";
33487
+ import { dirname as dirname13, join as join63 } from "node:path";
33362
33488
 
33363
33489
  // packages/core/src/release/release-config.ts
33364
33490
  init_paths();
33365
33491
  import { existsSync as existsSync58, readFileSync as readFileSync41 } from "node:fs";
33366
- import { join as join63 } from "node:path";
33492
+ import { join as join62 } from "node:path";
33367
33493
  function readConfigValueSync(path2, defaultValue, cwd) {
33368
33494
  try {
33369
- const configPath = join63(getCleoDir(cwd), "config.json");
33495
+ const configPath = join62(getCleoDir(cwd), "config.json");
33370
33496
  if (!existsSync58(configPath)) return defaultValue;
33371
33497
  const config = JSON.parse(readFileSync41(configPath, "utf-8"));
33372
33498
  const keys = path2.split(".");
@@ -33530,9 +33656,9 @@ function getPlatformPath(platform3) {
33530
33656
  }
33531
33657
  function detectCIPlatform(projectDir) {
33532
33658
  const dir = projectDir ?? process.cwd();
33533
- if (existsSync59(join64(dir, ".github"))) return "github-actions";
33534
- if (existsSync59(join64(dir, ".gitlab-ci.yml"))) return "gitlab-ci";
33535
- if (existsSync59(join64(dir, ".circleci"))) return "circleci";
33659
+ if (existsSync59(join63(dir, ".github"))) return "github-actions";
33660
+ if (existsSync59(join63(dir, ".gitlab-ci.yml"))) return "gitlab-ci";
33661
+ if (existsSync59(join63(dir, ".circleci"))) return "circleci";
33536
33662
  return null;
33537
33663
  }
33538
33664
  function generateGitHubActions(config) {
@@ -33634,7 +33760,7 @@ function generateCIConfig(platform3, cwd) {
33634
33760
  }
33635
33761
  function writeCIConfig(platform3, options = {}) {
33636
33762
  const projectDir = options.projectDir ?? process.cwd();
33637
- const outputPath = join64(projectDir, getPlatformPath(platform3));
33763
+ const outputPath = join63(projectDir, getPlatformPath(platform3));
33638
33764
  const content = generateCIConfig(platform3, projectDir);
33639
33765
  if (options.dryRun) {
33640
33766
  return { action: "would_write", path: outputPath, content };
@@ -33645,7 +33771,7 @@ function writeCIConfig(platform3, options = {}) {
33645
33771
  }
33646
33772
  function validateCIConfig(platform3, projectDir) {
33647
33773
  const dir = projectDir ?? process.cwd();
33648
- const configPath = join64(dir, getPlatformPath(platform3));
33774
+ const configPath = join63(dir, getPlatformPath(platform3));
33649
33775
  if (!existsSync59(configPath)) {
33650
33776
  return { valid: false, exists: false, errors: ["Config file not found"] };
33651
33777
  }
@@ -33903,8 +34029,8 @@ function checkDoubleListing(releaseTaskIds, existingReleases) {
33903
34029
  import { execFileSync as execFileSync7 } from "node:child_process";
33904
34030
  import { existsSync as existsSync61, renameSync as renameSync5 } from "node:fs";
33905
34031
  import { readFile as readFile12 } from "node:fs/promises";
33906
- import { join as join66 } from "node:path";
33907
- import { and as and4, count, desc as desc3, eq as eq6 } from "drizzle-orm";
34032
+ import { join as join65 } from "node:path";
34033
+ import { and as and5, count, desc as desc3, eq as eq7 } from "drizzle-orm";
33908
34034
  init_paths();
33909
34035
  init_tasks_schema();
33910
34036
 
@@ -33913,10 +34039,10 @@ init_src();
33913
34039
  init_errors3();
33914
34040
  init_paths();
33915
34041
  import { existsSync as existsSync60, readFileSync as readFileSync43, writeFileSync as writeFileSync7 } from "node:fs";
33916
- import { join as join65 } from "node:path";
34042
+ import { join as join64 } from "node:path";
33917
34043
  function readConfigValueSync2(path2, defaultValue, cwd) {
33918
34044
  try {
33919
- const configPath = join65(getCleoDir(cwd), "config.json");
34045
+ const configPath = join64(getCleoDir(cwd), "config.json");
33920
34046
  if (!existsSync60(configPath)) return defaultValue;
33921
34047
  const config = JSON.parse(readFileSync43(configPath, "utf-8"));
33922
34048
  const keys = path2.split(".");
@@ -34013,7 +34139,7 @@ function isVersionBumpConfigured(cwd) {
34013
34139
  return getVersionBumpConfig(cwd).length > 0;
34014
34140
  }
34015
34141
  function bumpFile(target, newVersion, projectRoot) {
34016
- const filePath = join65(projectRoot, target.file);
34142
+ const filePath = join64(projectRoot, target.file);
34017
34143
  if (!existsSync60(filePath)) {
34018
34144
  return {
34019
34145
  file: target.file,
@@ -34152,6 +34278,36 @@ function effectivePageLimit(limit, offset) {
34152
34278
  function isValidVersion(version) {
34153
34279
  return /^v?\d+\.\d+\.\d+(-[\w.]+)?(\+[\w.]+)?$/.test(version);
34154
34280
  }
34281
+ function validateCalVerWindow(version, now = /* @__PURE__ */ new Date()) {
34282
+ const normalized = version.startsWith("v") ? version.slice(1) : version;
34283
+ const base = normalized.split("-")[0] ?? normalized;
34284
+ const parts = base.split(".");
34285
+ if (parts.length !== 3) {
34286
+ return { valid: false, message: `Invalid CalVer format: ${version}` };
34287
+ }
34288
+ const tagYear = Number.parseInt(parts[0] ?? "", 10);
34289
+ const tagMonth = Number.parseInt(parts[1] ?? "", 10);
34290
+ if (!Number.isInteger(tagYear) || !Number.isInteger(tagMonth)) {
34291
+ return { valid: false, message: `Invalid CalVer date components: ${version}` };
34292
+ }
34293
+ const currentYear = now.getUTCFullYear();
34294
+ const currentMonth = now.getUTCMonth() + 1;
34295
+ const nextMonth = currentMonth === 12 ? 1 : currentMonth + 1;
34296
+ const nextYear = currentMonth === 12 ? currentYear + 1 : currentYear;
34297
+ const isPreRelease = normalized.includes("-");
34298
+ if (isPreRelease) {
34299
+ const valid2 = (tagYear === currentYear || tagYear === nextYear) && (tagMonth === currentMonth || tagMonth === nextMonth);
34300
+ return {
34301
+ valid: valid2,
34302
+ message: valid2 ? `CalVer OK (pre-release): ${version}` : `Pre-release ${version} outside allowed CalVer range ${currentYear}.${currentMonth} or ${nextYear}.${nextMonth}`
34303
+ };
34304
+ }
34305
+ const valid = tagYear === currentYear && tagMonth === currentMonth;
34306
+ return {
34307
+ valid,
34308
+ message: valid ? `CalVer OK (stable): ${version}` : `${version} does not match current CalVer ${currentYear}.${currentMonth}`
34309
+ };
34310
+ }
34155
34311
  function normalizeVersion(version) {
34156
34312
  return version.startsWith("v") ? version : `v${version}`;
34157
34313
  }
@@ -34174,7 +34330,7 @@ function rowToManifest(row) {
34174
34330
  }
34175
34331
  async function findLatestPushedVersion(cwd) {
34176
34332
  const db = await getDb2(cwd);
34177
- const rows = await db.select({ version: releaseManifests.version }).from(releaseManifests).where(eq6(releaseManifests.status, "pushed")).orderBy(desc3(releaseManifests.pushedAt)).limit(1).all();
34333
+ const rows = await db.select({ version: releaseManifests.version }).from(releaseManifests).where(eq7(releaseManifests.status, "pushed")).orderBy(desc3(releaseManifests.pushedAt)).limit(1).all();
34178
34334
  return rows[0]?.version;
34179
34335
  }
34180
34336
  async function prepareRelease(version, tasks2, notes, loadTasksFn, cwd) {
@@ -34186,7 +34342,7 @@ async function prepareRelease(version, tasks2, notes, loadTasksFn, cwd) {
34186
34342
  }
34187
34343
  const normalizedVersion = normalizeVersion(version);
34188
34344
  const db = await getDb2(cwd);
34189
- const existing = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34345
+ const existing = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34190
34346
  if (existing.length > 0) {
34191
34347
  throw new Error(`Release ${normalizedVersion} already exists (status: ${existing[0].status})`);
34192
34348
  }
@@ -34226,7 +34382,7 @@ async function generateReleaseChangelog(version, loadTasksFn, cwd) {
34226
34382
  }
34227
34383
  const normalizedVersion = normalizeVersion(version);
34228
34384
  const db = await getDb2(cwd);
34229
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34385
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34230
34386
  if (rows.length === 0) {
34231
34387
  throw new Error(`Release ${normalizedVersion} not found`);
34232
34388
  }
@@ -34363,8 +34519,8 @@ async function generateReleaseChangelog(version, loadTasksFn, cwd) {
34363
34519
  sections.push("");
34364
34520
  }
34365
34521
  const changelog = sections.join("\n");
34366
- await db.update(releaseManifests).set({ changelog }).where(eq6(releaseManifests.version, normalizedVersion)).run();
34367
- const changelogPath = join66(cwd ?? process.cwd(), "CHANGELOG.md");
34522
+ await db.update(releaseManifests).set({ changelog }).where(eq7(releaseManifests.version, normalizedVersion)).run();
34523
+ const changelogPath = join65(cwd ?? process.cwd(), "CHANGELOG.md");
34368
34524
  let existingChangelogContent = "";
34369
34525
  try {
34370
34526
  existingChangelogContent = await readFile12(changelogPath, "utf8");
@@ -34401,8 +34557,8 @@ async function listManifestReleases(optionsOrCwd, cwd) {
34401
34557
  const db = await getDb2(effectiveCwd);
34402
34558
  const totalRow = await db.select({ count: count() }).from(releaseManifests).get();
34403
34559
  const total = totalRow?.count ?? 0;
34404
- const conditions = options.status ? [eq6(releaseManifests.status, options.status)] : [];
34405
- const whereClause = conditions.length > 0 ? and4(...conditions) : void 0;
34560
+ const conditions = options.status ? [eq7(releaseManifests.status, options.status)] : [];
34561
+ const whereClause = conditions.length > 0 ? and5(...conditions) : void 0;
34406
34562
  const filteredRow = await db.select({ count: count() }).from(releaseManifests).where(whereClause).get();
34407
34563
  const filtered = filteredRow?.count ?? 0;
34408
34564
  let query = db.select().from(releaseManifests).where(whereClause).orderBy(desc3(releaseManifests.createdAt));
@@ -34433,7 +34589,7 @@ async function showManifestRelease(version, cwd) {
34433
34589
  }
34434
34590
  const normalizedVersion = normalizeVersion(version);
34435
34591
  const db = await getDb2(cwd);
34436
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34592
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34437
34593
  if (rows.length === 0) {
34438
34594
  throw new Error(`Release ${normalizedVersion} not found`);
34439
34595
  }
@@ -34445,7 +34601,7 @@ async function commitRelease(version, cwd) {
34445
34601
  }
34446
34602
  const normalizedVersion = normalizeVersion(version);
34447
34603
  const db = await getDb2(cwd);
34448
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34604
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34449
34605
  if (rows.length === 0) {
34450
34606
  throw new Error(`Release ${normalizedVersion} not found`);
34451
34607
  }
@@ -34455,7 +34611,7 @@ async function commitRelease(version, cwd) {
34455
34611
  );
34456
34612
  }
34457
34613
  const committedAt = (/* @__PURE__ */ new Date()).toISOString();
34458
- await db.update(releaseManifests).set({ status: "committed", committedAt }).where(eq6(releaseManifests.version, normalizedVersion)).run();
34614
+ await db.update(releaseManifests).set({ status: "committed", committedAt }).where(eq7(releaseManifests.version, normalizedVersion)).run();
34459
34615
  return { version: normalizedVersion, status: "committed", committedAt };
34460
34616
  }
34461
34617
  async function tagRelease(version, cwd) {
@@ -34464,12 +34620,12 @@ async function tagRelease(version, cwd) {
34464
34620
  }
34465
34621
  const normalizedVersion = normalizeVersion(version);
34466
34622
  const db = await getDb2(cwd);
34467
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34623
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34468
34624
  if (rows.length === 0) {
34469
34625
  throw new Error(`Release ${normalizedVersion} not found`);
34470
34626
  }
34471
34627
  const taggedAt = (/* @__PURE__ */ new Date()).toISOString();
34472
- await db.update(releaseManifests).set({ status: "tagged", taggedAt }).where(eq6(releaseManifests.version, normalizedVersion)).run();
34628
+ await db.update(releaseManifests).set({ status: "tagged", taggedAt }).where(eq7(releaseManifests.version, normalizedVersion)).run();
34473
34629
  return { version: normalizedVersion, status: "tagged", taggedAt };
34474
34630
  }
34475
34631
  async function runReleaseGates(version, loadTasksFn, cwd, opts) {
@@ -34478,7 +34634,7 @@ async function runReleaseGates(version, loadTasksFn, cwd, opts) {
34478
34634
  }
34479
34635
  const normalizedVersion = normalizeVersion(version);
34480
34636
  const db = await getDb2(cwd);
34481
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34637
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34482
34638
  if (rows.length === 0) {
34483
34639
  throw new Error(`Release ${normalizedVersion} not found`);
34484
34640
  }
@@ -34490,6 +34646,15 @@ async function runReleaseGates(version, loadTasksFn, cwd, opts) {
34490
34646
  status: isValidVersion(normalizedVersion) ? "passed" : "failed",
34491
34647
  message: isValidVersion(normalizedVersion) ? "Version format is valid" : "Invalid version format"
34492
34648
  });
34649
+ const releaseConfig = loadReleaseConfig(cwd);
34650
+ if (releaseConfig.versioningScheme === "calver") {
34651
+ const calver = validateCalVerWindow(normalizedVersion);
34652
+ gates.push({
34653
+ name: "calver_window",
34654
+ status: calver.valid ? "passed" : "failed",
34655
+ message: calver.message
34656
+ });
34657
+ }
34493
34658
  gates.push({
34494
34659
  name: "has_tasks",
34495
34660
  status: releaseTasks.length > 0 ? "passed" : "failed",
@@ -34511,10 +34676,10 @@ async function runReleaseGates(version, loadTasksFn, cwd, opts) {
34511
34676
  message: incompleteTasks.length === 0 ? "All tasks completed" : `${incompleteTasks.length} tasks not completed: ${incompleteTasks.join(", ")}`
34512
34677
  });
34513
34678
  const projectRoot = cwd ?? getProjectRoot();
34514
- const monorepoDist = join66(projectRoot, "packages", "cleo", "dist", "cli", "index.js");
34515
- const rootDist = join66(projectRoot, "dist", "cli", "index.js");
34679
+ const monorepoDist = join65(projectRoot, "packages", "cleo", "dist", "cli", "index.js");
34680
+ const rootDist = join65(projectRoot, "dist", "cli", "index.js");
34516
34681
  const distExists = existsSync61(monorepoDist) || existsSync61(rootDist);
34517
- const isNodeProject = existsSync61(join66(projectRoot, "package.json"));
34682
+ const isNodeProject = existsSync61(join65(projectRoot, "package.json"));
34518
34683
  if (isNodeProject) {
34519
34684
  gates.push({
34520
34685
  name: "build_artifact",
@@ -34560,7 +34725,6 @@ async function runReleaseGates(version, loadTasksFn, cwd, opts) {
34560
34725
  }).trim();
34561
34726
  } catch {
34562
34727
  }
34563
- const releaseConfig = loadReleaseConfig(cwd);
34564
34728
  const gitFlowCfg = getGitFlowConfig(releaseConfig);
34565
34729
  const channelCfg = getChannelConfig(releaseConfig);
34566
34730
  const expectedBranch = isPreRelease ? gitFlowCfg.branches.develop : gitFlowCfg.branches.main;
@@ -34618,7 +34782,7 @@ async function cancelRelease(version, projectRoot) {
34618
34782
  }
34619
34783
  const normalizedVersion = normalizeVersion(version);
34620
34784
  const db = await getDb2(projectRoot);
34621
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34785
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34622
34786
  if (rows.length === 0) {
34623
34787
  return {
34624
34788
  success: false,
@@ -34635,7 +34799,7 @@ async function cancelRelease(version, projectRoot) {
34635
34799
  version: normalizedVersion
34636
34800
  };
34637
34801
  }
34638
- await db.delete(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).run();
34802
+ await db.delete(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).run();
34639
34803
  return {
34640
34804
  success: true,
34641
34805
  message: `Release ${normalizedVersion} cancelled and removed`,
@@ -34648,12 +34812,12 @@ async function rollbackRelease(version, reason, cwd) {
34648
34812
  }
34649
34813
  const normalizedVersion = normalizeVersion(version);
34650
34814
  const db = await getDb2(cwd);
34651
- const rows = await db.select().from(releaseManifests).where(eq6(releaseManifests.version, normalizedVersion)).limit(1).all();
34815
+ const rows = await db.select().from(releaseManifests).where(eq7(releaseManifests.version, normalizedVersion)).limit(1).all();
34652
34816
  if (rows.length === 0) {
34653
34817
  throw new Error(`Release ${normalizedVersion} not found`);
34654
34818
  }
34655
34819
  const previousStatus = rows[0].status;
34656
- await db.update(releaseManifests).set({ status: "rolled_back" }).where(eq6(releaseManifests.version, normalizedVersion)).run();
34820
+ await db.update(releaseManifests).set({ status: "rolled_back" }).where(eq7(releaseManifests.version, normalizedVersion)).run();
34657
34821
  return {
34658
34822
  version: normalizedVersion,
34659
34823
  previousStatus,
@@ -34662,7 +34826,7 @@ async function rollbackRelease(version, reason, cwd) {
34662
34826
  };
34663
34827
  }
34664
34828
  async function readPushPolicy(cwd) {
34665
- const configPath = join66(getCleoDirAbsolute(cwd), "config.json");
34829
+ const configPath = join65(getCleoDirAbsolute(cwd), "config.json");
34666
34830
  let config;
34667
34831
  try {
34668
34832
  const raw = await readFile12(configPath, "utf-8");
@@ -34763,10 +34927,10 @@ async function markReleasePushed(version, pushedAt, cwd, provenance) {
34763
34927
  pushedAt,
34764
34928
  ...provenance?.commitSha != null ? { commitSha: provenance.commitSha } : {},
34765
34929
  ...provenance?.gitTag != null ? { gitTag: provenance.gitTag } : {}
34766
- }).where(eq6(releaseManifests.version, normalizedVersion)).run();
34930
+ }).where(eq7(releaseManifests.version, normalizedVersion)).run();
34767
34931
  }
34768
34932
  async function migrateReleasesJsonToSqlite(projectRoot) {
34769
- const releasesPath = join66(getCleoDirAbsolute(projectRoot), "releases.json");
34933
+ const releasesPath = join65(getCleoDirAbsolute(projectRoot), "releases.json");
34770
34934
  if (!existsSync61(releasesPath)) {
34771
34935
  return { migrated: 0 };
34772
34936
  }
@@ -34783,7 +34947,7 @@ async function migrateReleasesJsonToSqlite(projectRoot) {
34783
34947
  const db = await getDb2(projectRoot);
34784
34948
  let migrated = 0;
34785
34949
  for (const r of raw.releases) {
34786
- const existing = await db.select({ id: releaseManifests.id }).from(releaseManifests).where(eq6(releaseManifests.version, r.version)).limit(1).all();
34950
+ const existing = await db.select({ id: releaseManifests.id }).from(releaseManifests).where(eq7(releaseManifests.version, r.version)).limit(1).all();
34787
34951
  if (existing.length > 0) continue;
34788
34952
  const id = `rel-${r.version.replace(/[^a-z0-9]/gi, "-")}`;
34789
34953
  await db.insert(releaseManifests).values({
@@ -35089,11 +35253,11 @@ __export(roadmap_exports, {
35089
35253
  });
35090
35254
  init_data_accessor();
35091
35255
  import { existsSync as existsSync62, readFileSync as readFileSync44 } from "node:fs";
35092
- import { join as join67 } from "node:path";
35256
+ import { join as join66 } from "node:path";
35093
35257
  async function getRoadmap(opts, accessor) {
35094
35258
  const acc = accessor ?? await getAccessor(opts.cwd);
35095
35259
  const { tasks: tasks2 } = await acc.queryTasks({});
35096
- const versionPath = join67(opts.cwd ?? process.cwd(), "VERSION");
35260
+ const versionPath = join66(opts.cwd ?? process.cwd(), "VERSION");
35097
35261
  const currentVersion = existsSync62(versionPath) ? readFileSync44(versionPath, "utf-8").trim() : "unknown";
35098
35262
  const childParentIds = new Set(tasks2.filter((t) => t.parentId).map((t) => t.parentId));
35099
35263
  const epics = tasks2.filter((t) => childParentIds.has(t.id));
@@ -35101,7 +35265,7 @@ async function getRoadmap(opts, accessor) {
35101
35265
  const completed = epics.filter((e) => e.status === "done");
35102
35266
  const releaseHistory = [];
35103
35267
  if (opts.includeHistory) {
35104
- const changelogPath = join67(opts.cwd ?? process.cwd(), "CHANGELOG.md");
35268
+ const changelogPath = join66(opts.cwd ?? process.cwd(), "CHANGELOG.md");
35105
35269
  if (existsSync62(changelogPath)) {
35106
35270
  const content = readFileSync44(changelogPath, "utf-8");
35107
35271
  const versionRegex = /^##\s+\[?v?(\d+\.\d+\.\d+[^\]]*)\]?\s*[-(]?\s*(\d{4}-\d{2}-\d{2})?/gm;
@@ -35176,6 +35340,10 @@ var CAPABILITY_MATRIX = [
35176
35340
  { domain: "tasks", operation: "relates.add", gateway: "mutate", mode: "native" },
35177
35341
  { domain: "tasks", operation: "start", gateway: "mutate", mode: "native" },
35178
35342
  { domain: "tasks", operation: "stop", gateway: "mutate", mode: "native" },
35343
+ // Sync sub-domain (provider-agnostic task reconciliation)
35344
+ { domain: "tasks", operation: "sync.reconcile", gateway: "mutate", mode: "native" },
35345
+ { domain: "tasks", operation: "sync.links", gateway: "query", mode: "native" },
35346
+ { domain: "tasks", operation: "sync.links.remove", gateway: "mutate", mode: "native" },
35179
35347
  // === Session Domain ===
35180
35348
  // Query operations
35181
35349
  { domain: "session", operation: "status", gateway: "query", mode: "native" },
@@ -35346,10 +35514,6 @@ var CAPABILITY_MATRIX = [
35346
35514
  { domain: "tools", operation: "provider.supports", gateway: "query", mode: "native" },
35347
35515
  { domain: "tools", operation: "provider.hooks", gateway: "query", mode: "native" },
35348
35516
  { domain: "tools", operation: "provider.inject", gateway: "mutate", mode: "native" },
35349
- // TodoWrite operations
35350
- { domain: "tools", operation: "todowrite.status", gateway: "query", mode: "native" },
35351
- { domain: "tools", operation: "todowrite.sync", gateway: "mutate", mode: "native" },
35352
- { domain: "tools", operation: "todowrite.clear", gateway: "mutate", mode: "native" },
35353
35517
  // === Nexus Domain ===
35354
35518
  // Query operations
35355
35519
  { domain: "nexus", operation: "status", gateway: "query", mode: "native" },
@@ -36051,12 +36215,12 @@ import { catalog as catalog2 } from "@cleocode/caamp";
36051
36215
  // packages/core/src/skills/agents/config.ts
36052
36216
  init_paths();
36053
36217
  import { existsSync as existsSync65, readFileSync as readFileSync46 } from "node:fs";
36054
- import { basename as basename11, join as join70 } from "node:path";
36218
+ import { basename as basename11, join as join69 } from "node:path";
36055
36219
 
36056
36220
  // packages/core/src/skills/discovery.ts
36057
36221
  init_paths();
36058
36222
  import { existsSync as existsSync64, readdirSync as readdirSync24, readFileSync as readFileSync45, statSync as statSync17 } from "node:fs";
36059
- import { basename as basename10, join as join69 } from "node:path";
36223
+ import { basename as basename10, join as join68 } from "node:path";
36060
36224
  import {
36061
36225
  discoverSkill as caampDiscoverSkill,
36062
36226
  discoverSkills as caampDiscoverSkills,
@@ -36146,12 +36310,12 @@ var SKILL_NAME_MAP = {
36146
36310
  function getSkillSearchPaths(cwd) {
36147
36311
  const projectRoot = getProjectRoot(cwd);
36148
36312
  const cleoHome = getCleoHome();
36149
- const projectAgentsSkills = join69(getProjectAgentsDir(projectRoot), "skills");
36313
+ const projectAgentsSkills = join68(getProjectAgentsDir(projectRoot), "skills");
36150
36314
  const paths = [
36151
36315
  { scope: "agent-skills", path: getCanonicalSkillsDir(), priority: 1 },
36152
36316
  { scope: "project-custom", path: projectAgentsSkills, priority: 2 }
36153
36317
  ];
36154
- const mpCacheDir = process.env["CLEO_SKILLS_MP_CACHE"] ?? join69(cleoHome, ".skills-cache");
36318
+ const mpCacheDir = process.env["CLEO_SKILLS_MP_CACHE"] ?? join68(cleoHome, ".skills-cache");
36155
36319
  if (existsSync64(mpCacheDir)) {
36156
36320
  paths.push({ scope: "marketplace", path: mpCacheDir, priority: 4 });
36157
36321
  }
@@ -36162,7 +36326,7 @@ function getSkillsDir(cwd) {
36162
36326
  return getCanonicalSkillsDir();
36163
36327
  }
36164
36328
  function getSharedDir(cwd) {
36165
- return join69(getSkillsDir(cwd), "_shared");
36329
+ return join68(getSkillsDir(cwd), "_shared");
36166
36330
  }
36167
36331
  function mapSkillName(input) {
36168
36332
  if (SKILL_NAME_MAP[input]) {
@@ -36245,7 +36409,7 @@ function parseFrontmatter3(content) {
36245
36409
  };
36246
36410
  }
36247
36411
  function discoverSkill(skillDir) {
36248
- const skillMdPath = join69(skillDir, "SKILL.md");
36412
+ const skillMdPath = join68(skillDir, "SKILL.md");
36249
36413
  if (!existsSync64(skillMdPath)) {
36250
36414
  return null;
36251
36415
  }
@@ -36270,7 +36434,7 @@ function discoverSkillsInDir(dir) {
36270
36434
  const entries = readdirSync24(dir);
36271
36435
  for (const entry of entries) {
36272
36436
  if (entry.startsWith(".") || entry.startsWith("_")) continue;
36273
- const entryPath = join69(dir, entry);
36437
+ const entryPath = join68(dir, entry);
36274
36438
  try {
36275
36439
  if (statSync17(entryPath).isDirectory()) {
36276
36440
  const skill = discoverSkill(entryPath);
@@ -36304,14 +36468,14 @@ function findSkill(name2, cwd) {
36304
36468
  const { canonical } = mapSkillName(name2);
36305
36469
  const searchPaths = getSkillSearchPaths(cwd);
36306
36470
  for (const sp of searchPaths) {
36307
- const skillDir = join69(sp.path, canonical);
36471
+ const skillDir = join68(sp.path, canonical);
36308
36472
  const skill = discoverSkill(skillDir);
36309
36473
  if (skill) return skill;
36310
36474
  }
36311
36475
  if (canonical.startsWith("ct-")) {
36312
36476
  const legacy = canonical.slice(3);
36313
36477
  for (const sp of searchPaths) {
36314
- const skillDir = join69(sp.path, legacy);
36478
+ const skillDir = join68(sp.path, legacy);
36315
36479
  const skill = discoverSkill(skillDir);
36316
36480
  if (skill) return skill;
36317
36481
  }
@@ -36350,10 +36514,10 @@ function resolveTemplatePath(name2, cwd) {
36350
36514
 
36351
36515
  // packages/core/src/skills/agents/config.ts
36352
36516
  function getAgentsDir(cwd) {
36353
- return join70(getProjectRoot(cwd), "agents");
36517
+ return join69(getProjectRoot(cwd), "agents");
36354
36518
  }
36355
36519
  function parseAgentConfig(agentDir) {
36356
- const agentMdPath = join70(agentDir, "AGENT.md");
36520
+ const agentMdPath = join69(agentDir, "AGENT.md");
36357
36521
  if (!existsSync65(agentMdPath)) {
36358
36522
  return null;
36359
36523
  }
@@ -36369,7 +36533,7 @@ function parseAgentConfig(agentDir) {
36369
36533
  }
36370
36534
  function loadAgentConfig(agentName, cwd) {
36371
36535
  const agentsDir = getAgentsDir(cwd);
36372
- const agentDir = join70(agentsDir, agentName);
36536
+ const agentDir = join69(agentsDir, agentName);
36373
36537
  return parseAgentConfig(agentDir);
36374
36538
  }
36375
36539
  function getSubagentConfig(cwd) {
@@ -36377,7 +36541,7 @@ function getSubagentConfig(cwd) {
36377
36541
  }
36378
36542
  function agentExists(agentName, cwd) {
36379
36543
  const agentsDir = getAgentsDir(cwd);
36380
- const agentMdPath = join70(agentsDir, agentName, "AGENT.md");
36544
+ const agentMdPath = join69(agentsDir, agentName, "AGENT.md");
36381
36545
  return existsSync65(agentMdPath);
36382
36546
  }
36383
36547
  function extractBody(content) {
@@ -36400,14 +36564,14 @@ function extractBody(content) {
36400
36564
  // packages/core/src/skills/agents/install.ts
36401
36565
  init_paths();
36402
36566
  import { existsSync as existsSync66, mkdirSync as mkdirSync14, readdirSync as readdirSync25, readlinkSync, symlinkSync, unlinkSync as unlinkSync4 } from "node:fs";
36403
- import { basename as basename12, join as join71 } from "node:path";
36567
+ import { basename as basename12, join as join70 } from "node:path";
36404
36568
  function getAgentInstallDir() {
36405
36569
  return getClaudeAgentsDir();
36406
36570
  }
36407
36571
  function installAgent(agentDir) {
36408
36572
  const targetDir = getAgentInstallDir();
36409
36573
  const agentName = basename12(agentDir);
36410
- const targetPath = join71(targetDir, agentName);
36574
+ const targetPath = join70(targetDir, agentName);
36411
36575
  if (!existsSync66(targetDir)) {
36412
36576
  mkdirSync14(targetDir, { recursive: true });
36413
36577
  }
@@ -36445,8 +36609,8 @@ function installAllAgents(cwd) {
36445
36609
  const entries = readdirSync25(agentsDir);
36446
36610
  for (const entry of entries) {
36447
36611
  if (entry.startsWith(".")) continue;
36448
- const agentDir = join71(agentsDir, entry);
36449
- const agentMdPath = join71(agentDir, "AGENT.md");
36612
+ const agentDir = join70(agentsDir, entry);
36613
+ const agentMdPath = join70(agentDir, "AGENT.md");
36450
36614
  if (!existsSync66(agentMdPath)) continue;
36451
36615
  const result = installAgent(agentDir);
36452
36616
  results.push({
@@ -36459,7 +36623,7 @@ function installAllAgents(cwd) {
36459
36623
  }
36460
36624
  function uninstallAgent(agentName) {
36461
36625
  const targetDir = getAgentInstallDir();
36462
- const targetPath = join71(targetDir, agentName);
36626
+ const targetPath = join70(targetDir, agentName);
36463
36627
  if (!existsSync66(targetPath)) {
36464
36628
  return false;
36465
36629
  }
@@ -36474,9 +36638,9 @@ function uninstallAgent(agentName) {
36474
36638
  // packages/core/src/skills/agents/registry.ts
36475
36639
  init_paths();
36476
36640
  import { existsSync as existsSync67, mkdirSync as mkdirSync15, readdirSync as readdirSync26, readFileSync as readFileSync47, writeFileSync as writeFileSync8 } from "node:fs";
36477
- import { dirname as dirname14, join as join72 } from "node:path";
36641
+ import { dirname as dirname14, join as join71 } from "node:path";
36478
36642
  function getRegistryPath2() {
36479
- return join72(getCleoHome(), "agent-registry.json");
36643
+ return join71(getCleoHome(), "agent-registry.json");
36480
36644
  }
36481
36645
  function readRegistry2() {
36482
36646
  const registryPath = getRegistryPath2();
@@ -36545,7 +36709,7 @@ function syncRegistry(cwd) {
36545
36709
  const entries = readdirSync26(agentsDir);
36546
36710
  for (const entry of entries) {
36547
36711
  if (entry.startsWith(".")) continue;
36548
- const agentDir = join72(agentsDir, entry);
36712
+ const agentDir = join71(agentsDir, entry);
36549
36713
  try {
36550
36714
  const config = parseAgentConfig(agentDir);
36551
36715
  if (config) {
@@ -36559,7 +36723,7 @@ function syncRegistry(cwd) {
36559
36723
  if (existingNames.has(name2)) {
36560
36724
  result.unchanged.push(name2);
36561
36725
  } else {
36562
- registerAgent(name2, join72(agentsDir, name2), config);
36726
+ registerAgent(name2, join71(agentsDir, name2), config);
36563
36727
  result.added.push(name2);
36564
36728
  }
36565
36729
  }
@@ -36579,7 +36743,7 @@ import { catalog } from "@cleocode/caamp";
36579
36743
  // packages/core/src/skills/injection/token.ts
36580
36744
  init_paths();
36581
36745
  import { existsSync as existsSync68, readFileSync as readFileSync48 } from "node:fs";
36582
- import { join as join73 } from "node:path";
36746
+ import { join as join72 } from "node:path";
36583
36747
  var REQUIRED_TOKENS = ["TASK_ID", "DATE", "TOPIC_SLUG"];
36584
36748
  var TOKEN_PATTERNS = {
36585
36749
  TASK_ID: /^T\d+$/,
@@ -36615,7 +36779,7 @@ var CLEO_DEFAULTS = {
36615
36779
  };
36616
36780
  function loadPlaceholders(cwd) {
36617
36781
  const projectRoot = getProjectRoot(cwd);
36618
- const path2 = join73(projectRoot, "skills", "_shared", "placeholders.json");
36782
+ const path2 = join72(projectRoot, "skills", "_shared", "placeholders.json");
36619
36783
  if (!existsSync68(path2)) return null;
36620
36784
  try {
36621
36785
  return JSON.parse(readFileSync48(path2, "utf-8"));
@@ -36999,9 +37163,9 @@ init_src();
36999
37163
  init_errors3();
37000
37164
  init_paths();
37001
37165
  import { existsSync as existsSync69, readFileSync as readFileSync49 } from "node:fs";
37002
- import { join as join74 } from "node:path";
37166
+ import { join as join73 } from "node:path";
37003
37167
  function getProtocolBasePath(cwd) {
37004
- return join74(getProjectRoot(cwd), "skills", "_shared", "subagent-protocol-base.md");
37168
+ return join73(getProjectRoot(cwd), "skills", "_shared", "subagent-protocol-base.md");
37005
37169
  }
37006
37170
  function loadProtocolBase(cwd) {
37007
37171
  const path2 = getProtocolBasePath(cwd);
@@ -37295,12 +37459,12 @@ init_src();
37295
37459
  init_errors3();
37296
37460
  init_paths();
37297
37461
  import { appendFileSync as appendFileSync8, existsSync as existsSync71, mkdirSync as mkdirSync16, readFileSync as readFileSync51, writeFileSync as writeFileSync9 } from "node:fs";
37298
- import { join as join75 } from "node:path";
37462
+ import { join as join74 } from "node:path";
37299
37463
  function ensureOutputs(cwd) {
37300
37464
  const outputDir = getAgentOutputsDir(cwd);
37301
37465
  const absOutputDir = getAgentOutputsAbsolute(cwd);
37302
37466
  const manifestPath = getManifestPath(cwd);
37303
- const archiveDir = join75(absOutputDir, "archive");
37467
+ const archiveDir = join74(absOutputDir, "archive");
37304
37468
  const created = [];
37305
37469
  if (!existsSync71(absOutputDir)) {
37306
37470
  mkdirSync16(absOutputDir, { recursive: true });
@@ -37429,13 +37593,13 @@ function rotateManifest(maxEntries = 100, cwd) {
37429
37593
  if (entries.length <= maxEntries) return 0;
37430
37594
  const manifestPath = getManifestPath(cwd);
37431
37595
  const absOutputDir = getAgentOutputsAbsolute(cwd);
37432
- const archiveDir = join75(absOutputDir, "archive");
37596
+ const archiveDir = join74(absOutputDir, "archive");
37433
37597
  const toKeep = entries.slice(-maxEntries);
37434
37598
  const toArchive = entries.slice(0, entries.length - maxEntries);
37435
37599
  if (!existsSync71(archiveDir)) {
37436
37600
  mkdirSync16(archiveDir, { recursive: true });
37437
37601
  }
37438
- const archivePath = join75(archiveDir, `MANIFEST-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.jsonl`);
37602
+ const archivePath = join74(archiveDir, `MANIFEST-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.jsonl`);
37439
37603
  const archiveContent = toArchive.map((e) => JSON.stringify(e)).join("\n") + "\n";
37440
37604
  appendFileSync8(archivePath, archiveContent, "utf-8");
37441
37605
  const keepContent = toKeep.map((e) => JSON.stringify(e)).join("\n") + "\n";
@@ -37498,13 +37662,13 @@ function validateEntry(entry) {
37498
37662
  // packages/core/src/skills/manifests/resolver.ts
37499
37663
  init_paths();
37500
37664
  import { existsSync as existsSync72, mkdirSync as mkdirSync17, readFileSync as readFileSync52, writeFileSync as writeFileSync10 } from "node:fs";
37501
- import { join as join76 } from "node:path";
37665
+ import { join as join75 } from "node:path";
37502
37666
  var DEFAULT_CACHE_TTL = 300;
37503
37667
  function getCacheDir() {
37504
- return process.env["CLEO_MANIFEST_CACHE_DIR"] ?? join76(getCleoHome(), "cache");
37668
+ return process.env["CLEO_MANIFEST_CACHE_DIR"] ?? join75(getCleoHome(), "cache");
37505
37669
  }
37506
37670
  function getCachedManifestPath() {
37507
- return join76(getCacheDir(), "skills-manifest.json");
37671
+ return join75(getCacheDir(), "skills-manifest.json");
37508
37672
  }
37509
37673
  function isCacheFresh(cachePath) {
37510
37674
  const path2 = cachePath ?? getCachedManifestPath();
@@ -37578,11 +37742,11 @@ function regenerateCache(cwd) {
37578
37742
  // packages/core/src/skills/marketplace.ts
37579
37743
  init_paths();
37580
37744
  import { existsSync as existsSync73, readFileSync as readFileSync53 } from "node:fs";
37581
- import { join as join77 } from "node:path";
37745
+ import { join as join76 } from "node:path";
37582
37746
  import { searchSkills as caampSearchSkills, MarketplaceClient } from "@cleocode/caamp";
37583
37747
  function loadConfig2(cwd) {
37584
37748
  const projectRoot = getProjectRoot(cwd);
37585
- const configFile = join77(projectRoot, ".cleo", "skillsmp.json");
37749
+ const configFile = join76(projectRoot, ".cleo", "skillsmp.json");
37586
37750
  if (!existsSync73(configFile)) return null;
37587
37751
  try {
37588
37752
  const data = JSON.parse(readFileSync53(configFile, "utf-8"));
@@ -37770,7 +37934,7 @@ function spawnBatch(taskIds, templateName, cwd, tier) {
37770
37934
  // packages/core/src/skills/orchestrator/startup.ts
37771
37935
  init_paths();
37772
37936
  import { existsSync as existsSync75, readFileSync as readFileSync55 } from "node:fs";
37773
- import { join as join78 } from "node:path";
37937
+ import { join as join77 } from "node:path";
37774
37938
  var DEFAULT_THRESHOLDS = { warning: 70, critical: 80 };
37775
37939
  function getThresholds(config) {
37776
37940
  const orc = config?.orchestrator?.contextThresholds;
@@ -37792,13 +37956,13 @@ function getContextState(sessionId, cwd) {
37792
37956
  };
37793
37957
  let stateFile = "";
37794
37958
  if (sessionId) {
37795
- stateFile = join78(cleoDirAbs, "sessions", sessionId, ".context-state.json");
37959
+ stateFile = join77(cleoDirAbs, "sessions", sessionId, ".context-state.json");
37796
37960
  if (!existsSync75(stateFile)) {
37797
- stateFile = join78(cleoDirAbs, `.context-state-${sessionId}.json`);
37961
+ stateFile = join77(cleoDirAbs, `.context-state-${sessionId}.json`);
37798
37962
  }
37799
37963
  }
37800
37964
  if (!stateFile || !existsSync75(stateFile)) {
37801
- stateFile = join78(cleoDirAbs, ".context-state.json");
37965
+ stateFile = join77(cleoDirAbs, ".context-state.json");
37802
37966
  }
37803
37967
  if (!existsSync75(stateFile)) {
37804
37968
  return defaultState;
@@ -37827,7 +37991,7 @@ function getContextState(sessionId, cwd) {
37827
37991
  async function sessionInit(_epicId, cwd) {
37828
37992
  const sessionsPath = getSessionsPath(cwd);
37829
37993
  const cleoDirAbs = getCleoDirAbsolute(cwd);
37830
- const focusPath = join78(cleoDirAbs, "focus.json");
37994
+ const focusPath = join77(cleoDirAbs, "focus.json");
37831
37995
  let activeSessions = 0;
37832
37996
  let activeSessionId = null;
37833
37997
  let activeScope = null;
@@ -38020,13 +38184,13 @@ async function generateHitlSummary(epicId, stopReason = "context-limit", cwd) {
38020
38184
  const taskPath = getTaskPath(cwd);
38021
38185
  const cleoDirAbs = getCleoDirAbsolute(cwd);
38022
38186
  let sessionId = null;
38023
- const currentSessionFile = join78(cleoDirAbs, ".current-session");
38187
+ const currentSessionFile = join77(cleoDirAbs, ".current-session");
38024
38188
  if (existsSync75(currentSessionFile)) {
38025
38189
  sessionId = readFileSync55(currentSessionFile, "utf-8").trim() || null;
38026
38190
  }
38027
38191
  let focusedTask = null;
38028
38192
  let progressNote = null;
38029
- const focusPath = join78(cleoDirAbs, "focus.json");
38193
+ const focusPath = join77(cleoDirAbs, "focus.json");
38030
38194
  if (existsSync75(focusPath)) {
38031
38195
  try {
38032
38196
  const focus = JSON.parse(readFileSync55(focusPath, "utf-8"));
@@ -38109,7 +38273,7 @@ function priorityRank(priority) {
38109
38273
  init_src();
38110
38274
  init_paths();
38111
38275
  import { existsSync as existsSync76, readFileSync as readFileSync56 } from "node:fs";
38112
- import { join as join79 } from "node:path";
38276
+ import { join as join78 } from "node:path";
38113
38277
  var KEY_FINDINGS_MIN = 3;
38114
38278
  var KEY_FINDINGS_MAX = 7;
38115
38279
  var MANIFEST_REQUIRED_FIELDS = [
@@ -38190,7 +38354,7 @@ function validateSubagentOutput(researchId, cwd) {
38190
38354
  }
38191
38355
  if (entry.file) {
38192
38356
  const absOutputDir = getAgentOutputsAbsolute(cwd);
38193
- const filePath = join79(absOutputDir, entry.file);
38357
+ const filePath = join78(absOutputDir, entry.file);
38194
38358
  if (!existsSync76(filePath)) {
38195
38359
  issues.push(`FILE_NOT_FOUND: Expected file at ${filePath}`);
38196
38360
  }
@@ -38233,7 +38397,7 @@ function validateManifestIntegrity(cwd) {
38233
38397
  seenIds.add(entry.id);
38234
38398
  if (entry.file) {
38235
38399
  const absOutputDir = getAgentOutputsAbsolute(cwd);
38236
- const filePath = join79(absOutputDir, entry.file);
38400
+ const filePath = join78(absOutputDir, entry.file);
38237
38401
  if (!existsSync76(filePath)) {
38238
38402
  issues.push(`LINE_${lineNum}_FILE_MISSING: ${entry.file} does not exist`);
38239
38403
  }
@@ -38349,13 +38513,13 @@ function validateOrchestratorCompliance(epicId, cwd) {
38349
38513
  // packages/core/src/skills/skill-paths.ts
38350
38514
  init_paths();
38351
38515
  import { existsSync as existsSync77, lstatSync, readlinkSync as readlinkSync2, realpathSync as realpathSync2 } from "node:fs";
38352
- import { delimiter, join as join80, resolve as resolve9 } from "node:path";
38516
+ import { delimiter, join as join79, resolve as resolve9 } from "node:path";
38353
38517
  function getCaampCanonical() {
38354
- return join80(getAgentsHome(), "skills");
38518
+ return join79(getAgentsHome(), "skills");
38355
38519
  }
38356
38520
  function getProjectEmbedded(projectRoot) {
38357
38521
  const root = projectRoot ?? process.cwd();
38358
- return join80(root, "skills");
38522
+ return join79(root, "skills");
38359
38523
  }
38360
38524
  function getProjectRoot3(cwd) {
38361
38525
  return cwd ?? process.cwd();
@@ -38405,8 +38569,8 @@ function getSkillSearchPaths2(projectRoot) {
38405
38569
  function resolveSkillPath(skillName, projectRoot) {
38406
38570
  const searchPaths = getSkillSearchPaths2(projectRoot);
38407
38571
  for (const { path: searchPath } of searchPaths) {
38408
- const candidate = join80(searchPath, skillName);
38409
- if (existsSync77(join80(candidate, "SKILL.md"))) {
38572
+ const candidate = join79(searchPath, skillName);
38573
+ if (existsSync77(join79(candidate, "SKILL.md"))) {
38410
38574
  return safeRealpath(candidate);
38411
38575
  }
38412
38576
  }
@@ -38415,13 +38579,13 @@ function resolveSkillPath(skillName, projectRoot) {
38415
38579
  function resolveProtocolPath(protocolName, projectRoot) {
38416
38580
  const searchPaths = getSkillSearchPaths2(projectRoot);
38417
38581
  for (const { path: searchPath } of searchPaths) {
38418
- const candidate = join80(searchPath, "_ct-skills-protocols", `${protocolName}.md`);
38582
+ const candidate = join79(searchPath, "_ct-skills-protocols", `${protocolName}.md`);
38419
38583
  if (existsSync77(candidate)) {
38420
38584
  return safeRealpath(candidate);
38421
38585
  }
38422
38586
  }
38423
38587
  const root = getProjectRoot3(projectRoot);
38424
- const legacy = join80(root, "src", "protocols", `${protocolName}.md`);
38588
+ const legacy = join79(root, "src", "protocols", `${protocolName}.md`);
38425
38589
  if (existsSync77(legacy)) {
38426
38590
  return safeRealpath(legacy);
38427
38591
  }
@@ -38430,11 +38594,11 @@ function resolveProtocolPath(protocolName, projectRoot) {
38430
38594
  function resolveSharedPath(resourceName, projectRoot) {
38431
38595
  const searchPaths = getSkillSearchPaths2(projectRoot);
38432
38596
  for (const { path: searchPath } of searchPaths) {
38433
- const candidate = join80(searchPath, "_ct-skills-shared", `${resourceName}.md`);
38597
+ const candidate = join79(searchPath, "_ct-skills-shared", `${resourceName}.md`);
38434
38598
  if (existsSync77(candidate)) {
38435
38599
  return safeRealpath(candidate);
38436
38600
  }
38437
- const legacy = join80(searchPath, "_shared", `${resourceName}.md`);
38601
+ const legacy = join79(searchPath, "_shared", `${resourceName}.md`);
38438
38602
  if (existsSync77(legacy)) {
38439
38603
  return safeRealpath(legacy);
38440
38604
  }
@@ -38460,7 +38624,7 @@ function getSkillSourceType(skillDir, projectRoot) {
38460
38624
  }
38461
38625
  } catch {
38462
38626
  }
38463
- if (normalizedDir.startsWith(resolve9(embeddedDir)) || normalizedDir.startsWith(join80(root, "skills"))) {
38627
+ if (normalizedDir.startsWith(resolve9(embeddedDir)) || normalizedDir.startsWith(join79(root, "skills"))) {
38464
38628
  return "embedded";
38465
38629
  }
38466
38630
  if (normalizedDir.startsWith(caampDir)) {
@@ -38492,7 +38656,7 @@ function formatDateYMD(date2) {
38492
38656
 
38493
38657
  // packages/core/src/skills/validation.ts
38494
38658
  import { existsSync as existsSync78, readFileSync as readFileSync57 } from "node:fs";
38495
- import { basename as basename13, join as join81 } from "node:path";
38659
+ import { basename as basename13, join as join80 } from "node:path";
38496
38660
  var VALID_PROTOCOLS = /* @__PURE__ */ new Set([
38497
38661
  "research",
38498
38662
  "consensus",
@@ -38515,7 +38679,7 @@ function validateSkill(skillDir) {
38515
38679
  });
38516
38680
  return buildResult(dirName, skillDir, issues);
38517
38681
  }
38518
- const skillMdPath = join81(skillDir, "SKILL.md");
38682
+ const skillMdPath = join80(skillDir, "SKILL.md");
38519
38683
  if (!existsSync78(skillMdPath)) {
38520
38684
  issues.push({
38521
38685
  severity: "error",
@@ -38537,7 +38701,7 @@ function validateSkill(skillDir) {
38537
38701
  }
38538
38702
  const optionalFiles = ["README.md", "references"];
38539
38703
  for (const file of optionalFiles) {
38540
- const filePath = join81(skillDir, file);
38704
+ const filePath = join80(skillDir, file);
38541
38705
  if (!existsSync78(filePath)) {
38542
38706
  issues.push({
38543
38707
  severity: "info",
@@ -38686,8 +38850,8 @@ init_paths();
38686
38850
  init_data_accessor();
38687
38851
  import { createHash as createHash8 } from "node:crypto";
38688
38852
  import { existsSync as existsSync79 } from "node:fs";
38689
- import { mkdir as mkdir14, readFile as readFile13, writeFile as writeFile10 } from "node:fs/promises";
38690
- import { dirname as dirname15, join as join82 } from "node:path";
38853
+ import { mkdir as mkdir13, readFile as readFile13, writeFile as writeFile10 } from "node:fs/promises";
38854
+ import { dirname as dirname15, join as join81 } from "node:path";
38691
38855
  var SNAPSHOT_FORMAT_VERSION = "1.0.0";
38692
38856
  function toSnapshotTask(task) {
38693
38857
  return {
@@ -38746,7 +38910,7 @@ async function exportSnapshot(cwd) {
38746
38910
  async function writeSnapshot(snapshot, outputPath) {
38747
38911
  const dir = dirname15(outputPath);
38748
38912
  if (!existsSync79(dir)) {
38749
- await mkdir14(dir, { recursive: true });
38913
+ await mkdir13(dir, { recursive: true });
38750
38914
  }
38751
38915
  await writeFile10(outputPath, JSON.stringify(snapshot, null, 2) + "\n");
38752
38916
  }
@@ -38763,7 +38927,7 @@ async function readSnapshot(inputPath) {
38763
38927
  function getDefaultSnapshotPath(cwd) {
38764
38928
  const cleoDir = getCleoDirAbsolute(cwd);
38765
38929
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
38766
- return join82(cleoDir, "snapshots", `snapshot-${timestamp2}.json`);
38930
+ return join81(cleoDir, "snapshots", `snapshot-${timestamp2}.json`);
38767
38931
  }
38768
38932
  async function importSnapshot(snapshot, cwd) {
38769
38933
  const accessor = await getAccessor(cwd);
@@ -38991,8 +39155,8 @@ async function initializeSpawnAdapters(manifests) {
38991
39155
  if (!manifest.capabilities?.supportsSpawn) continue;
38992
39156
  if (spawnRegistry.hasAdapterForProvider(manifest.provider)) continue;
38993
39157
  try {
38994
- const { join: join105 } = await import("node:path");
38995
- const modulePath = join105(manifest.packagePath, manifest.entryPoint);
39158
+ const { join: join103 } = await import("node:path");
39159
+ const modulePath = join103(manifest.packagePath, manifest.entryPoint);
38996
39160
  const adapterModule = await import(modulePath);
38997
39161
  let SpawnProviderClass;
38998
39162
  for (const [exportName, exportValue] of Object.entries(adapterModule)) {
@@ -39943,13 +40107,13 @@ async function getArchiveStats(opts, accessor) {
39943
40107
  // packages/core/src/system/audit.ts
39944
40108
  init_data_accessor();
39945
40109
  import { existsSync as existsSync80, readFileSync as readFileSync58 } from "node:fs";
39946
- import { join as join83 } from "node:path";
40110
+ import { join as join82 } from "node:path";
39947
40111
  async function auditData(projectRoot, opts) {
39948
- const cleoDir = join83(projectRoot, ".cleo");
40112
+ const cleoDir = join82(projectRoot, ".cleo");
39949
40113
  const scope = opts?.scope ?? "all";
39950
40114
  const issues = [];
39951
40115
  if (scope === "all" || scope === "tasks") {
39952
- const tasksDbPath = join83(cleoDir, "tasks.db");
40116
+ const tasksDbPath = join82(cleoDir, "tasks.db");
39953
40117
  if (existsSync80(tasksDbPath)) {
39954
40118
  try {
39955
40119
  const accessor = await getAccessor(projectRoot);
@@ -40012,7 +40176,7 @@ async function auditData(projectRoot, opts) {
40012
40176
  }
40013
40177
  }
40014
40178
  if (scope === "all" || scope === "sessions") {
40015
- const sessPath = join83(cleoDir, "sessions.json");
40179
+ const sessPath = join82(cleoDir, "sessions.json");
40016
40180
  if (existsSync80(sessPath)) {
40017
40181
  try {
40018
40182
  const data = JSON.parse(readFileSync58(sessPath, "utf-8"));
@@ -40047,7 +40211,7 @@ async function auditData(projectRoot, opts) {
40047
40211
  }
40048
40212
  }
40049
40213
  if (scope === "all") {
40050
- const seqPath = join83(cleoDir, ".sequence.json");
40214
+ const seqPath = join82(cleoDir, ".sequence.json");
40051
40215
  if (existsSync80(seqPath)) {
40052
40216
  try {
40053
40217
  const seq = JSON.parse(readFileSync58(seqPath, "utf-8"));
@@ -40082,22 +40246,22 @@ async function auditData(projectRoot, opts) {
40082
40246
  init_src();
40083
40247
  init_errors3();
40084
40248
  import { existsSync as existsSync81, mkdirSync as mkdirSync18, readFileSync as readFileSync59, writeFileSync as writeFileSync11 } from "node:fs";
40085
- import { join as join84 } from "node:path";
40249
+ import { join as join83 } from "node:path";
40086
40250
  function createBackup2(projectRoot, opts) {
40087
- const cleoDir = join84(projectRoot, ".cleo");
40251
+ const cleoDir = join83(projectRoot, ".cleo");
40088
40252
  const btype = opts?.type || "snapshot";
40089
40253
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
40090
40254
  const backupId = `${btype}-${timestamp2.replace(/[:.]/g, "-")}`;
40091
- const backupDir = join84(cleoDir, "backups", btype);
40255
+ const backupDir = join83(cleoDir, "backups", btype);
40092
40256
  if (!existsSync81(backupDir)) {
40093
40257
  mkdirSync18(backupDir, { recursive: true });
40094
40258
  }
40095
40259
  const filesToBackup = ["tasks.db", "brain.db", "config.json", "project-info.json"];
40096
40260
  const backedUp = [];
40097
40261
  for (const file of filesToBackup) {
40098
- const src = join84(cleoDir, file);
40262
+ const src = join83(cleoDir, file);
40099
40263
  if (existsSync81(src)) {
40100
- const dest = join84(backupDir, `${file}.${backupId}`);
40264
+ const dest = join83(backupDir, `${file}.${backupId}`);
40101
40265
  try {
40102
40266
  const content = readFileSync59(src);
40103
40267
  writeFileSync11(dest, content);
@@ -40106,7 +40270,7 @@ function createBackup2(projectRoot, opts) {
40106
40270
  }
40107
40271
  }
40108
40272
  }
40109
- const metaPath = join84(backupDir, `${backupId}.meta.json`);
40273
+ const metaPath = join83(backupDir, `${backupId}.meta.json`);
40110
40274
  try {
40111
40275
  writeFileSync11(
40112
40276
  metaPath,
@@ -40131,15 +40295,15 @@ function restoreBackup(projectRoot, params) {
40131
40295
  if (!params.backupId) {
40132
40296
  throw new CleoError(2 /* INVALID_INPUT */, "backupId is required");
40133
40297
  }
40134
- const cleoDir = join84(projectRoot, ".cleo");
40298
+ const cleoDir = join83(projectRoot, ".cleo");
40135
40299
  const backupTypes = ["snapshot", "safety", "migration"];
40136
40300
  let metaPath = null;
40137
40301
  let backupDir = null;
40138
40302
  for (const btype of backupTypes) {
40139
- const candidateMeta = join84(cleoDir, "backups", btype, `${params.backupId}.meta.json`);
40303
+ const candidateMeta = join83(cleoDir, "backups", btype, `${params.backupId}.meta.json`);
40140
40304
  if (existsSync81(candidateMeta)) {
40141
40305
  metaPath = candidateMeta;
40142
- backupDir = join84(cleoDir, "backups", btype);
40306
+ backupDir = join83(cleoDir, "backups", btype);
40143
40307
  break;
40144
40308
  }
40145
40309
  }
@@ -40154,11 +40318,11 @@ function restoreBackup(projectRoot, params) {
40154
40318
  }
40155
40319
  const restored = [];
40156
40320
  for (const file of meta.files ?? []) {
40157
- const backupFile = join84(backupDir, `${file}.${params.backupId}`);
40321
+ const backupFile = join83(backupDir, `${file}.${params.backupId}`);
40158
40322
  if (existsSync81(backupFile)) {
40159
40323
  try {
40160
40324
  const content = readFileSync59(backupFile);
40161
- writeFileSync11(join84(cleoDir, file), content);
40325
+ writeFileSync11(join83(cleoDir, file), content);
40162
40326
  restored.push(file);
40163
40327
  } catch {
40164
40328
  }
@@ -40175,12 +40339,12 @@ function restoreBackup(projectRoot, params) {
40175
40339
  // packages/core/src/system/cleanup.ts
40176
40340
  init_src();
40177
40341
  import { existsSync as existsSync82, readdirSync as readdirSync27, readFileSync as readFileSync60, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
40178
- import { join as join86 } from "node:path";
40342
+ import { join as join85 } from "node:path";
40179
40343
 
40180
40344
  // packages/core/src/audit-prune.ts
40181
40345
  init_logger();
40182
40346
  import { createWriteStream, mkdirSync as mkdirSync19 } from "node:fs";
40183
- import { join as join85 } from "node:path";
40347
+ import { join as join84 } from "node:path";
40184
40348
  import { Readable } from "node:stream";
40185
40349
  import { pipeline } from "node:stream/promises";
40186
40350
  import { createGzip } from "node:zlib";
@@ -40192,7 +40356,7 @@ async function pruneAuditLog(cleoDir, config) {
40192
40356
  return { rowsArchived: 0, rowsDeleted: 0 };
40193
40357
  }
40194
40358
  const cutoff = new Date(Date.now() - config.auditRetentionDays * 864e5).toISOString();
40195
- const projectRoot = join85(cleoDir, "..");
40359
+ const projectRoot = join84(cleoDir, "..");
40196
40360
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
40197
40361
  const { auditLog: auditLog2 } = await Promise.resolve().then(() => (init_tasks_schema(), tasks_schema_exports));
40198
40362
  const { lt: lt2 } = await import("drizzle-orm");
@@ -40206,10 +40370,10 @@ async function pruneAuditLog(cleoDir, config) {
40206
40370
  let rowsArchived = 0;
40207
40371
  if (config.archiveBeforePrune) {
40208
40372
  try {
40209
- const archiveDir = join85(cleoDir, "backups", "logs");
40373
+ const archiveDir = join84(cleoDir, "backups", "logs");
40210
40374
  mkdirSync19(archiveDir, { recursive: true });
40211
40375
  const dateStamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
40212
- archivePath = join85(archiveDir, `audit-${dateStamp}.jsonl.gz`);
40376
+ archivePath = join84(archiveDir, `audit-${dateStamp}.jsonl.gz`);
40213
40377
  const lines = oldRows.map((row) => JSON.stringify(row));
40214
40378
  const jsonlContent = lines.join("\n") + "\n";
40215
40379
  const gzip = createGzip();
@@ -40252,7 +40416,7 @@ async function cleanupSystem(projectRoot, params) {
40252
40416
  "target is required (sessions|backups|logs|archive)"
40253
40417
  );
40254
40418
  }
40255
- const cleoDir = join86(projectRoot, ".cleo");
40419
+ const cleoDir = join85(projectRoot, ".cleo");
40256
40420
  const dryRun = params.dryRun ?? false;
40257
40421
  const items = [];
40258
40422
  let prunedRows;
@@ -40260,7 +40424,7 @@ async function cleanupSystem(projectRoot, params) {
40260
40424
  let archivePath;
40261
40425
  switch (params.target) {
40262
40426
  case "sessions": {
40263
- const sessPath = join86(cleoDir, "sessions.json");
40427
+ const sessPath = join85(cleoDir, "sessions.json");
40264
40428
  if (existsSync82(sessPath)) {
40265
40429
  try {
40266
40430
  const data = JSON.parse(readFileSync60(sessPath, "utf-8"));
@@ -40289,14 +40453,14 @@ async function cleanupSystem(projectRoot, params) {
40289
40453
  break;
40290
40454
  }
40291
40455
  case "backups": {
40292
- const backupBaseDir = join86(cleoDir, "backups");
40456
+ const backupBaseDir = join85(cleoDir, "backups");
40293
40457
  if (existsSync82(backupBaseDir)) {
40294
40458
  for (const typeDir of readdirSync27(backupBaseDir)) {
40295
- const fullDir = join86(backupBaseDir, typeDir);
40459
+ const fullDir = join85(backupBaseDir, typeDir);
40296
40460
  try {
40297
40461
  for (const file of readdirSync27(fullDir)) {
40298
40462
  if (file.endsWith(".meta.json")) {
40299
- const metaFilePath = join86(fullDir, file);
40463
+ const metaFilePath = join85(fullDir, file);
40300
40464
  try {
40301
40465
  const meta = JSON.parse(readFileSync60(metaFilePath, "utf-8"));
40302
40466
  if (params.olderThan && meta.timestamp < params.olderThan) {
@@ -40306,7 +40470,7 @@ async function cleanupSystem(projectRoot, params) {
40306
40470
  for (const bf of readdirSync27(fullDir)) {
40307
40471
  if (bf.includes(meta.backupId)) {
40308
40472
  try {
40309
- unlinkSync5(join86(fullDir, bf));
40473
+ unlinkSync5(join85(fullDir, bf));
40310
40474
  } catch {
40311
40475
  }
40312
40476
  }
@@ -40338,7 +40502,7 @@ async function cleanupSystem(projectRoot, params) {
40338
40502
  items.push(file);
40339
40503
  if (!dryRun) {
40340
40504
  try {
40341
- unlinkSync5(join86(cleoDir, file));
40505
+ unlinkSync5(join85(cleoDir, file));
40342
40506
  } catch {
40343
40507
  }
40344
40508
  }
@@ -40368,7 +40532,7 @@ init_paths();
40368
40532
  import { execFile as execFile6, execFileSync as execFileSync10 } from "node:child_process";
40369
40533
  import { existsSync as existsSync86, readFileSync as readFileSync63, statSync as statSync19 } from "node:fs";
40370
40534
  import { createRequire as createRequire4 } from "node:module";
40371
- import { join as join90 } from "node:path";
40535
+ import { join as join89 } from "node:path";
40372
40536
  import { promisify as promisify6 } from "node:util";
40373
40537
 
40374
40538
  // packages/core/src/platform.ts
@@ -40395,25 +40559,25 @@ import {
40395
40559
  unlinkSync as unlinkSync6,
40396
40560
  writeFileSync as writeFileSync13
40397
40561
  } from "node:fs";
40398
- import { basename as basename14, dirname as dirname16, join as join88 } from "node:path";
40562
+ import { basename as basename14, dirname as dirname16, join as join87 } from "node:path";
40399
40563
  import * as lockfile2 from "proper-lockfile";
40400
40564
  var MAX_BACKUPS = 10;
40401
40565
  function rotateBackup(filePath) {
40402
40566
  const dir = dirname16(filePath);
40403
40567
  const name2 = basename14(filePath);
40404
- const backupDir = join88(dir, ".backups");
40568
+ const backupDir = join87(dir, ".backups");
40405
40569
  if (!existsSync84(backupDir)) {
40406
40570
  mkdirSync20(backupDir, { recursive: true });
40407
40571
  }
40408
40572
  for (let i = MAX_BACKUPS; i >= 1; i--) {
40409
- const current = join88(backupDir, `${name2}.${i}`);
40573
+ const current = join87(backupDir, `${name2}.${i}`);
40410
40574
  if (i === MAX_BACKUPS) {
40411
40575
  try {
40412
40576
  unlinkSync6(current);
40413
40577
  } catch {
40414
40578
  }
40415
40579
  } else {
40416
- const next = join88(backupDir, `${name2}.${i + 1}`);
40580
+ const next = join87(backupDir, `${name2}.${i + 1}`);
40417
40581
  try {
40418
40582
  if (existsSync84(current)) renameSync6(current, next);
40419
40583
  } catch {
@@ -40422,13 +40586,13 @@ function rotateBackup(filePath) {
40422
40586
  }
40423
40587
  try {
40424
40588
  const content = readFileSync61(filePath, "utf-8");
40425
- writeFileSync13(join88(backupDir, `${name2}.1`), content, "utf-8");
40589
+ writeFileSync13(join87(backupDir, `${name2}.1`), content, "utf-8");
40426
40590
  } catch {
40427
40591
  }
40428
40592
  }
40429
40593
  function writeJsonFileAtomic(filePath, data, indent = 2) {
40430
40594
  const dir = dirname16(filePath);
40431
- const tempPath = join88(dir, `.${basename14(filePath)}.${randomBytes8(6).toString("hex")}.tmp`);
40595
+ const tempPath = join87(dir, `.${basename14(filePath)}.${randomBytes8(6).toString("hex")}.tmp`);
40432
40596
  const content = JSON.stringify(data, null, indent) + "\n";
40433
40597
  writeFileSync13(tempPath, content, "utf-8");
40434
40598
  try {
@@ -40445,7 +40609,7 @@ function writeJsonFileAtomic(filePath, data, indent = 2) {
40445
40609
  }
40446
40610
  }
40447
40611
  function getDataPath(projectRoot, filename) {
40448
- return join88(projectRoot, ".cleo", filename);
40612
+ return join87(projectRoot, ".cleo", filename);
40449
40613
  }
40450
40614
 
40451
40615
  // packages/core/src/platform.ts
@@ -40569,7 +40733,7 @@ init_data_accessor();
40569
40733
  import { execFileSync as execFileSync9 } from "node:child_process";
40570
40734
  import { accessSync as accessSync2, constants as constants2, existsSync as existsSync85, readFileSync as readFileSync62, statSync as statSync18 } from "node:fs";
40571
40735
  import { homedir as homedir4 } from "node:os";
40572
- import { join as join89 } from "node:path";
40736
+ import { join as join88 } from "node:path";
40573
40737
 
40574
40738
  // packages/core/src/constants.ts
40575
40739
  var CORE_PROTECTED_FILES = [
@@ -40596,7 +40760,7 @@ function checkCliInstallation(cleoHome = getCleoHome()) {
40596
40760
  }
40597
40761
  var VERSION_REGEX = /^\d+\.\d+\.\d+$/;
40598
40762
  function checkCliVersion(cleoHome = getCleoHome()) {
40599
- const versionFile = join89(cleoHome, "VERSION");
40763
+ const versionFile = join88(cleoHome, "VERSION");
40600
40764
  if (!existsSync85(versionFile)) {
40601
40765
  return {
40602
40766
  id: "cli_version",
@@ -40619,7 +40783,7 @@ function checkCliVersion(cleoHome = getCleoHome()) {
40619
40783
  };
40620
40784
  }
40621
40785
  function checkDocsAccessibility(cleoHome = getCleoHome()) {
40622
- const docsFile = join89(cleoHome, "templates", "CLEO-INJECTION.md");
40786
+ const docsFile = join88(cleoHome, "templates", "CLEO-INJECTION.md");
40623
40787
  if (!existsSync85(docsFile)) {
40624
40788
  return {
40625
40789
  id: "docs_accessibility",
@@ -40653,7 +40817,7 @@ function checkDocsAccessibility(cleoHome = getCleoHome()) {
40653
40817
  };
40654
40818
  }
40655
40819
  function checkAtReferenceResolution(cleoHome = getCleoHome()) {
40656
- const docsFile = join89(cleoHome, "templates", "CLEO-INJECTION.md");
40820
+ const docsFile = join88(cleoHome, "templates", "CLEO-INJECTION.md");
40657
40821
  const reference = "@~/.cleo/templates/CLEO-INJECTION.md";
40658
40822
  if (!existsSync85(docsFile)) {
40659
40823
  return {
@@ -40701,7 +40865,7 @@ function checkAtReferenceResolution(cleoHome = getCleoHome()) {
40701
40865
  }
40702
40866
  function checkAgentsMdHub(projectRoot) {
40703
40867
  const root = projectRoot ?? process.cwd();
40704
- const agentsMdPath = join89(root, "AGENTS.md");
40868
+ const agentsMdPath = join88(root, "AGENTS.md");
40705
40869
  if (!existsSync85(agentsMdPath)) {
40706
40870
  return {
40707
40871
  id: "agents_md_hub",
@@ -40746,7 +40910,7 @@ function checkAgentsMdHub(projectRoot) {
40746
40910
  }
40747
40911
  function checkRootGitignore(projectRoot) {
40748
40912
  const root = projectRoot ?? process.cwd();
40749
- const gitignorePath = join89(root, ".gitignore");
40913
+ const gitignorePath = join88(root, ".gitignore");
40750
40914
  if (!existsSync85(gitignorePath)) {
40751
40915
  return {
40752
40916
  id: "root_gitignore",
@@ -40797,7 +40961,7 @@ function checkRootGitignore(projectRoot) {
40797
40961
  }
40798
40962
  function checkCleoGitignore(projectRoot) {
40799
40963
  const root = projectRoot ?? process.cwd();
40800
- const gitignorePath = join89(root, ".cleo", ".gitignore");
40964
+ const gitignorePath = join88(root, ".cleo", ".gitignore");
40801
40965
  if (!existsSync85(gitignorePath)) {
40802
40966
  return {
40803
40967
  id: "cleo_gitignore",
@@ -40827,8 +40991,8 @@ function checkCleoGitignore(projectRoot) {
40827
40991
  } catch {
40828
40992
  try {
40829
40993
  const templatePaths = [
40830
- join89(root, "templates", "cleo-gitignore"),
40831
- join89(getCleoHome(), "templates", "cleo-gitignore")
40994
+ join88(root, "templates", "cleo-gitignore"),
40995
+ join88(getCleoHome(), "templates", "cleo-gitignore")
40832
40996
  ];
40833
40997
  for (const tp of templatePaths) {
40834
40998
  if (existsSync85(tp)) {
@@ -40869,7 +41033,7 @@ function detectStorageEngine(_projectRoot) {
40869
41033
  }
40870
41034
  function checkVitalFilesTracked(projectRoot) {
40871
41035
  const root = projectRoot ?? process.cwd();
40872
- const gitDir = join89(root, ".git");
41036
+ const gitDir = join88(root, ".git");
40873
41037
  if (!existsSync85(gitDir)) {
40874
41038
  return {
40875
41039
  id: "vital_files_tracked",
@@ -40884,7 +41048,7 @@ function checkVitalFilesTracked(projectRoot) {
40884
41048
  const vitalFiles = CORE_PROTECTED_FILES.map((f) => `.cleo/${f}`);
40885
41049
  const untracked = [];
40886
41050
  for (const file of vitalFiles) {
40887
- const fullPath = join89(root, file);
41051
+ const fullPath = join88(root, file);
40888
41052
  if (!existsSync85(fullPath)) continue;
40889
41053
  try {
40890
41054
  execFileSync9("git", ["ls-files", "--error-unmatch", file], {
@@ -40916,7 +41080,7 @@ function checkVitalFilesTracked(projectRoot) {
40916
41080
  }
40917
41081
  function checkCoreFilesNotIgnored(projectRoot) {
40918
41082
  const root = projectRoot ?? process.cwd();
40919
- const gitDir = join89(root, ".git");
41083
+ const gitDir = join88(root, ".git");
40920
41084
  if (!existsSync85(gitDir)) {
40921
41085
  return {
40922
41086
  id: "core_files_not_ignored",
@@ -40930,7 +41094,7 @@ function checkCoreFilesNotIgnored(projectRoot) {
40930
41094
  const ignoredFiles = [];
40931
41095
  for (const file of CORE_PROTECTED_FILES) {
40932
41096
  const relPath = `.cleo/${file}`;
40933
- const fullPath = join89(root, relPath);
41097
+ const fullPath = join88(root, relPath);
40934
41098
  if (!existsSync85(fullPath)) continue;
40935
41099
  try {
40936
41100
  execFileSync9("git", ["check-ignore", "-q", relPath], {
@@ -40962,7 +41126,7 @@ function checkCoreFilesNotIgnored(projectRoot) {
40962
41126
  }
40963
41127
  function checkSqliteNotTracked(projectRoot) {
40964
41128
  const root = projectRoot ?? process.cwd();
40965
- const gitDir = join89(root, ".git");
41129
+ const gitDir = join88(root, ".git");
40966
41130
  if (!existsSync85(gitDir)) {
40967
41131
  return {
40968
41132
  id: "sqlite_not_tracked",
@@ -40974,7 +41138,7 @@ function checkSqliteNotTracked(projectRoot) {
40974
41138
  };
40975
41139
  }
40976
41140
  const sqliteFile = ".cleo/tasks.db";
40977
- const fullPath = join89(root, sqliteFile);
41141
+ const fullPath = join88(root, sqliteFile);
40978
41142
  if (!existsSync85(fullPath)) {
40979
41143
  return {
40980
41144
  id: "sqlite_not_tracked",
@@ -41011,7 +41175,7 @@ function checkSqliteNotTracked(projectRoot) {
41011
41175
  }
41012
41176
  function checkLegacyAgentOutputs(projectRoot) {
41013
41177
  const root = projectRoot ?? process.cwd();
41014
- const cleoDir = join89(root, ".cleo");
41178
+ const cleoDir = join88(root, ".cleo");
41015
41179
  const detection = detectLegacyAgentOutputs(root, cleoDir);
41016
41180
  if (detection.hasLegacy) {
41017
41181
  return {
@@ -41037,7 +41201,7 @@ function checkCaampMarkerIntegrity(projectRoot) {
41037
41201
  const files = ["CLAUDE.md", "AGENTS.md"];
41038
41202
  const issues = [];
41039
41203
  for (const file of files) {
41040
- const filePath = join89(root, file);
41204
+ const filePath = join88(root, file);
41041
41205
  if (!existsSync85(filePath)) continue;
41042
41206
  let content;
41043
41207
  try {
@@ -41075,7 +41239,7 @@ function checkCaampMarkerIntegrity(projectRoot) {
41075
41239
  }
41076
41240
  function checkAtReferenceTargetExists(projectRoot) {
41077
41241
  const root = projectRoot ?? process.cwd();
41078
- const agentsPath = join89(root, "AGENTS.md");
41242
+ const agentsPath = join88(root, "AGENTS.md");
41079
41243
  if (!existsSync85(agentsPath)) {
41080
41244
  return {
41081
41245
  id: "at_reference_targets",
@@ -41115,7 +41279,7 @@ function checkAtReferenceTargetExists(projectRoot) {
41115
41279
  const missing = [];
41116
41280
  for (const ref of refs) {
41117
41281
  const rawPath = ref.slice(1).trim();
41118
- const resolvedPath = rawPath.startsWith("~/") ? join89(homedir4(), rawPath.slice(2)) : join89(root, rawPath);
41282
+ const resolvedPath = rawPath.startsWith("~/") ? join88(homedir4(), rawPath.slice(2)) : join88(root, rawPath);
41119
41283
  if (!existsSync85(resolvedPath)) {
41120
41284
  missing.push(rawPath);
41121
41285
  }
@@ -41142,8 +41306,8 @@ function checkAtReferenceTargetExists(projectRoot) {
41142
41306
  function checkTemplateFreshness(projectRoot, cleoHome) {
41143
41307
  const root = projectRoot ?? process.cwd();
41144
41308
  const home = cleoHome ?? getCleoHome();
41145
- const sourcePath = join89(root, "templates", "CLEO-INJECTION.md");
41146
- const deployedPath = join89(home, "templates", "CLEO-INJECTION.md");
41309
+ const sourcePath = join88(root, "templates", "CLEO-INJECTION.md");
41310
+ const deployedPath = join88(home, "templates", "CLEO-INJECTION.md");
41147
41311
  if (!existsSync85(sourcePath)) {
41148
41312
  return {
41149
41313
  id: "template_freshness",
@@ -41187,7 +41351,7 @@ function checkTemplateFreshness(projectRoot, cleoHome) {
41187
41351
  }
41188
41352
  function checkTierMarkersPresent(cleoHome) {
41189
41353
  const home = cleoHome ?? getCleoHome();
41190
- const templatePath = join89(home, "templates", "CLEO-INJECTION.md");
41354
+ const templatePath = join88(home, "templates", "CLEO-INJECTION.md");
41191
41355
  if (!existsSync85(templatePath)) {
41192
41356
  return {
41193
41357
  id: "tier_markers_present",
@@ -41309,7 +41473,7 @@ function checkGlobalSchemaHealth(_projectRoot) {
41309
41473
  }
41310
41474
  function checkNoLocalSchemas(projectRoot) {
41311
41475
  const root = projectRoot ?? process.cwd();
41312
- const localSchemasDir = join89(root, ".cleo", "schemas");
41476
+ const localSchemasDir = join88(root, ".cleo", "schemas");
41313
41477
  if (!existsSync85(localSchemasDir)) {
41314
41478
  return {
41315
41479
  id: "no_local_schemas",
@@ -41374,13 +41538,13 @@ var databaseSyncCtor = (() => {
41374
41538
  })();
41375
41539
  var STALE_JSON_FILES = ["todo.json", "sessions.json", "todo-archive.json"];
41376
41540
  function resolveStructuredLogPath(cleoDir) {
41377
- const defaultPath = join90(cleoDir, "logs", "cleo.log");
41378
- const configPath = join90(cleoDir, "config.json");
41541
+ const defaultPath = join89(cleoDir, "logs", "cleo.log");
41542
+ const configPath = join89(cleoDir, "config.json");
41379
41543
  if (!existsSync86(configPath)) return defaultPath;
41380
41544
  try {
41381
41545
  const config = JSON.parse(readFileSync63(configPath, "utf-8"));
41382
41546
  if (!config.logging?.filePath) return defaultPath;
41383
- return join90(cleoDir, config.logging.filePath);
41547
+ return join89(cleoDir, config.logging.filePath);
41384
41548
  } catch {
41385
41549
  return defaultPath;
41386
41550
  }
@@ -41422,14 +41586,14 @@ function checkAuditLogAvailability(dbPath) {
41422
41586
  }
41423
41587
  }
41424
41588
  function getSystemHealth(projectRoot, opts) {
41425
- const cleoDir = join90(projectRoot, ".cleo");
41589
+ const cleoDir = join89(projectRoot, ".cleo");
41426
41590
  const checks = [];
41427
41591
  if (existsSync86(cleoDir)) {
41428
41592
  checks.push({ name: "cleo_dir", status: "pass", message: ".cleo directory exists" });
41429
41593
  } else {
41430
41594
  checks.push({ name: "cleo_dir", status: "fail", message: ".cleo directory not found" });
41431
41595
  }
41432
- const dbPath = join90(cleoDir, "tasks.db");
41596
+ const dbPath = join89(cleoDir, "tasks.db");
41433
41597
  if (existsSync86(dbPath)) {
41434
41598
  try {
41435
41599
  const dbSize = statSync19(dbPath).size;
@@ -41451,7 +41615,7 @@ function getSystemHealth(projectRoot, opts) {
41451
41615
  if (existsSync86(dbPath)) {
41452
41616
  checks.push(checkAuditLogAvailability(dbPath));
41453
41617
  }
41454
- const configPath = join90(cleoDir, "config.json");
41618
+ const configPath = join89(cleoDir, "config.json");
41455
41619
  if (existsSync86(configPath)) {
41456
41620
  try {
41457
41621
  JSON.parse(readFileSync63(configPath, "utf-8"));
@@ -41467,7 +41631,7 @@ function getSystemHealth(projectRoot, opts) {
41467
41631
  checks.push({ name: "config_json", status: "warn", message: "config.json not found" });
41468
41632
  }
41469
41633
  if (existsSync86(dbPath)) {
41470
- const staleFiles = STALE_JSON_FILES.filter((f) => existsSync86(join90(cleoDir, f)));
41634
+ const staleFiles = STALE_JSON_FILES.filter((f) => existsSync86(join89(cleoDir, f)));
41471
41635
  if (staleFiles.length > 0) {
41472
41636
  checks.push({
41473
41637
  name: "stale_json",
@@ -41491,7 +41655,7 @@ function getSystemHealth(projectRoot, opts) {
41491
41655
  message: `structured log not found: ${logPath}`
41492
41656
  });
41493
41657
  }
41494
- const backupDir = join90(cleoDir, ".backups");
41658
+ const backupDir = join89(cleoDir, ".backups");
41495
41659
  if (existsSync86(backupDir)) {
41496
41660
  checks.push({ name: "backups_dir", status: "pass", message: ".backups directory exists" });
41497
41661
  } else {
@@ -41504,7 +41668,7 @@ function getSystemHealth(projectRoot, opts) {
41504
41668
  }
41505
41669
  let version = "unknown";
41506
41670
  try {
41507
- const pkgPath = join90(projectRoot, "package.json");
41671
+ const pkgPath = join89(projectRoot, "package.json");
41508
41672
  if (existsSync86(pkgPath)) {
41509
41673
  const pkg = JSON.parse(readFileSync63(pkgPath, "utf-8"));
41510
41674
  version = pkg.version || "unknown";
@@ -41540,8 +41704,8 @@ async function getSystemDiagnostics(projectRoot, opts) {
41540
41704
  details: preflight.summary
41541
41705
  });
41542
41706
  }
41543
- const cleoDir = join90(projectRoot, ".cleo");
41544
- const dbPath = join90(cleoDir, "tasks.db");
41707
+ const cleoDir = join89(projectRoot, ".cleo");
41708
+ const dbPath = join89(cleoDir, "tasks.db");
41545
41709
  if (existsSync86(dbPath)) {
41546
41710
  try {
41547
41711
  const accessor = await getAccessor(projectRoot);
@@ -41681,7 +41845,7 @@ function mapSchemaCheckResult(sr) {
41681
41845
  };
41682
41846
  }
41683
41847
  function checkContributorChannel(projectRoot) {
41684
- const configPath = join90(projectRoot, ".cleo", "config.json");
41848
+ const configPath = join89(projectRoot, ".cleo", "config.json");
41685
41849
  if (!existsSync86(configPath)) {
41686
41850
  return { check: "contributor_channel", status: "ok", message: "Not a contributor project" };
41687
41851
  }
@@ -41698,7 +41862,7 @@ function checkContributorChannel(projectRoot) {
41698
41862
  return { check: "contributor_channel", status: "ok", message: "Not a contributor project" };
41699
41863
  }
41700
41864
  const pathDirs = (process.env["PATH"] ?? "").split(":").filter(Boolean);
41701
- const devCliOnPath = pathDirs.some((dir) => existsSync86(join90(dir, devCli)));
41865
+ const devCliOnPath = pathDirs.some((dir) => existsSync86(join89(dir, devCli)));
41702
41866
  if (!devCliOnPath) {
41703
41867
  return {
41704
41868
  check: "contributor_channel",
@@ -41731,14 +41895,14 @@ async function coreDoctorReport(projectRoot) {
41731
41895
  status: gitPath ? "ok" : "warning",
41732
41896
  message: gitPath ? `git found: ${gitPath}` : "git not found (optional, needed for version control features)"
41733
41897
  });
41734
- const cleoDir = join90(projectRoot, ".cleo");
41898
+ const cleoDir = join89(projectRoot, ".cleo");
41735
41899
  const dirExists = existsSync86(cleoDir);
41736
41900
  checks.push({
41737
41901
  check: "project_dir",
41738
41902
  status: dirExists ? "ok" : "error",
41739
41903
  message: dirExists ? `Project dir: ${cleoDir}` : `Project dir not found: ${cleoDir}. Run: cleo init`
41740
41904
  });
41741
- const dbPath = join90(cleoDir, "tasks.db");
41905
+ const dbPath = join89(cleoDir, "tasks.db");
41742
41906
  const dbExists2 = existsSync86(dbPath);
41743
41907
  const dbSize = await fileSize(dbPath);
41744
41908
  checks.push({
@@ -41788,14 +41952,14 @@ async function coreDoctorReport(projectRoot) {
41788
41952
  } catch {
41789
41953
  }
41790
41954
  }
41791
- const configPath = join90(cleoDir, "config.json");
41955
+ const configPath = join89(cleoDir, "config.json");
41792
41956
  const configExists = existsSync86(configPath);
41793
41957
  checks.push({
41794
41958
  check: "config_file",
41795
41959
  status: configExists ? "ok" : "warning",
41796
41960
  message: configExists ? "config.json present" : "config.json not found (using defaults)"
41797
41961
  });
41798
- const staleJsonFiles = STALE_JSON_FILES.filter((f) => existsSync86(join90(cleoDir, f)));
41962
+ const staleJsonFiles = STALE_JSON_FILES.filter((f) => existsSync86(join89(cleoDir, f)));
41799
41963
  if (dbExists2 && staleJsonFiles.length > 0) {
41800
41964
  checks.push({
41801
41965
  check: "stale_json",
@@ -41811,7 +41975,7 @@ async function coreDoctorReport(projectRoot) {
41811
41975
  status: logExists ? "ok" : "warning",
41812
41976
  message: logExists ? `structured log present: ${logPath}` : `structured log not found: ${logPath}`
41813
41977
  });
41814
- const rootGitignorePath = join90(projectRoot, ".gitignore");
41978
+ const rootGitignorePath = join89(projectRoot, ".gitignore");
41815
41979
  if (existsSync86(rootGitignorePath)) {
41816
41980
  try {
41817
41981
  const gitignoreContent = readFileSync63(rootGitignorePath, "utf-8");
@@ -41833,7 +41997,7 @@ async function coreDoctorReport(projectRoot) {
41833
41997
  checks.push(mapCheckResult(checkVitalFilesTracked(projectRoot)));
41834
41998
  checks.push(mapCheckResult(checkCoreFilesNotIgnored(projectRoot)));
41835
41999
  checks.push(mapCheckResult(checkLegacyAgentOutputs(projectRoot)));
41836
- const cleoGitHeadExists = existsSync86(join90(cleoDir, ".git", "HEAD"));
42000
+ const cleoGitHeadExists = existsSync86(join89(cleoDir, ".git", "HEAD"));
41837
42001
  checks.push({
41838
42002
  check: "cleo_git_repo",
41839
42003
  status: cleoGitHeadExists ? "ok" : "warning",
@@ -41849,15 +42013,15 @@ async function coreDoctorReport(projectRoot) {
41849
42013
  checks.push(mapCheckResult(checkProjectContext(projectRoot)));
41850
42014
  checks.push(mapCheckResult(checkInjection2(projectRoot)));
41851
42015
  checks.push(checkContributorChannel(projectRoot));
41852
- const agentDefPath = join90(getAgentsHome(), "agents", "cleo-subagent");
42016
+ const agentDefPath = join89(getAgentsHome(), "agents", "cleo-subagent");
41853
42017
  checks.push({
41854
42018
  check: "agent_definition",
41855
42019
  status: existsSync86(agentDefPath) ? "ok" : "warning",
41856
42020
  message: existsSync86(agentDefPath) ? "cleo-subagent agent definition installed" : "cleo-subagent not found \u2014 run: cleo init",
41857
42021
  ...existsSync86(agentDefPath) ? {} : { fix: "cleo init" }
41858
42022
  });
41859
- const gitDir = join90(projectRoot, ".git");
41860
- const gitHubTemplatesDir = join90(projectRoot, ".github", "ISSUE_TEMPLATE");
42023
+ const gitDir = join89(projectRoot, ".git");
42024
+ const gitHubTemplatesDir = join89(projectRoot, ".github", "ISSUE_TEMPLATE");
41861
42025
  if (existsSync86(gitDir)) {
41862
42026
  checks.push({
41863
42027
  check: "github_templates",
@@ -41893,11 +42057,11 @@ async function coreDoctorReport(projectRoot) {
41893
42057
  init_paths();
41894
42058
  init_data_accessor();
41895
42059
  import { existsSync as existsSync87, readFileSync as readFileSync64 } from "node:fs";
41896
- import { join as join91 } from "node:path";
42060
+ import { join as join90 } from "node:path";
41897
42061
  async function generateInjection(projectRoot, accessor) {
41898
42062
  let version = "unknown";
41899
42063
  try {
41900
- const pkgPath = join91(projectRoot, "package.json");
42064
+ const pkgPath = join90(projectRoot, "package.json");
41901
42065
  if (existsSync87(pkgPath)) {
41902
42066
  const pkg = JSON.parse(readFileSync64(pkgPath, "utf-8"));
41903
42067
  version = pkg.version || "unknown";
@@ -42031,9 +42195,9 @@ async function getLabels(cwd, accessor) {
42031
42195
 
42032
42196
  // packages/core/src/system/metrics.ts
42033
42197
  import { existsSync as existsSync88, readFileSync as readFileSync65 } from "node:fs";
42034
- import { join as join92 } from "node:path";
42198
+ import { join as join91 } from "node:path";
42035
42199
  async function getSystemMetrics(projectRoot, opts, accessor) {
42036
- const cleoDir = join92(projectRoot, ".cleo");
42200
+ const cleoDir = join91(projectRoot, ".cleo");
42037
42201
  let complianceEntries = readComplianceJsonl(projectRoot);
42038
42202
  if (opts?.since) {
42039
42203
  complianceEntries = complianceEntries.filter((e) => e.timestamp >= opts.since);
@@ -42060,7 +42224,7 @@ async function getSystemMetrics(projectRoot, opts, accessor) {
42060
42224
  sessionsActive = sessions2.filter((s) => s.status === "active").length;
42061
42225
  sessionsCompleted = sessions2.filter((s) => s.status === "ended").length;
42062
42226
  } else {
42063
- const sessionsPath = join92(cleoDir, "sessions.json");
42227
+ const sessionsPath = join91(cleoDir, "sessions.json");
42064
42228
  if (existsSync88(sessionsPath)) {
42065
42229
  const sessionsData = JSON.parse(readFileSync65(sessionsPath, "utf-8"));
42066
42230
  const sessions2 = sessionsData.sessions ?? [];
@@ -42085,9 +42249,9 @@ init_src();
42085
42249
  init_errors3();
42086
42250
  init_data_accessor();
42087
42251
  import { existsSync as existsSync89 } from "node:fs";
42088
- import { join as join93 } from "node:path";
42252
+ import { join as join92 } from "node:path";
42089
42253
  async function getMigrationStatus2(projectRoot, opts) {
42090
- const taskPath = join93(projectRoot, ".cleo", "tasks.db");
42254
+ const taskPath = join92(projectRoot, ".cleo", "tasks.db");
42091
42255
  let currentVersion = "unknown";
42092
42256
  if (existsSync89(taskPath)) {
42093
42257
  try {
@@ -42119,7 +42283,7 @@ init_paths();
42119
42283
  import { execFile as execFile7 } from "node:child_process";
42120
42284
  import { existsSync as existsSync90 } from "node:fs";
42121
42285
  import { readFile as readFile15 } from "node:fs/promises";
42122
- import { basename as basename15, join as join94 } from "node:path";
42286
+ import { basename as basename15, join as join93 } from "node:path";
42123
42287
  import { promisify as promisify7 } from "node:util";
42124
42288
  function normalizeChannel(value) {
42125
42289
  if (!value) return null;
@@ -42152,7 +42316,7 @@ function getExpectedNaming(channel) {
42152
42316
  }
42153
42317
  }
42154
42318
  async function parseVersionFile(dataRoot) {
42155
- const versionPath = join94(dataRoot, "VERSION");
42319
+ const versionPath = join93(dataRoot, "VERSION");
42156
42320
  if (!existsSync90(versionPath)) return null;
42157
42321
  let content;
42158
42322
  try {
@@ -42182,9 +42346,9 @@ async function parseVersionFile(dataRoot) {
42182
42346
  async function getPackageInfo(sourceDir) {
42183
42347
  const candidates = [];
42184
42348
  if (sourceDir && sourceDir !== "unknown" && sourceDir !== "npm") {
42185
- candidates.push(join94(sourceDir, "package.json"));
42349
+ candidates.push(join93(sourceDir, "package.json"));
42186
42350
  }
42187
- candidates.push(join94(process.cwd(), "package.json"));
42351
+ candidates.push(join93(process.cwd(), "package.json"));
42188
42352
  for (const candidate of candidates) {
42189
42353
  try {
42190
42354
  const raw = await readFile15(candidate, "utf-8");
@@ -42264,13 +42428,13 @@ init_src();
42264
42428
  init_errors3();
42265
42429
  init_data_accessor();
42266
42430
  import { existsSync as existsSync91, readFileSync as readFileSync66, writeFileSync as writeFileSync14 } from "node:fs";
42267
- import { join as join95 } from "node:path";
42431
+ import { join as join94 } from "node:path";
42268
42432
  function safestop(projectRoot, opts) {
42269
42433
  const dryRun = opts?.dryRun ?? false;
42270
42434
  const reason = opts?.reason ?? "Manual safestop";
42271
42435
  let sessionEnded = false;
42272
42436
  if (!dryRun && !opts?.noSessionEnd) {
42273
- const sessPath = join95(projectRoot, ".cleo", "sessions.json");
42437
+ const sessPath = join94(projectRoot, ".cleo", "sessions.json");
42274
42438
  if (existsSync91(sessPath)) {
42275
42439
  try {
42276
42440
  const data = JSON.parse(readFileSync66(sessPath, "utf-8"));
@@ -42298,7 +42462,7 @@ async function uncancelTask(projectRoot, params) {
42298
42462
  if (!params.taskId) {
42299
42463
  throw new CleoError(2 /* INVALID_INPUT */, "taskId is required");
42300
42464
  }
42301
- const taskDbPath = join95(projectRoot, ".cleo", "tasks.db");
42465
+ const taskDbPath = join94(projectRoot, ".cleo", "tasks.db");
42302
42466
  if (!existsSync91(taskDbPath)) {
42303
42467
  throw new CleoError(8 /* CONFIG_ERROR */, "No tasks.db found");
42304
42468
  }
@@ -42355,11 +42519,9 @@ async function uncancelTask(projectRoot, params) {
42355
42519
  // packages/core/src/task-work/index.ts
42356
42520
  var task_work_exports = {};
42357
42521
  __export(task_work_exports, {
42358
- analyzeTodoWriteChanges: () => analyzeChanges,
42359
42522
  currentTask: () => currentTask,
42360
42523
  getTaskHistory: () => getTaskHistory,
42361
42524
  getWorkHistory: () => getWorkHistory,
42362
- mergeTodoWriteState: () => mergeTodoWriteState,
42363
42525
  startTask: () => startTask,
42364
42526
  stopTask: () => stopTask
42365
42527
  });
@@ -42380,153 +42542,6 @@ function getUnresolvedDeps(taskId, tasks2) {
42380
42542
 
42381
42543
  // packages/core/src/task-work/index.ts
42382
42544
  init_handlers();
42383
-
42384
- // packages/core/src/task-work/todowrite-merge.ts
42385
- init_src();
42386
- init_errors3();
42387
- init_paths();
42388
- init_data_accessor();
42389
- init_json2();
42390
- init_add();
42391
- init_complete();
42392
- init_update2();
42393
- import { readFile as readFile16, rm as rm3, stat as stat2 } from "node:fs/promises";
42394
- import { join as join96 } from "node:path";
42395
- function parseTaskId(content) {
42396
- const match = content.match(/^\[T(\d+)\]/);
42397
- return match ? `T${match[1]}` : null;
42398
- }
42399
- function stripPrefixes(content) {
42400
- return content.replace(/^\[T\d+\]\s*/, "").replace(/^\[!\]\s*/, "").replace(/^\[BLOCKED\]\s*/, "");
42401
- }
42402
- function analyzeChanges(todowriteState, injectedIds) {
42403
- const foundIds = [];
42404
- const completed = [];
42405
- const progressed = [];
42406
- const newTasks = [];
42407
- for (const item of todowriteState.todos) {
42408
- const taskId = parseTaskId(item.content);
42409
- if (taskId) {
42410
- foundIds.push(taskId);
42411
- if (item.status === "completed") {
42412
- completed.push(taskId);
42413
- } else if (item.status === "in_progress") {
42414
- progressed.push(taskId);
42415
- }
42416
- } else {
42417
- const cleanTitle = stripPrefixes(item.content);
42418
- if (cleanTitle.trim()) {
42419
- newTasks.push(cleanTitle);
42420
- }
42421
- }
42422
- }
42423
- const foundSet = new Set(foundIds);
42424
- const removed = injectedIds.filter((id) => !foundSet.has(id));
42425
- return { completed, progressed, newTasks, removed };
42426
- }
42427
- async function mergeTodoWriteState(options) {
42428
- const { file, dryRun = false, defaultPhase, cwd } = options;
42429
- const acc = options.accessor ?? await getAccessor(cwd);
42430
- try {
42431
- await stat2(file);
42432
- } catch {
42433
- throw new CleoError(4 /* NOT_FOUND */, `File not found: ${file}`);
42434
- }
42435
- const content = await readFile16(file, "utf-8");
42436
- let todowriteState;
42437
- try {
42438
- todowriteState = JSON.parse(content);
42439
- } catch {
42440
- throw new CleoError(2 /* INVALID_INPUT */, `Invalid JSON in ${file}`);
42441
- }
42442
- if (!todowriteState.todos || !Array.isArray(todowriteState.todos)) {
42443
- throw new CleoError(2 /* INVALID_INPUT */, 'File must contain a "todos" array');
42444
- }
42445
- const cleoDir = getCleoDir(cwd);
42446
- const stateFile = join96(cleoDir, "sync", "todowrite-session.json");
42447
- let sessionState = null;
42448
- try {
42449
- sessionState = await readJson(stateFile);
42450
- } catch {
42451
- }
42452
- const injectedIds = sessionState?.injected_tasks ?? [];
42453
- const changes = analyzeChanges(todowriteState, injectedIds);
42454
- const totalChanges = changes.completed.length + changes.progressed.length + changes.newTasks.length;
42455
- if (totalChanges === 0) {
42456
- return {
42457
- dryRun,
42458
- changes: {
42459
- completed: 0,
42460
- progressed: 0,
42461
- new: 0,
42462
- removed: changes.removed.length,
42463
- applied: 0
42464
- },
42465
- sessionCleared: false
42466
- };
42467
- }
42468
- let appliedCount = 0;
42469
- if (!dryRun) {
42470
- const { tasks: allTasks } = await acc.queryTasks({});
42471
- for (const taskId of changes.completed) {
42472
- const task = allTasks.find((t) => t.id === taskId);
42473
- if (!task) continue;
42474
- if (task.status === "done") continue;
42475
- try {
42476
- await completeTask({ taskId, notes: "Completed via TodoWrite session sync" }, cwd, acc);
42477
- appliedCount++;
42478
- } catch {
42479
- }
42480
- }
42481
- for (const taskId of changes.progressed) {
42482
- const task = allTasks.find((t) => t.id === taskId);
42483
- if (!task) continue;
42484
- if (task.status !== "pending" && task.status !== "blocked") continue;
42485
- try {
42486
- await updateTask(
42487
- { taskId, status: "active", notes: "Progressed during TodoWrite session" },
42488
- cwd,
42489
- acc
42490
- );
42491
- appliedCount++;
42492
- } catch {
42493
- }
42494
- }
42495
- for (const title of changes.newTasks) {
42496
- try {
42497
- await addTask(
42498
- {
42499
- title,
42500
- description: "Created during TodoWrite session",
42501
- labels: ["session-created"],
42502
- ...defaultPhase ? { phase: defaultPhase, addPhase: true } : {}
42503
- },
42504
- cwd,
42505
- acc
42506
- );
42507
- appliedCount++;
42508
- } catch {
42509
- }
42510
- }
42511
- try {
42512
- await rm3(stateFile);
42513
- } catch {
42514
- }
42515
- }
42516
- return {
42517
- dryRun,
42518
- changes: {
42519
- completed: changes.completed.length,
42520
- progressed: changes.progressed.length,
42521
- new: changes.newTasks.length,
42522
- removed: changes.removed.length,
42523
- applied: dryRun ? 0 : appliedCount
42524
- },
42525
- sessionCleared: !dryRun
42526
- };
42527
- }
42528
-
42529
- // packages/core/src/task-work/index.ts
42530
42545
  async function currentTask(cwd, accessor) {
42531
42546
  const acc = accessor ?? await getAccessor(cwd);
42532
42547
  const focus = await acc.getMetaValue("focus_state");
@@ -43088,7 +43103,7 @@ __export(templates_exports, {
43088
43103
 
43089
43104
  // packages/core/src/templates/parser.ts
43090
43105
  import { existsSync as existsSync92, readdirSync as readdirSync29, readFileSync as readFileSync67 } from "fs";
43091
- import { join as join97 } from "path";
43106
+ import { join as join95 } from "path";
43092
43107
  import { parse as parseYaml } from "yaml";
43093
43108
  var SUFFIX_PATTERNS = ["_report", "_request", "_question"];
43094
43109
  function deriveSubcommand(filename) {
@@ -43103,7 +43118,7 @@ function deriveSubcommand(filename) {
43103
43118
  return firstWord.toLowerCase();
43104
43119
  }
43105
43120
  function parseTemplateFile2(templateDir, filename) {
43106
- const filePath = join97(templateDir, filename);
43121
+ const filePath = join95(templateDir, filename);
43107
43122
  const raw = readFileSync67(filePath, "utf-8");
43108
43123
  const parsed = parseYaml(raw);
43109
43124
  const name2 = typeof parsed.name === "string" ? parsed.name : filename;
@@ -43153,7 +43168,7 @@ function parseTemplateFile2(templateDir, filename) {
43153
43168
  };
43154
43169
  }
43155
43170
  function parseIssueTemplates2(projectRoot) {
43156
- const templateDir = join97(projectRoot, ".github", "ISSUE_TEMPLATE");
43171
+ const templateDir = join95(projectRoot, ".github", "ISSUE_TEMPLATE");
43157
43172
  if (!existsSync92(templateDir)) {
43158
43173
  return {
43159
43174
  success: false,
@@ -43305,7 +43320,7 @@ __export(ui_exports, {
43305
43320
  // packages/core/src/ui/aliases.ts
43306
43321
  import { existsSync as existsSync93, readFileSync as readFileSync68, writeFileSync as writeFileSync15 } from "node:fs";
43307
43322
  import { homedir as homedir5, platform as platform2 } from "node:os";
43308
- import { join as join98 } from "node:path";
43323
+ import { join as join96 } from "node:path";
43309
43324
  var MARKER_START = "# CLEO-CLAUDE-ALIASES:START";
43310
43325
  var MARKER_END = "# CLEO-CLAUDE-ALIASES:END";
43311
43326
  var ALIASES_VERSION = "1.0.0";
@@ -43327,16 +43342,16 @@ function getRcFilePath(shell) {
43327
43342
  const sh = shell ?? getCurrentShell();
43328
43343
  switch (sh) {
43329
43344
  case "bash":
43330
- return join98(home, ".bashrc");
43345
+ return join96(home, ".bashrc");
43331
43346
  case "zsh":
43332
- return join98(home, ".zshrc");
43347
+ return join96(home, ".zshrc");
43333
43348
  case "powershell":
43334
- return join98(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
43349
+ return join96(home, "Documents", "PowerShell", "Microsoft.PowerShell_profile.ps1");
43335
43350
  case "cmd":
43336
43351
  return "";
43337
43352
  // CMD doesn't have a standard RC
43338
43353
  default:
43339
- return join98(home, ".bashrc");
43354
+ return join96(home, ".bashrc");
43340
43355
  }
43341
43356
  }
43342
43357
  function detectAvailableShells() {
@@ -43576,7 +43591,7 @@ ${markdown}`);
43576
43591
 
43577
43592
  // packages/core/src/ui/command-registry.ts
43578
43593
  import { existsSync as existsSync95, readdirSync as readdirSync30, readFileSync as readFileSync70 } from "node:fs";
43579
- import { basename as basename16, join as join99 } from "node:path";
43594
+ import { basename as basename16, join as join97 } from "node:path";
43580
43595
  var CLEO_HEADER_START = "###CLEO";
43581
43596
  var CLEO_HEADER_END = "###END";
43582
43597
  function parseCommandHeader(scriptPath) {
@@ -43662,7 +43677,7 @@ function scanAllCommands(scriptsDir) {
43662
43677
  if (!existsSync95(scriptsDir)) return registry;
43663
43678
  for (const file of readdirSync30(scriptsDir)) {
43664
43679
  if (!file.endsWith(".sh") && !file.endsWith(".ts")) continue;
43665
- const meta = parseCommandHeader(join99(scriptsDir, file));
43680
+ const meta = parseCommandHeader(join97(scriptsDir, file));
43666
43681
  if (meta) {
43667
43682
  registry.set(meta.command, meta);
43668
43683
  }
@@ -44006,7 +44021,7 @@ function calculateOrchestrationOverhead(orchestratorTokens, totalSubagentTokens,
44006
44021
 
44007
44022
  // packages/core/src/validation/docs-sync.ts
44008
44023
  import { existsSync as existsSync96, readdirSync as readdirSync31, readFileSync as readFileSync71 } from "node:fs";
44009
- import { join as join100 } from "node:path";
44024
+ import { join as join98 } from "node:path";
44010
44025
  function getScriptCommands(scriptsDir) {
44011
44026
  if (!existsSync96(scriptsDir)) return [];
44012
44027
  try {
@@ -44099,13 +44114,13 @@ var CRITICAL_COMMANDS = [
44099
44114
  ];
44100
44115
  function detectDrift(mode = "full", projectRoot = ".") {
44101
44116
  const issues = [];
44102
- const scriptsDir = join100(projectRoot, "scripts");
44103
- const indexPath = join100(projectRoot, "docs/commands/COMMANDS-INDEX.json");
44117
+ const scriptsDir = join98(projectRoot, "scripts");
44118
+ const indexPath = join98(projectRoot, "docs/commands/COMMANDS-INDEX.json");
44104
44119
  issues.push(...checkCommandsSync(scriptsDir, indexPath));
44105
- const wrapperPath = join100(projectRoot, "installer/lib/link.sh");
44120
+ const wrapperPath = join98(projectRoot, "installer/lib/link.sh");
44106
44121
  issues.push(...checkWrapperSync(wrapperPath, indexPath));
44107
44122
  if (mode === "full") {
44108
- const readmePath = join100(projectRoot, "README.md");
44123
+ const readmePath = join98(projectRoot, "README.md");
44109
44124
  if (existsSync96(readmePath)) {
44110
44125
  try {
44111
44126
  const readme = readFileSync71(readmePath, "utf-8");
@@ -44143,13 +44158,13 @@ function shouldRunDriftDetection(enabled = true, autoCheck = false, command, cri
44143
44158
  init_paths();
44144
44159
  import { createHash as createHash10 } from "node:crypto";
44145
44160
  import { existsSync as existsSync97, mkdirSync as mkdirSync21, readFileSync as readFileSync72, unlinkSync as unlinkSync7, writeFileSync as writeFileSync17 } from "node:fs";
44146
- import { dirname as dirname17, join as join101 } from "node:path";
44161
+ import { dirname as dirname17, join as join99 } from "node:path";
44147
44162
  var CACHE_VERSION = "1.0.0";
44148
44163
  var CACHE_TTL_SECONDS = 300;
44149
44164
  var CACHE_FILE2 = "doctor-project-cache.json";
44150
44165
  function getCacheFilePath(cleoHome) {
44151
44166
  const home = cleoHome ?? getCleoHome();
44152
- return join101(home, CACHE_FILE2);
44167
+ return join99(home, CACHE_FILE2);
44153
44168
  }
44154
44169
  function initCacheFile(cacheFile) {
44155
44170
  const cache = {
@@ -44193,8 +44208,8 @@ function getCachedValidation(projectHash, projectPath, cacheFile) {
44193
44208
  const now = Date.now();
44194
44209
  const age = (now - lastValidated) / 1e3;
44195
44210
  if (age > (entry.ttl || CACHE_TTL_SECONDS)) return null;
44196
- const currentTasksDbHash = getFileHash(join101(projectPath, ".cleo", "tasks.db"));
44197
- const currentConfigHash = getFileHash(join101(projectPath, ".cleo", "config.json"));
44211
+ const currentTasksDbHash = getFileHash(join99(projectPath, ".cleo", "tasks.db"));
44212
+ const currentConfigHash = getFileHash(join99(projectPath, ".cleo", "config.json"));
44198
44213
  if (currentTasksDbHash !== (entry.fileHashes["tasks.db"] ?? "")) return null;
44199
44214
  if (currentConfigHash !== (entry.fileHashes["config.json"] ?? "")) return null;
44200
44215
  return entry;
@@ -44205,8 +44220,8 @@ function cacheValidationResult(projectHash, projectPath, validationStatus, issue
44205
44220
  if (!cache) {
44206
44221
  cache = initCacheFile(cachePath);
44207
44222
  }
44208
- const tasksDbHash = getFileHash(join101(projectPath, ".cleo", "tasks.db"));
44209
- const configHash = getFileHash(join101(projectPath, ".cleo", "config.json"));
44223
+ const tasksDbHash = getFileHash(join99(projectPath, ".cleo", "tasks.db"));
44224
+ const configHash = getFileHash(join99(projectPath, ".cleo", "config.json"));
44210
44225
  const timestamp2 = (/* @__PURE__ */ new Date()).toISOString();
44211
44226
  cache.projects[projectHash] = {
44212
44227
  path: projectPath,
@@ -45204,7 +45219,7 @@ function formatGapReport(report) {
45204
45219
  // packages/core/src/validation/manifest.ts
45205
45220
  init_paths();
45206
45221
  import { existsSync as existsSync98 } from "node:fs";
45207
- import { appendFile as appendFile3, mkdir as mkdir16, readFile as readFile17 } from "node:fs/promises";
45222
+ import { appendFile as appendFile3, mkdir as mkdir15, readFile as readFile16 } from "node:fs/promises";
45208
45223
  import { dirname as dirname18 } from "node:path";
45209
45224
  var DEFAULT_MANIFEST_PATH = ".cleo/agent-outputs/MANIFEST.jsonl";
45210
45225
  var DEFAULT_COMPLIANCE_PATH = ".cleo/metrics/COMPLIANCE.jsonl";
@@ -45217,7 +45232,7 @@ async function findManifestEntry(taskId, manifestPath) {
45217
45232
  }
45218
45233
  }
45219
45234
  if (!existsSync98(manifestPath)) return null;
45220
- const content = await readFile17(manifestPath, "utf-8");
45235
+ const content = await readFile16(manifestPath, "utf-8");
45221
45236
  const lines = content.split("\n").filter((l) => l.trim());
45222
45237
  for (let i = lines.length - 1; i >= 0; i--) {
45223
45238
  const line2 = lines[i];
@@ -45329,7 +45344,7 @@ async function validateManifestEntry(taskId, manifestEntry, manifestPath = DEFAU
45329
45344
  }
45330
45345
  async function logRealCompliance(taskId, validationResult, agentType = "unknown", compliancePath = DEFAULT_COMPLIANCE_PATH) {
45331
45346
  const metricsDir = dirname18(compliancePath);
45332
- await mkdir16(metricsDir, { recursive: true });
45347
+ await mkdir15(metricsDir, { recursive: true });
45333
45348
  const { score, pass, violations } = validationResult;
45334
45349
  const violationCount = violations.length;
45335
45350
  let severity = "none";
@@ -46124,25 +46139,25 @@ init_hooks();
46124
46139
  init_injection();
46125
46140
  init_memory_bridge();
46126
46141
  import { existsSync as existsSync100, readdirSync as readdirSync33, readFileSync as readFileSync74 } from "node:fs";
46127
- import { copyFile as copyFile3, lstat, mkdir as mkdir17, readFile as readFile18, symlink, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
46128
- import { basename as basename17, dirname as dirname19, join as join102 } from "node:path";
46142
+ import { copyFile as copyFile3, lstat, mkdir as mkdir16, readFile as readFile17, symlink, unlink as unlink4, writeFile as writeFile11 } from "node:fs/promises";
46143
+ import { basename as basename17, dirname as dirname19, join as join100 } from "node:path";
46129
46144
  init_paths();
46130
46145
  init_scaffold();
46131
46146
  init_schema_management();
46132
46147
  init_json2();
46133
46148
  async function initAgentDefinition(created, warnings) {
46134
46149
  const packageRoot = getPackageRoot();
46135
- const agentSourceDir = join102(packageRoot, "agents", "cleo-subagent");
46150
+ const agentSourceDir = join100(packageRoot, "agents", "cleo-subagent");
46136
46151
  if (!existsSync100(agentSourceDir)) {
46137
46152
  warnings.push("agents/cleo-subagent/ not found in package, skipping agent definition install");
46138
46153
  return;
46139
46154
  }
46140
- const globalAgentsDir = join102(getAgentsHome(), "agents", "cleo-subagent");
46141
- await mkdir17(dirname19(globalAgentsDir), { recursive: true });
46155
+ const globalAgentsDir = join100(getAgentsHome(), "agents", "cleo-subagent");
46156
+ await mkdir16(dirname19(globalAgentsDir), { recursive: true });
46142
46157
  try {
46143
46158
  try {
46144
- const stat3 = await lstat(globalAgentsDir);
46145
- if (stat3.isSymbolicLink() || stat3.isDirectory()) {
46159
+ const stat2 = await lstat(globalAgentsDir);
46160
+ if (stat2.isSymbolicLink() || stat2.isDirectory()) {
46146
46161
  return;
46147
46162
  }
46148
46163
  } catch {
@@ -46151,10 +46166,10 @@ async function initAgentDefinition(created, warnings) {
46151
46166
  created.push("agent: cleo-subagent (symlinked)");
46152
46167
  } catch (_err) {
46153
46168
  try {
46154
- await mkdir17(globalAgentsDir, { recursive: true });
46169
+ await mkdir16(globalAgentsDir, { recursive: true });
46155
46170
  const files = readdirSync33(agentSourceDir);
46156
46171
  for (const file of files) {
46157
- await copyFile3(join102(agentSourceDir, file), join102(globalAgentsDir, file));
46172
+ await copyFile3(join100(agentSourceDir, file), join100(globalAgentsDir, file));
46158
46173
  }
46159
46174
  created.push("agent: cleo-subagent (copied)");
46160
46175
  } catch (copyErr) {
@@ -46174,12 +46189,12 @@ async function initCoreSkills(created, warnings) {
46174
46189
  const packageRoot = getPackageRoot();
46175
46190
  let ctSkillsRoot = null;
46176
46191
  try {
46177
- const bundledPath = join102(packageRoot, "packages", "skills");
46178
- if (existsSync100(join102(bundledPath, "skills.json"))) {
46192
+ const bundledPath = join100(packageRoot, "packages", "skills");
46193
+ if (existsSync100(join100(bundledPath, "skills.json"))) {
46179
46194
  ctSkillsRoot = bundledPath;
46180
46195
  } else {
46181
- const ctSkillsPath = join102(packageRoot, "node_modules", "@cleocode", "skills");
46182
- if (existsSync100(join102(ctSkillsPath, "skills.json"))) {
46196
+ const ctSkillsPath = join100(packageRoot, "node_modules", "@cleocode", "skills");
46197
+ if (existsSync100(join100(ctSkillsPath, "skills.json"))) {
46183
46198
  ctSkillsRoot = ctSkillsPath;
46184
46199
  }
46185
46200
  }
@@ -46194,13 +46209,13 @@ async function initCoreSkills(created, warnings) {
46194
46209
  } catch {
46195
46210
  warnings.push("Failed to register skill library with CAAMP");
46196
46211
  }
46197
- const catalogPath = join102(ctSkillsRoot, "skills.json");
46212
+ const catalogPath = join100(ctSkillsRoot, "skills.json");
46198
46213
  const catalog3 = JSON.parse(readFileSync74(catalogPath, "utf-8"));
46199
46214
  const skills = catalog3.skills ?? [];
46200
46215
  const coreSkills = skills.filter((s) => s.tier <= 2);
46201
46216
  const installed = [];
46202
46217
  for (const skill of coreSkills) {
46203
- const skillSourceDir = dirname19(join102(ctSkillsRoot, skill.path));
46218
+ const skillSourceDir = dirname19(join100(ctSkillsRoot, skill.path));
46204
46219
  if (!existsSync100(skillSourceDir)) {
46205
46220
  continue;
46206
46221
  }
@@ -46244,33 +46259,33 @@ async function initNexusRegistration(projectRoot, created, warnings) {
46244
46259
  }
46245
46260
  }
46246
46261
  async function installGitHubTemplates(projectRoot, created, skipped) {
46247
- if (!existsSync100(join102(projectRoot, ".git"))) {
46262
+ if (!existsSync100(join100(projectRoot, ".git"))) {
46248
46263
  return;
46249
46264
  }
46250
- const githubDir = join102(projectRoot, ".github");
46251
- const issueTemplateDir = join102(githubDir, "ISSUE_TEMPLATE");
46265
+ const githubDir = join100(projectRoot, ".github");
46266
+ const issueTemplateDir = join100(githubDir, "ISSUE_TEMPLATE");
46252
46267
  const packageRoot = getPackageRoot();
46253
- const templateSrcDir = join102(packageRoot, "templates", "github");
46268
+ const templateSrcDir = join100(packageRoot, "templates", "github");
46254
46269
  if (!existsSync100(templateSrcDir)) {
46255
46270
  return;
46256
46271
  }
46257
- await mkdir17(issueTemplateDir, { recursive: true });
46258
- const issueSrcDir = join102(templateSrcDir, "ISSUE_TEMPLATE");
46272
+ await mkdir16(issueTemplateDir, { recursive: true });
46273
+ const issueSrcDir = join100(templateSrcDir, "ISSUE_TEMPLATE");
46259
46274
  if (existsSync100(issueSrcDir)) {
46260
46275
  const issueFiles = readdirSync33(issueSrcDir);
46261
46276
  for (const file of issueFiles) {
46262
- const dest = join102(issueTemplateDir, file);
46277
+ const dest = join100(issueTemplateDir, file);
46263
46278
  if (existsSync100(dest)) {
46264
46279
  skipped.push(`.github/ISSUE_TEMPLATE/${file}`);
46265
46280
  continue;
46266
46281
  }
46267
- const content = readFileSync74(join102(issueSrcDir, file), "utf-8");
46282
+ const content = readFileSync74(join100(issueSrcDir, file), "utf-8");
46268
46283
  await writeFile11(dest, content, "utf-8");
46269
46284
  created.push(`.github/ISSUE_TEMPLATE/${file}`);
46270
46285
  }
46271
46286
  }
46272
- const prTemplateSrc = join102(templateSrcDir, "pull_request_template.md");
46273
- const prTemplateDest = join102(githubDir, "pull_request_template.md");
46287
+ const prTemplateSrc = join100(templateSrcDir, "pull_request_template.md");
46288
+ const prTemplateDest = join100(githubDir, "pull_request_template.md");
46274
46289
  if (existsSync100(prTemplateSrc)) {
46275
46290
  if (existsSync100(prTemplateDest)) {
46276
46291
  skipped.push(".github/pull_request_template.md");
@@ -46309,7 +46324,7 @@ async function initProject(opts = {}) {
46309
46324
  }
46310
46325
  const cleoDir = getCleoDirAbsolute();
46311
46326
  const projRoot = getProjectRoot();
46312
- const alreadyInitialized = existsSync100(cleoDir) && (existsSync100(join102(cleoDir, "tasks.db")) || existsSync100(join102(cleoDir, "config.json")));
46327
+ const alreadyInitialized = existsSync100(cleoDir) && (existsSync100(join100(cleoDir, "tasks.db")) || existsSync100(join100(cleoDir, "config.json")));
46313
46328
  if (alreadyInitialized && !opts.force) {
46314
46329
  throw new CleoError(
46315
46330
  1 /* GENERAL_ERROR */,
@@ -46333,7 +46348,7 @@ async function initProject(opts = {}) {
46333
46348
  }
46334
46349
  try {
46335
46350
  const { getDb: getDb3 } = await Promise.resolve().then(() => (init_sqlite2(), sqlite_exports));
46336
- await getDb3(join102(cleoDir, ".."));
46351
+ await getDb3(join100(cleoDir, ".."));
46337
46352
  created.push("tasks.db");
46338
46353
  } catch (err) {
46339
46354
  created.push(`tasks.db (deferred: ${err instanceof Error ? err.message : String(err)})`);
@@ -46354,7 +46369,7 @@ async function initProject(opts = {}) {
46354
46369
  created.push(".gitignore");
46355
46370
  }
46356
46371
  } else {
46357
- const gitignorePath = join102(cleoDir, ".gitignore");
46372
+ const gitignorePath = join100(cleoDir, ".gitignore");
46358
46373
  if (existsSync100(gitignorePath)) {
46359
46374
  skipped.push(".gitignore");
46360
46375
  } else {
@@ -46366,12 +46381,12 @@ async function initProject(opts = {}) {
46366
46381
  }
46367
46382
  }
46368
46383
  }
46369
- const legacySequencePath = join102(cleoDir, ".sequence");
46384
+ const legacySequencePath = join100(cleoDir, ".sequence");
46370
46385
  try {
46371
46386
  await unlink4(legacySequencePath);
46372
46387
  } catch {
46373
46388
  }
46374
- const legacySequenceJsonPath = join102(cleoDir, ".sequence.json");
46389
+ const legacySequenceJsonPath = join100(cleoDir, ".sequence.json");
46375
46390
  try {
46376
46391
  await unlink4(legacySequenceJsonPath);
46377
46392
  } catch {
@@ -46533,8 +46548,8 @@ function isAutoInitEnabled() {
46533
46548
  }
46534
46549
  async function ensureInitialized(projectRoot) {
46535
46550
  const root = projectRoot ?? getProjectRoot();
46536
- const cleoDir = join102(root, ".cleo");
46537
- const isInit = existsSync100(cleoDir) && (existsSync100(join102(cleoDir, "tasks.db")) || existsSync100(join102(cleoDir, "config.json")));
46551
+ const cleoDir = join100(root, ".cleo");
46552
+ const isInit = existsSync100(cleoDir) && (existsSync100(join100(cleoDir, "tasks.db")) || existsSync100(join100(cleoDir, "config.json")));
46538
46553
  if (isInit) {
46539
46554
  return { initialized: true };
46540
46555
  }
@@ -46546,10 +46561,10 @@ async function ensureInitialized(projectRoot) {
46546
46561
  }
46547
46562
  async function getVersion2(projectRoot) {
46548
46563
  const root = projectRoot ?? getProjectRoot();
46549
- const versionPaths = [join102(root, "VERSION"), join102(root, "..", "VERSION")];
46564
+ const versionPaths = [join100(root, "VERSION"), join100(root, "..", "VERSION")];
46550
46565
  for (const versionPath of versionPaths) {
46551
46566
  try {
46552
- const content = await readFile18(versionPath, "utf-8");
46567
+ const content = await readFile17(versionPath, "utf-8");
46553
46568
  const version = content.trim();
46554
46569
  if (version) {
46555
46570
  return { version };
@@ -46557,7 +46572,7 @@ async function getVersion2(projectRoot) {
46557
46572
  } catch {
46558
46573
  }
46559
46574
  }
46560
- const pkg = await readJson(join102(root, "package.json"));
46575
+ const pkg = await readJson(join100(root, "package.json"));
46561
46576
  if (pkg?.version) {
46562
46577
  return { version: pkg.version };
46563
46578
  }
@@ -46570,15 +46585,15 @@ init_logger();
46570
46585
 
46571
46586
  // packages/core/src/output.ts
46572
46587
  init_errors3();
46573
- import { randomUUID as randomUUID4 } from "node:crypto";
46588
+ import { randomUUID as randomUUID5 } from "node:crypto";
46574
46589
 
46575
46590
  // packages/core/src/sessions/context-alert.ts
46576
46591
  init_paths();
46577
46592
  import { existsSync as existsSync101, readFileSync as readFileSync75, writeFileSync as writeFileSync18 } from "node:fs";
46578
- import { join as join103 } from "node:path";
46593
+ import { join as join101 } from "node:path";
46579
46594
  function getCurrentSessionId(cwd) {
46580
46595
  if (process.env.CLEO_SESSION) return process.env.CLEO_SESSION;
46581
- const sessionFile = join103(getCleoDir(cwd), ".current-session");
46596
+ const sessionFile = join101(getCleoDir(cwd), ".current-session");
46582
46597
  if (existsSync101(sessionFile)) {
46583
46598
  return readFileSync75(sessionFile, "utf-8").trim() || null;
46584
46599
  }
@@ -46603,7 +46618,7 @@ function createCliMeta(operation, mvi = "standard") {
46603
46618
  schemaVersion: "2026.2.1",
46604
46619
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
46605
46620
  operation,
46606
- requestId: randomUUID4(),
46621
+ requestId: randomUUID5(),
46607
46622
  transport: "cli",
46608
46623
  strict: true,
46609
46624
  mvi,
@@ -46656,13 +46671,13 @@ init_paths();
46656
46671
  // packages/core/src/project-info.ts
46657
46672
  init_paths();
46658
46673
  import { existsSync as existsSync102, readFileSync as readFileSync76 } from "node:fs";
46659
- import { readFile as readFile19 } from "node:fs/promises";
46660
- import { join as join104 } from "node:path";
46674
+ import { readFile as readFile18 } from "node:fs/promises";
46675
+ import { join as join102 } from "node:path";
46661
46676
  async function getProjectInfo(cwd) {
46662
46677
  const projectRoot = cwd ?? process.cwd();
46663
46678
  const cleoDir = getCleoDirAbsolute(projectRoot);
46664
- const infoPath = join104(cleoDir, "project-info.json");
46665
- const raw = await readFile19(infoPath, "utf-8");
46679
+ const infoPath = join102(cleoDir, "project-info.json");
46680
+ const raw = await readFile18(infoPath, "utf-8");
46666
46681
  const data = JSON.parse(raw);
46667
46682
  if (typeof data.projectHash !== "string" || data.projectHash.length === 0) {
46668
46683
  throw new Error(`project-info.json missing required field: projectHash`);
@@ -46679,7 +46694,7 @@ async function getProjectInfo(cwd) {
46679
46694
  function getProjectInfoSync(cwd) {
46680
46695
  const projectRoot = cwd ?? process.cwd();
46681
46696
  const cleoDir = getCleoDirAbsolute(projectRoot);
46682
- const infoPath = join104(cleoDir, "project-info.json");
46697
+ const infoPath = join102(cleoDir, "project-info.json");
46683
46698
  if (!existsSync102(infoPath)) return null;
46684
46699
  try {
46685
46700
  const raw = readFileSync76(infoPath, "utf-8");
@@ -46940,9 +46955,9 @@ var Cleo = class _Cleo {
46940
46955
  },
46941
46956
  store
46942
46957
  ),
46943
- readState: (providerId) => readSyncState(providerId, root),
46944
- writeState: (providerId, state) => writeSyncState(providerId, state, root),
46945
- clearState: (providerId) => clearSyncState(providerId, root)
46958
+ getLinks: (providerId) => getLinksByProvider(providerId, root),
46959
+ getTaskLinks: (taskId) => getLinksByTaskId(taskId, root),
46960
+ removeProviderLinks: (providerId) => removeLinksByProvider(providerId, root)
46946
46961
  };
46947
46962
  }
46948
46963
  };