@cleocode/cleo 2026.4.98 → 2026.4.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -2458,7 +2458,7 @@ var init_sql = __esm({
2458
2458
  return new SQL([new StringChunk(str2)]);
2459
2459
  }
2460
2460
  _sql.raw = raw;
2461
- function join162(chunks, separator) {
2461
+ function join155(chunks, separator) {
2462
2462
  const result = [];
2463
2463
  for (const [i, chunk] of chunks.entries()) {
2464
2464
  if (i > 0 && separator !== void 0) result.push(separator);
@@ -2466,7 +2466,7 @@ var init_sql = __esm({
2466
2466
  }
2467
2467
  return new SQL(result);
2468
2468
  }
2469
- _sql.join = join162;
2469
+ _sql.join = join155;
2470
2470
  function identifier(value) {
2471
2471
  return new Name(value);
2472
2472
  }
@@ -7289,7 +7289,7 @@ var init_select2 = __esm({
7289
7289
  const baseTableName = this.tableName;
7290
7290
  const tableName = getTableLikeName(table);
7291
7291
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
7292
- if (typeof tableName === "string" && this.config.joins?.some((join162) => join162.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
7292
+ if (typeof tableName === "string" && this.config.joins?.some((join155) => join155.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
7293
7293
  if (!this.isPartialSelect) {
7294
7294
  if (Object.keys(this.joinsNotNullableMap).length === 1 && typeof baseTableName === "string") this.config.fields = { [baseTableName]: this.config.fields };
7295
7295
  if (typeof tableName === "string" && !is(table, SQL)) {
@@ -8592,7 +8592,7 @@ var init_dialect = __esm({
8592
8592
  if (!joins2) return;
8593
8593
  const withEntries = Object.entries(joins2).filter(([_2, v2]) => v2);
8594
8594
  if (!withEntries.length) return;
8595
- return sql.join(withEntries.map(([k2, join162]) => {
8595
+ return sql.join(withEntries.map(([k2, join155]) => {
8596
8596
  const relation = tableConfig.relations[k2];
8597
8597
  const isSingle2 = is(relation, One3);
8598
8598
  const targetTable = aliasedTable(relation.targetTable, `d${currentDepth + 1}`);
@@ -8603,7 +8603,7 @@ var init_dialect = __esm({
8603
8603
  table: targetTable,
8604
8604
  mode: isSingle2 ? "first" : "many",
8605
8605
  schema: schema2,
8606
- queryConfig: join162,
8606
+ queryConfig: join155,
8607
8607
  tableConfig: schema2[relation.targetTableName],
8608
8608
  relationWhere: filter,
8609
8609
  isNested: true,
@@ -8617,7 +8617,7 @@ var init_dialect = __esm({
8617
8617
  key: k2,
8618
8618
  selection: innerQuery.selection,
8619
8619
  isArray: !isSingle2,
8620
- isOptional: (relation.optional ?? false) || join162 !== true && !!join162.where
8620
+ isOptional: (relation.optional ?? false) || join155 !== true && !!join155.where
8621
8621
  });
8622
8622
  const jsonColumns = sql.join(innerQuery.selection.map((s3) => {
8623
8623
  return sql`${sql.raw(this.escapeString(s3.key))}, ${s3.selection ? sql`${jsonb2}(${sql.identifier(s3.key)})` : sql.identifier(s3.key)}`;
@@ -9016,7 +9016,7 @@ var init_update = __esm({
9016
9016
  createJoin(joinType) {
9017
9017
  return ((table, on) => {
9018
9018
  const tableName = getTableLikeName(table);
9019
- if (typeof tableName === "string" && this.config.joins.some((join162) => join162.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
9019
+ if (typeof tableName === "string" && this.config.joins.some((join155) => join155.alias === tableName)) throw new Error(`Alias "${tableName}" is already used in this query`);
9020
9020
  if (typeof on === "function") {
9021
9021
  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;
9022
9022
  on = on(new Proxy(this.config.table[Table.Symbol.Columns], new SelectionProxyHandler({
@@ -13288,14 +13288,14 @@ function getGlobalSalt() {
13288
13288
  cached = salt2;
13289
13289
  return cached;
13290
13290
  }
13291
- const stat10 = fs2.statSync(saltPath);
13292
- if (stat10.size !== GLOBAL_SALT_SIZE) {
13291
+ const stat8 = fs2.statSync(saltPath);
13292
+ if (stat8.size !== GLOBAL_SALT_SIZE) {
13293
13293
  throw new Error(
13294
- `global-salt at ${saltPath} has wrong size: expected ${GLOBAL_SALT_SIZE} bytes, got ${stat10.size}. Refusing to use a corrupted salt file. Delete the file manually if you intend to regenerate it (this will invalidate all stored API keys).`
13294
+ `global-salt at ${saltPath} has wrong size: expected ${GLOBAL_SALT_SIZE} bytes, got ${stat8.size}. Refusing to use a corrupted salt file. Delete the file manually if you intend to regenerate it (this will invalidate all stored API keys).`
13295
13295
  );
13296
13296
  }
13297
13297
  if (process.platform !== "win32") {
13298
- const mode = stat10.mode & 511;
13298
+ const mode = stat8.mode & 511;
13299
13299
  if (mode !== SALT_FILE_MODE) {
13300
13300
  throw new Error(
13301
13301
  `global-salt at ${saltPath} has wrong permissions: expected 0o600, got 0o${mode.toString(8)}. Fix with: chmod 600 ${saltPath}`
@@ -13311,14 +13311,14 @@ function validateGlobalSalt() {
13311
13311
  if (!fs2.existsSync(saltPath)) {
13312
13312
  return;
13313
13313
  }
13314
- const stat10 = fs2.statSync(saltPath);
13315
- if (stat10.size !== GLOBAL_SALT_SIZE) {
13314
+ const stat8 = fs2.statSync(saltPath);
13315
+ if (stat8.size !== GLOBAL_SALT_SIZE) {
13316
13316
  throw new Error(
13317
- `global-salt validation failed: size ${stat10.size}, expected ${GLOBAL_SALT_SIZE}`
13317
+ `global-salt validation failed: size ${stat8.size}, expected ${GLOBAL_SALT_SIZE}`
13318
13318
  );
13319
13319
  }
13320
13320
  if (process.platform !== "win32") {
13321
- const mode = stat10.mode & 511;
13321
+ const mode = stat8.mode & 511;
13322
13322
  if (mode !== SALT_FILE_MODE) {
13323
13323
  throw new Error(
13324
13324
  `global-salt validation failed: permissions 0o${mode.toString(8)}, expected 0o600`
@@ -15893,7 +15893,7 @@ var init_backup = __esm({
15893
15893
  import lockfile from "proper-lockfile";
15894
15894
  async function acquireLock(filePath, options) {
15895
15895
  try {
15896
- const release3 = await lockfile.lock(filePath, {
15896
+ const release2 = await lockfile.lock(filePath, {
15897
15897
  ...DEFAULT_LOCK_OPTIONS,
15898
15898
  ...options?.stale !== void 0 && { stale: options.stale },
15899
15899
  ...options?.retries !== void 0 && {
@@ -15903,7 +15903,7 @@ async function acquireLock(filePath, options) {
15903
15903
  }
15904
15904
  }
15905
15905
  });
15906
- return release3;
15906
+ return release2;
15907
15907
  } catch (err2) {
15908
15908
  throw new CleoError(7 /* LOCK_TIMEOUT */, `Failed to acquire lock: ${filePath}`, {
15909
15909
  fix: `Another process may be writing to this file. Wait and retry.`,
@@ -15912,11 +15912,11 @@ async function acquireLock(filePath, options) {
15912
15912
  }
15913
15913
  }
15914
15914
  async function withLock(filePath, fn2, options) {
15915
- const release3 = await acquireLock(filePath, options);
15915
+ const release2 = await acquireLock(filePath, options);
15916
15916
  try {
15917
15917
  return await fn2();
15918
15918
  } finally {
15919
- await release3();
15919
+ await release2();
15920
15920
  }
15921
15921
  }
15922
15922
  var DEFAULT_LOCK_OPTIONS;
@@ -23065,8 +23065,8 @@ function analyzeArchitecture(projectRoot, _projectContext) {
23065
23065
  for (const entry of entries) {
23066
23066
  const entryPath = join25(srcPath, entry);
23067
23067
  try {
23068
- const stat10 = statSync2(entryPath);
23069
- if (stat10.isDirectory()) {
23068
+ const stat8 = statSync2(entryPath);
23069
+ if (stat8.isDirectory()) {
23070
23070
  const purpose = LAYER_PURPOSE[entry.toLowerCase()] ?? `${entry} layer`;
23071
23071
  layers.push({ name: entry, path: `src/${entry}`, purpose });
23072
23072
  } else if (ENTRY_POINT_NAMES.has(entry)) {
@@ -23186,8 +23186,8 @@ function analyzeStructure(projectRoot) {
23186
23186
  if (EXCLUDED_DIRS.has(entry) || entry.startsWith(".")) continue;
23187
23187
  const entryPath = join26(projectRoot, entry);
23188
23188
  try {
23189
- const stat10 = statSync3(entryPath);
23190
- if (stat10.isDirectory()) {
23189
+ const stat8 = statSync3(entryPath);
23190
+ if (stat8.isDirectory()) {
23191
23191
  const fileCount = countFiles(entryPath);
23192
23192
  totalFiles += fileCount;
23193
23193
  const purpose = DIR_PURPOSE[entry.toLowerCase()] ?? "Project directory";
@@ -23230,8 +23230,8 @@ function countFiles(dir, depth = 0) {
23230
23230
  if (EXCLUDED_DIRS.has(entry) || entry.startsWith(".")) continue;
23231
23231
  const entryPath = join26(dir, entry);
23232
23232
  try {
23233
- const stat10 = statSync3(entryPath);
23234
- if (stat10.isDirectory()) {
23233
+ const stat8 = statSync3(entryPath);
23234
+ if (stat8.isDirectory()) {
23235
23235
  count5 += countFiles(entryPath, depth + 1);
23236
23236
  } else {
23237
23237
  count5++;
@@ -23671,8 +23671,8 @@ function walkSourceFiles(dir, projectRoot, callback, depth = 0) {
23671
23671
  if (EXCLUDED_DIRS2.has(entry) || entry.startsWith(".")) continue;
23672
23672
  const fullPath = join30(dir, entry);
23673
23673
  try {
23674
- const stat10 = statSync5(fullPath);
23675
- if (stat10.isDirectory()) {
23674
+ const stat8 = statSync5(fullPath);
23675
+ if (stat8.isDirectory()) {
23676
23676
  walkSourceFiles(fullPath, projectRoot, callback, depth + 1);
23677
23677
  } else {
23678
23678
  const ext = entry.slice(entry.lastIndexOf("."));
@@ -30544,24 +30544,24 @@ var init_detect_platform = __esm({
30544
30544
  return `other:${arch2}`;
30545
30545
  return "unknown";
30546
30546
  };
30547
- normalizePlatform = (platform6) => {
30548
- platform6 = platform6.toLowerCase();
30549
- if (platform6.includes("ios"))
30547
+ normalizePlatform = (platform5) => {
30548
+ platform5 = platform5.toLowerCase();
30549
+ if (platform5.includes("ios"))
30550
30550
  return "iOS";
30551
- if (platform6 === "android")
30551
+ if (platform5 === "android")
30552
30552
  return "Android";
30553
- if (platform6 === "darwin")
30553
+ if (platform5 === "darwin")
30554
30554
  return "MacOS";
30555
- if (platform6 === "win32")
30555
+ if (platform5 === "win32")
30556
30556
  return "Windows";
30557
- if (platform6 === "freebsd")
30557
+ if (platform5 === "freebsd")
30558
30558
  return "FreeBSD";
30559
- if (platform6 === "openbsd")
30559
+ if (platform5 === "openbsd")
30560
30560
  return "OpenBSD";
30561
- if (platform6 === "linux")
30561
+ if (platform5 === "linux")
30562
30562
  return "Linux";
30563
- if (platform6)
30564
- return `Other:${platform6}`;
30563
+ if (platform5)
30564
+ return `Other:${platform5}`;
30565
30565
  return "Unknown";
30566
30566
  };
30567
30567
  getPlatformHeaders = () => {
@@ -64228,8 +64228,8 @@ async function cleanProjectSchemas(projectRoot) {
64228
64228
  return { cleaned: false };
64229
64229
  }
64230
64230
  try {
64231
- const stat10 = statSync7(projectSchemasDir);
64232
- if (!stat10.isDirectory()) {
64231
+ const stat8 = statSync7(projectSchemasDir);
64232
+ if (!stat8.isDirectory()) {
64233
64233
  return { cleaned: false };
64234
64234
  }
64235
64235
  } catch {
@@ -64861,8 +64861,8 @@ async function ensureGitignore(projectRoot) {
64861
64861
  const templateContent = getGitignoreContent();
64862
64862
  if (existsSync40(gitignorePath)) {
64863
64863
  const existing = readFileSync26(gitignorePath, "utf-8");
64864
- const normalize3 = (s3) => s3.trim().replace(/\r\n/g, "\n");
64865
- if (normalize3(existing) === normalize3(templateContent)) {
64864
+ const normalize2 = (s3) => s3.trim().replace(/\r\n/g, "\n");
64865
+ if (normalize2(existing) === normalize2(templateContent)) {
64866
64866
  return { action: "skipped", path: gitignorePath, details: "Already matches template" };
64867
64867
  }
64868
64868
  await writeFile7(gitignorePath, templateContent);
@@ -65102,8 +65102,8 @@ function checkGitignore(projectRoot) {
65102
65102
  }
65103
65103
  const installed = readFileSync26(gitignorePath, "utf-8");
65104
65104
  const template = getGitignoreContent();
65105
- const normalize3 = (s3) => s3.trim().replace(/\r\n/g, "\n");
65106
- const matches = normalize3(installed) === normalize3(template);
65105
+ const normalize2 = (s3) => s3.trim().replace(/\r\n/g, "\n");
65106
+ const matches = normalize2(installed) === normalize2(template);
65107
65107
  return {
65108
65108
  id: "cleo_gitignore",
65109
65109
  category: "scaffold",
@@ -65284,8 +65284,8 @@ function checkSqliteDb(projectRoot) {
65284
65284
  fix: "cleo init"
65285
65285
  };
65286
65286
  }
65287
- const stat10 = statSync8(dbPath);
65288
- if (stat10.size === 0) {
65287
+ const stat8 = statSync8(dbPath);
65288
+ if (stat8.size === 0) {
65289
65289
  return {
65290
65290
  id: "sqlite_db",
65291
65291
  category: "scaffold",
@@ -65299,8 +65299,8 @@ function checkSqliteDb(projectRoot) {
65299
65299
  id: "sqlite_db",
65300
65300
  category: "scaffold",
65301
65301
  status: "passed",
65302
- message: `tasks.db exists (${stat10.size} bytes)`,
65303
- details: { path: dbPath, exists: true, size: stat10.size },
65302
+ message: `tasks.db exists (${stat8.size} bytes)`,
65303
+ details: { path: dbPath, exists: true, size: stat8.size },
65304
65304
  fix: null
65305
65305
  };
65306
65306
  }
@@ -65352,8 +65352,8 @@ function checkBrainDb(projectRoot) {
65352
65352
  fix: "cleo init"
65353
65353
  };
65354
65354
  }
65355
- const stat10 = statSync8(dbPath);
65356
- if (stat10.size === 0) {
65355
+ const stat8 = statSync8(dbPath);
65356
+ if (stat8.size === 0) {
65357
65357
  return {
65358
65358
  id: "brain_db",
65359
65359
  category: "scaffold",
@@ -65367,8 +65367,8 @@ function checkBrainDb(projectRoot) {
65367
65367
  id: "brain_db",
65368
65368
  category: "scaffold",
65369
65369
  status: "passed",
65370
- message: `brain.db exists (${stat10.size} bytes)`,
65371
- details: { path: dbPath, exists: true, size: stat10.size },
65370
+ message: `brain.db exists (${stat8.size} bytes)`,
65371
+ details: { path: dbPath, exists: true, size: stat8.size },
65372
65372
  fix: null
65373
65373
  };
65374
65374
  }
@@ -65432,8 +65432,8 @@ async function ensureGlobalHome() {
65432
65432
  await writeFile7(globalConfigPath, resolved);
65433
65433
  }
65434
65434
  }
65435
- const homedir17 = (await import("node:os")).homedir();
65436
- const legacyCleoHome = join44(homedir17, ".cleo");
65435
+ const homedir15 = (await import("node:os")).homedir();
65436
+ const legacyCleoHome = join44(homedir15, ".cleo");
65437
65437
  const cleanupPaths = [cleoHome];
65438
65438
  if (legacyCleoHome !== cleoHome && existsSync40(legacyCleoHome)) {
65439
65439
  cleanupPaths.push(legacyCleoHome);
@@ -70575,8 +70575,8 @@ function parseTokenMetrics(inputFile, cwd) {
70575
70575
  const raw = JSON.parse(readFileSync34(file2, "utf-8"));
70576
70576
  if (raw.resourceMetrics) {
70577
70577
  const points = [];
70578
- for (const rm6 of raw.resourceMetrics ?? []) {
70579
- for (const sm of rm6.scopeMetrics ?? []) {
70578
+ for (const rm5 of raw.resourceMetrics ?? []) {
70579
+ for (const sm of rm5.scopeMetrics ?? []) {
70580
70580
  for (const metric of sm.metrics ?? []) {
70581
70581
  if (metric.name !== "claude_code.token.usage") continue;
70582
70582
  for (const dp of metric.sum?.dataPoints ?? []) {
@@ -73365,10 +73365,10 @@ async function readProjectMeta(projectPath) {
73365
73365
  }
73366
73366
  async function readProjectId(projectPath) {
73367
73367
  try {
73368
- const { readFileSync: readFileSync116, existsSync: existsSync143 } = await import("node:fs");
73368
+ const { readFileSync: readFileSync115, existsSync: existsSync143 } = await import("node:fs");
73369
73369
  const infoPath = join66(projectPath, ".cleo", "project-info.json");
73370
73370
  if (!existsSync143(infoPath)) return "";
73371
- const data = JSON.parse(readFileSync116(infoPath, "utf-8"));
73371
+ const data = JSON.parse(readFileSync115(infoPath, "utf-8"));
73372
73372
  return typeof data.projectId === "string" ? data.projectId : "";
73373
73373
  } catch {
73374
73374
  return "";
@@ -74519,8 +74519,8 @@ function collectCleoFiles(cleoDir) {
74519
74519
  const fullPath = join68(dir, entry);
74520
74520
  const relPath = relative9(cleoDir, fullPath);
74521
74521
  try {
74522
- const stat10 = statSync16(fullPath);
74523
- if (stat10.isDirectory()) {
74522
+ const stat8 = statSync16(fullPath);
74523
+ if (stat8.isDirectory()) {
74524
74524
  walk(fullPath);
74525
74525
  } else {
74526
74526
  files.push(relPath.replaceAll("\\", "/"));
@@ -76482,17 +76482,17 @@ function scanLogDir(dir, includeMigration) {
76482
76482
  const isMigration = MIGRATION_LOG_PATTERN.test(name2);
76483
76483
  if (!cleoMatch && (!isMigration || !includeMigration)) continue;
76484
76484
  const filePath = join69(dir, name2);
76485
- let stat10;
76485
+ let stat8;
76486
76486
  try {
76487
- stat10 = statSync17(filePath);
76487
+ stat8 = statSync17(filePath);
76488
76488
  } catch {
76489
76489
  continue;
76490
76490
  }
76491
76491
  files.push({
76492
76492
  path: filePath,
76493
76493
  name: name2,
76494
- size: stat10.size,
76495
- mtime: stat10.mtime.toISOString(),
76494
+ size: stat8.size,
76495
+ mtime: stat8.mtime.toISOString(),
76496
76496
  date: cleoMatch ? cleoMatch[1] : null,
76497
76497
  isActive: false
76498
76498
  // set below
@@ -77940,8 +77940,8 @@ function readMachineKey() {
77940
77940
  return key2;
77941
77941
  }
77942
77942
  if (process.platform !== "win32") {
77943
- const stat10 = statSync18(keyPath);
77944
- const mode = stat10.mode & 511;
77943
+ const stat8 = statSync18(keyPath);
77944
+ const mode = stat8.mode & 511;
77945
77945
  if (mode !== 384) {
77946
77946
  throw new Error(
77947
77947
  `Machine key at ${keyPath} has wrong permissions: expected 0o600, got 0o${mode.toString(8)}. Fix with: chmod 600 ${keyPath}`
@@ -80867,8 +80867,8 @@ var init_release_config = __esm({
80867
80867
  // packages/core/src/release/ci.ts
80868
80868
  import { existsSync as existsSync72, mkdirSync as mkdirSync18, readFileSync as readFileSync52, writeFileSync as writeFileSync9 } from "node:fs";
80869
80869
  import { dirname as dirname19, join as join77 } from "node:path";
80870
- function getPlatformPath(platform6) {
80871
- return PLATFORM_PATHS[platform6];
80870
+ function getPlatformPath(platform5) {
80871
+ return PLATFORM_PATHS[platform5];
80872
80872
  }
80873
80873
  function detectCIPlatform(projectDir) {
80874
80874
  const dir = projectDir ?? process.cwd();
@@ -80962,10 +80962,10 @@ workflows:
80962
80962
  only: /^v.*/
80963
80963
  `;
80964
80964
  }
80965
- function generateCIConfig(platform6, cwd) {
80965
+ function generateCIConfig(platform5, cwd) {
80966
80966
  const releaseConfig = loadReleaseConfig(cwd);
80967
80967
  const gates = releaseConfig.gates.map((g2) => ({ name: g2.name, command: g2.command }));
80968
- switch (platform6) {
80968
+ switch (platform5) {
80969
80969
  case "github-actions":
80970
80970
  return generateGitHubActions({ gates });
80971
80971
  case "gitlab-ci":
@@ -80974,10 +80974,10 @@ function generateCIConfig(platform6, cwd) {
80974
80974
  return generateCircleCI({ gates });
80975
80975
  }
80976
80976
  }
80977
- function writeCIConfig(platform6, options = {}) {
80977
+ function writeCIConfig(platform5, options = {}) {
80978
80978
  const projectDir = options.projectDir ?? process.cwd();
80979
- const outputPath = join77(projectDir, getPlatformPath(platform6));
80980
- const content = generateCIConfig(platform6, projectDir);
80979
+ const outputPath = join77(projectDir, getPlatformPath(platform5));
80980
+ const content = generateCIConfig(platform5, projectDir);
80981
80981
  if (options.dryRun) {
80982
80982
  return { action: "would_write", path: outputPath, content };
80983
80983
  }
@@ -80985,9 +80985,9 @@ function writeCIConfig(platform6, options = {}) {
80985
80985
  writeFileSync9(outputPath, content, "utf-8");
80986
80986
  return { action: "wrote", path: outputPath, content };
80987
80987
  }
80988
- function validateCIConfig(platform6, projectDir) {
80988
+ function validateCIConfig(platform5, projectDir) {
80989
80989
  const dir = projectDir ?? process.cwd();
80990
- const configPath = join77(dir, getPlatformPath(platform6));
80990
+ const configPath = join77(dir, getPlatformPath(platform5));
80991
80991
  if (!existsSync72(configPath)) {
80992
80992
  return { valid: false, exists: false, errors: ["Config file not found"] };
80993
80993
  }
@@ -82087,9 +82087,9 @@ async function readPushPolicy(cwd) {
82087
82087
  return void 0;
82088
82088
  }
82089
82089
  if (!config2) return void 0;
82090
- const release3 = config2.release;
82091
- if (!release3) return void 0;
82092
- return release3.push;
82090
+ const release2 = config2.release;
82091
+ if (!release2) return void 0;
82092
+ return release2.push;
82093
82093
  }
82094
82094
  async function pushRelease(version2, remote, cwd, opts) {
82095
82095
  if (!version2) {
@@ -86738,8 +86738,8 @@ async function initializeSpawnAdapters(manifests) {
86738
86738
  if (!manifest.capabilities?.supportsSpawn) continue;
86739
86739
  if (spawnRegistry.hasAdapterForProvider(manifest.provider)) continue;
86740
86740
  try {
86741
- const { join: join162 } = await import("node:path");
86742
- const modulePath = join162(manifest.packagePath, manifest.entryPoint);
86741
+ const { join: join155 } = await import("node:path");
86742
+ const modulePath = join155(manifest.packagePath, manifest.entryPoint);
86743
86743
  const adapterModule = await import(modulePath);
86744
86744
  let SpawnProviderClass;
86745
86745
  for (const [exportName, exportValue] of Object.entries(adapterModule)) {
@@ -88993,7 +88993,7 @@ function getNodeVersionInfo() {
88993
88993
  };
88994
88994
  }
88995
88995
  function getNodeUpgradeInstructions() {
88996
- const platform6 = detectPlatform();
88996
+ const platform5 = detectPlatform();
88997
88997
  const arch2 = process.arch;
88998
88998
  const instructions = [];
88999
88999
  const hasFnm = commandExists2("fnm");
@@ -89008,7 +89008,7 @@ function getNodeUpgradeInstructions() {
89008
89008
  if (hasVolta) {
89009
89009
  instructions.push(`volta install node@${MINIMUM_NODE_MAJOR}`);
89010
89010
  }
89011
- switch (platform6) {
89011
+ switch (platform5) {
89012
89012
  case "linux":
89013
89013
  if (commandExists2("dnf")) {
89014
89014
  instructions.push(
@@ -89040,7 +89040,7 @@ function getNodeUpgradeInstructions() {
89040
89040
  }
89041
89041
  instructions.push(`https://nodejs.org/en/download/`);
89042
89042
  const recommended = instructions[0] ?? `https://nodejs.org/en/download/`;
89043
- return { platform: platform6, arch: arch2, instructions, recommended };
89043
+ return { platform: platform5, arch: arch2, instructions, recommended };
89044
89044
  }
89045
89045
  function getSystemInfo2() {
89046
89046
  return {
@@ -90525,11 +90525,11 @@ async function checkDependency(name2) {
90525
90525
  }
90526
90526
  async function checkAllDependencies() {
90527
90527
  const timestamp3 = (/* @__PURE__ */ new Date()).toISOString();
90528
- const platform6 = process.platform;
90528
+ const platform5 = process.platform;
90529
90529
  const nodeVersion = process.version.replace(/^v/, "");
90530
90530
  const applicableSpecs = DEPENDENCY_SPECS.filter((spec) => {
90531
90531
  if (!spec.platforms) return true;
90532
- return spec.platforms.includes(platform6);
90532
+ return spec.platforms.includes(platform5);
90533
90533
  });
90534
90534
  const results = await Promise.all(applicableSpecs.map((spec) => checkDependency(spec.name)));
90535
90535
  const requiredResults = results.filter((r) => r.category === "required");
@@ -90542,7 +90542,7 @@ async function checkAllDependencies() {
90542
90542
  }
90543
90543
  return {
90544
90544
  timestamp: timestamp3,
90545
- platform: platform6,
90545
+ platform: platform5,
90546
90546
  nodeVersion,
90547
90547
  results,
90548
90548
  allRequiredMet,
@@ -97539,8 +97539,8 @@ function classifyProject(directory) {
97539
97539
  }
97540
97540
  function isNonEmptyDir(dirPath) {
97541
97541
  try {
97542
- const stat10 = statSync21(dirPath);
97543
- if (!stat10.isDirectory()) return false;
97542
+ const stat8 = statSync21(dirPath);
97543
+ if (!stat8.isDirectory()) return false;
97544
97544
  const entries = readdirSync35(dirPath).filter((e) => !e.startsWith("."));
97545
97545
  return entries.length > 0;
97546
97546
  } catch {
@@ -97998,15 +97998,15 @@ async function initAgentDefinition(created, warnings) {
97998
97998
  await mkdir19(dirname30(globalAgentsDir), { recursive: true });
97999
97999
  try {
98000
98000
  try {
98001
- const stat10 = await lstat(globalAgentsDir);
98002
- if (stat10.isSymbolicLink()) {
98001
+ const stat8 = await lstat(globalAgentsDir);
98002
+ if (stat8.isSymbolicLink()) {
98003
98003
  const { readlink: readlink2 } = await import("node:fs/promises");
98004
98004
  const currentTarget = await readlink2(globalAgentsDir);
98005
98005
  if (currentTarget === agentSourceDir) {
98006
98006
  return;
98007
98007
  }
98008
98008
  await unlink4(globalAgentsDir);
98009
- } else if (stat10.isDirectory()) {
98009
+ } else if (stat8.isDirectory()) {
98010
98010
  return;
98011
98011
  }
98012
98012
  } catch {
@@ -98758,8 +98758,8 @@ async function ensureCleoSymlink(ctx) {
98758
98758
  ctx.created.push(`~/.cleo \u2192 ${canonicalTarget} (${linkType} link)`);
98759
98759
  return;
98760
98760
  }
98761
- const stat10 = lstatSync2(legacyPath);
98762
- if (stat10.isSymbolicLink()) {
98761
+ const stat8 = lstatSync2(legacyPath);
98762
+ if (stat8.isSymbolicLink()) {
98763
98763
  const currentTarget = await readlink(legacyPath);
98764
98764
  if (currentTarget === canonicalTarget) {
98765
98765
  return;
@@ -98769,7 +98769,7 @@ async function ensureCleoSymlink(ctx) {
98769
98769
  );
98770
98770
  return;
98771
98771
  }
98772
- if (stat10.isDirectory()) {
98772
+ if (stat8.isDirectory()) {
98773
98773
  const backupPath = `${legacyPath}.bak-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}`;
98774
98774
  await rename2(legacyPath, backupPath);
98775
98775
  await symlink2(canonicalTarget, legacyPath, linkType);
@@ -98792,8 +98792,8 @@ async function ensureCleoSymlink(ctx) {
98792
98792
  }
98793
98793
  async function writeTemplateTo(content, destPath, isDryRun) {
98794
98794
  if (isDryRun) return false;
98795
- const { dirname: dirname43 } = await import("node:path");
98796
- await mkdir20(dirname43(destPath), { recursive: true });
98795
+ const { dirname: dirname41 } = await import("node:path");
98796
+ await mkdir20(dirname41(destPath), { recursive: true });
98797
98797
  await writeFile13(destPath, content);
98798
98798
  return true;
98799
98799
  }
@@ -99074,8 +99074,8 @@ async function verifyBootstrapHealth(ctx) {
99074
99074
  const legacyPath = join117(homedir8(), ".cleo");
99075
99075
  const canonicalTarget = getCleoHome();
99076
99076
  if (existsSync114(legacyPath)) {
99077
- const stat10 = lstatSync2(legacyPath);
99078
- if (stat10.isSymbolicLink()) {
99077
+ const stat8 = lstatSync2(legacyPath);
99078
+ if (stat8.isSymbolicLink()) {
99079
99079
  const target = await readlink(legacyPath);
99080
99080
  if (target !== canonicalTarget) {
99081
99081
  ctx.warnings.push(
@@ -101040,15 +101040,15 @@ function mimeFromAttachment(attachment) {
101040
101040
  }
101041
101041
  async function withWriteLock(fn2) {
101042
101042
  const prev = writeLock;
101043
- let release3;
101043
+ let release2;
101044
101044
  writeLock = new Promise((resolve20) => {
101045
- release3 = resolve20;
101045
+ release2 = resolve20;
101046
101046
  });
101047
101047
  await prev;
101048
101048
  try {
101049
101049
  return await fn2();
101050
101050
  } finally {
101051
- release3();
101051
+ release2();
101052
101052
  }
101053
101053
  }
101054
101054
  function rowToMetadata(row) {
@@ -102103,9 +102103,9 @@ async function runHttpGate(gate, index2, _projectRoot, timeoutMs) {
102103
102103
  const startMs = Date.now();
102104
102104
  let serverProcess = null;
102105
102105
  if (gate.startCommand) {
102106
- const { spawn: spawn7 } = await import("node:child_process");
102106
+ const { spawn: spawn4 } = await import("node:child_process");
102107
102107
  const [cmd, ...args] = gate.startCommand.split(" ");
102108
- serverProcess = spawn7(cmd, args, { detached: true, stdio: "ignore" });
102108
+ serverProcess = spawn4(cmd, args, { detached: true, stdio: "ignore" });
102109
102109
  serverProcess.unref();
102110
102110
  const delayMs = gate.startupDelayMs ?? 2e3;
102111
102111
  await new Promise((resolve20) => setTimeout(resolve20, delayMs));
@@ -108097,8 +108097,8 @@ var init_llmtxt_blob_adapter = __esm({
108097
108097
  db = this.opts.db;
108098
108098
  } else {
108099
108099
  const { drizzle: drizzle2, BetterSqlite3Database } = await loadDrizzle();
108100
- const { mkdir: mkdir29 } = await import("node:fs/promises");
108101
- await mkdir29(path5.dirname(manifestDbPath), { recursive: true });
108100
+ const { mkdir: mkdir25 } = await import("node:fs/promises");
108101
+ await mkdir25(path5.dirname(manifestDbPath), { recursive: true });
108102
108102
  const nativeDb = new BetterSqlite3Database(manifestDbPath);
108103
108103
  this.ownedNativeDb = nativeDb;
108104
108104
  db = drizzle2({ client: nativeDb });
@@ -111687,32 +111687,32 @@ async function packBundle(input) {
111687
111687
  }
111688
111688
  }
111689
111689
  const databaseEntries = stagedDbs.map((db) => {
111690
- const stat10 = fs5.statSync(db.stagedPath);
111690
+ const stat8 = fs5.statSync(db.stagedPath);
111691
111691
  return {
111692
111692
  name: db.name,
111693
111693
  filename: `databases/${db.name}.db`,
111694
- size: stat10.size,
111694
+ size: stat8.size,
111695
111695
  sha256: sha256OfFile(db.stagedPath),
111696
111696
  schemaVersion: schemaVersionForDb(db.stagedPath),
111697
111697
  rowCounts: rowCountsForDb(db.stagedPath)
111698
111698
  };
111699
111699
  });
111700
111700
  const jsonEntries = stagedJson.map((jf) => {
111701
- const stat10 = fs5.statSync(jf.stagedPath);
111701
+ const stat8 = fs5.statSync(jf.stagedPath);
111702
111702
  return {
111703
111703
  filename: jf.filename,
111704
- size: stat10.size,
111704
+ size: stat8.size,
111705
111705
  sha256: sha256OfFile(jf.stagedPath)
111706
111706
  };
111707
111707
  });
111708
111708
  let globalFiles;
111709
111709
  if (includesGlobal && globalSaltStaged) {
111710
111710
  const saltStaged = path6.join(stagingDir, "global", "global-salt");
111711
- const stat10 = fs5.statSync(saltStaged);
111711
+ const stat8 = fs5.statSync(saltStaged);
111712
111712
  globalFiles = [
111713
111713
  {
111714
111714
  filename: "global/global-salt",
111715
- size: stat10.size,
111715
+ size: stat8.size,
111716
111716
  sha256: sha256OfFile(saltStaged)
111717
111717
  }
111718
111718
  ];
@@ -120345,8 +120345,8 @@ var require_resolve = __commonJS({
120345
120345
  }
120346
120346
  return count5;
120347
120347
  }
120348
- function getFullPath(resolver, id = "", normalize3) {
120349
- if (normalize3 !== false)
120348
+ function getFullPath(resolver, id = "", normalize2) {
120349
+ if (normalize2 !== false)
120350
120350
  id = normalizeId(id);
120351
120351
  const p2 = resolver.parse(id);
120352
120352
  return _getFullPath(resolver, p2);
@@ -121686,7 +121686,7 @@ var require_fast_uri = __commonJS({
121686
121686
  "use strict";
121687
121687
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils();
121688
121688
  var { SCHEMES, getSchemeHandler } = require_schemes();
121689
- function normalize3(uri, options) {
121689
+ function normalize2(uri, options) {
121690
121690
  if (typeof uri === "string") {
121691
121691
  uri = /** @type {T} */
121692
121692
  serialize(parse3(uri, options), options);
@@ -121922,7 +121922,7 @@ var require_fast_uri = __commonJS({
121922
121922
  }
121923
121923
  var fastUri = {
121924
121924
  SCHEMES,
121925
- normalize: normalize3,
121925
+ normalize: normalize2,
121926
121926
  resolve: resolve20,
121927
121927
  resolveComponent,
121928
121928
  equal,
@@ -138257,9 +138257,9 @@ async function systemLog(projectRoot, filters) {
138257
138257
  }
138258
138258
  async function queryAuditLogSqlite(projectRoot, filters) {
138259
138259
  try {
138260
- const { join: join162 } = await import("node:path");
138260
+ const { join: join155 } = await import("node:path");
138261
138261
  const { existsSync: existsSync143 } = await import("node:fs");
138262
- const dbPath = join162(projectRoot, CLEO_DIR_NAME, TASKS_DB_FILENAME);
138262
+ const dbPath = join155(projectRoot, CLEO_DIR_NAME, TASKS_DB_FILENAME);
138263
138263
  if (!existsSync143(dbPath)) {
138264
138264
  const offset = filters?.offset ?? 0;
138265
138265
  const limit = filters?.limit ?? 20;
@@ -141027,10 +141027,10 @@ function countHookEvents(hooksSrcPath, canonicalEvents) {
141027
141027
  return count5;
141028
141028
  }
141029
141029
  function buildReport(partial2) {
141030
- const sep3 = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
141030
+ const sep2 = "\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550";
141031
141031
  const lines = [
141032
141032
  `CLEO Smoke Probe \u2014 provider: ${partial2.providerId}`,
141033
- sep3,
141033
+ sep2,
141034
141034
  ` Adapter loaded: ${partial2.adapterLoaded ? "yes" : "no"}`
141035
141035
  ];
141036
141036
  for (const db of partial2.dbChecks) {
@@ -151321,8 +151321,8 @@ var init_playbook = __esm({
151321
151321
  async function orchestrateClassify(request, context, projectRoot) {
151322
151322
  try {
151323
151323
  const { getCleoCantWorkflowsDir: getCleoCantWorkflowsDir2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
151324
- const { readFileSync: readFileSync116, readdirSync: readdirSync44, existsSync: existsSync143 } = await import("node:fs");
151325
- const { join: join162 } = await import("node:path");
151324
+ const { readFileSync: readFileSync115, readdirSync: readdirSync44, existsSync: existsSync143 } = await import("node:fs");
151325
+ const { join: join155 } = await import("node:path");
151326
151326
  const workflowsDir = getCleoCantWorkflowsDir2();
151327
151327
  const combined = `${request} ${context ?? ""}`.toLowerCase();
151328
151328
  const matches = [];
@@ -151330,7 +151330,7 @@ async function orchestrateClassify(request, context, projectRoot) {
151330
151330
  const files = readdirSync44(workflowsDir).filter((f2) => f2.endsWith(".cant"));
151331
151331
  for (const file2 of files) {
151332
151332
  try {
151333
- const src = readFileSync116(join162(workflowsDir, file2), "utf-8");
151333
+ const src = readFileSync115(join155(workflowsDir, file2), "utf-8");
151334
151334
  const teamMatch = /^team\s+(\S+):/m.exec(src);
151335
151335
  if (!teamMatch) continue;
151336
151336
  const teamName = teamMatch[1];
@@ -151345,12 +151345,12 @@ async function orchestrateClassify(request, context, projectRoot) {
151345
151345
  }
151346
151346
  }
151347
151347
  }
151348
- const localCantDir = join162(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
151348
+ const localCantDir = join155(projectRoot, CLEO_DIR_NAME, WORKFLOWS_SUBDIR);
151349
151349
  if (existsSync143(localCantDir)) {
151350
151350
  const files = readdirSync44(localCantDir).filter((f2) => f2.endsWith(".cant"));
151351
151351
  for (const file2 of files) {
151352
151352
  try {
151353
- const src = readFileSync116(join162(localCantDir, file2), "utf-8");
151353
+ const src = readFileSync115(join155(localCantDir, file2), "utf-8");
151354
151354
  const teamMatch = /^team\s+(\S+):/m.exec(src);
151355
151355
  if (!teamMatch) continue;
151356
151356
  const teamName = teamMatch[1];
@@ -153249,1180 +153249,8 @@ var init_pipeline5 = __esm({
153249
153249
  }
153250
153250
  });
153251
153251
 
153252
- // packages/cleo/src/sentient/ingesters/brain-ingester.ts
153253
- function computeBrainWeight(citationCount, qualityScore) {
153254
- return Math.min(citationCount / 10 * qualityScore, 1);
153255
- }
153256
- function runBrainIngester(nativeDb) {
153257
- if (!nativeDb) {
153258
- return [];
153259
- }
153260
- try {
153261
- const stmt = nativeDb.prepare(`
153262
- SELECT id, title, text, citation_count, quality_score
153263
- FROM brain_observations
153264
- WHERE type IN ('bugfix', 'decision')
153265
- AND citation_count >= :minCitations
153266
- AND created_at >= datetime('now', :lookback)
153267
- AND quality_score >= :minQuality
153268
- ORDER BY citation_count DESC, quality_score DESC
153269
- LIMIT :limit
153270
- `);
153271
- const rows = stmt.all({
153272
- minCitations: BRAIN_MIN_CITATION_COUNT,
153273
- lookback: `-${BRAIN_LOOKBACK_DAYS} days`,
153274
- minQuality: BRAIN_MIN_QUALITY_SCORE,
153275
- limit: BRAIN_INGESTER_LIMIT
153276
- });
153277
- const candidates = rows.map((row) => {
153278
- const label = row.title ?? row.text.slice(0, 80);
153279
- return {
153280
- source: "brain",
153281
- sourceId: row.id,
153282
- title: `[T2-BRAIN] Recurring issue: ${label}`,
153283
- rationale: `Brain entry ${row.id} cited ${row.citation_count} times (quality ${row.quality_score.toFixed(2)}) in the last ${BRAIN_LOOKBACK_DAYS} days`,
153284
- weight: computeBrainWeight(row.citation_count, row.quality_score)
153285
- };
153286
- });
153287
- candidates.sort((a, b2) => b2.weight - a.weight);
153288
- return candidates;
153289
- } catch (err2) {
153290
- const message = err2 instanceof Error ? err2.message : String(err2);
153291
- process.stderr.write(`[sentient/brain-ingester] WARNING: ${message}
153292
- `);
153293
- return [];
153294
- }
153295
- }
153296
- var BRAIN_INGESTER_LIMIT, BRAIN_MIN_CITATION_COUNT, BRAIN_MIN_QUALITY_SCORE, BRAIN_LOOKBACK_DAYS;
153297
- var init_brain_ingester = __esm({
153298
- "packages/cleo/src/sentient/ingesters/brain-ingester.ts"() {
153299
- "use strict";
153300
- BRAIN_INGESTER_LIMIT = 10;
153301
- BRAIN_MIN_CITATION_COUNT = 3;
153302
- BRAIN_MIN_QUALITY_SCORE = 0.5;
153303
- BRAIN_LOOKBACK_DAYS = 7;
153304
- }
153305
- });
153306
-
153307
- // packages/cleo/src/sentient/ingesters/nexus-ingester.ts
153308
- function toFingerprint(nodeId) {
153309
- return nodeId;
153310
- }
153311
- function runNexusIngester(nativeDb) {
153312
- if (!nativeDb) {
153313
- return [];
153314
- }
153315
- const seenIds = /* @__PURE__ */ new Set();
153316
- const candidates = [];
153317
- try {
153318
- const stmtA = nativeDb.prepare(`
153319
- SELECT n.id, n.name, n.file_path, COUNT(r.id) as caller_count
153320
- FROM nexus_nodes n
153321
- JOIN nexus_relations r ON r.target_id = n.id AND r.kind = 'calls'
153322
- WHERE NOT EXISTS (
153323
- SELECT 1 FROM nexus_relations r2
153324
- WHERE r2.source_id = n.id AND r2.kind = 'calls'
153325
- )
153326
- AND n.kind = 'function'
153327
- GROUP BY n.id
153328
- HAVING caller_count > :minCallers
153329
- ORDER BY caller_count DESC
153330
- LIMIT :limit
153331
- `);
153332
- const rowsA = stmtA.all({
153333
- minCallers: NEXUS_MIN_CALLER_COUNT,
153334
- limit: NEXUS_QUERY_LIMIT
153335
- });
153336
- for (const row of rowsA) {
153337
- const fp = toFingerprint(row.id);
153338
- if (seenIds.has(fp)) continue;
153339
- seenIds.add(fp);
153340
- candidates.push({
153341
- source: "nexus",
153342
- sourceId: row.id,
153343
- title: `[T2-NEXUS] Over-coupled symbol: ${row.name} (${row.caller_count} callers)`,
153344
- rationale: `Function ${row.name} in ${row.file_path} has ${row.caller_count} callers but makes no outbound calls \u2014 review for abstraction opportunity`,
153345
- weight: NEXUS_BASE_WEIGHT
153346
- });
153347
- }
153348
- } catch (err2) {
153349
- const message = err2 instanceof Error ? err2.message : String(err2);
153350
- process.stderr.write(`[sentient/nexus-ingester] WARNING query A: ${message}
153351
- `);
153352
- }
153353
- try {
153354
- const stmtB = nativeDb.prepare(`
153355
- SELECT n.id, n.name, n.file_path, COUNT(r.id) as degree
153356
- FROM nexus_nodes n
153357
- JOIN nexus_relations r ON r.source_id = n.id OR r.target_id = n.id
153358
- GROUP BY n.id
153359
- HAVING degree > :minDegree
153360
- ORDER BY degree DESC
153361
- LIMIT :limit
153362
- `);
153363
- const rowsB = stmtB.all({
153364
- minDegree: NEXUS_MIN_DEGREE,
153365
- limit: NEXUS_QUERY_LIMIT
153366
- });
153367
- for (const row of rowsB) {
153368
- const fp = toFingerprint(row.id);
153369
- if (seenIds.has(fp)) continue;
153370
- seenIds.add(fp);
153371
- candidates.push({
153372
- source: "nexus",
153373
- sourceId: row.id,
153374
- title: `[T2-NEXUS] Over-coupled symbol: ${row.name} (${row.degree} edges)`,
153375
- rationale: `Symbol ${row.name} in ${row.file_path} has ${row.degree} total edges \u2014 review for over-coupling`,
153376
- weight: NEXUS_BASE_WEIGHT
153377
- });
153378
- }
153379
- } catch (err2) {
153380
- const message = err2 instanceof Error ? err2.message : String(err2);
153381
- process.stderr.write(`[sentient/nexus-ingester] WARNING query B: ${message}
153382
- `);
153383
- }
153384
- return candidates;
153385
- }
153386
- var NEXUS_BASE_WEIGHT, NEXUS_MIN_CALLER_COUNT, NEXUS_MIN_DEGREE, NEXUS_QUERY_LIMIT;
153387
- var init_nexus_ingester = __esm({
153388
- "packages/cleo/src/sentient/ingesters/nexus-ingester.ts"() {
153389
- "use strict";
153390
- NEXUS_BASE_WEIGHT = 0.3;
153391
- NEXUS_MIN_CALLER_COUNT = 5;
153392
- NEXUS_MIN_DEGREE = 20;
153393
- NEXUS_QUERY_LIMIT = 5;
153394
- }
153395
- });
153396
-
153397
- // packages/cleo/src/sentient/ingesters/test-ingester.ts
153398
- import { readFileSync as readFileSync106 } from "node:fs";
153399
- import { join as join138 } from "node:path";
153400
- function runGatesIngester(projectRoot) {
153401
- const gatesPath = join138(projectRoot, GATES_JSONL_PATH);
153402
- let raw;
153403
- try {
153404
- raw = readFileSync106(gatesPath, "utf-8");
153405
- } catch {
153406
- return [];
153407
- }
153408
- const candidates = [];
153409
- const seenKeys = /* @__PURE__ */ new Set();
153410
- for (const line2 of raw.split("\n")) {
153411
- const trimmed = line2.trim();
153412
- if (!trimmed) continue;
153413
- let record2;
153414
- try {
153415
- record2 = JSON.parse(trimmed);
153416
- } catch {
153417
- continue;
153418
- }
153419
- const taskId = record2.taskId;
153420
- const gate = record2.gate ?? "unknown";
153421
- const failCount = record2.failCount ?? 0;
153422
- if (typeof taskId !== "string" || failCount <= 0) continue;
153423
- const key = `${taskId}.${gate}`;
153424
- if (seenKeys.has(key)) continue;
153425
- seenKeys.add(key);
153426
- candidates.push({
153427
- source: "test",
153428
- sourceId: key,
153429
- title: `[T2-TEST] Fix flaky gate: ${taskId}.${gate}`,
153430
- rationale: `Gate '${gate}' on task ${taskId} has failed ${failCount} time(s)`,
153431
- weight: TEST_BASE_WEIGHT
153432
- });
153433
- }
153434
- return candidates;
153435
- }
153436
- function runCoverageIngester(projectRoot) {
153437
- const coveragePath = join138(projectRoot, COVERAGE_SUMMARY_PATH);
153438
- let summary;
153439
- try {
153440
- const raw = readFileSync106(coveragePath, "utf-8");
153441
- summary = JSON.parse(raw);
153442
- } catch {
153443
- return [];
153444
- }
153445
- const candidates = [];
153446
- for (const [filePath, entry] of Object.entries(summary)) {
153447
- if (filePath === "total") continue;
153448
- const pct = entry?.lines?.pct;
153449
- if (typeof pct !== "number" || pct >= MIN_LINE_COVERAGE_PCT) continue;
153450
- candidates.push({
153451
- source: "test",
153452
- sourceId: filePath,
153453
- title: `[T2-TEST] Increase coverage: ${filePath} (${pct}% lines)`,
153454
- rationale: `File ${filePath} has ${pct}% line coverage (target: ${MIN_LINE_COVERAGE_PCT}%)`,
153455
- weight: TEST_BASE_WEIGHT
153456
- });
153457
- }
153458
- return candidates;
153459
- }
153460
- function runTestIngester(projectRoot) {
153461
- try {
153462
- const gatesCandidates = runGatesIngester(projectRoot);
153463
- const coverageCandidates = runCoverageIngester(projectRoot);
153464
- const seenSourceIds = /* @__PURE__ */ new Set();
153465
- const merged = [];
153466
- for (const candidate of [...gatesCandidates, ...coverageCandidates]) {
153467
- if (seenSourceIds.has(candidate.sourceId)) continue;
153468
- seenSourceIds.add(candidate.sourceId);
153469
- merged.push(candidate);
153470
- }
153471
- return merged;
153472
- } catch (err2) {
153473
- const message = err2 instanceof Error ? err2.message : String(err2);
153474
- process.stderr.write(`[sentient/test-ingester] WARNING: ${message}
153475
- `);
153476
- return [];
153477
- }
153478
- }
153479
- var GATES_JSONL_PATH, COVERAGE_SUMMARY_PATH, MIN_LINE_COVERAGE_PCT, TEST_BASE_WEIGHT;
153480
- var init_test_ingester = __esm({
153481
- "packages/cleo/src/sentient/ingesters/test-ingester.ts"() {
153482
- "use strict";
153483
- GATES_JSONL_PATH = ".cleo/audit/gates.jsonl";
153484
- COVERAGE_SUMMARY_PATH = ".cleo/coverage-summary.json";
153485
- MIN_LINE_COVERAGE_PCT = 80;
153486
- TEST_BASE_WEIGHT = 0.5;
153487
- }
153488
- });
153489
-
153490
- // packages/cleo/src/sentient/proposal-rate-limiter.ts
153491
- function countTodayProposals(nativeDb) {
153492
- if (!nativeDb) return 0;
153493
- const stmt = nativeDb.prepare(`
153494
- SELECT COUNT(*) as cnt
153495
- FROM tasks
153496
- WHERE labels_json LIKE :labelPattern
153497
- AND date(created_at) = date('now')
153498
- AND status IN ('proposed', 'pending', 'active', 'done')
153499
- `);
153500
- const row = stmt.get({ labelPattern: `%${SENTIENT_TIER2_TAG}%` });
153501
- return row?.cnt ?? 0;
153502
- }
153503
- function transactionalInsertProposal(nativeDb, insertSql, insertParams, limit = DEFAULT_DAILY_PROPOSAL_LIMIT) {
153504
- try {
153505
- nativeDb.exec("BEGIN IMMEDIATE");
153506
- } catch (err2) {
153507
- const msg = err2 instanceof Error ? err2.message : String(err2);
153508
- if (msg.includes(SQLITE_BUSY_CODE)) {
153509
- return { inserted: false, countBeforeInsert: 0, reason: "busy" };
153510
- }
153511
- throw err2;
153512
- }
153513
- try {
153514
- const countBeforeInsert = countTodayProposals(nativeDb);
153515
- if (countBeforeInsert >= limit) {
153516
- nativeDb.exec("ROLLBACK");
153517
- return { inserted: false, countBeforeInsert, reason: "rate-limit" };
153518
- }
153519
- const stmt = nativeDb.prepare(insertSql);
153520
- stmt.run(insertParams);
153521
- nativeDb.exec("COMMIT");
153522
- return { inserted: true, countBeforeInsert };
153523
- } catch (err2) {
153524
- try {
153525
- nativeDb.exec("ROLLBACK");
153526
- } catch {
153527
- }
153528
- throw err2;
153529
- }
153530
- }
153531
- var SENTIENT_TIER2_TAG, DEFAULT_DAILY_PROPOSAL_LIMIT, SQLITE_BUSY_CODE;
153532
- var init_proposal_rate_limiter = __esm({
153533
- "packages/cleo/src/sentient/proposal-rate-limiter.ts"() {
153534
- "use strict";
153535
- SENTIENT_TIER2_TAG = "sentient-tier2";
153536
- DEFAULT_DAILY_PROPOSAL_LIMIT = 3;
153537
- SQLITE_BUSY_CODE = "SQLITE_BUSY";
153538
- }
153539
- });
153540
-
153541
- // packages/cleo/src/sentient/state.ts
153542
- var state_exports2 = {};
153543
- __export(state_exports2, {
153544
- DEFAULT_SENTIENT_STATE: () => DEFAULT_SENTIENT_STATE,
153545
- SENTIENT_STATE_SCHEMA_VERSION: () => SENTIENT_STATE_SCHEMA_VERSION,
153546
- incrementStats: () => incrementStats,
153547
- patchSentientState: () => patchSentientState,
153548
- readSentientState: () => readSentientState,
153549
- writeSentientState: () => writeSentientState
153550
- });
153551
- import { mkdir as mkdir23, readFile as readFile30, rename as rename3, writeFile as writeFile16 } from "node:fs/promises";
153552
- import { dirname as dirname35, join as join139 } from "node:path";
153553
- async function readSentientState(statePath) {
153554
- try {
153555
- const raw = await readFile30(statePath, "utf-8");
153556
- const parsed = JSON.parse(raw);
153557
- return {
153558
- ...DEFAULT_SENTIENT_STATE,
153559
- ...parsed,
153560
- stats: { ...DEFAULT_SENTIENT_STATE.stats, ...parsed.stats ?? {} },
153561
- stuckTasks: parsed.stuckTasks ?? {},
153562
- stuckTimestamps: parsed.stuckTimestamps ?? [],
153563
- tier2Enabled: parsed.tier2Enabled ?? false,
153564
- tier2Stats: { ...DEFAULT_SENTIENT_STATE.tier2Stats, ...parsed.tier2Stats ?? {} }
153565
- };
153566
- } catch {
153567
- return { ...DEFAULT_SENTIENT_STATE };
153568
- }
153569
- }
153570
- async function writeSentientState(statePath, state) {
153571
- const dir = dirname35(statePath);
153572
- await mkdir23(dir, { recursive: true });
153573
- const tmpPath = join139(dir, `.sentient-state-${process.pid}.tmp`);
153574
- const json4 = JSON.stringify(state, null, 2);
153575
- await writeFile16(tmpPath, json4, "utf-8");
153576
- await rename3(tmpPath, statePath);
153577
- }
153578
- async function patchSentientState(statePath, patch) {
153579
- const current = await readSentientState(statePath);
153580
- const updated = {
153581
- ...current,
153582
- ...patch,
153583
- stats: { ...current.stats, ...patch.stats ?? {} }
153584
- };
153585
- await writeSentientState(statePath, updated);
153586
- return updated;
153587
- }
153588
- async function incrementStats(statePath, delta) {
153589
- const current = await readSentientState(statePath);
153590
- const nextStats = {
153591
- tasksPicked: current.stats.tasksPicked + (delta.tasksPicked ?? 0),
153592
- tasksCompleted: current.stats.tasksCompleted + (delta.tasksCompleted ?? 0),
153593
- tasksFailed: current.stats.tasksFailed + (delta.tasksFailed ?? 0),
153594
- ticksExecuted: current.stats.ticksExecuted + (delta.ticksExecuted ?? 0),
153595
- ticksKilled: current.stats.ticksKilled + (delta.ticksKilled ?? 0)
153596
- };
153597
- const updated = { ...current, stats: nextStats };
153598
- await writeSentientState(statePath, updated);
153599
- return updated;
153600
- }
153601
- var SENTIENT_STATE_SCHEMA_VERSION, DEFAULT_SENTIENT_STATE;
153602
- var init_state3 = __esm({
153603
- "packages/cleo/src/sentient/state.ts"() {
153604
- "use strict";
153605
- SENTIENT_STATE_SCHEMA_VERSION = "1.0";
153606
- DEFAULT_SENTIENT_STATE = {
153607
- schemaVersion: SENTIENT_STATE_SCHEMA_VERSION,
153608
- pid: null,
153609
- startedAt: null,
153610
- lastTickAt: null,
153611
- killSwitch: false,
153612
- killSwitchReason: null,
153613
- stats: {
153614
- tasksPicked: 0,
153615
- tasksCompleted: 0,
153616
- tasksFailed: 0,
153617
- ticksExecuted: 0,
153618
- ticksKilled: 0
153619
- },
153620
- stuckTasks: {},
153621
- stuckTimestamps: [],
153622
- activeTaskId: null,
153623
- tier2Enabled: false,
153624
- tier2Stats: {
153625
- proposalsGenerated: 0,
153626
- proposalsAccepted: 0,
153627
- proposalsRejected: 0
153628
- }
153629
- };
153630
- }
153631
- });
153632
-
153633
- // packages/cleo/src/sentient/propose-tick.ts
153634
- var propose_tick_exports = {};
153635
- __export(propose_tick_exports, {
153636
- PROPOSAL_TITLE_PATTERN: () => PROPOSAL_TITLE_PATTERN,
153637
- TIER2_LABEL: () => TIER2_LABEL,
153638
- runProposeTick: () => runProposeTick,
153639
- safeRunProposeTick: () => safeRunProposeTick
153640
- });
153641
- function fingerprint(candidate) {
153642
- return `${candidate.source}:${candidate.sourceId}`;
153643
- }
153644
- async function killSwitchActive(statePath) {
153645
- const state = await readSentientState(statePath);
153646
- return state.killSwitch === true;
153647
- }
153648
- async function runProposeTick(options) {
153649
- const { projectRoot, statePath } = options;
153650
- if (await killSwitchActive(statePath)) {
153651
- return { kind: "killed", written: 0, count: 0, detail: "killSwitch active before ingest" };
153652
- }
153653
- const state = await readSentientState(statePath);
153654
- if (!state.tier2Enabled) {
153655
- return {
153656
- kind: "disabled",
153657
- written: 0,
153658
- count: 0,
153659
- detail: "tier2Enabled=false; enable via cleo sentient propose enable"
153660
- };
153661
- }
153662
- let brainDb;
153663
- let nexusDb;
153664
- let tasksNativeDb;
153665
- if (options.brainDb !== void 0) {
153666
- brainDb = options.brainDb;
153667
- } else {
153668
- try {
153669
- const { getBrainDb: getBrainDb2, getBrainNativeDb: getBrainNativeDb2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
153670
- await getBrainDb2(projectRoot);
153671
- brainDb = getBrainNativeDb2();
153672
- } catch {
153673
- brainDb = null;
153674
- }
153675
- }
153676
- if (options.nexusDb !== void 0) {
153677
- nexusDb = options.nexusDb;
153678
- } else {
153679
- try {
153680
- const { getNexusNativeDb: getNexusNativeDb2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
153681
- nexusDb = getNexusNativeDb2();
153682
- } catch {
153683
- nexusDb = null;
153684
- }
153685
- }
153686
- if (options.tasksDb !== void 0) {
153687
- tasksNativeDb = options.tasksDb;
153688
- } else {
153689
- const { getNativeDb: getNativeDb3, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
153690
- await getDb4(projectRoot);
153691
- tasksNativeDb = getNativeDb3();
153692
- }
153693
- const [brainCandidates, nexusCandidates, testCandidates] = await Promise.all([
153694
- Promise.resolve(runBrainIngester(brainDb)),
153695
- Promise.resolve(runNexusIngester(nexusDb)),
153696
- Promise.resolve(runTestIngester(projectRoot))
153697
- ]);
153698
- if (await killSwitchActive(statePath)) {
153699
- return {
153700
- kind: "killed",
153701
- written: 0,
153702
- count: 0,
153703
- detail: "killSwitch active after ingest phase"
153704
- };
153705
- }
153706
- const seenFingerprints = /* @__PURE__ */ new Set();
153707
- const merged = [];
153708
- for (const candidate of [...brainCandidates, ...nexusCandidates, ...testCandidates]) {
153709
- if (!PROPOSAL_TITLE_PATTERN.test(candidate.title)) {
153710
- process.stderr.write(
153711
- `[sentient/propose-tick] Rejected candidate with invalid title format: "${candidate.title}"
153712
- `
153713
- );
153714
- continue;
153715
- }
153716
- const fp = fingerprint(candidate);
153717
- if (seenFingerprints.has(fp)) continue;
153718
- seenFingerprints.add(fp);
153719
- merged.push(candidate);
153720
- }
153721
- if (merged.length === 0) {
153722
- return { kind: "no-candidates", written: 0, count: 0, detail: "no candidates from ingesters" };
153723
- }
153724
- merged.sort((a, b2) => b2.weight - a.weight);
153725
- const currentCount = tasksNativeDb ? countTodayProposals(tasksNativeDb) : 0;
153726
- const slotsRemaining = Math.max(0, DEFAULT_DAILY_PROPOSAL_LIMIT - currentCount);
153727
- if (slotsRemaining === 0) {
153728
- return {
153729
- kind: "rate-limited",
153730
- written: 0,
153731
- count: currentCount,
153732
- detail: `daily limit reached (${currentCount}/${DEFAULT_DAILY_PROPOSAL_LIMIT})`
153733
- };
153734
- }
153735
- const toWrite = merged.slice(0, slotsRemaining);
153736
- if (await killSwitchActive(statePath)) {
153737
- return {
153738
- kind: "killed",
153739
- written: 0,
153740
- count: currentCount,
153741
- detail: "killSwitch active before write phase"
153742
- };
153743
- }
153744
- let written = 0;
153745
- for (const candidate of toWrite) {
153746
- let taskId;
153747
- if (options.allocateTaskId) {
153748
- taskId = await options.allocateTaskId();
153749
- } else {
153750
- const { allocateNextTaskId: allocateNextTaskId2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
153751
- taskId = await allocateNextTaskId2(projectRoot);
153752
- }
153753
- const now2 = (/* @__PURE__ */ new Date()).toISOString();
153754
- const labels = JSON.stringify([TIER2_LABEL, `source:${candidate.source}`]);
153755
- if (!tasksNativeDb) {
153756
- process.stderr.write("[sentient/propose-tick] tasks DB not available; skipping write\n");
153757
- break;
153758
- }
153759
- const notesJson = JSON.stringify([
153760
- JSON.stringify({
153761
- kind: "proposal-meta",
153762
- proposedBy: "sentient-tier2",
153763
- source: candidate.source,
153764
- sourceId: candidate.sourceId,
153765
- weight: candidate.weight,
153766
- proposedAt: now2
153767
- })
153768
- ]);
153769
- const insertSql = `
153770
- INSERT INTO tasks (
153771
- id, title, description, status, priority,
153772
- labels_json, notes_json,
153773
- created_at, updated_at,
153774
- role, scope
153775
- ) VALUES (
153776
- :id, :title, :description, :status, :priority,
153777
- :labelsJson, :notesJson,
153778
- :createdAt, :updatedAt,
153779
- :role, :scope
153780
- )
153781
- `;
153782
- const insertParams = {
153783
- id: taskId,
153784
- title: candidate.title,
153785
- description: candidate.rationale,
153786
- status: "proposed",
153787
- priority: "medium",
153788
- labelsJson: labels,
153789
- notesJson,
153790
- createdAt: now2,
153791
- updatedAt: now2,
153792
- role: "work",
153793
- scope: "feature"
153794
- };
153795
- try {
153796
- const result = transactionalInsertProposal(
153797
- tasksNativeDb,
153798
- insertSql,
153799
- insertParams,
153800
- DEFAULT_DAILY_PROPOSAL_LIMIT
153801
- );
153802
- if (result.inserted) {
153803
- written++;
153804
- } else if (result.reason === "rate-limit") {
153805
- break;
153806
- }
153807
- } catch (err2) {
153808
- const message = err2 instanceof Error ? err2.message : String(err2);
153809
- process.stderr.write(`[sentient/propose-tick] INSERT failed for ${taskId}: ${message}
153810
- `);
153811
- }
153812
- }
153813
- if (written > 0) {
153814
- const latestState = await readSentientState(statePath);
153815
- await patchSentientState(statePath, {
153816
- tier2Stats: {
153817
- ...latestState.tier2Stats,
153818
- proposalsGenerated: latestState.tier2Stats.proposalsGenerated + written
153819
- }
153820
- });
153821
- }
153822
- const finalCount = tasksNativeDb ? countTodayProposals(tasksNativeDb) : currentCount + written;
153823
- if (written === 0) {
153824
- return {
153825
- kind: "no-candidates",
153826
- written: 0,
153827
- count: finalCount,
153828
- detail: "candidates available but none written (rate limit or DB unavailable)"
153829
- };
153830
- }
153831
- return {
153832
- kind: "wrote",
153833
- written,
153834
- count: finalCount,
153835
- detail: `wrote ${written} proposal(s) (${finalCount}/${DEFAULT_DAILY_PROPOSAL_LIMIT} today)`
153836
- };
153837
- }
153838
- async function safeRunProposeTick(options) {
153839
- try {
153840
- return await runProposeTick(options);
153841
- } catch (err2) {
153842
- const message = err2 instanceof Error ? err2.message : String(err2);
153843
- return {
153844
- kind: "error",
153845
- written: 0,
153846
- count: 0,
153847
- detail: `propose tick threw: ${message}`
153848
- };
153849
- }
153850
- }
153851
- var PROPOSAL_TITLE_PATTERN, TIER2_LABEL;
153852
- var init_propose_tick = __esm({
153853
- "packages/cleo/src/sentient/propose-tick.ts"() {
153854
- "use strict";
153855
- init_brain_ingester();
153856
- init_nexus_ingester();
153857
- init_test_ingester();
153858
- init_proposal_rate_limiter();
153859
- init_state3();
153860
- PROPOSAL_TITLE_PATTERN = /^\[T2-(BRAIN|NEXUS|TEST)\]/;
153861
- TIER2_LABEL = "sentient-tier2";
153862
- }
153863
- });
153864
-
153865
- // packages/cleo/src/sentient/tick.ts
153866
- import { spawn as spawn3 } from "node:child_process";
153867
- async function killSwitchActive2(statePath) {
153868
- const state = await readSentientState(statePath);
153869
- return state.killSwitch === true;
153870
- }
153871
- function pruneStuckWindow(timestamps, now2) {
153872
- const cutoff = now2 - SELF_PAUSE_WINDOW_MS;
153873
- return timestamps.filter((t) => t >= cutoff);
153874
- }
153875
- async function defaultPickTask(projectRoot) {
153876
- const { Cleo: Cleo2 } = await import("@cleocode/core/sdk");
153877
- const { getReadyTasks: getReadyTasks4 } = await import("@cleocode/core/tasks");
153878
- const cleo = await Cleo2.init(projectRoot);
153879
- const pending = await cleo.tasks.find({ status: "pending", limit: 500 });
153880
- const candidates = Array.isArray(pending?.data?.tasks) ? pending.data.tasks : [];
153881
- if (candidates.length === 0) return null;
153882
- const ready = getReadyTasks4(candidates);
153883
- if (ready.length === 0) return null;
153884
- ready.sort((a, b2) => a.id.localeCompare(b2.id));
153885
- return ready[0];
153886
- }
153887
- function defaultSpawn(taskId, adapter, projectRoot) {
153888
- return new Promise((resolve20) => {
153889
- const args = ["orchestrate", "spawn", taskId, "--adapter", adapter];
153890
- const child = spawn3("cleo", args, {
153891
- cwd: projectRoot,
153892
- env: { ...process.env, CLEO_SENTIENT_SPAWN: "1" },
153893
- stdio: ["ignore", "pipe", "pipe"]
153894
- });
153895
- let stdout = "";
153896
- let stderr2 = "";
153897
- child.stdout?.on("data", (chunk) => {
153898
- stdout += chunk.toString("utf-8");
153899
- });
153900
- child.stderr?.on("data", (chunk) => {
153901
- stderr2 += chunk.toString("utf-8");
153902
- });
153903
- const timer = setTimeout(() => {
153904
- child.kill("SIGTERM");
153905
- }, SPAWN_TIMEOUT_MS);
153906
- child.on("error", (err2) => {
153907
- clearTimeout(timer);
153908
- resolve20({
153909
- exitCode: 1,
153910
- stdout,
153911
- stderr: stderr2 + `
153912
- [sentient] spawn error: ${err2.message}`
153913
- });
153914
- });
153915
- child.on("exit", (code) => {
153916
- clearTimeout(timer);
153917
- resolve20({
153918
- exitCode: code ?? 1,
153919
- stdout: stdout.slice(-4e3),
153920
- stderr: stderr2.slice(-4e3)
153921
- });
153922
- });
153923
- });
153924
- }
153925
- async function writeSuccessReceipt(projectRoot, taskId, exitCode) {
153926
- try {
153927
- const { Cleo: Cleo2 } = await import("@cleocode/core/sdk");
153928
- const cleo = await Cleo2.init(projectRoot);
153929
- await cleo.memory.observe({
153930
- text: `sentient-tier1: task ${taskId} completed successfully (exit=${exitCode})`,
153931
- title: `sentient-receipt: ${taskId}`
153932
- });
153933
- } catch {
153934
- }
153935
- }
153936
- async function maybeTriggerDream(projectRoot, opts, pickedTask) {
153937
- const volumeThreshold = opts.dreamVolumeThreshold ?? DREAM_VOLUME_THRESHOLD_DEFAULT;
153938
- const idleTicksThreshold = opts.dreamIdleTicks ?? DREAM_IDLE_TICKS_DEFAULT;
153939
- if (volumeThreshold <= 0 && idleTicksThreshold <= 0) return;
153940
- if (pickedTask) {
153941
- consecutiveIdleTicks = 0;
153942
- } else {
153943
- consecutiveIdleTicks += 1;
153944
- }
153945
- const dreamer = opts.checkAndDream ?? (async (root, dreamerOpts) => {
153946
- const { checkAndDream: checkAndDream2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
153947
- return checkAndDream2(root, dreamerOpts);
153948
- });
153949
- try {
153950
- await dreamer(projectRoot, {
153951
- volumeThreshold: volumeThreshold > 0 ? volumeThreshold : void 0,
153952
- inline: false
153953
- }).catch((err2) => {
153954
- console.warn("[sentient/tick] dream trigger error:", err2);
153955
- });
153956
- } catch (err2) {
153957
- console.warn("[sentient/tick] dream trigger threw:", err2);
153958
- }
153959
- }
153960
- async function writeFailureReceipt(projectRoot, taskId, attempt, exitCode, reason) {
153961
- try {
153962
- const { Cleo: Cleo2 } = await import("@cleocode/core/sdk");
153963
- const cleo = await Cleo2.init(projectRoot);
153964
- await cleo.memory.observe({
153965
- text: `sentient-tier1: task ${taskId} failed (attempt=${attempt}/${MAX_TASK_ATTEMPTS}, exit=${exitCode}). reason=${reason.slice(0, 500)}`,
153966
- title: `sentient-failure: ${taskId}`
153967
- });
153968
- } catch {
153969
- }
153970
- }
153971
- async function runTick(options) {
153972
- const { projectRoot, statePath } = options;
153973
- const adapter = options.adapter ?? DEFAULT_ADAPTER;
153974
- const now2 = Date.now();
153975
- if (await killSwitchActive2(statePath)) {
153976
- await incrementStats(statePath, { ticksKilled: 1 });
153977
- await patchSentientState(statePath, { lastTickAt: new Date(now2).toISOString() });
153978
- return { kind: "killed", taskId: null, detail: "killSwitch active before pick" };
153979
- }
153980
- const picker = options.pickTask ?? defaultPickTask;
153981
- let task;
153982
- try {
153983
- task = await picker(projectRoot);
153984
- } catch (err2) {
153985
- const message = err2 instanceof Error ? err2.message : String(err2);
153986
- await incrementStats(statePath, { ticksExecuted: 1 });
153987
- await patchSentientState(statePath, { lastTickAt: new Date(now2).toISOString() });
153988
- return { kind: "error", taskId: null, detail: `picker threw: ${message}` };
153989
- }
153990
- if (task === null) {
153991
- await incrementStats(statePath, { ticksExecuted: 1 });
153992
- await patchSentientState(statePath, { lastTickAt: new Date(now2).toISOString() });
153993
- return { kind: "no-task", taskId: null, detail: "no unblocked tasks available" };
153994
- }
153995
- const preSpawnState = await readSentientState(statePath);
153996
- const existingStuck = preSpawnState.stuckTasks[task.id];
153997
- if (existingStuck && existingStuck.nextRetryAt > now2) {
153998
- await incrementStats(statePath, { ticksExecuted: 1 });
153999
- await patchSentientState(statePath, { lastTickAt: new Date(now2).toISOString() });
154000
- return {
154001
- kind: "backoff",
154002
- taskId: task.id,
154003
- detail: `task ${task.id} in backoff until ${new Date(existingStuck.nextRetryAt).toISOString()}`
154004
- };
154005
- }
154006
- if (await killSwitchActive2(statePath)) {
154007
- await incrementStats(statePath, { ticksKilled: 1 });
154008
- await patchSentientState(statePath, { lastTickAt: new Date(now2).toISOString() });
154009
- return { kind: "killed", taskId: task.id, detail: "killSwitch active before spawn" };
154010
- }
154011
- await incrementStats(statePath, { tasksPicked: 1 });
154012
- await patchSentientState(statePath, { activeTaskId: task.id });
154013
- let spawnResult;
154014
- if (options.dryRun === true) {
154015
- spawnResult = {
154016
- exitCode: 0,
154017
- stdout: "[dry-run] spawn skipped",
154018
- stderr: ""
154019
- };
154020
- } else {
154021
- try {
154022
- const spawner = options.spawn ?? ((tid, adp) => defaultSpawn(tid, adp, projectRoot));
154023
- spawnResult = await spawner(task.id, adapter);
154024
- } catch (err2) {
154025
- const message = err2 instanceof Error ? err2.message : String(err2);
154026
- spawnResult = { exitCode: 1, stdout: "", stderr: `spawn threw: ${message}` };
154027
- }
154028
- }
154029
- if (await killSwitchActive2(statePath)) {
154030
- await incrementStats(statePath, { ticksKilled: 1 });
154031
- await patchSentientState(statePath, {
154032
- lastTickAt: new Date(Date.now()).toISOString(),
154033
- activeTaskId: null
154034
- });
154035
- return {
154036
- kind: "killed",
154037
- taskId: task.id,
154038
- detail: "killSwitch active after spawn; result not recorded"
154039
- };
154040
- }
154041
- if (spawnResult.exitCode === 0) {
154042
- await writeSuccessReceipt(projectRoot, task.id, spawnResult.exitCode);
154043
- const post2 = await readSentientState(statePath);
154044
- const { [task.id]: _removed, ...rest } = post2.stuckTasks;
154045
- void _removed;
154046
- await patchSentientState(statePath, {
154047
- stuckTasks: rest,
154048
- activeTaskId: null,
154049
- lastTickAt: new Date(Date.now()).toISOString()
154050
- });
154051
- await incrementStats(statePath, { tasksCompleted: 1, ticksExecuted: 1 });
154052
- return {
154053
- kind: "success",
154054
- taskId: task.id,
154055
- detail: `task ${task.id} completed (exit=0)`
154056
- };
154057
- }
154058
- const currentAttempts = existingStuck?.attempts ?? 0;
154059
- const nextAttempts = currentAttempts + 1;
154060
- const failureReason = spawnResult.stderr.slice(-500) || `exit=${spawnResult.exitCode}`;
154061
- await writeFailureReceipt(
154062
- projectRoot,
154063
- task.id,
154064
- nextAttempts,
154065
- spawnResult.exitCode,
154066
- failureReason
154067
- );
154068
- await incrementStats(statePath, { tasksFailed: 1, ticksExecuted: 1 });
154069
- if (nextAttempts >= MAX_TASK_ATTEMPTS) {
154070
- const windowed = pruneStuckWindow(preSpawnState.stuckTimestamps, now2);
154071
- windowed.push(now2);
154072
- const stuckRecord2 = {
154073
- attempts: nextAttempts,
154074
- lastFailureAt: new Date(now2).toISOString(),
154075
- nextRetryAt: Number.MAX_SAFE_INTEGER,
154076
- // owner-only release
154077
- lastReason: failureReason
154078
- };
154079
- const post2 = await readSentientState(statePath);
154080
- const updatedStuckTasks = {
154081
- ...post2.stuckTasks,
154082
- [task.id]: stuckRecord2
154083
- };
154084
- const shouldSelfPause = windowed.length >= SELF_PAUSE_STUCK_THRESHOLD;
154085
- await patchSentientState(statePath, {
154086
- stuckTasks: updatedStuckTasks,
154087
- stuckTimestamps: windowed,
154088
- activeTaskId: null,
154089
- lastTickAt: new Date(now2).toISOString(),
154090
- ...shouldSelfPause ? { killSwitch: true, killSwitchReason: SELF_PAUSE_REASON } : {}
154091
- });
154092
- if (shouldSelfPause) {
154093
- return {
154094
- kind: "self-paused",
154095
- taskId: task.id,
154096
- detail: `task ${task.id} is stuck; self-pause fired (${windowed.length}/${SELF_PAUSE_STUCK_THRESHOLD} stucks in window)`
154097
- };
154098
- }
154099
- return {
154100
- kind: "stuck",
154101
- taskId: task.id,
154102
- detail: `task ${task.id} stuck after ${nextAttempts} attempts; owner must re-enable via \`cleo sentient resume\``
154103
- };
154104
- }
154105
- const backoff = RETRY_BACKOFF_MS[nextAttempts - 1] ?? RETRY_BACKOFF_MS[RETRY_BACKOFF_MS.length - 1];
154106
- const stuckRecord = {
154107
- attempts: nextAttempts,
154108
- lastFailureAt: new Date(now2).toISOString(),
154109
- nextRetryAt: now2 + backoff,
154110
- lastReason: failureReason
154111
- };
154112
- const post = await readSentientState(statePath);
154113
- await patchSentientState(statePath, {
154114
- stuckTasks: { ...post.stuckTasks, [task.id]: stuckRecord },
154115
- activeTaskId: null,
154116
- lastTickAt: new Date(now2).toISOString()
154117
- });
154118
- return {
154119
- kind: "failure",
154120
- taskId: task.id,
154121
- detail: `task ${task.id} failed (attempt=${nextAttempts}/${MAX_TASK_ATTEMPTS}); retry scheduled at ${new Date(now2 + backoff).toISOString()}`
154122
- };
154123
- }
154124
- async function safeRunTick(options) {
154125
- let outcome;
154126
- try {
154127
- outcome = await runTick(options);
154128
- } catch (err2) {
154129
- const message = err2 instanceof Error ? err2.message : String(err2);
154130
- try {
154131
- await incrementStats(options.statePath, { ticksExecuted: 1 });
154132
- } catch {
154133
- }
154134
- outcome = { kind: "error", taskId: null, detail: `tick threw: ${message}` };
154135
- }
154136
- const pickedTask = outcome.kind !== "no-task" && outcome.kind !== "killed" && outcome.kind !== "error" && outcome.taskId !== null;
154137
- await maybeTriggerDream(options.projectRoot, options, pickedTask).catch(() => {
154138
- });
154139
- return outcome;
154140
- }
154141
- var DREAM_VOLUME_THRESHOLD_DEFAULT, DREAM_IDLE_TICKS_DEFAULT, DEFAULT_ADAPTER, RETRY_BACKOFF_MS, MAX_TASK_ATTEMPTS, SELF_PAUSE_STUCK_THRESHOLD, SELF_PAUSE_WINDOW_MS, SELF_PAUSE_REASON, SPAWN_TIMEOUT_MS, consecutiveIdleTicks;
154142
- var init_tick = __esm({
154143
- "packages/cleo/src/sentient/tick.ts"() {
154144
- "use strict";
154145
- init_state3();
154146
- DREAM_VOLUME_THRESHOLD_DEFAULT = 50;
154147
- DREAM_IDLE_TICKS_DEFAULT = 5;
154148
- DEFAULT_ADAPTER = "claude-code";
154149
- RETRY_BACKOFF_MS = [3e4, 3e5, 18e5];
154150
- MAX_TASK_ATTEMPTS = RETRY_BACKOFF_MS.length;
154151
- SELF_PAUSE_STUCK_THRESHOLD = 5;
154152
- SELF_PAUSE_WINDOW_MS = 60 * 60 * 1e3;
154153
- SELF_PAUSE_REASON = "self-pause: 5 stuck tasks in 1 hour";
154154
- SPAWN_TIMEOUT_MS = 30 * 60 * 1e3;
154155
- consecutiveIdleTicks = 0;
154156
- }
154157
- });
154158
-
154159
- // packages/cleo/src/sentient/daemon.ts
154160
- var daemon_exports = {};
154161
- __export(daemon_exports, {
154162
- SENTIENT_CRON_EXPR: () => SENTIENT_CRON_EXPR,
154163
- SENTIENT_ERR: () => SENTIENT_ERR,
154164
- SENTIENT_LOCK_FILE: () => SENTIENT_LOCK_FILE,
154165
- SENTIENT_LOG: () => SENTIENT_LOG,
154166
- SENTIENT_LOG_DIR: () => SENTIENT_LOG_DIR,
154167
- SENTIENT_PROPOSE_CRON_EXPR: () => SENTIENT_PROPOSE_CRON_EXPR,
154168
- SENTIENT_STATE_FILE: () => SENTIENT_STATE_FILE,
154169
- acquireLock: () => acquireLock2,
154170
- bootstrapDaemon: () => bootstrapDaemon,
154171
- getSentientDaemonStatus: () => getSentientDaemonStatus,
154172
- releaseLock: () => releaseLock,
154173
- resumeSentientDaemon: () => resumeSentientDaemon,
154174
- spawnSentientDaemon: () => spawnSentientDaemon,
154175
- stopSentientDaemon: () => stopSentientDaemon
154176
- });
154177
- import { spawn as spawn4 } from "node:child_process";
154178
- import { createWriteStream as createWriteStream2, constants as fsConstants4, watch } from "node:fs";
154179
- import { open as fsOpen, mkdir as mkdir24 } from "node:fs/promises";
154180
- import { join as join140 } from "node:path";
154181
- import { fileURLToPath as fileURLToPath10 } from "node:url";
154182
- import cron from "node-cron";
154183
- async function acquireLock2(lockPath) {
154184
- await mkdir24(join140(lockPath, ".."), { recursive: true });
154185
- try {
154186
- const handle = await fsOpen(
154187
- lockPath,
154188
- fsConstants4.O_CREAT | fsConstants4.O_EXCL | fsConstants4.O_RDWR,
154189
- 420
154190
- );
154191
- await handle.writeFile(String(process.pid), "utf-8");
154192
- return { path: lockPath, handle };
154193
- } catch (err2) {
154194
- const code = err2.code;
154195
- if (code !== "EEXIST") throw err2;
154196
- }
154197
- let existing = null;
154198
- try {
154199
- existing = await fsOpen(lockPath, fsConstants4.O_RDWR);
154200
- const buf = await existing.readFile({ encoding: "utf-8" });
154201
- const recordedPid = Number.parseInt(buf.trim(), 10);
154202
- if (Number.isFinite(recordedPid) && recordedPid > 0) {
154203
- try {
154204
- process.kill(recordedPid, 0);
154205
- await existing.close();
154206
- return null;
154207
- } catch {
154208
- }
154209
- }
154210
- await existing.truncate(0);
154211
- const pidBytes = Buffer.from(String(process.pid), "utf-8");
154212
- await existing.write(pidBytes, 0, pidBytes.length, 0);
154213
- return { path: lockPath, handle: existing };
154214
- } catch (err2) {
154215
- if (existing) {
154216
- try {
154217
- await existing.close();
154218
- } catch {
154219
- }
154220
- }
154221
- throw err2;
154222
- }
154223
- }
154224
- async function releaseLock(lock2) {
154225
- try {
154226
- await lock2.handle.close();
154227
- } catch {
154228
- }
154229
- }
154230
- async function bootstrapDaemon(projectRoot) {
154231
- const statePath = join140(projectRoot, SENTIENT_STATE_FILE);
154232
- const lockPath = join140(projectRoot, SENTIENT_LOCK_FILE);
154233
- const lock2 = await acquireLock2(lockPath);
154234
- if (!lock2) {
154235
- process.stderr.write(`[CLEO SENTIENT] lock acquisition failed \u2014 another daemon is running
154236
- `);
154237
- process.exit(2);
154238
- }
154239
- await patchSentientState(statePath, {
154240
- pid: process.pid,
154241
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
154242
- // Clear killSwitch on boot only if owner did not explicitly leave it set.
154243
- // We preserve it here: re-starting a killed daemon must not silently
154244
- // resume. Owner explicitly clears via `cleo sentient resume`.
154245
- });
154246
- let watcher = null;
154247
- try {
154248
- watcher = watch(statePath, { persistent: false }, () => {
154249
- });
154250
- } catch {
154251
- watcher = null;
154252
- }
154253
- const shutdown = async (reason) => {
154254
- try {
154255
- watcher?.close();
154256
- } catch {
154257
- }
154258
- try {
154259
- await patchSentientState(statePath, {
154260
- pid: null,
154261
- killSwitchReason: reason
154262
- });
154263
- } catch {
154264
- }
154265
- try {
154266
- await releaseLock(lock2);
154267
- } catch {
154268
- }
154269
- process.exit(0);
154270
- };
154271
- process.on("SIGTERM", () => {
154272
- void shutdown("SIGTERM");
154273
- });
154274
- process.on("SIGINT", () => {
154275
- void shutdown("SIGINT");
154276
- });
154277
- const tickOptions = { projectRoot, statePath };
154278
- const outcome = await safeRunTick(tickOptions);
154279
- process.stdout.write(
154280
- `[CLEO SENTIENT] boot tick: ${outcome.kind} (task=${outcome.taskId ?? "n/a"}) ${outcome.detail}
154281
- `
154282
- );
154283
- cron.schedule(
154284
- SENTIENT_CRON_EXPR,
154285
- async () => {
154286
- const result = await safeRunTick(tickOptions);
154287
- process.stdout.write(
154288
- `[CLEO SENTIENT] tick: ${result.kind} (task=${result.taskId ?? "n/a"}) ${result.detail}
154289
- `
154290
- );
154291
- },
154292
- {
154293
- timezone: "UTC",
154294
- noOverlap: true,
154295
- name: "cleo-sentient"
154296
- }
154297
- );
154298
- const proposeOptions = { projectRoot, statePath };
154299
- cron.schedule(
154300
- SENTIENT_PROPOSE_CRON_EXPR,
154301
- async () => {
154302
- const state = await readSentientState(statePath);
154303
- if (!state.tier2Enabled) return;
154304
- const result = await safeRunProposeTick(proposeOptions);
154305
- process.stdout.write(
154306
- `[CLEO SENTIENT T2] propose: ${result.kind} (written=${result.written}, count=${result.count}) ${result.detail}
154307
- `
154308
- );
154309
- },
154310
- {
154311
- timezone: "UTC",
154312
- noOverlap: true,
154313
- name: "cleo-sentient-propose"
154314
- }
154315
- );
154316
- }
154317
- async function spawnSentientDaemon(projectRoot) {
154318
- const logsDir = join140(projectRoot, SENTIENT_LOG_DIR);
154319
- await mkdir24(logsDir, { recursive: true });
154320
- const logPath = join140(logsDir, SENTIENT_LOG);
154321
- const errPath = join140(logsDir, SENTIENT_ERR);
154322
- const outStream = createWriteStream2(logPath, { flags: "a" });
154323
- const errStream = createWriteStream2(errPath, { flags: "a" });
154324
- const daemonEntry = join140(fileURLToPath10(import.meta.url), "..", "daemon-entry.js");
154325
- const child = spawn4(process.execPath, [daemonEntry, projectRoot], {
154326
- detached: true,
154327
- stdio: ["ignore", outStream, errStream],
154328
- env: { ...process.env, CLEO_SENTIENT_DAEMON: "1" }
154329
- });
154330
- child.unref();
154331
- const pid = child.pid ?? 0;
154332
- const statePath = join140(projectRoot, SENTIENT_STATE_FILE);
154333
- await patchSentientState(statePath, {
154334
- pid,
154335
- startedAt: (/* @__PURE__ */ new Date()).toISOString()
154336
- });
154337
- return { pid, statePath, logPath };
154338
- }
154339
- async function stopSentientDaemon(projectRoot, reason = "cleo sentient stop") {
154340
- const statePath = join140(projectRoot, SENTIENT_STATE_FILE);
154341
- const state = await readSentientState(statePath);
154342
- await patchSentientState(statePath, {
154343
- killSwitch: true,
154344
- killSwitchReason: reason
154345
- });
154346
- const pid = state.pid;
154347
- if (!pid) {
154348
- return {
154349
- stopped: false,
154350
- pid: null,
154351
- reason: "killSwitch set; no daemon pid recorded (no active process to signal)"
154352
- };
154353
- }
154354
- try {
154355
- process.kill(pid, 0);
154356
- } catch {
154357
- await patchSentientState(statePath, { pid: null });
154358
- return {
154359
- stopped: true,
154360
- pid,
154361
- reason: `killSwitch set; daemon pid ${pid} was already dead (cleared)`
154362
- };
154363
- }
154364
- try {
154365
- process.kill(pid, "SIGTERM");
154366
- return { stopped: true, pid, reason: `killSwitch set + SIGTERM delivered to pid ${pid}` };
154367
- } catch (err2) {
154368
- const message = err2 instanceof Error ? err2.message : String(err2);
154369
- return {
154370
- stopped: false,
154371
- pid,
154372
- reason: `killSwitch set but SIGTERM failed: ${message}`
154373
- };
154374
- }
154375
- }
154376
- async function resumeSentientDaemon(projectRoot) {
154377
- const statePath = join140(projectRoot, SENTIENT_STATE_FILE);
154378
- return patchSentientState(statePath, {
154379
- killSwitch: false,
154380
- killSwitchReason: null
154381
- });
154382
- }
154383
- async function getSentientDaemonStatus(projectRoot) {
154384
- const statePath = join140(projectRoot, SENTIENT_STATE_FILE);
154385
- const state = await readSentientState(statePath);
154386
- let running = false;
154387
- if (state.pid) {
154388
- try {
154389
- process.kill(state.pid, 0);
154390
- running = true;
154391
- } catch {
154392
- running = false;
154393
- }
154394
- }
154395
- return {
154396
- running,
154397
- pid: running ? state.pid : null,
154398
- startedAt: state.startedAt,
154399
- lastTickAt: state.lastTickAt,
154400
- killSwitch: state.killSwitch,
154401
- killSwitchReason: state.killSwitchReason,
154402
- stats: state.stats,
154403
- stuckCount: Object.keys(state.stuckTasks).length,
154404
- activeTaskId: state.activeTaskId
154405
- };
154406
- }
154407
- var SENTIENT_STATE_FILE, SENTIENT_LOCK_FILE, SENTIENT_CRON_EXPR, SENTIENT_PROPOSE_CRON_EXPR, SENTIENT_LOG_DIR, SENTIENT_LOG, SENTIENT_ERR;
154408
- var init_daemon = __esm({
154409
- "packages/cleo/src/sentient/daemon.ts"() {
154410
- "use strict";
154411
- init_propose_tick();
154412
- init_state3();
154413
- init_tick();
154414
- SENTIENT_STATE_FILE = ".cleo/sentient-state.json";
154415
- SENTIENT_LOCK_FILE = ".cleo/sentient.lock";
154416
- SENTIENT_CRON_EXPR = "*/5 * * * *";
154417
- SENTIENT_PROPOSE_CRON_EXPR = "0 */2 * * *";
154418
- SENTIENT_LOG_DIR = ".cleo/logs";
154419
- SENTIENT_LOG = "sentient.log";
154420
- SENTIENT_ERR = "sentient.err";
154421
- }
154422
- });
154423
-
154424
153252
  // packages/cleo/src/dispatch/domains/sentient.ts
154425
- import { join as join141 } from "node:path";
153253
+ import { join as join138 } from "node:path";
154426
153254
  function safeParseJsonArray2(json4) {
154427
153255
  if (!json4) return [];
154428
153256
  try {
@@ -154448,9 +153276,9 @@ function safeParseProposalMeta(notesJson) {
154448
153276
  }
154449
153277
  async function incrementTier2Stat(projectRoot, field) {
154450
153278
  try {
154451
- const { patchSentientState: patchSentientState2, readSentientState: readSentientState2 } = await Promise.resolve().then(() => (init_state3(), state_exports2));
154452
- const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
154453
- const statePath = join141(projectRoot, SENTIENT_STATE_FILE2);
153279
+ const { patchSentientState: patchSentientState2, readSentientState: readSentientState2 } = await import("@cleocode/core/sentient/state.js");
153280
+ const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await import("@cleocode/core/sentient/daemon.js");
153281
+ const statePath = join138(projectRoot, SENTIENT_STATE_FILE2);
154454
153282
  const state = await readSentientState2(statePath);
154455
153283
  await patchSentientState2(statePath, {
154456
153284
  tier2Stats: {
@@ -154461,13 +153289,13 @@ async function incrementTier2Stat(projectRoot, field) {
154461
153289
  } catch {
154462
153290
  }
154463
153291
  }
154464
- var TIER2_LABEL2, SentientHandler;
153292
+ var TIER2_LABEL, SentientHandler;
154465
153293
  var init_sentient = __esm({
154466
153294
  "packages/cleo/src/dispatch/domains/sentient.ts"() {
154467
153295
  "use strict";
154468
153296
  init_src3();
154469
153297
  init_base();
154470
- TIER2_LABEL2 = "sentient-tier2";
153298
+ TIER2_LABEL = "sentient-tier2";
154471
153299
  SentientHandler = class {
154472
153300
  // -----------------------------------------------------------------------
154473
153301
  // Supported operations
@@ -154602,7 +153430,7 @@ var init_sentient = __esm({
154602
153430
  const { and: and18, eq: eq22, like: like4 } = await import("drizzle-orm");
154603
153431
  const db = await getDb4(projectRoot);
154604
153432
  const limit = typeof params?.limit === "number" && params.limit > 0 ? params.limit : 50;
154605
- const rows = await db.select().from(tasks2).where(and18(eq22(tasks2.status, "proposed"), like4(tasks2.labelsJson, `%${TIER2_LABEL2}%`))).limit(limit).all();
153433
+ const rows = await db.select().from(tasks2).where(and18(eq22(tasks2.status, "proposed"), like4(tasks2.labelsJson, `%${TIER2_LABEL}%`))).limit(limit).all();
154606
153434
  const proposals = rows.map((row) => ({
154607
153435
  id: row.id,
154608
153436
  title: row.title,
@@ -154633,7 +153461,7 @@ var init_sentient = __esm({
154633
153461
  and18(
154634
153462
  eq22(tasks2.id, id),
154635
153463
  eq22(tasks2.status, "proposed"),
154636
- like4(tasks2.labelsJson, `%${TIER2_LABEL2}%`)
153464
+ like4(tasks2.labelsJson, `%${TIER2_LABEL}%`)
154637
153465
  )
154638
153466
  ).get();
154639
153467
  if (!existing) {
@@ -154641,7 +153469,7 @@ var init_sentient = __esm({
154641
153469
  success: false,
154642
153470
  error: {
154643
153471
  code: "E_NOT_FOUND",
154644
- message: `Task ${id} is not a pending proposal (status must be 'proposed' with label '${TIER2_LABEL2}')`
153472
+ message: `Task ${id} is not a pending proposal (status must be 'proposed' with label '${TIER2_LABEL}')`
154645
153473
  }
154646
153474
  };
154647
153475
  }
@@ -154663,7 +153491,7 @@ var init_sentient = __esm({
154663
153491
  and18(
154664
153492
  eq22(tasks2.id, id),
154665
153493
  eq22(tasks2.status, "proposed"),
154666
- like4(tasks2.labelsJson, `%${TIER2_LABEL2}%`)
153494
+ like4(tasks2.labelsJson, `%${TIER2_LABEL}%`)
154667
153495
  )
154668
153496
  ).get();
154669
153497
  if (!existing) {
@@ -154671,7 +153499,7 @@ var init_sentient = __esm({
154671
153499
  success: false,
154672
153500
  error: {
154673
153501
  code: "E_NOT_FOUND",
154674
- message: `Task ${id} is not a pending proposal (status must be 'proposed' with label '${TIER2_LABEL2}')`
153502
+ message: `Task ${id} is not a pending proposal (status must be 'proposed' with label '${TIER2_LABEL}')`
154675
153503
  }
154676
153504
  };
154677
153505
  }
@@ -154690,9 +153518,9 @@ var init_sentient = __esm({
154690
153518
  * Useful for owner testing without starting the daemon.
154691
153519
  */
154692
153520
  async runProposeTick(projectRoot, params) {
154693
- const { safeRunProposeTick: safeRunProposeTick2 } = await Promise.resolve().then(() => (init_propose_tick(), propose_tick_exports));
154694
- const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
154695
- const statePath = join141(projectRoot, SENTIENT_STATE_FILE2);
153521
+ const { safeRunProposeTick: safeRunProposeTick2 } = await import("@cleocode/core/sentient/propose-tick.js");
153522
+ const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await import("@cleocode/core/sentient/daemon.js");
153523
+ const statePath = join138(projectRoot, SENTIENT_STATE_FILE2);
154696
153524
  const outcome = await safeRunProposeTick2({ projectRoot, statePath });
154697
153525
  const _2 = params;
154698
153526
  void _2;
@@ -154702,9 +153530,9 @@ var init_sentient = __esm({
154702
153530
  * Enable or disable Tier-2 proposal generation.
154703
153531
  */
154704
153532
  async setTier2Enabled(projectRoot, enabled) {
154705
- const { patchSentientState: patchSentientState2 } = await Promise.resolve().then(() => (init_state3(), state_exports2));
154706
- const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await Promise.resolve().then(() => (init_daemon(), daemon_exports));
154707
- const statePath = join141(projectRoot, SENTIENT_STATE_FILE2);
153533
+ const { patchSentientState: patchSentientState2 } = await import("@cleocode/core/sentient/state.js");
153534
+ const { SENTIENT_STATE_FILE: SENTIENT_STATE_FILE2 } = await import("@cleocode/core/sentient/daemon.js");
153535
+ const statePath = join138(projectRoot, SENTIENT_STATE_FILE2);
154708
153536
  const updated = await patchSentientState2(statePath, { tier2Enabled: enabled });
154709
153537
  return {
154710
153538
  success: true,
@@ -155832,7 +154660,7 @@ var init_tasks4 = __esm({
155832
154660
  });
155833
154661
 
155834
154662
  // packages/cleo/src/dispatch/engines/code-engine.ts
155835
- import { join as join142 } from "node:path";
154663
+ import { join as join139 } from "node:path";
155836
154664
  async function codeOutline(params) {
155837
154665
  const { smartOutline: smartOutline2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
155838
154666
  const filePath = params?.file;
@@ -155842,7 +154670,7 @@ async function codeOutline(params) {
155842
154670
  error: { code: "E_INVALID_INPUT", message: "file parameter required" }
155843
154671
  };
155844
154672
  const root = getProjectRoot();
155845
- const absPath = filePath.startsWith("/") ? filePath : join142(root, filePath);
154673
+ const absPath = filePath.startsWith("/") ? filePath : join139(root, filePath);
155846
154674
  return { success: true, data: smartOutline2(absPath, root) };
155847
154675
  }
155848
154676
  async function codeSearch(params) {
@@ -155874,7 +154702,7 @@ async function codeUnfold(params) {
155874
154702
  error: { code: "E_INVALID_INPUT", message: "file and symbol parameters required" }
155875
154703
  };
155876
154704
  const root = getProjectRoot();
155877
- const absPath = filePath.startsWith("/") ? filePath : join142(root, filePath);
154705
+ const absPath = filePath.startsWith("/") ? filePath : join139(root, filePath);
155878
154706
  return { success: true, data: smartUnfold2(absPath, symbol2, root) };
155879
154707
  }
155880
154708
  async function codeParse(params) {
@@ -155886,7 +154714,7 @@ async function codeParse(params) {
155886
154714
  error: { code: "E_INVALID_INPUT", message: "file parameter required" }
155887
154715
  };
155888
154716
  const root = getProjectRoot();
155889
- const absPath = filePath.startsWith("/") ? filePath : join142(root, filePath);
154717
+ const absPath = filePath.startsWith("/") ? filePath : join139(root, filePath);
155890
154718
  return { success: true, data: parseFile3(absPath, root) };
155891
154719
  }
155892
154720
  var init_code_engine = __esm({
@@ -157056,8 +155884,8 @@ var init_defaults = __esm({
157056
155884
  });
157057
155885
 
157058
155886
  // packages/cleo/src/dispatch/lib/config-loader.ts
157059
- import { existsSync as existsSync135, readFileSync as readFileSync107 } from "fs";
157060
- import { join as join143 } from "path";
155887
+ import { existsSync as existsSync135, readFileSync as readFileSync106 } from "fs";
155888
+ import { join as join140 } from "path";
157061
155889
  function loadFromEnv(key) {
157062
155890
  const envKey = `${ENV_PREFIX}${key.toUpperCase()}`;
157063
155891
  return process.env[envKey];
@@ -157078,12 +155906,12 @@ function parseEnvValue2(key, value) {
157078
155906
  }
157079
155907
  function loadFromFile(projectRoot) {
157080
155908
  const root = projectRoot || process.cwd();
157081
- const configPath = join143(root, CLEO_DIR_NAME, CONFIG_JSON2);
155909
+ const configPath = join140(root, CLEO_DIR_NAME, CONFIG_JSON2);
157082
155910
  if (!existsSync135(configPath)) {
157083
155911
  return {};
157084
155912
  }
157085
155913
  try {
157086
- const content = readFileSync107(configPath, "utf-8");
155914
+ const content = readFileSync106(configPath, "utf-8");
157087
155915
  const config2 = JSON.parse(content);
157088
155916
  const result = {};
157089
155917
  if (config2.lifecycleEnforcement) {
@@ -157536,8 +156364,8 @@ __export(cli_exports, {
157536
156364
  import { randomUUID as randomUUID19 } from "node:crypto";
157537
156365
  import { existsSync as existsSync136 } from "node:fs";
157538
156366
  import { createRequire as createRequire22 } from "node:module";
157539
- import { dirname as dirname36, join as join144 } from "node:path";
157540
- import { fileURLToPath as fileURLToPath11 } from "node:url";
156367
+ import { dirname as dirname35, join as join141 } from "node:path";
156368
+ import { fileURLToPath as fileURLToPath10 } from "node:url";
157541
156369
  import { catalog as catalog4, registerSkillLibraryFromPath } from "@cleocode/caamp";
157542
156370
  function ensureCaampLibrary() {
157543
156371
  if (catalog4.isCatalogAvailable()) return;
@@ -157546,17 +156374,17 @@ function ensureCaampLibrary() {
157546
156374
  try {
157547
156375
  const req = createRequire22(import.meta.url);
157548
156376
  const skillsPkgJson = req.resolve("@cleocode/skills/package.json");
157549
- const candidate = dirname36(skillsPkgJson);
157550
- if (existsSync136(join144(candidate, "skills.json"))) {
156377
+ const candidate = dirname35(skillsPkgJson);
156378
+ if (existsSync136(join141(candidate, "skills.json"))) {
157551
156379
  skillsRoot = candidate;
157552
156380
  }
157553
156381
  } catch {
157554
156382
  }
157555
156383
  if (!skillsRoot) {
157556
- const thisFile = fileURLToPath11(import.meta.url);
157557
- const packageRoot = join144(dirname36(thisFile), "..", "..", "..", "..", "..");
157558
- const candidate = join144(packageRoot, "packages", "skills");
157559
- if (existsSync136(join144(candidate, "skills.json"))) {
156384
+ const thisFile = fileURLToPath10(import.meta.url);
156385
+ const packageRoot = join141(dirname35(thisFile), "..", "..", "..", "..", "..");
156386
+ const candidate = join141(packageRoot, "packages", "skills");
156387
+ if (existsSync136(join141(candidate, "skills.json"))) {
157560
156388
  skillsRoot = candidate;
157561
156389
  }
157562
156390
  }
@@ -157777,9 +156605,9 @@ var init_cli = __esm({
157777
156605
 
157778
156606
  // packages/cleo/src/cli/index.ts
157779
156607
  init_internal();
157780
- import { readFileSync as readFileSync115 } from "node:fs";
157781
- import { dirname as dirname42, join as join161 } from "node:path";
157782
- import { fileURLToPath as fileURLToPath13 } from "node:url";
156608
+ import { readFileSync as readFileSync114 } from "node:fs";
156609
+ import { dirname as dirname40, join as join154 } from "node:path";
156610
+ import { fileURLToPath as fileURLToPath11 } from "node:url";
157783
156611
 
157784
156612
  // node_modules/.pnpm/citty@0.2.1/node_modules/citty/dist/_chunks/libs/scule.mjs
157785
156613
  var NUMBER_CHAR_RE = /\d/;
@@ -158675,7 +157503,7 @@ var addCommand = defineCommand({
158675
157503
  });
158676
157504
 
158677
157505
  // packages/cleo/src/cli/commands/add-batch.ts
158678
- import { existsSync as existsSync137, readFileSync as readFileSync108 } from "node:fs";
157506
+ import { existsSync as existsSync137, readFileSync as readFileSync107 } from "node:fs";
158679
157507
  init_cli();
158680
157508
  init_renderers();
158681
157509
  var addBatchCommand = defineCommand({
@@ -158732,7 +157560,7 @@ var addBatchCommand = defineCommand({
158732
157560
  process.exit(2);
158733
157561
  return;
158734
157562
  }
158735
- raw = readFileSync108(filePath, "utf-8");
157563
+ raw = readFileSync107(filePath, "utf-8");
158736
157564
  }
158737
157565
  let tasks2;
158738
157566
  try {
@@ -159337,9 +158165,9 @@ var registerCommand = defineCommand({
159337
158165
  isActive: true
159338
158166
  });
159339
158167
  const { existsSync: existsSync143, mkdirSync: mkdirSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
159340
- const { join: join162 } = await import("node:path");
159341
- const cantDir = join162(CLEO_DIR_NAME, AGENTS_SUBDIR);
159342
- const cantPath = join162(cantDir, `${agentId}.cant`);
158168
+ const { join: join155 } = await import("node:path");
158169
+ const cantDir = join155(CLEO_DIR_NAME, AGENTS_SUBDIR);
158170
+ const cantPath = join155(cantDir, `${agentId}.cant`);
159343
158171
  let cantScaffolded = false;
159344
158172
  if (!existsSync143(cantPath)) {
159345
158173
  mkdirSync38(cantDir, { recursive: true });
@@ -159520,8 +158348,8 @@ var startCommand = defineCommand({
159520
158348
  try {
159521
158349
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
159522
158350
  const { createRuntime } = await import("@cleocode/runtime");
159523
- const { existsSync: existsSync143, readFileSync: readFileSync116 } = await import("node:fs");
159524
- const { join: join162 } = await import("node:path");
158351
+ const { existsSync: existsSync143, readFileSync: readFileSync115 } = await import("node:fs");
158352
+ const { join: join155 } = await import("node:path");
159525
158353
  await getDb4();
159526
158354
  const registry2 = new AgentRegistryAccessor2(process.cwd());
159527
158355
  const credential = await registry2.get(args.agentId);
@@ -159541,9 +158369,9 @@ var startCommand = defineCommand({
159541
158369
  }
159542
158370
  let profile = null;
159543
158371
  let cantValidation = null;
159544
- const cantPath = args.cant ?? join162(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
158372
+ const cantPath = args.cant ?? join155(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
159545
158373
  if (existsSync143(cantPath)) {
159546
- profile = readFileSync116(cantPath, "utf-8");
158374
+ profile = readFileSync115(cantPath, "utf-8");
159547
158375
  try {
159548
158376
  const cantModule = await import("@cleocode/cant");
159549
158377
  const validate = "validate" in cantModule ? cantModule.validate : null;
@@ -160067,10 +158895,10 @@ var workCommand = defineCommand({
160067
158895
  const { AgentRegistryAccessor: AgentRegistryAccessor2, getDb: getDb4 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
160068
158896
  const { createRuntime } = await import("@cleocode/runtime");
160069
158897
  const { existsSync: existsSync143 } = await import("node:fs");
160070
- const { join: join162 } = await import("node:path");
160071
- const { execFile: execFile10 } = await import("node:child_process");
160072
- const { promisify: promisify10 } = await import("node:util");
160073
- const execFileAsync7 = promisify10(execFile10);
158898
+ const { join: join155 } = await import("node:path");
158899
+ const { execFile: execFile9 } = await import("node:child_process");
158900
+ const { promisify: promisify9 } = await import("node:util");
158901
+ const execFileAsync7 = promisify9(execFile9);
160074
158902
  await getDb4();
160075
158903
  const registry2 = new AgentRegistryAccessor2(process.cwd());
160076
158904
  const credential = await registry2.get(args.agentId);
@@ -160087,7 +158915,7 @@ var workCommand = defineCommand({
160087
158915
  }
160088
158916
  await registry2.update(args.agentId, { isActive: true });
160089
158917
  await registry2.markUsed(args.agentId);
160090
- const cantPath = join162(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
158918
+ const cantPath = join155(CLEO_DIR_NAME, AGENTS_SUBDIR, `${args.agentId}.cant`);
160091
158919
  const hasProfile = existsSync143(cantPath);
160092
158920
  const runtime = await createRuntime(registry2, {
160093
158921
  agentId: args.agentId,
@@ -160939,7 +159767,7 @@ var installCommand = defineCommand({
160939
159767
  let tempDir = null;
160940
159768
  try {
160941
159769
  const { existsSync: existsSync143, mkdirSync: mkdirSync38, statSync: statSync22, readdirSync: readdirSync44, copyFileSync: copyFileSync11 } = await import("node:fs");
160942
- const { join: join162, basename: basename21, resolve: resolve20, extname: extname2 } = await import("node:path");
159770
+ const { join: join155, basename: basename21, resolve: resolve20, extname: extname2 } = await import("node:path");
160943
159771
  const { tmpdir: tmpdir2 } = await import("node:os");
160944
159772
  const resolvedPath = resolve20(args.path);
160945
159773
  if (!existsSync143(resolvedPath)) {
@@ -160957,13 +159785,13 @@ var installCommand = defineCommand({
160957
159785
  return;
160958
159786
  }
160959
159787
  let cantPath;
160960
- const stat10 = statSync22(resolvedPath);
159788
+ const stat8 = statSync22(resolvedPath);
160961
159789
  const ext = extname2(resolvedPath);
160962
- if (stat10.isFile() && ext === ".cant") {
159790
+ if (stat8.isFile() && ext === ".cant") {
160963
159791
  cantPath = resolvedPath;
160964
- } else if (stat10.isFile() && ext === ".cantz") {
159792
+ } else if (stat8.isFile() && ext === ".cantz") {
160965
159793
  const { execFileSync: execFileSync19 } = await import("node:child_process");
160966
- tempDir = join162(tmpdir2(), `cleo-agent-install-${Date.now()}`);
159794
+ tempDir = join155(tmpdir2(), `cleo-agent-install-${Date.now()}`);
160967
159795
  mkdirSync38(tempDir, { recursive: true });
160968
159796
  try {
160969
159797
  execFileSync19("unzip", ["-o", "-q", resolvedPath, "-d", tempDir], {
@@ -160985,7 +159813,7 @@ var installCommand = defineCommand({
160985
159813
  return;
160986
159814
  }
160987
159815
  const topLevel = readdirSync44(tempDir).filter(
160988
- (entry) => statSync22(join162(tempDir, entry)).isDirectory()
159816
+ (entry) => statSync22(join155(tempDir, entry)).isDirectory()
160989
159817
  );
160990
159818
  if (topLevel.length !== 1) {
160991
159819
  cliOutput(
@@ -161002,7 +159830,7 @@ var installCommand = defineCommand({
161002
159830
  return;
161003
159831
  }
161004
159832
  const agentName = topLevel[0];
161005
- const personaPath = join162(tempDir, agentName, "persona.cant");
159833
+ const personaPath = join155(tempDir, agentName, "persona.cant");
161006
159834
  if (!existsSync143(personaPath)) {
161007
159835
  cliOutput(
161008
159836
  {
@@ -161017,11 +159845,11 @@ var installCommand = defineCommand({
161017
159845
  process.exitCode = 6;
161018
159846
  return;
161019
159847
  }
161020
- cantPath = join162(tempDir, `${agentName}.cant`);
159848
+ cantPath = join155(tempDir, `${agentName}.cant`);
161021
159849
  copyFileSync11(personaPath, cantPath);
161022
- } else if (stat10.isDirectory()) {
159850
+ } else if (stat8.isDirectory()) {
161023
159851
  const agentName = basename21(resolvedPath);
161024
- const personaPath = join162(resolvedPath, "persona.cant");
159852
+ const personaPath = join155(resolvedPath, "persona.cant");
161025
159853
  if (!existsSync143(personaPath)) {
161026
159854
  cliOutput(
161027
159855
  {
@@ -161036,9 +159864,9 @@ var installCommand = defineCommand({
161036
159864
  process.exitCode = 6;
161037
159865
  return;
161038
159866
  }
161039
- tempDir = join162(tmpdir2(), `cleo-agent-install-${Date.now()}`);
159867
+ tempDir = join155(tmpdir2(), `cleo-agent-install-${Date.now()}`);
161040
159868
  mkdirSync38(tempDir, { recursive: true });
161041
- cantPath = join162(tempDir, `${agentName}.cant`);
159869
+ cantPath = join155(tempDir, `${agentName}.cant`);
161042
159870
  copyFileSync11(personaPath, cantPath);
161043
159871
  } else {
161044
159872
  cliOutput(
@@ -161166,7 +159994,7 @@ var packCommand = defineCommand({
161166
159994
  async run({ args }) {
161167
159995
  try {
161168
159996
  const { existsSync: existsSync143, statSync: statSync22 } = await import("node:fs");
161169
- const { resolve: resolve20, basename: basename21, dirname: dirname43 } = await import("node:path");
159997
+ const { resolve: resolve20, basename: basename21, dirname: dirname41 } = await import("node:path");
161170
159998
  const { execFileSync: execFileSync19 } = await import("node:child_process");
161171
159999
  const resolvedDir = resolve20(args.dir);
161172
160000
  if (!existsSync143(resolvedDir) || !statSync22(resolvedDir).isDirectory()) {
@@ -161183,8 +160011,8 @@ var packCommand = defineCommand({
161183
160011
  process.exitCode = 4;
161184
160012
  return;
161185
160013
  }
161186
- const { join: join162 } = await import("node:path");
161187
- const personaPath = join162(resolvedDir, "persona.cant");
160014
+ const { join: join155 } = await import("node:path");
160015
+ const personaPath = join155(resolvedDir, "persona.cant");
161188
160016
  if (!existsSync143(personaPath)) {
161189
160017
  cliOutput(
161190
160018
  {
@@ -161202,7 +160030,7 @@ var packCommand = defineCommand({
161202
160030
  const agentName = basename21(resolvedDir);
161203
160031
  const archiveName = `${agentName}.cantz`;
161204
160032
  const archivePath = resolve20(archiveName);
161205
- const parentDir = dirname43(resolvedDir);
160033
+ const parentDir = dirname41(resolvedDir);
161206
160034
  try {
161207
160035
  execFileSync19("zip", ["-r", archivePath, agentName], {
161208
160036
  cwd: parentDir,
@@ -161232,7 +160060,7 @@ var packCommand = defineCommand({
161232
160060
  if (entry.isFile()) {
161233
160061
  fileCount++;
161234
160062
  } else if (entry.isDirectory()) {
161235
- countFiles2(join162(dirPath, entry.name));
160063
+ countFiles2(join155(dirPath, entry.name));
161236
160064
  }
161237
160065
  }
161238
160066
  };
@@ -161302,8 +160130,8 @@ var createCommand = defineCommand({
161302
160130
  async run({ args }) {
161303
160131
  try {
161304
160132
  const { existsSync: existsSync143, mkdirSync: mkdirSync38, writeFileSync: writeFileSync28 } = await import("node:fs");
161305
- const { join: join162 } = await import("node:path");
161306
- const { homedir: homedir17 } = await import("node:os");
160133
+ const { join: join155 } = await import("node:path");
160134
+ const { homedir: homedir15 } = await import("node:os");
161307
160135
  const name2 = args.name;
161308
160136
  const role = args.role;
161309
160137
  const tier = args.tier ?? inferTierFromRole(role);
@@ -161361,13 +160189,13 @@ var createCommand = defineCommand({
161361
160189
  }
161362
160190
  let targetRoot;
161363
160191
  if (isGlobal) {
161364
- const home = homedir17();
161365
- const xdgData = process.env["XDG_DATA_HOME"] ?? join162(home, ".local", "share");
161366
- targetRoot = join162(xdgData, "cleo", "cant", "agents");
160192
+ const home = homedir15();
160193
+ const xdgData = process.env["XDG_DATA_HOME"] ?? join155(home, ".local", "share");
160194
+ targetRoot = join155(xdgData, "cleo", "cant", "agents");
161367
160195
  } else {
161368
- targetRoot = join162(process.cwd(), CLEO_DIR_NAME, CANT_AGENTS_SUBDIR);
160196
+ targetRoot = join155(process.cwd(), CLEO_DIR_NAME, CANT_AGENTS_SUBDIR);
161369
160197
  }
161370
- const agentDir = join162(targetRoot, name2);
160198
+ const agentDir = join155(targetRoot, name2);
161371
160199
  if (existsSync143(agentDir)) {
161372
160200
  cliOutput(
161373
160201
  {
@@ -161392,33 +160220,33 @@ var createCommand = defineCommand({
161392
160220
  domain: domain2,
161393
160221
  parent
161394
160222
  });
161395
- writeFileSync28(join162(agentDir, "persona.cant"), personaContent, "utf-8");
160223
+ writeFileSync28(join155(agentDir, "persona.cant"), personaContent, "utf-8");
161396
160224
  const manifest = generateManifest2({ name: name2, role, tier, domain: domain2 });
161397
160225
  writeFileSync28(
161398
- join162(agentDir, "manifest.json"),
160226
+ join155(agentDir, "manifest.json"),
161399
160227
  `${JSON.stringify(manifest, null, 2)}
161400
160228
  `,
161401
160229
  "utf-8"
161402
160230
  );
161403
160231
  const createdFiles = [
161404
- join162(agentDir, "persona.cant"),
161405
- join162(agentDir, "manifest.json")
160232
+ join155(agentDir, "persona.cant"),
160233
+ join155(agentDir, "manifest.json")
161406
160234
  ];
161407
160235
  if (team) {
161408
160236
  const teamConfigContent = generateTeamConfig(name2, role, team);
161409
- writeFileSync28(join162(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
161410
- createdFiles.push(join162(agentDir, "team-config.cant"));
160237
+ writeFileSync28(join155(agentDir, "team-config.cant"), teamConfigContent, "utf-8");
160238
+ createdFiles.push(join155(agentDir, "team-config.cant"));
161411
160239
  }
161412
160240
  if (seedBrain) {
161413
- const expertiseDir = join162(agentDir, "expertise");
160241
+ const expertiseDir = join155(agentDir, "expertise");
161414
160242
  mkdirSync38(expertiseDir, { recursive: true });
161415
160243
  const seedContent = generateMentalModelSeed(name2, role, domain2);
161416
- writeFileSync28(join162(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
161417
- createdFiles.push(join162(expertiseDir, "mental-model-seed.md"));
160244
+ writeFileSync28(join155(expertiseDir, "mental-model-seed.md"), seedContent, "utf-8");
160245
+ createdFiles.push(join155(expertiseDir, "mental-model-seed.md"));
161418
160246
  try {
161419
- const { execFile: execFile10 } = await import("node:child_process");
161420
- const { promisify: promisify10 } = await import("node:util");
161421
- const execFileAsync7 = promisify10(execFile10);
160247
+ const { execFile: execFile9 } = await import("node:child_process");
160248
+ const { promisify: promisify9 } = await import("node:util");
160249
+ const execFileAsync7 = promisify9(execFile9);
161422
160250
  await execFileAsync7(
161423
160251
  "cleo",
161424
160252
  [
@@ -162486,8 +161314,8 @@ async function inspectTarball(tarPath, displayPath, encrypted) {
162486
161314
  return;
162487
161315
  }
162488
161316
  const integrityOk = verifyManifestHash(manifestContent, manifest);
162489
- const stat10 = fs9.statSync(displayPath);
162490
- printInspectReport(displayPath, stat10.size, encrypted, manifest, integrityOk);
161317
+ const stat8 = fs9.statSync(displayPath);
161318
+ printInspectReport(displayPath, stat8.size, encrypted, manifest, integrityOk);
162491
161319
  process.exitCode = 0;
162492
161320
  }
162493
161321
  var backupInspectSubCommand = defineCommand({
@@ -163409,8 +162237,8 @@ var briefingCommand = defineCommand({
163409
162237
  // packages/cleo/src/cli/commands/bug.ts
163410
162238
  init_src3();
163411
162239
  import { existsSync as existsSync138 } from "node:fs";
163412
- import { appendFile as appendFile6, mkdir as mkdir25, readFile as readFile31 } from "node:fs/promises";
163413
- import { dirname as dirname37, join as join145 } from "node:path";
162240
+ import { appendFile as appendFile6, mkdir as mkdir23, readFile as readFile30 } from "node:fs/promises";
162241
+ import { dirname as dirname36, join as join142 } from "node:path";
163414
162242
  init_cli();
163415
162243
  var SEVERITY_MAP = {
163416
162244
  P0: { priority: "critical", labels: ["bug", "p0"] },
@@ -163425,7 +162253,7 @@ async function loadOwnerPubkeys() {
163425
162253
  return [];
163426
162254
  }
163427
162255
  try {
163428
- const raw = await readFile31(configPath, "utf-8");
162256
+ const raw = await readFile30(configPath, "utf-8");
163429
162257
  const parsed = JSON.parse(raw);
163430
162258
  if (typeof parsed !== "object" || parsed === null) {
163431
162259
  return [];
@@ -163462,8 +162290,8 @@ async function appendSignedBugSeverity(record2) {
163462
162290
  const sig = await signAuditLine(id, canonical);
163463
162291
  const line2 = `${JSON.stringify({ ...full, _sig: sig })}
163464
162292
  `;
163465
- const auditPath = join145(getCleoDirAbsolute(), "audit", "bug-severity.jsonl");
163466
- await mkdir25(dirname37(auditPath), { recursive: true });
162293
+ const auditPath = join142(getCleoDirAbsolute(), "audit", "bug-severity.jsonl");
162294
+ await mkdir23(dirname36(auditPath), { recursive: true });
163467
162295
  await appendFile6(auditPath, line2, { encoding: "utf-8" });
163468
162296
  }
163469
162297
  var bugCommand = defineCommand({
@@ -163575,8 +162403,8 @@ var cancelCommand = defineCommand({
163575
162403
  });
163576
162404
 
163577
162405
  // packages/cleo/src/cli/commands/cant.ts
163578
- import { existsSync as existsSync139, mkdirSync as mkdirSync35, readFileSync as readFileSync109, writeFileSync as writeFileSync25 } from "node:fs";
163579
- import { dirname as dirname38, isAbsolute as isAbsolute5, join as join146, resolve as resolve19 } from "node:path";
162406
+ import { existsSync as existsSync139, mkdirSync as mkdirSync35, readFileSync as readFileSync108, writeFileSync as writeFileSync25 } from "node:fs";
162407
+ import { dirname as dirname37, isAbsolute as isAbsolute5, join as join143, resolve as resolve19 } from "node:path";
163580
162408
  init_renderers();
163581
162409
  function resolveFilePath(file2) {
163582
162410
  return isAbsolute5(file2) ? file2 : resolve19(process.cwd(), file2);
@@ -163726,7 +162554,7 @@ var cantMigrateCommand = defineCommand({
163726
162554
  if (!ensureExists(filePath, "cant.migrate")) return;
163727
162555
  try {
163728
162556
  const mod = await loadMigrateEngine();
163729
- const content = readFileSync109(filePath, "utf-8");
162557
+ const content = readFileSync108(filePath, "utf-8");
163730
162558
  const result = mod.migrateMarkdown(content, filePath, {
163731
162559
  write: isWrite,
163732
162560
  verbose: isVerbose,
@@ -163736,8 +162564,8 @@ var cantMigrateCommand = defineCommand({
163736
162564
  const projectRoot = process.cwd();
163737
162565
  let written = 0;
163738
162566
  for (const outputFile of result.outputFiles) {
163739
- const outputPath = isAbsolute5(outputFile.path) ? outputFile.path : join146(projectRoot, outputFile.path);
163740
- mkdirSync35(dirname38(outputPath), { recursive: true });
162567
+ const outputPath = isAbsolute5(outputFile.path) ? outputFile.path : join143(projectRoot, outputFile.path);
162568
+ mkdirSync35(dirname37(outputPath), { recursive: true });
163741
162569
  writeFileSync25(outputPath, outputFile.content, "utf-8");
163742
162570
  written++;
163743
162571
  }
@@ -163786,7 +162614,7 @@ var cantCommand = defineCommand({
163786
162614
  });
163787
162615
 
163788
162616
  // packages/cleo/src/cli/commands/chain.ts
163789
- import { readFileSync as readFileSync110 } from "node:fs";
162617
+ import { readFileSync as readFileSync109 } from "node:fs";
163790
162618
  init_cli();
163791
162619
  var showCommand3 = defineCommand({
163792
162620
  meta: { name: "show", description: "Show details for a WarpChain definition" },
@@ -163823,7 +162651,7 @@ var addCommand3 = defineCommand({
163823
162651
  }
163824
162652
  },
163825
162653
  async run({ args }) {
163826
- const chainJson = JSON.parse(readFileSync110(args.file, "utf-8"));
162654
+ const chainJson = JSON.parse(readFileSync109(args.file, "utf-8"));
163827
162655
  await dispatchFromCli(
163828
162656
  "mutate",
163829
162657
  "pipeline",
@@ -163992,10 +162820,10 @@ var checkChainValidateCommand = defineCommand({
163992
162820
  }
163993
162821
  },
163994
162822
  async run({ args }) {
163995
- const { readFileSync: readFileSync116 } = await import("node:fs");
162823
+ const { readFileSync: readFileSync115 } = await import("node:fs");
163996
162824
  let chain;
163997
162825
  try {
163998
- chain = JSON.parse(readFileSync116(args.file, "utf8"));
162826
+ chain = JSON.parse(readFileSync115(args.file, "utf8"));
163999
162827
  } catch (err2) {
164000
162828
  const message = err2 instanceof Error ? err2.message : String(err2);
164001
162829
  console.error(`Failed to read or parse chain file: ${message}`);
@@ -164328,9 +163156,9 @@ var codeCommand = defineCommand({
164328
163156
  async run({ args }) {
164329
163157
  await requireTreeSitter();
164330
163158
  const { smartOutline: smartOutline2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
164331
- const { join: join162 } = await import("node:path");
163159
+ const { join: join155 } = await import("node:path");
164332
163160
  const root = process.cwd();
164333
- const absPath = args.file.startsWith("/") ? args.file : join162(root, args.file);
163161
+ const absPath = args.file.startsWith("/") ? args.file : join155(root, args.file);
164334
163162
  const result = smartOutline2(absPath, root);
164335
163163
  if (result.errors.length > 0 && result.symbols.length === 0) {
164336
163164
  console.error(`Error: ${result.errors.join(", ")}`);
@@ -164421,9 +163249,9 @@ var codeCommand = defineCommand({
164421
163249
  async run({ args }) {
164422
163250
  await requireTreeSitter();
164423
163251
  const { smartUnfold: smartUnfold2 } = await Promise.resolve().then(() => (init_internal(), internal_exports));
164424
- const { join: join162 } = await import("node:path");
163252
+ const { join: join155 } = await import("node:path");
164425
163253
  const root = process.cwd();
164426
- const absPath = args.file.startsWith("/") ? args.file : join162(root, args.file);
163254
+ const absPath = args.file.startsWith("/") ? args.file : join155(root, args.file);
164427
163255
  const result = smartUnfold2(absPath, args.symbol, root);
164428
163256
  if (!result.found) {
164429
163257
  console.error(`Symbol "${args.symbol}" not found in ${args.file}`);
@@ -165331,441 +164159,9 @@ var currentCommand = defineCommand({
165331
164159
  });
165332
164160
 
165333
164161
  // packages/cleo/src/cli/commands/daemon.ts
165334
- import { homedir as homedir12 } from "node:os";
165335
- import { join as join150 } from "node:path";
165336
-
165337
- // packages/cleo/src/gc/daemon.ts
165338
- import { spawn as spawn5 } from "node:child_process";
165339
- import { createWriteStream as createWriteStream3 } from "node:fs";
165340
- import { mkdir as mkdir27 } from "node:fs/promises";
165341
- import { join as join149 } from "node:path";
165342
- import { fileURLToPath as fileURLToPath12 } from "node:url";
165343
- import cron2 from "node-cron";
165344
-
165345
- // packages/cleo/src/gc/runner.ts
165346
- import { lstat as lstat2, readdir as readdir5, rm as rm4, stat as stat7 } from "node:fs/promises";
165347
164162
  import { homedir as homedir11 } from "node:os";
165348
- import { join as join148 } from "node:path";
165349
-
165350
- // node_modules/.pnpm/check-disk-space@3.4.0/node_modules/check-disk-space/dist/check-disk-space.mjs
165351
- import { execFile as execFile8 } from "node:child_process";
165352
- import { access as access5 } from "node:fs/promises";
165353
- import { release as release2 } from "node:os";
165354
- import { normalize as normalize2, sep as sep2 } from "node:path";
165355
- import { platform as platform5 } from "node:process";
165356
- import { promisify as promisify8 } from "node:util";
165357
- var InvalidPathError = class _InvalidPathError extends Error {
165358
- constructor(message) {
165359
- super(message);
165360
- this.name = "InvalidPathError";
165361
- Object.setPrototypeOf(this, _InvalidPathError.prototype);
165362
- }
165363
- };
165364
- var NoMatchError = class _NoMatchError extends Error {
165365
- constructor(message) {
165366
- super(message);
165367
- this.name = "NoMatchError";
165368
- Object.setPrototypeOf(this, _NoMatchError.prototype);
165369
- }
165370
- };
165371
- async function isDirectoryExisting(directoryPath, dependencies) {
165372
- try {
165373
- await dependencies.fsAccess(directoryPath);
165374
- return Promise.resolve(true);
165375
- } catch (error48) {
165376
- return Promise.resolve(false);
165377
- }
165378
- }
165379
- async function getFirstExistingParentPath(directoryPath, dependencies) {
165380
- let parentDirectoryPath = directoryPath;
165381
- let parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
165382
- while (!parentDirectoryFound) {
165383
- parentDirectoryPath = dependencies.pathNormalize(parentDirectoryPath + "/..");
165384
- parentDirectoryFound = await isDirectoryExisting(parentDirectoryPath, dependencies);
165385
- }
165386
- return parentDirectoryPath;
165387
- }
165388
- async function hasPowerShell3(dependencies) {
165389
- const major = parseInt(dependencies.release.split(".")[0], 10);
165390
- if (major <= 6) {
165391
- return false;
165392
- }
165393
- try {
165394
- await dependencies.cpExecFile("where", ["powershell"], { windowsHide: true });
165395
- return true;
165396
- } catch (error48) {
165397
- return false;
165398
- }
165399
- }
165400
- function checkDiskSpace(directoryPath, dependencies = {
165401
- platform: platform5,
165402
- release: release2(),
165403
- fsAccess: access5,
165404
- pathNormalize: normalize2,
165405
- pathSep: sep2,
165406
- cpExecFile: promisify8(execFile8)
165407
- }) {
165408
- function mapOutput(stdout, filter, mapping, coefficient) {
165409
- const parsed = stdout.split("\n").map((line2) => line2.trim()).filter((line2) => line2.length !== 0).slice(1).map((line2) => line2.split(/\s+(?=[\d/])/));
165410
- const filtered = parsed.filter(filter);
165411
- if (filtered.length === 0) {
165412
- throw new NoMatchError();
165413
- }
165414
- const diskData = filtered[0];
165415
- return {
165416
- diskPath: diskData[mapping.diskPath],
165417
- free: parseInt(diskData[mapping.free], 10) * coefficient,
165418
- size: parseInt(diskData[mapping.size], 10) * coefficient
165419
- };
165420
- }
165421
- async function check2(cmd, filter, mapping, coefficient = 1) {
165422
- const [file2, ...args] = cmd;
165423
- if (file2 === void 0) {
165424
- return Promise.reject(new Error("cmd must contain at least one item"));
165425
- }
165426
- try {
165427
- const { stdout } = await dependencies.cpExecFile(file2, args, { windowsHide: true });
165428
- return mapOutput(stdout, filter, mapping, coefficient);
165429
- } catch (error48) {
165430
- return Promise.reject(error48);
165431
- }
165432
- }
165433
- async function checkWin32(directoryPath2) {
165434
- if (directoryPath2.charAt(1) !== ":") {
165435
- return Promise.reject(new InvalidPathError(`The following path is invalid (should be X:\\...): ${directoryPath2}`));
165436
- }
165437
- const powershellCmd = [
165438
- "powershell",
165439
- "Get-CimInstance -ClassName Win32_LogicalDisk | Select-Object Caption, FreeSpace, Size"
165440
- ];
165441
- const wmicCmd = [
165442
- "wmic",
165443
- "logicaldisk",
165444
- "get",
165445
- "size,freespace,caption"
165446
- ];
165447
- const cmd = await hasPowerShell3(dependencies) ? powershellCmd : wmicCmd;
165448
- return check2(cmd, (driveData) => {
165449
- const driveLetter = driveData[0];
165450
- return directoryPath2.toUpperCase().startsWith(driveLetter.toUpperCase());
165451
- }, {
165452
- diskPath: 0,
165453
- free: 1,
165454
- size: 2
165455
- });
165456
- }
165457
- async function checkUnix(directoryPath2) {
165458
- if (!dependencies.pathNormalize(directoryPath2).startsWith(dependencies.pathSep)) {
165459
- return Promise.reject(new InvalidPathError(`The following path is invalid (should start by ${dependencies.pathSep}): ${directoryPath2}`));
165460
- }
165461
- const pathToCheck = await getFirstExistingParentPath(directoryPath2, dependencies);
165462
- return check2(
165463
- [
165464
- "df",
165465
- "-Pk",
165466
- "--",
165467
- pathToCheck
165468
- ],
165469
- () => true,
165470
- // We should only get one line, so we did not need to filter
165471
- {
165472
- diskPath: 5,
165473
- free: 3,
165474
- size: 1
165475
- },
165476
- 1024
165477
- );
165478
- }
165479
- if (dependencies.platform === "win32") {
165480
- return checkWin32(directoryPath);
165481
- }
165482
- return checkUnix(directoryPath);
165483
- }
165484
-
165485
- // packages/cleo/src/gc/state.ts
165486
- import { mkdir as mkdir26, readFile as readFile32, rename as rename4, writeFile as writeFile17 } from "node:fs/promises";
165487
- import { dirname as dirname39, join as join147 } from "node:path";
165488
- var GC_STATE_SCHEMA_VERSION = "1.0";
165489
- var DEFAULT_GC_STATE = {
165490
- schemaVersion: GC_STATE_SCHEMA_VERSION,
165491
- lastRunAt: null,
165492
- lastRunResult: null,
165493
- lastRunBytesFreed: 0,
165494
- pendingPrune: null,
165495
- consecutiveFailures: 0,
165496
- diskThresholdBreached: false,
165497
- lastDiskUsedPct: null,
165498
- escalationNeeded: false,
165499
- escalationReason: null,
165500
- daemonPid: null,
165501
- daemonStartedAt: null
165502
- };
165503
- async function readGCState(statePath) {
165504
- try {
165505
- const raw = await readFile32(statePath, "utf-8");
165506
- const parsed = JSON.parse(raw);
165507
- return { ...DEFAULT_GC_STATE, ...parsed };
165508
- } catch {
165509
- return { ...DEFAULT_GC_STATE };
165510
- }
165511
- }
165512
- async function writeGCState(statePath, state) {
165513
- const dir = dirname39(statePath);
165514
- await mkdir26(dir, { recursive: true });
165515
- const tmpPath = join147(dir, `.gc-state-${process.pid}.tmp`);
165516
- const json4 = JSON.stringify(state, null, 2);
165517
- await writeFile17(tmpPath, json4, "utf-8");
165518
- await rename4(tmpPath, statePath);
165519
- }
165520
- async function patchGCState(statePath, patch) {
165521
- const current = await readGCState(statePath);
165522
- const updated = { ...current, ...patch };
165523
- await writeGCState(statePath, updated);
165524
- return updated;
165525
- }
165526
-
165527
- // packages/cleo/src/gc/runner.ts
165528
- var checkDiskSpace2 = checkDiskSpace;
165529
- var DISK_THRESHOLDS = {
165530
- WATCH: 70,
165531
- WARN: 85,
165532
- URGENT: 90,
165533
- EMERGENCY: 95
165534
- };
165535
- function classifyDiskTier(pct) {
165536
- if (pct >= DISK_THRESHOLDS.EMERGENCY) return "emergency";
165537
- if (pct >= DISK_THRESHOLDS.URGENT) return "urgent";
165538
- if (pct >= DISK_THRESHOLDS.WARN) return "warn";
165539
- if (pct >= DISK_THRESHOLDS.WATCH) return "watch";
165540
- return "ok";
165541
- }
165542
- function retentionMs(tier) {
165543
- switch (tier) {
165544
- case "emergency":
165545
- return 1 * 24 * 60 * 60 * 1e3;
165546
- // 1 day
165547
- case "urgent":
165548
- return 3 * 24 * 60 * 60 * 1e3;
165549
- // 3 days
165550
- case "warn":
165551
- return 7 * 24 * 60 * 60 * 1e3;
165552
- // 7 days
165553
- default:
165554
- return 30 * 24 * 60 * 60 * 1e3;
165555
- }
165556
- }
165557
- async function getPathBytes(targetPath) {
165558
- try {
165559
- const info = await lstat2(targetPath);
165560
- if (info.isFile()) return info.size;
165561
- if (!info.isDirectory()) return 0;
165562
- const entries = await readdir5(targetPath, { withFileTypes: true });
165563
- let total = 0;
165564
- for (const entry of entries) {
165565
- total += await getPathBytes(join148(targetPath, entry.name));
165566
- }
165567
- return total;
165568
- } catch {
165569
- return 0;
165570
- }
165571
- }
165572
- async function idempotentRm(targetPath) {
165573
- try {
165574
- await rm4(targetPath, { recursive: true, force: true });
165575
- } catch (err2) {
165576
- const nodeErr = err2;
165577
- if (nodeErr.code === "ENOENT") return;
165578
- throw err2;
165579
- }
165580
- }
165581
- async function gatherPruneCandidates(maxAgeMs, projectsDir) {
165582
- const resolvedProjectsDir = projectsDir ?? join148(homedir11(), ".claude", "projects");
165583
- const candidates = [];
165584
- const now2 = Date.now();
165585
- let projectSlugs;
165586
- try {
165587
- const entries = await readdir5(resolvedProjectsDir, { withFileTypes: true });
165588
- projectSlugs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
165589
- } catch {
165590
- return candidates;
165591
- }
165592
- for (const slug of projectSlugs) {
165593
- const slugDir = join148(resolvedProjectsDir, slug);
165594
- let slugEntries;
165595
- try {
165596
- slugEntries = await readdir5(slugDir, { withFileTypes: true });
165597
- } catch {
165598
- continue;
165599
- }
165600
- for (const entry of slugEntries) {
165601
- const entryPath = join148(slugDir, entry.name);
165602
- if (entry.isFile() && entry.name.endsWith(".jsonl")) {
165603
- try {
165604
- const info = await stat7(entryPath);
165605
- const ageMs = now2 - info.mtimeMs;
165606
- if (ageMs > maxAgeMs) {
165607
- candidates.push(entryPath);
165608
- }
165609
- } catch {
165610
- }
165611
- } else if (entry.isDirectory()) {
165612
- try {
165613
- const info = await stat7(entryPath);
165614
- const ageMs = now2 - info.mtimeMs;
165615
- if (ageMs > maxAgeMs) {
165616
- candidates.push(entryPath);
165617
- }
165618
- } catch {
165619
- }
165620
- }
165621
- }
165622
- }
165623
- return candidates;
165624
- }
165625
- async function runGC(opts = {}) {
165626
- const cleoDir = opts.cleoDir ?? join148(homedir11(), ".cleo");
165627
- const statePath = join148(cleoDir, "gc-state.json");
165628
- const dryRun = opts.dryRun ?? false;
165629
- const projectsDir = opts.projectsDir;
165630
- const initialState = await readGCState(statePath);
165631
- const resumePaths = opts.resumeFrom ?? initialState.pendingPrune ?? [];
165632
- let diskUsedPct = 0;
165633
- try {
165634
- const { free, size } = await checkDiskSpace2(cleoDir);
165635
- diskUsedPct = size > 0 ? (size - free) / size * 100 : 0;
165636
- } catch {
165637
- diskUsedPct = 0;
165638
- }
165639
- const tier = classifyDiskTier(diskUsedPct);
165640
- const maxAgeMs = retentionMs(tier);
165641
- const candidatesFromScan = resumePaths.length > 0 ? resumePaths : await gatherPruneCandidates(maxAgeMs, projectsDir);
165642
- if (!dryRun && candidatesFromScan.length > 0) {
165643
- await patchGCState(statePath, { pendingPrune: candidatesFromScan });
165644
- }
165645
- const pruned = [];
165646
- let bytesFreed = 0;
165647
- const remaining = [...candidatesFromScan];
165648
- for (const candidatePath of candidatesFromScan) {
165649
- const bytes = await getPathBytes(candidatePath);
165650
- if (dryRun) {
165651
- pruned.push({ path: candidatePath, bytes });
165652
- bytesFreed += bytes;
165653
- continue;
165654
- }
165655
- try {
165656
- await idempotentRm(candidatePath);
165657
- pruned.push({ path: candidatePath, bytes });
165658
- bytesFreed += bytes;
165659
- const idx = remaining.indexOf(candidatePath);
165660
- if (idx !== -1) remaining.splice(idx, 1);
165661
- await patchGCState(statePath, {
165662
- pendingPrune: remaining.length > 0 ? remaining : null
165663
- });
165664
- } catch {
165665
- }
165666
- }
165667
- const escalationSet = tier === "warn" || tier === "urgent" || tier === "emergency";
165668
- let escalationReason = null;
165669
- if (escalationSet) {
165670
- escalationReason = `Disk at ${diskUsedPct.toFixed(1)}% (${tier.toUpperCase()}): ${pruned.length} paths pruned, ${bytesFreed} bytes freed`;
165671
- }
165672
- const completedAt = (/* @__PURE__ */ new Date()).toISOString();
165673
- if (!dryRun) {
165674
- await patchGCState(statePath, {
165675
- lastRunAt: completedAt,
165676
- lastRunResult: remaining.length === 0 ? "success" : "partial",
165677
- lastRunBytesFreed: bytesFreed,
165678
- pendingPrune: remaining.length > 0 ? remaining : null,
165679
- consecutiveFailures: remaining.length > 0 ? initialState.consecutiveFailures + 1 : 0,
165680
- diskThresholdBreached: diskUsedPct >= DISK_THRESHOLDS.WATCH,
165681
- lastDiskUsedPct: diskUsedPct,
165682
- escalationNeeded: escalationSet || initialState.escalationNeeded,
165683
- escalationReason: escalationReason ?? initialState.escalationReason
165684
- });
165685
- }
165686
- return {
165687
- diskUsedPct,
165688
- threshold: tier,
165689
- pruned,
165690
- bytesFreed,
165691
- escalationSet,
165692
- escalationReason,
165693
- completedAt
165694
- };
165695
- }
165696
-
165697
- // packages/cleo/src/gc/daemon.ts
165698
- var GC_INTERVAL_MS = 24 * 60 * 60 * 1e3;
165699
- async function spawnGCDaemon(cleoDir) {
165700
- const logsDir = join149(cleoDir, "logs");
165701
- await mkdir27(logsDir, { recursive: true });
165702
- const logPath = join149(logsDir, "gc.log");
165703
- const errPath = join149(logsDir, "gc.err");
165704
- const outStream = createWriteStream3(logPath, { flags: "a" });
165705
- const errStream = createWriteStream3(errPath, { flags: "a" });
165706
- const daemonEntry = join149(fileURLToPath12(import.meta.url), "..", "daemon-entry.js");
165707
- const child = spawn5(process.execPath, [daemonEntry, cleoDir], {
165708
- detached: true,
165709
- stdio: ["ignore", outStream, errStream],
165710
- env: { ...process.env, CLEO_GC_DAEMON: "1" }
165711
- });
165712
- child.unref();
165713
- const pid = child.pid ?? 0;
165714
- await patchGCState(join149(cleoDir, "gc-state.json"), {
165715
- daemonPid: pid,
165716
- daemonStartedAt: (/* @__PURE__ */ new Date()).toISOString()
165717
- });
165718
- return pid;
165719
- }
165720
- async function stopGCDaemon(cleoDir) {
165721
- const statePath = join149(cleoDir, "gc-state.json");
165722
- const state = await readGCState(statePath);
165723
- const pid = state.daemonPid;
165724
- if (!pid) {
165725
- return { stopped: false, pid: null, reason: "Daemon PID not found in gc-state.json" };
165726
- }
165727
- try {
165728
- process.kill(pid, 0);
165729
- } catch {
165730
- await patchGCState(statePath, { daemonPid: null });
165731
- return {
165732
- stopped: false,
165733
- pid,
165734
- reason: `Daemon PID ${pid} is not running (stale state cleared)`
165735
- };
165736
- }
165737
- try {
165738
- process.kill(pid, "SIGTERM");
165739
- await patchGCState(statePath, { daemonPid: null });
165740
- return { stopped: true, pid, reason: `SIGTERM sent to PID ${pid}` };
165741
- } catch (err2) {
165742
- const msg = err2 instanceof Error ? err2.message : String(err2);
165743
- return { stopped: false, pid, reason: `Failed to send SIGTERM to PID ${pid}: ${msg}` };
165744
- }
165745
- }
165746
- async function getGCDaemonStatus(cleoDir) {
165747
- const state = await readGCState(join149(cleoDir, "gc-state.json"));
165748
- const pid = state.daemonPid;
165749
- let running = false;
165750
- if (pid) {
165751
- try {
165752
- process.kill(pid, 0);
165753
- running = true;
165754
- } catch {
165755
- running = false;
165756
- }
165757
- }
165758
- return {
165759
- running,
165760
- pid: running ? pid : null,
165761
- startedAt: state.daemonStartedAt,
165762
- lastRunAt: state.lastRunAt,
165763
- lastDiskUsedPct: state.lastDiskUsedPct,
165764
- escalationNeeded: state.escalationNeeded
165765
- };
165766
- }
165767
-
165768
- // packages/cleo/src/cli/commands/daemon.ts
164163
+ import { join as join144 } from "node:path";
164164
+ import { getGCDaemonStatus, spawnGCDaemon, stopGCDaemon } from "@cleocode/core/gc/daemon.js";
165769
164165
  async function showDaemonStatus(cleoDir, json4) {
165770
164166
  try {
165771
164167
  const status = await getGCDaemonStatus(cleoDir);
@@ -165817,7 +164213,7 @@ var startCommand3 = defineCommand({
165817
164213
  }
165818
164214
  },
165819
164215
  async run({ args }) {
165820
- const cleoDir = args["cleo-dir"] ?? join150(homedir12(), ".cleo");
164216
+ const cleoDir = args["cleo-dir"] ?? join144(homedir11(), ".cleo");
165821
164217
  const jsonMode = args.json ?? false;
165822
164218
  try {
165823
164219
  const status = await getGCDaemonStatus(cleoDir);
@@ -165848,7 +164244,7 @@ var startCommand3 = defineCommand({
165848
164244
  } else {
165849
164245
  process.stdout.write(`GC daemon started (PID ${pid})
165850
164246
  `);
165851
- process.stdout.write(`Logs: ${join150(cleoDir, "logs", "gc.log")}
164247
+ process.stdout.write(`Logs: ${join144(cleoDir, "logs", "gc.log")}
165852
164248
  `);
165853
164249
  }
165854
164250
  } catch (err2) {
@@ -165877,7 +164273,7 @@ var stopCommand3 = defineCommand({
165877
164273
  }
165878
164274
  },
165879
164275
  async run({ args }) {
165880
- const cleoDir = args["cleo-dir"] ?? join150(homedir12(), ".cleo");
164276
+ const cleoDir = args["cleo-dir"] ?? join144(homedir11(), ".cleo");
165881
164277
  const jsonMode = args.json ?? false;
165882
164278
  try {
165883
164279
  const stopResult = await stopGCDaemon(cleoDir);
@@ -165923,7 +164319,7 @@ var statusCommand4 = defineCommand({
165923
164319
  }
165924
164320
  },
165925
164321
  async run({ args }) {
165926
- const cleoDir = args["cleo-dir"] ?? join150(homedir12(), ".cleo");
164322
+ const cleoDir = args["cleo-dir"] ?? join144(homedir11(), ".cleo");
165927
164323
  await showDaemonStatus(cleoDir, args.json ?? false);
165928
164324
  }
165929
164325
  });
@@ -165948,7 +164344,7 @@ var daemonCommand = defineCommand({
165948
164344
  status: statusCommand4
165949
164345
  },
165950
164346
  async run({ args }) {
165951
- const cleoDir = args["cleo-dir"] ?? join150(homedir12(), ".cleo");
164347
+ const cleoDir = args["cleo-dir"] ?? join144(homedir11(), ".cleo");
165952
164348
  await showDaemonStatus(cleoDir, args.json ?? false);
165953
164349
  }
165954
164350
  });
@@ -166287,17 +164683,17 @@ var detectCommand2 = defineCommand({
166287
164683
 
166288
164684
  // packages/cleo/src/cli/commands/detect-drift.ts
166289
164685
  init_src();
166290
- import { existsSync as existsSync140, readdirSync as readdirSync42, readFileSync as readFileSync111 } from "node:fs";
166291
- import { dirname as dirname40, join as join151 } from "node:path";
164686
+ import { existsSync as existsSync140, readdirSync as readdirSync42, readFileSync as readFileSync110 } from "node:fs";
164687
+ import { dirname as dirname38, join as join145 } from "node:path";
166292
164688
  init_paths2();
166293
164689
  init_renderers();
166294
164690
  function findProjectRoot() {
166295
164691
  let currentDir = process.cwd();
166296
164692
  while (currentDir !== "/") {
166297
- if (existsSync140(join151(currentDir, "package.json"))) {
164693
+ if (existsSync140(join145(currentDir, "package.json"))) {
166298
164694
  return currentDir;
166299
164695
  }
166300
- const parent = dirname40(currentDir);
164696
+ const parent = dirname38(currentDir);
166301
164697
  if (parent === currentDir) break;
166302
164698
  currentDir = parent;
166303
164699
  }
@@ -166310,11 +164706,11 @@ var detectDriftCommand = defineCommand({
166310
164706
  },
166311
164707
  async run() {
166312
164708
  const projectRoot = findProjectRoot();
166313
- const isCleoRepo = existsSync140(join151(projectRoot, "packages", "cleo", "src"));
166314
- const cleoSrcRoot = isCleoRepo ? join151(projectRoot, "packages", "cleo", "src") : join151(projectRoot, "src");
164709
+ const isCleoRepo = existsSync140(join145(projectRoot, "packages", "cleo", "src"));
164710
+ const cleoSrcRoot = isCleoRepo ? join145(projectRoot, "packages", "cleo", "src") : join145(projectRoot, "src");
166315
164711
  const safeRead = (filePath) => {
166316
164712
  try {
166317
- return readFileSync111(filePath, "utf-8");
164713
+ return readFileSync110(filePath, "utf-8");
166318
164714
  } catch {
166319
164715
  return "";
166320
164716
  }
@@ -166325,7 +164721,7 @@ var detectDriftCommand = defineCommand({
166325
164721
  checks: [],
166326
164722
  recommendations: []
166327
164723
  };
166328
- const injPath = join151(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
164724
+ const injPath = join145(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
166329
164725
  if (existsSync140(injPath)) {
166330
164726
  const content = safeRead(injPath);
166331
164727
  userResult.checks.push({
@@ -166377,9 +164773,9 @@ var detectDriftCommand = defineCommand({
166377
164773
  }
166378
164774
  };
166379
164775
  try {
166380
- const specPath = join151(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
166381
- const registryPath = join151(cleoSrcRoot, "dispatch", "registry.ts");
166382
- const dispatchDomainsDir = join151(cleoSrcRoot, "dispatch", "domains");
164776
+ const specPath = join145(projectRoot, "docs", "specs", "CLEO-OPERATION-CONSTITUTION.md");
164777
+ const registryPath = join145(cleoSrcRoot, "dispatch", "registry.ts");
164778
+ const dispatchDomainsDir = join145(cleoSrcRoot, "dispatch", "domains");
166383
164779
  if (!existsSync140(specPath)) {
166384
164780
  addCheck("Gateway-to-spec sync", "fail", "CLEO-OPERATION-CONSTITUTION.md missing", [
166385
164781
  {
@@ -166448,8 +164844,8 @@ var detectDriftCommand = defineCommand({
166448
164844
  ]);
166449
164845
  }
166450
164846
  try {
166451
- const cliDir = join151(cleoSrcRoot, "cli", "commands");
166452
- const coreDir = isCleoRepo ? join151(projectRoot, "packages", "core", "src") : join151(projectRoot, "src", "core");
164847
+ const cliDir = join145(cleoSrcRoot, "cli", "commands");
164848
+ const coreDir = isCleoRepo ? join145(projectRoot, "packages", "core", "src") : join145(projectRoot, "src", "core");
166453
164849
  if (!existsSync140(cliDir)) {
166454
164850
  addCheck("CLI-to-core sync", "fail", "CLI commands directory missing", [
166455
164851
  {
@@ -166476,7 +164872,7 @@ var detectDriftCommand = defineCommand({
166476
164872
  addCheck("CLI-to-core sync", "fail", `Error: ${getErrorMessage(e)}`);
166477
164873
  }
166478
164874
  try {
166479
- const domainsDir = join151(cleoSrcRoot, "dispatch", "domains");
164875
+ const domainsDir = join145(cleoSrcRoot, "dispatch", "domains");
166480
164876
  if (!existsSync140(domainsDir)) {
166481
164877
  addCheck("Domain handler coverage", "fail", "Dispatch domains directory missing", [
166482
164878
  {
@@ -166494,7 +164890,7 @@ var detectDriftCommand = defineCommand({
166494
164890
  addCheck("Domain handler coverage", "fail", `Error: ${getErrorMessage(e)}`);
166495
164891
  }
166496
164892
  try {
166497
- const matrixPath = join151(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
164893
+ const matrixPath = join145(cleoSrcRoot, "dispatch", "lib", "capability-matrix.ts");
166498
164894
  if (!existsSync140(matrixPath)) {
166499
164895
  addCheck("Capability matrix", "fail", "Capability matrix missing", [
166500
164896
  {
@@ -166511,7 +164907,7 @@ var detectDriftCommand = defineCommand({
166511
164907
  addCheck("Capability matrix", "fail", `Error: ${getErrorMessage(e)}`);
166512
164908
  }
166513
164909
  try {
166514
- const schemaPath = join151(projectRoot, "src", "store", "schema.ts");
164910
+ const schemaPath = join145(projectRoot, "src", "store", "schema.ts");
166515
164911
  if (!existsSync140(schemaPath)) {
166516
164912
  addCheck("Schema validation", "fail", "Schema definition missing", [
166517
164913
  {
@@ -166546,8 +164942,8 @@ var detectDriftCommand = defineCommand({
166546
164942
  addCheck("Schema validation", "fail", `Error: ${getErrorMessage(e)}`);
166547
164943
  }
166548
164944
  try {
166549
- const visionPath = join151(projectRoot, "docs", "concepts", "CLEO-VISION.md");
166550
- const specPath = join151(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
164945
+ const visionPath = join145(projectRoot, "docs", "concepts", "CLEO-VISION.md");
164946
+ const specPath = join145(projectRoot, "docs", "specs", "CLEO-PORTABLE-PROJECT-BRAIN-SPEC.md");
166551
164947
  const issues = [];
166552
164948
  if (!existsSync140(visionPath)) {
166553
164949
  issues.push({
@@ -166602,7 +164998,7 @@ var detectDriftCommand = defineCommand({
166602
164998
  addCheck("Canonical identity", "fail", `Error: ${getErrorMessage(e)}`);
166603
164999
  }
166604
165000
  try {
166605
- const injectionPath = join151(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
165001
+ const injectionPath = join145(projectRoot, CLEO_DIR_NAME, TEMPLATES_SUBDIR, CLEO_INJECTION_MD);
166606
165002
  if (!existsSync140(injectionPath)) {
166607
165003
  addCheck("Agent injection", "fail", "Agent injection template missing", [
166608
165004
  {
@@ -166632,7 +165028,7 @@ var detectDriftCommand = defineCommand({
166632
165028
  addCheck("Agent injection", "fail", `Error: ${getErrorMessage(e)}`);
166633
165029
  }
166634
165030
  try {
166635
- const exitCodesPath = join151(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
165031
+ const exitCodesPath = join145(cleoSrcRoot, "dispatch", "lib", "exit-codes.ts");
166636
165032
  if (!existsSync140(exitCodesPath)) {
166637
165033
  addCheck("Exit codes", "fail", "Exit codes definition missing", [
166638
165034
  {
@@ -166764,21 +165160,21 @@ var diagnosticsCommand = defineCommand({
166764
165160
 
166765
165161
  // packages/cleo/src/cli/commands/docs.ts
166766
165162
  init_internal();
166767
- import { readdir as readdir6, readFile as readFile33 } from "node:fs/promises";
166768
- import { join as join152 } from "node:path";
165163
+ import { readdir as readdir5, readFile as readFile31 } from "node:fs/promises";
165164
+ import { join as join146 } from "node:path";
166769
165165
  init_cli();
166770
165166
  init_renderers();
166771
165167
  async function getScriptNames(projectRoot) {
166772
- const scriptsDir = join152(projectRoot, "scripts");
165168
+ const scriptsDir = join146(projectRoot, "scripts");
166773
165169
  try {
166774
- const files = await readdir6(scriptsDir);
165170
+ const files = await readdir5(scriptsDir);
166775
165171
  return files.filter((f2) => f2.endsWith(".sh")).map((f2) => f2.replace(".sh", "")).sort();
166776
165172
  } catch {
166777
165173
  return [];
166778
165174
  }
166779
165175
  }
166780
165176
  async function getIndexedCommands(projectRoot) {
166781
- const indexPath = join152(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
165177
+ const indexPath = join146(projectRoot, "docs", "commands", "COMMANDS-INDEX.json");
166782
165178
  const index2 = await readJson(indexPath);
166783
165179
  if (!index2) return [];
166784
165180
  return index2.commands.map((c) => c.name).sort();
@@ -166807,12 +165203,12 @@ async function runGapCheck(_projectRoot, filterId) {
166807
165203
  const reviewDir = getAgentOutputsAbsolute();
166808
165204
  const results = [];
166809
165205
  try {
166810
- const files = await readdir6(reviewDir);
165206
+ const files = await readdir5(reviewDir);
166811
165207
  const reviewFiles = files.filter((f2) => f2.endsWith(".md"));
166812
165208
  for (const file2 of reviewFiles) {
166813
165209
  if (filterId && !file2.includes(filterId)) continue;
166814
- const filePath = join152(reviewDir, file2);
166815
- const content = await readFile33(filePath, "utf-8");
165210
+ const filePath = join146(reviewDir, file2);
165211
+ const content = await readFile31(filePath, "utf-8");
166816
165212
  const taskMatch = file2.match(/^(T\d+)/);
166817
165213
  const taskId = taskMatch ? taskMatch[1] : "UNKNOWN";
166818
165214
  const gaps = [];
@@ -167776,8 +166172,10 @@ var findCommand2 = defineCommand({
167776
166172
  });
167777
166173
 
167778
166174
  // packages/cleo/src/cli/commands/gc.ts
167779
- import { homedir as homedir13 } from "node:os";
167780
- import { join as join153 } from "node:path";
166175
+ import { homedir as homedir12 } from "node:os";
166176
+ import { join as join147 } from "node:path";
166177
+ import { runGC } from "@cleocode/core/gc/runner.js";
166178
+ import { readGCState } from "@cleocode/core/gc/state.js";
167781
166179
  function formatBytes(bytes) {
167782
166180
  if (bytes === 0) return "0 B";
167783
166181
  const units = ["B", "KB", "MB", "GB", "TB"];
@@ -167807,7 +166205,7 @@ var runCommand3 = defineCommand({
167807
166205
  }
167808
166206
  },
167809
166207
  async run({ args }) {
167810
- const cleoDir = args["cleo-dir"] ?? join153(homedir13(), ".cleo");
166208
+ const cleoDir = args["cleo-dir"] ?? join147(homedir12(), ".cleo");
167811
166209
  const dryRun = args["dry-run"];
167812
166210
  try {
167813
166211
  const gcResult = await runGC({ cleoDir, dryRun });
@@ -167862,8 +166260,8 @@ var statusCommand6 = defineCommand({
167862
166260
  }
167863
166261
  },
167864
166262
  async run({ args }) {
167865
- const cleoDir = args["cleo-dir"] ?? join153(homedir13(), ".cleo");
167866
- const statePath = join153(cleoDir, "gc-state.json");
166263
+ const cleoDir = args["cleo-dir"] ?? join147(homedir12(), ".cleo");
166264
+ const statePath = join147(cleoDir, "gc-state.json");
167867
166265
  try {
167868
166266
  const state = await readGCState(statePath);
167869
166267
  const result = { success: true, data: state };
@@ -167923,13 +166321,13 @@ var gcCommand = defineCommand({
167923
166321
  init_src();
167924
166322
  init_src3();
167925
166323
  import { execFileSync as execFileSync16 } from "node:child_process";
167926
- import { existsSync as existsSync141, mkdirSync as mkdirSync36, readFileSync as readFileSync112, writeFileSync as writeFileSync26 } from "node:fs";
167927
- import { dirname as dirname41, join as join154 } from "node:path";
166324
+ import { existsSync as existsSync141, mkdirSync as mkdirSync36, readFileSync as readFileSync111, writeFileSync as writeFileSync26 } from "node:fs";
166325
+ import { dirname as dirname39, join as join148 } from "node:path";
167928
166326
  init_renderers();
167929
166327
  function getChangelogSource(cwd) {
167930
166328
  const configPath = getConfigPath(cwd);
167931
166329
  try {
167932
- const config2 = JSON.parse(readFileSync112(configPath, "utf-8"));
166330
+ const config2 = JSON.parse(readFileSync111(configPath, "utf-8"));
167933
166331
  return config2?.release?.changelog?.source ?? "CHANGELOG.md";
167934
166332
  } catch {
167935
166333
  return "CHANGELOG.md";
@@ -167938,15 +166336,15 @@ function getChangelogSource(cwd) {
167938
166336
  function getEnabledPlatforms(cwd) {
167939
166337
  const configPath = getConfigPath(cwd);
167940
166338
  try {
167941
- const config2 = JSON.parse(readFileSync112(configPath, "utf-8"));
166339
+ const config2 = JSON.parse(readFileSync111(configPath, "utf-8"));
167942
166340
  const outputs = config2?.release?.changelog?.outputs ?? [];
167943
166341
  return outputs.filter((o) => o.enabled);
167944
166342
  } catch {
167945
166343
  return [];
167946
166344
  }
167947
166345
  }
167948
- function getDefaultOutputPath(platform6) {
167949
- switch (platform6) {
166346
+ function getDefaultOutputPath(platform5) {
166347
+ switch (platform5) {
167950
166348
  case "mintlify":
167951
166349
  return "docs/changelog/overview.mdx";
167952
166350
  case "docusaurus":
@@ -167968,8 +166366,8 @@ function getGitHubRepoSlug(cwd) {
167968
166366
  return "";
167969
166367
  }
167970
166368
  }
167971
- function generateForPlatform(platform6, sourceContent, repoSlug, limit) {
167972
- switch (platform6) {
166369
+ function generateForPlatform(platform5, sourceContent, repoSlug, limit) {
166370
+ switch (platform5) {
167973
166371
  case "mintlify":
167974
166372
  return generateMintlify(sourceContent, repoSlug, limit);
167975
166373
  case "docusaurus":
@@ -168082,11 +166480,11 @@ var generateChangelogCommand = defineCommand({
168082
166480
  const targetPlatform = args.platform;
168083
166481
  const dryRun = args["dry-run"] === true;
168084
166482
  const sourceFile = getChangelogSource();
168085
- const sourcePath = join154(getProjectRoot(), sourceFile);
166483
+ const sourcePath = join148(getProjectRoot(), sourceFile);
168086
166484
  if (!existsSync141(sourcePath)) {
168087
166485
  throw new CleoError(4 /* NOT_FOUND */, `Changelog source not found: ${sourcePath}`);
168088
166486
  }
168089
- const sourceContent = readFileSync112(sourcePath, "utf-8");
166487
+ const sourceContent = readFileSync111(sourcePath, "utf-8");
168090
166488
  const repoSlug = getGitHubRepoSlug();
168091
166489
  const results = [];
168092
166490
  if (targetPlatform) {
@@ -168095,8 +166493,8 @@ var generateChangelogCommand = defineCommand({
168095
166493
  const outputPath = platformConfig?.path ?? getDefaultOutputPath(targetPlatform);
168096
166494
  const content = generateForPlatform(targetPlatform, sourceContent, repoSlug, limit);
168097
166495
  if (!dryRun) {
168098
- const fullPath = join154(getProjectRoot(), outputPath);
168099
- mkdirSync36(dirname41(fullPath), { recursive: true });
166496
+ const fullPath = join148(getProjectRoot(), outputPath);
166497
+ mkdirSync36(dirname39(fullPath), { recursive: true });
168100
166498
  writeFileSync26(fullPath, content, "utf-8");
168101
166499
  }
168102
166500
  results.push({ platform: targetPlatform, path: outputPath, written: !dryRun });
@@ -168116,8 +166514,8 @@ var generateChangelogCommand = defineCommand({
168116
166514
  limit
168117
166515
  );
168118
166516
  if (!dryRun) {
168119
- const fullPath = join154(getProjectRoot(), platformConfig.path);
168120
- mkdirSync36(dirname41(fullPath), { recursive: true });
166517
+ const fullPath = join148(getProjectRoot(), platformConfig.path);
166518
+ mkdirSync36(dirname39(fullPath), { recursive: true });
168121
166519
  writeFileSync26(fullPath, content, "utf-8");
168122
166520
  }
168123
166521
  results.push({
@@ -169216,9 +167614,9 @@ var mapCommand = defineCommand({
169216
167614
  // packages/cleo/src/cli/commands/memory.ts
169217
167615
  init_internal();
169218
167616
  import { createHash as createHash29 } from "node:crypto";
169219
- import { existsSync as existsSync142, mkdirSync as mkdirSync37, readdirSync as readdirSync43, readFileSync as readFileSync113, writeFileSync as writeFileSync27 } from "node:fs";
169220
- import { homedir as homedir14 } from "node:os";
169221
- import { join as join155 } from "node:path";
167617
+ import { existsSync as existsSync142, mkdirSync as mkdirSync37, readdirSync as readdirSync43, readFileSync as readFileSync112, writeFileSync as writeFileSync27 } from "node:fs";
167618
+ import { homedir as homedir13 } from "node:os";
167619
+ import { join as join149 } from "node:path";
169222
167620
  init_cli();
169223
167621
  init_paths2();
169224
167622
  init_renderers();
@@ -169255,7 +167653,7 @@ ${body}`).digest("hex").slice(0, 16);
169255
167653
  function loadImportHashes(stateFile) {
169256
167654
  try {
169257
167655
  if (!existsSync142(stateFile)) return /* @__PURE__ */ new Set();
169258
- const raw = readFileSync113(stateFile, "utf-8");
167656
+ const raw = readFileSync112(stateFile, "utf-8");
169259
167657
  const parsed = JSON.parse(raw);
169260
167658
  return new Set(parsed.hashes);
169261
167659
  } catch {
@@ -170509,11 +168907,11 @@ var importCommand3 = defineCommand({
170509
168907
  }
170510
168908
  },
170511
168909
  async run({ args }) {
170512
- const sourceDir = args.from ?? join155(homedir14(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
168910
+ const sourceDir = args.from ?? join149(homedir13(), ".claude", "projects", "-mnt-projects-cleocode", "memory");
170513
168911
  const isDryRun = !!args["dry-run"];
170514
168912
  const isJson = !!args.json;
170515
168913
  const projectRoot = getProjectRoot();
170516
- const stateFile = join155(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
168914
+ const stateFile = join149(projectRoot, CLEO_DIR_NAME, MIGRATE_MEMORY_HASHES_JSON);
170517
168915
  if (!existsSync142(sourceDir)) {
170518
168916
  const msg = `Source directory not found: ${sourceDir}`;
170519
168917
  if (isJson) {
@@ -170523,7 +168921,7 @@ var importCommand3 = defineCommand({
170523
168921
  }
170524
168922
  process.exit(1);
170525
168923
  }
170526
- const files = readdirSync43(sourceDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md").map((f2) => join155(sourceDir, f2));
168924
+ const files = readdirSync43(sourceDir).filter((f2) => f2.endsWith(".md") && f2 !== "MEMORY.md").map((f2) => join149(sourceDir, f2));
170527
168925
  const importedHashes = isDryRun ? /* @__PURE__ */ new Set() : loadImportHashes(stateFile);
170528
168926
  const stats2 = { total: files.length, imported: 0, skipped: 0, errors: 0 };
170529
168927
  const importedEntries = [];
@@ -170538,7 +168936,7 @@ var importCommand3 = defineCommand({
170538
168936
  for (const filePath of files) {
170539
168937
  const fileName = filePath.split("/").pop() ?? filePath;
170540
168938
  try {
170541
- const raw = readFileSync113(filePath, "utf-8");
168939
+ const raw = readFileSync112(filePath, "utf-8");
170542
168940
  if (!raw.trim()) {
170543
168941
  stats2.skipped++;
170544
168942
  skippedEntries.push({ file: fileName, reason: "empty file" });
@@ -173180,8 +171578,8 @@ var projectsScanCommand = defineCommand({
173180
171578
  const autoRegister = !!args["auto-register"];
173181
171579
  const includeExisting = !!args["include-existing"];
173182
171580
  const maxDepth = Math.max(1, Math.min(parseInt(args["max-depth"], 10), 20));
173183
- const { homedir: homedir17 } = await import("node:os");
173184
- const home = homedir17();
171581
+ const { homedir: homedir15 } = await import("node:os");
171582
+ const home = homedir15();
173185
171583
  const defaultRoots = [path12.join(home, "code"), path12.join(home, "projects"), "/mnt/projects"];
173186
171584
  const rawRoots = typeof args.roots === "string" && args.roots.trim().length > 0 ? args.roots.split(",").map((r) => r.trim()).filter((r) => r.length > 0).map((r) => r.startsWith("~") ? path12.join(home, r.slice(1)) : path12.resolve(r)) : defaultRoots;
173187
171585
  const { existsSync: existsSync143, readdirSync: readdirSync44, statSync: statSync22 } = await import("node:fs");
@@ -173915,8 +172313,8 @@ var diffCommand = defineCommand({
173915
172313
  }
173916
172314
  try {
173917
172315
  const { execFile: execFileNode } = await import("node:child_process");
173918
- const { promisify: promisify10 } = await import("node:util");
173919
- const execFileAsync7 = promisify10(execFileNode);
172316
+ const { promisify: promisify9 } = await import("node:util");
172317
+ const execFileAsync7 = promisify9(execFileNode);
173920
172318
  const resolveSha = async (ref) => {
173921
172319
  try {
173922
172320
  const { stdout } = await execFileAsync7("git", ["rev-parse", "--short", ref], {
@@ -177445,18 +175843,18 @@ var schemaCommand = defineCommand({
177445
175843
  // packages/cleo/src/cli/commands/self-update.ts
177446
175844
  init_src();
177447
175845
  init_internal();
177448
- import { execFile as execFile9 } from "node:child_process";
177449
- import { readFile as readFile34 } from "node:fs/promises";
177450
- import { join as join156 } from "node:path";
175846
+ import { execFile as execFile8 } from "node:child_process";
175847
+ import { readFile as readFile32 } from "node:fs/promises";
175848
+ import { join as join150 } from "node:path";
177451
175849
  import * as readline2 from "node:readline";
177452
- import { promisify as promisify9 } from "node:util";
175850
+ import { promisify as promisify8 } from "node:util";
177453
175851
  init_renderers();
177454
- var execAsync = promisify9(execFile9);
175852
+ var execAsync = promisify8(execFile8);
177455
175853
  var GITHUB_REPO = BUILD_CONFIG.repository.fullName;
177456
175854
  async function getCurrentVersion() {
177457
175855
  const cleoHome = getCleoHome();
177458
175856
  try {
177459
- const content = await readFile34(join156(cleoHome, "VERSION"), "utf-8");
175857
+ const content = await readFile32(join150(cleoHome, "VERSION"), "utf-8");
177460
175858
  return (content.split("\n")[0] ?? "unknown").trim();
177461
175859
  } catch {
177462
175860
  return "unknown";
@@ -177509,8 +175907,8 @@ async function writeRuntimeVersionMetadata(mode, source, version2) {
177509
175907
  `installed=${(/* @__PURE__ */ new Date()).toISOString()}`
177510
175908
  ];
177511
175909
  await import("node:fs/promises").then(
177512
- ({ writeFile: writeFile19, mkdir: mkdir29 }) => mkdir29(cleoHome, { recursive: true }).then(
177513
- () => writeFile19(join156(cleoHome, "VERSION"), `${lines.join("\n")}
175910
+ ({ writeFile: writeFile17, mkdir: mkdir25 }) => mkdir25(cleoHome, { recursive: true }).then(
175911
+ () => writeFile17(join150(cleoHome, "VERSION"), `${lines.join("\n")}
177514
175912
  `, "utf-8")
177515
175913
  )
177516
175914
  );
@@ -177911,12 +176309,18 @@ async function runPostUpdateDiagnostics(opts) {
177911
176309
  }
177912
176310
 
177913
176311
  // packages/cleo/src/cli/commands/sentient.ts
177914
- import { join as join157 } from "node:path";
176312
+ import { join as join151 } from "node:path";
177915
176313
  import { cwd as processCwd } from "node:process";
177916
- init_daemon();
177917
- init_propose_tick();
177918
- init_state3();
177919
- init_tick();
176314
+ import {
176315
+ getSentientDaemonStatus,
176316
+ resumeSentientDaemon,
176317
+ SENTIENT_STATE_FILE,
176318
+ spawnSentientDaemon,
176319
+ stopSentientDaemon
176320
+ } from "@cleocode/core/sentient/daemon.js";
176321
+ import { safeRunProposeTick } from "@cleocode/core/sentient/propose-tick.js";
176322
+ import { patchSentientState, readSentientState } from "@cleocode/core/sentient/state.js";
176323
+ import { safeRunTick } from "@cleocode/core/sentient/tick.js";
177920
176324
  var projectArgs = {
177921
176325
  project: {
177922
176326
  type: "string",
@@ -177976,7 +176380,7 @@ var startSub = defineCommand({
177976
176380
  return;
177977
176381
  }
177978
176382
  if (dryRun) {
177979
- const statePath2 = join157(projectRoot, SENTIENT_STATE_FILE);
176383
+ const statePath2 = join151(projectRoot, SENTIENT_STATE_FILE);
177980
176384
  const outcome = await safeRunTick({ projectRoot, statePath: statePath2, dryRun: true });
177981
176385
  emitSuccess(
177982
176386
  { dryRun: true, outcome },
@@ -178110,7 +176514,7 @@ var tickSub = defineCommand({
178110
176514
  const jsonMode = args.json === true;
178111
176515
  const dryRun = args["dry-run"] === true;
178112
176516
  try {
178113
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176517
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178114
176518
  const outcome = await safeRunTick({ projectRoot, statePath, dryRun });
178115
176519
  emitSuccess(
178116
176520
  { outcome, dryRun },
@@ -178179,7 +176583,7 @@ var proposeAcceptSub = defineCommand({
178179
176583
  return;
178180
176584
  }
178181
176585
  await db.update(tasks2).set({ status: "pending", updatedAt: now2 }).where(eq22(tasks2.id, id)).run();
178182
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176586
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178183
176587
  const state = await readSentientState(statePath);
178184
176588
  await patchSentientState(statePath, {
178185
176589
  tier2Stats: {
@@ -178231,7 +176635,7 @@ var proposeRejectSub = defineCommand({
178231
176635
  return;
178232
176636
  }
178233
176637
  await db.update(tasks2).set({ status: "cancelled", cancellationReason: reason, cancelledAt: now2, updatedAt: now2 }).where(eq22(tasks2.id, id)).run();
178234
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176638
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178235
176639
  const state = await readSentientState(statePath);
178236
176640
  await patchSentientState(statePath, {
178237
176641
  tier2Stats: {
@@ -178276,7 +176680,7 @@ var proposeRunSub = defineCommand({
178276
176680
  const projectRoot = resolveProjectRoot2(args.project);
178277
176681
  const jsonMode = args.json === true;
178278
176682
  try {
178279
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176683
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178280
176684
  const outcome = await safeRunProposeTick({ projectRoot, statePath });
178281
176685
  emitSuccess(
178282
176686
  { outcome },
@@ -178296,7 +176700,7 @@ var proposeEnableSub = defineCommand({
178296
176700
  const projectRoot = resolveProjectRoot2(args.project);
178297
176701
  const jsonMode = args.json === true;
178298
176702
  try {
178299
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176703
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178300
176704
  const updated = await patchSentientState(statePath, { tier2Enabled: true });
178301
176705
  emitSuccess({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals enabled");
178302
176706
  } catch (err2) {
@@ -178315,7 +176719,7 @@ var proposeDisableSub = defineCommand({
178315
176719
  const projectRoot = resolveProjectRoot2(args.project);
178316
176720
  const jsonMode = args.json === true;
178317
176721
  try {
178318
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176722
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178319
176723
  const updated = await patchSentientState(statePath, { tier2Enabled: false });
178320
176724
  emitSuccess({ tier2Enabled: updated.tier2Enabled }, jsonMode, "Tier-2 proposals disabled");
178321
176725
  } catch (err2) {
@@ -178346,7 +176750,7 @@ var proposeSub = defineCommand({
178346
176750
  const projectRoot = resolveProjectRoot2(args.project);
178347
176751
  const jsonMode = args.json === true;
178348
176752
  try {
178349
- const statePath = join157(projectRoot, SENTIENT_STATE_FILE);
176753
+ const statePath = join151(projectRoot, SENTIENT_STATE_FILE);
178350
176754
  const state = await readSentientState(statePath);
178351
176755
  emitSuccess(
178352
176756
  {
@@ -179313,8 +177717,8 @@ var exportCommand6 = defineCommand({
179313
177717
  handleRawError(response, { command: "snapshot", operation: "admin.export" });
179314
177718
  const data = response.data;
179315
177719
  if (data?.outputPath) {
179316
- const { readFile: readFile36 } = await import("node:fs/promises");
179317
- const content = await readFile36(data.outputPath, "utf-8");
177720
+ const { readFile: readFile34 } = await import("node:fs/promises");
177721
+ const content = await readFile34(data.outputPath, "utf-8");
179318
177722
  process.stdout.write(content);
179319
177723
  if (!content.endsWith("\n")) process.stdout.write("\n");
179320
177724
  }
@@ -179845,10 +178249,10 @@ var reconcileCommand2 = defineCommand({
179845
178249
  }
179846
178250
  },
179847
178251
  async run({ args }) {
179848
- const { readFileSync: readFileSync116 } = await import("node:fs");
178252
+ const { readFileSync: readFileSync115 } = await import("node:fs");
179849
178253
  let externalTasks;
179850
178254
  try {
179851
- externalTasks = JSON.parse(readFileSync116(args.file, "utf8"));
178255
+ externalTasks = JSON.parse(readFileSync115(args.file, "utf8"));
179852
178256
  } catch (err2) {
179853
178257
  const message = err2 instanceof Error ? err2.message : String(err2);
179854
178258
  console.error(`Failed to read or parse external tasks file: ${message}`);
@@ -180001,13 +178405,13 @@ var testingCommand = defineCommand({
180001
178405
 
180002
178406
  // packages/cleo/src/cli/commands/token.ts
180003
178407
  init_internal();
180004
- import { readFileSync as readFileSync114 } from "node:fs";
178408
+ import { readFileSync as readFileSync113 } from "node:fs";
180005
178409
  init_cli();
180006
178410
  init_renderers();
180007
178411
  function readPayload(args, textKey, fileKey) {
180008
178412
  const text3 = args[textKey];
180009
178413
  const file2 = args[fileKey];
180010
- if (file2) return readFileSync114(file2, "utf-8");
178414
+ if (file2) return readFileSync113(file2, "utf-8");
180011
178415
  return text3;
180012
178416
  }
180013
178417
  var filterArgs = {
@@ -180189,183 +178593,13 @@ var tokenCommand = defineCommand({
180189
178593
 
180190
178594
  // packages/cleo/src/cli/commands/transcript.ts
180191
178595
  init_src3();
180192
- import { homedir as homedir16 } from "node:os";
180193
- import { join as join159 } from "node:path";
180194
-
180195
- // packages/cleo/src/gc/transcript.ts
180196
- import { lstat as lstat3, readdir as readdir7, stat as stat8 } from "node:fs/promises";
180197
- import { homedir as homedir15 } from "node:os";
180198
- import { join as join158 } from "node:path";
180199
- var HOT_MAX_MS = 24 * 60 * 60 * 1e3;
180200
- var WARM_MAX_MS = 7 * 24 * 60 * 60 * 1e3;
180201
- function classifyTranscriptTier(ageMs) {
180202
- if (ageMs < HOT_MAX_MS) return "hot";
180203
- if (ageMs < WARM_MAX_MS) return "warm";
180204
- return "cold";
180205
- }
180206
- function parseSessionId(filename) {
180207
- return filename.replace(/\.jsonl$/, "");
180208
- }
180209
- async function scanTranscripts(projectsDir) {
180210
- const resolvedProjectsDir = projectsDir ?? join158(homedir15(), ".claude", "projects");
180211
- const now2 = Date.now();
180212
- const hot = [];
180213
- const warm = [];
180214
- let totalBytes = 0;
180215
- let slugs;
180216
- try {
180217
- const entries = await readdir7(resolvedProjectsDir, { withFileTypes: true });
180218
- slugs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
180219
- } catch {
180220
- return { totalSessions: 0, hot, warm, totalBytes, projectsDir: resolvedProjectsDir };
180221
- }
180222
- for (const slug of slugs) {
180223
- const slugDir = join158(resolvedProjectsDir, slug);
180224
- let entries;
180225
- try {
180226
- entries = await readdir7(slugDir, { withFileTypes: true });
180227
- } catch {
180228
- continue;
180229
- }
180230
- for (const entry of entries) {
180231
- if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
180232
- const jsonlPath = join158(slugDir, entry.name);
180233
- const sessionId = parseSessionId(entry.name);
180234
- let fileInfo;
180235
- try {
180236
- fileInfo = await stat8(jsonlPath);
180237
- } catch {
180238
- continue;
180239
- }
180240
- const mtimeMs = fileInfo.mtimeMs;
180241
- const ageMs = now2 - mtimeMs;
180242
- const tier = classifyTranscriptTier(ageMs);
180243
- const bytes = fileInfo.size;
180244
- const candidateSessionDir = join158(slugDir, sessionId);
180245
- let sessionDir = null;
180246
- let sessionDirBytes = 0;
180247
- try {
180248
- const dirInfo = await lstat3(candidateSessionDir);
180249
- if (dirInfo.isDirectory()) {
180250
- sessionDir = candidateSessionDir;
180251
- sessionDirBytes = await getPathBytes(candidateSessionDir);
180252
- }
180253
- } catch {
180254
- }
180255
- const info = {
180256
- jsonlPath,
180257
- projectSlug: slug,
180258
- sessionId,
180259
- mtimeMs,
180260
- ageMs,
180261
- tier,
180262
- bytes,
180263
- sessionDir,
180264
- sessionDirBytes
180265
- };
180266
- totalBytes += bytes + sessionDirBytes;
180267
- if (tier === "hot") {
180268
- hot.push(info);
180269
- } else if (tier === "warm") {
180270
- warm.push(info);
180271
- }
180272
- }
180273
- }
180274
- const totalSessions = hot.length + warm.length;
180275
- return { totalSessions, hot, warm, totalBytes, projectsDir: resolvedProjectsDir };
180276
- }
180277
- async function pruneTranscripts(opts) {
180278
- const { olderThanMs, confirm, projectsDir } = opts;
180279
- const dryRun = !confirm;
180280
- const hasApiKey = Boolean(process.env["ANTHROPIC_API_KEY"]);
180281
- const effectiveMaxAgeMs = hasApiKey ? olderThanMs : Math.max(olderThanMs, 30 * 24 * 60 * 60 * 1e3);
180282
- const now2 = Date.now();
180283
- const deletedPaths = [];
180284
- let bytesFreed = 0;
180285
- let pruned = 0;
180286
- const resolvedProjectsDir = projectsDir ?? join158(homedir15(), ".claude", "projects");
180287
- let slugs;
180288
- try {
180289
- const entries = await readdir7(resolvedProjectsDir, { withFileTypes: true });
180290
- slugs = entries.filter((e) => e.isDirectory()).map((e) => e.name);
180291
- } catch {
180292
- return { pruned: 0, bytesFreed: 0, deletedPaths: [], dryRun };
180293
- }
180294
- for (const slug of slugs) {
180295
- const slugDir = join158(resolvedProjectsDir, slug);
180296
- let entries;
180297
- try {
180298
- entries = await readdir7(slugDir, { withFileTypes: true });
180299
- } catch {
180300
- continue;
180301
- }
180302
- for (const entry of entries) {
180303
- if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
180304
- const jsonlPath = join158(slugDir, entry.name);
180305
- let fileInfo;
180306
- try {
180307
- fileInfo = await stat8(jsonlPath);
180308
- } catch {
180309
- continue;
180310
- }
180311
- const ageMs = now2 - fileInfo.mtimeMs;
180312
- if (ageMs <= effectiveMaxAgeMs) continue;
180313
- const sessionId = parseSessionId(entry.name);
180314
- const sessionDir = join158(slugDir, sessionId);
180315
- const jsonlBytes = fileInfo.size;
180316
- let sessionDirBytes = 0;
180317
- try {
180318
- const dirInfo = await lstat3(sessionDir);
180319
- if (dirInfo.isDirectory()) {
180320
- sessionDirBytes = await getPathBytes(sessionDir);
180321
- }
180322
- } catch {
180323
- }
180324
- if (dryRun) {
180325
- deletedPaths.push(jsonlPath);
180326
- if (sessionDirBytes > 0) deletedPaths.push(sessionDir);
180327
- bytesFreed += jsonlBytes + sessionDirBytes;
180328
- pruned++;
180329
- continue;
180330
- }
180331
- try {
180332
- await idempotentRm(jsonlPath);
180333
- deletedPaths.push(jsonlPath);
180334
- bytesFreed += jsonlBytes;
180335
- pruned++;
180336
- } catch {
180337
- continue;
180338
- }
180339
- try {
180340
- const dirInfo = await lstat3(sessionDir);
180341
- if (dirInfo.isDirectory()) {
180342
- await idempotentRm(sessionDir);
180343
- deletedPaths.push(sessionDir);
180344
- bytesFreed += sessionDirBytes;
180345
- }
180346
- } catch {
180347
- }
180348
- }
180349
- }
180350
- return { pruned, bytesFreed, deletedPaths, dryRun };
180351
- }
180352
- function parseDurationMs(duration3) {
180353
- const match = /^(\d+(\.\d+)?)(d|h|m|s)$/.exec(duration3.trim());
180354
- if (!match?.[1] || !match[3]) {
180355
- throw new Error(`Invalid duration format: "${duration3}". Use format like 7d, 24h, 30m, 60s.`);
180356
- }
180357
- const value = parseFloat(match[1]);
180358
- const unit = match[3];
180359
- const multipliers = {
180360
- d: 24 * 60 * 60 * 1e3,
180361
- h: 60 * 60 * 1e3,
180362
- m: 60 * 1e3,
180363
- s: 1e3
180364
- };
180365
- return value * (multipliers[unit] ?? 1e3);
180366
- }
180367
-
180368
- // packages/cleo/src/cli/commands/transcript.ts
178596
+ import { homedir as homedir14 } from "node:os";
178597
+ import { join as join152 } from "node:path";
178598
+ import {
178599
+ parseDurationMs,
178600
+ pruneTranscripts,
178601
+ scanTranscripts
178602
+ } from "@cleocode/core/gc/transcript.js";
180369
178603
  var scanCommand = defineCommand({
180370
178604
  meta: {
180371
178605
  name: "scan",
@@ -180417,7 +178651,7 @@ var scanCommand = defineCommand({
180417
178651
  }
180418
178652
  return;
180419
178653
  }
180420
- const projectsDir = args["projects-dir"] ?? join159(homedir16(), ".claude", "projects");
178654
+ const projectsDir = args["projects-dir"] ?? join152(homedir14(), ".claude", "projects");
180421
178655
  try {
180422
178656
  const result = await scanTranscripts(projectsDir);
180423
178657
  const envelope = {
@@ -180802,7 +179036,7 @@ var pruneCommand = defineCommand({
180802
179036
  process.exit(2);
180803
179037
  return;
180804
179038
  }
180805
- const projectsDir = args["projects-dir"] ?? join159(homedir16(), ".claude", "projects");
179039
+ const projectsDir = args["projects-dir"] ?? join152(homedir14(), ".claude", "projects");
180806
179040
  try {
180807
179041
  const pruneResult = await pruneTranscripts({
180808
179042
  olderThanMs,
@@ -181201,19 +179435,19 @@ var verifyCommand2 = defineCommand({
181201
179435
  // packages/cleo/src/cli/commands/web.ts
181202
179436
  init_src();
181203
179437
  init_src3();
181204
- import { execFileSync as execFileSync18, spawn as spawn6 } from "node:child_process";
181205
- import { mkdir as mkdir28, open, readFile as readFile35, rm as rm5, stat as stat9, writeFile as writeFile18 } from "node:fs/promises";
181206
- import { join as join160 } from "node:path";
179438
+ import { execFileSync as execFileSync18, spawn as spawn3 } from "node:child_process";
179439
+ import { mkdir as mkdir24, open, readFile as readFile33, rm as rm4, stat as stat7, writeFile as writeFile16 } from "node:fs/promises";
179440
+ import { join as join153 } from "node:path";
181207
179441
  init_renderers();
181208
179442
  var DEFAULT_PORT = 3456;
181209
179443
  var DEFAULT_HOST = "127.0.0.1";
181210
179444
  function getWebPaths() {
181211
179445
  const cleoHome = getCleoHome();
181212
179446
  return {
181213
- pidFile: join160(cleoHome, "web-server.pid"),
181214
- configFile: join160(cleoHome, "web-server.json"),
181215
- logDir: join160(cleoHome, "logs"),
181216
- logFile: join160(cleoHome, "logs", "web-server.log")
179447
+ pidFile: join153(cleoHome, "web-server.pid"),
179448
+ configFile: join153(cleoHome, "web-server.json"),
179449
+ logDir: join153(cleoHome, "logs"),
179450
+ logFile: join153(cleoHome, "logs", "web-server.log")
181217
179451
  };
181218
179452
  }
181219
179453
  function isProcessRunning(pid) {
@@ -181227,7 +179461,7 @@ function isProcessRunning(pid) {
181227
179461
  async function getStatus() {
181228
179462
  const { pidFile, configFile } = getWebPaths();
181229
179463
  try {
181230
- const pidStr = (await readFile35(pidFile, "utf-8")).trim();
179464
+ const pidStr = (await readFile33(pidFile, "utf-8")).trim();
181231
179465
  const pid = Number.parseInt(pidStr, 10);
181232
179466
  if (Number.isNaN(pid) || !isProcessRunning(pid)) {
181233
179467
  return { running: false, pid: null, port: null, host: null, url: null };
@@ -181235,7 +179469,7 @@ async function getStatus() {
181235
179469
  let port = DEFAULT_PORT;
181236
179470
  let host = DEFAULT_HOST;
181237
179471
  try {
181238
- const config2 = JSON.parse(await readFile35(configFile, "utf-8"));
179472
+ const config2 = JSON.parse(await readFile33(configFile, "utf-8"));
181239
179473
  port = config2.port ?? DEFAULT_PORT;
181240
179474
  host = config2.host ?? DEFAULT_HOST;
181241
179475
  } catch {
@@ -181252,9 +179486,9 @@ async function startWebServer(port, host) {
181252
179486
  throw new CleoError(1 /* GENERAL_ERROR */, `Server already running (PID: ${status.pid})`);
181253
179487
  }
181254
179488
  const projectRoot = process.env["CLEO_ROOT"] ?? process.cwd();
181255
- const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join160(projectRoot, "packages", "studio", "build");
181256
- await mkdir28(logDir, { recursive: true });
181257
- await writeFile18(
179489
+ const studioDir = process.env["CLEO_STUDIO_DIR"] ?? join153(projectRoot, "packages", "studio", "build");
179490
+ await mkdir24(logDir, { recursive: true });
179491
+ await writeFile16(
181258
179492
  configFile,
181259
179493
  JSON.stringify({
181260
179494
  port,
@@ -181262,9 +179496,9 @@ async function startWebServer(port, host) {
181262
179496
  startedAt: (/* @__PURE__ */ new Date()).toISOString()
181263
179497
  })
181264
179498
  );
181265
- const webIndexPath = join160(studioDir, "index.js");
179499
+ const webIndexPath = join153(studioDir, "index.js");
181266
179500
  try {
181267
- await stat9(webIndexPath);
179501
+ await stat7(webIndexPath);
181268
179502
  } catch {
181269
179503
  try {
181270
179504
  execFileSync18("pnpm", ["--filter", "@cleocode/studio", "run", "build"], {
@@ -181280,7 +179514,7 @@ Logs: ${logFile}`
181280
179514
  }
181281
179515
  }
181282
179516
  const logFileHandle = await open(logFile, "a");
181283
- const serverProcess = spawn6("node", [webIndexPath], {
179517
+ const serverProcess = spawn3("node", [webIndexPath], {
181284
179518
  cwd: studioDir,
181285
179519
  env: {
181286
179520
  ...process.env,
@@ -181294,10 +179528,10 @@ Logs: ${logFile}`
181294
179528
  });
181295
179529
  serverProcess.unref();
181296
179530
  const pidFileTmp = `${pidFile}.tmp`;
181297
- await writeFile18(pidFileTmp, String(serverProcess.pid));
181298
- await rm5(pidFile, { force: true });
181299
- await writeFile18(pidFile, String(serverProcess.pid));
181300
- await rm5(pidFileTmp, { force: true });
179531
+ await writeFile16(pidFileTmp, String(serverProcess.pid));
179532
+ await rm4(pidFile, { force: true });
179533
+ await writeFile16(pidFile, String(serverProcess.pid));
179534
+ await rm4(pidFileTmp, { force: true });
181301
179535
  await logFileHandle.close();
181302
179536
  const maxAttempts = 30;
181303
179537
  let started = false;
@@ -181317,7 +179551,7 @@ Logs: ${logFile}`
181317
179551
  process.kill(serverProcess.pid);
181318
179552
  } catch {
181319
179553
  }
181320
- await rm5(pidFile, { force: true });
179554
+ await rm4(pidFile, { force: true });
181321
179555
  throw new CleoError(1 /* GENERAL_ERROR */, "Server failed to start within 15 seconds");
181322
179556
  }
181323
179557
  cliOutput(
@@ -181364,13 +179598,13 @@ var stopCommand5 = defineCommand({
181364
179598
  const { pidFile } = getWebPaths();
181365
179599
  const status = await getStatus();
181366
179600
  if (!status.running || !status.pid) {
181367
- await rm5(pidFile, { force: true });
179601
+ await rm4(pidFile, { force: true });
181368
179602
  cliOutput({ running: false }, { command: "web", message: "Server is not running" });
181369
179603
  return;
181370
179604
  }
181371
179605
  try {
181372
179606
  if (process.platform === "win32") {
181373
- spawn6("taskkill", ["/PID", String(status.pid), "/T"], { stdio: "ignore" });
179607
+ spawn3("taskkill", ["/PID", String(status.pid), "/T"], { stdio: "ignore" });
181374
179608
  } else {
181375
179609
  process.kill(status.pid, "SIGTERM");
181376
179610
  }
@@ -181383,14 +179617,14 @@ var stopCommand5 = defineCommand({
181383
179617
  if (isProcessRunning(status.pid)) {
181384
179618
  try {
181385
179619
  if (process.platform === "win32") {
181386
- spawn6("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
179620
+ spawn3("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
181387
179621
  } else {
181388
179622
  process.kill(status.pid, "SIGKILL");
181389
179623
  }
181390
179624
  } catch {
181391
179625
  }
181392
179626
  }
181393
- await rm5(pidFile, { force: true });
179627
+ await rm4(pidFile, { force: true });
181394
179628
  cliOutput({ stopped: true }, { command: "web", message: "CLEO Web UI stopped" });
181395
179629
  } catch (err2) {
181396
179630
  if (err2 instanceof CleoError) {
@@ -181422,7 +179656,7 @@ var restartCommand = defineCommand({
181422
179656
  if (status.running && status.pid) {
181423
179657
  try {
181424
179658
  if (process.platform === "win32") {
181425
- spawn6("taskkill", ["/PID", String(status.pid), "/T"], { stdio: "ignore" });
179659
+ spawn3("taskkill", ["/PID", String(status.pid), "/T"], { stdio: "ignore" });
181426
179660
  } else {
181427
179661
  process.kill(status.pid, "SIGTERM");
181428
179662
  }
@@ -181435,14 +179669,14 @@ var restartCommand = defineCommand({
181435
179669
  if (isProcessRunning(status.pid)) {
181436
179670
  try {
181437
179671
  if (process.platform === "win32") {
181438
- spawn6("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
179672
+ spawn3("taskkill", ["/PID", String(status.pid), "/F", "/T"], { stdio: "ignore" });
181439
179673
  } else {
181440
179674
  process.kill(status.pid, "SIGKILL");
181441
179675
  }
181442
179676
  } catch {
181443
179677
  }
181444
179678
  }
181445
- await rm5(pidFile, { force: true });
179679
+ await rm4(pidFile, { force: true });
181446
179680
  }
181447
179681
  await startWebServer(Number.parseInt(args.port, 10), args.host);
181448
179682
  } catch (err2) {
@@ -181481,14 +179715,14 @@ var openCommand = defineCommand({
181481
179715
  );
181482
179716
  }
181483
179717
  const url2 = status.url;
181484
- const platform6 = process.platform;
179718
+ const platform5 = process.platform;
181485
179719
  try {
181486
- if (platform6 === "linux") {
181487
- spawn6("xdg-open", [url2], { detached: true, stdio: "ignore" }).unref();
181488
- } else if (platform6 === "darwin") {
181489
- spawn6("open", [url2], { detached: true, stdio: "ignore" }).unref();
181490
- } else if (platform6 === "win32") {
181491
- spawn6("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore" }).unref();
179720
+ if (platform5 === "linux") {
179721
+ spawn3("xdg-open", [url2], { detached: true, stdio: "ignore" }).unref();
179722
+ } else if (platform5 === "darwin") {
179723
+ spawn3("open", [url2], { detached: true, stdio: "ignore" }).unref();
179724
+ } else if (platform5 === "win32") {
179725
+ spawn3("cmd", ["/c", "start", "", url2], { detached: true, stdio: "ignore" }).unref();
181492
179726
  }
181493
179727
  } catch {
181494
179728
  }
@@ -181520,8 +179754,8 @@ var webCommand = defineCommand({
181520
179754
 
181521
179755
  // packages/cleo/src/cli/index.ts
181522
179756
  function getPackageVersion() {
181523
- const pkgPath = join161(dirname42(fileURLToPath13(import.meta.url)), "../../package.json");
181524
- const pkg = JSON.parse(readFileSync115(pkgPath, "utf-8"));
179757
+ const pkgPath = join154(dirname40(fileURLToPath11(import.meta.url)), "../../package.json");
179758
+ const pkg = JSON.parse(readFileSync114(pkgPath, "utf-8"));
181525
179759
  return pkg.version;
181526
179760
  }
181527
179761
  var CLI_VERSION = getPackageVersion();
@@ -181711,8 +179945,8 @@ subCommands["pipeline"] = phaseCommand;
181711
179945
  try {
181712
179946
  validateGlobalSalt();
181713
179947
  const salt = getGlobalSalt();
181714
- const fingerprint2 = salt.subarray(0, 4).toString("hex");
181715
- _startupLog.info({ fingerprint: fingerprint2 }, "global-salt fingerprint");
179948
+ const fingerprint = salt.subarray(0, 4).toString("hex");
179949
+ _startupLog.info({ fingerprint }, "global-salt fingerprint");
181716
179950
  } catch (err2) {
181717
179951
  _startupLog.warn(
181718
179952
  { error: err2 instanceof Error ? err2.message : String(err2) },