@vladimir-ks/aigile 0.2.7 → 0.2.8

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.
@@ -1246,7 +1246,7 @@ var init_connection = __esm({
1246
1246
  import { Command as Command23 } from "commander";
1247
1247
 
1248
1248
  // src/index.ts
1249
- var VERSION = true ? "0.2.7" : "0.0.0-dev";
1249
+ var VERSION = true ? "0.2.8" : "0.0.0-dev";
1250
1250
 
1251
1251
  // src/bin/aigile.ts
1252
1252
  init_connection();
@@ -1254,7 +1254,7 @@ init_connection();
1254
1254
  // src/commands/init.ts
1255
1255
  import { Command } from "commander";
1256
1256
  import { existsSync as existsSync4, mkdirSync as mkdirSync4, appendFileSync, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
1257
- import { resolve, join as join4, relative, basename as basename2 } from "path";
1257
+ import { resolve as resolve2, join as join4, relative, basename as basename2 } from "path";
1258
1258
 
1259
1259
  // src/utils/git.ts
1260
1260
  import { execSync } from "child_process";
@@ -1413,7 +1413,7 @@ function header(title, opts = {}) {
1413
1413
 
1414
1414
  // src/services/template-loader.ts
1415
1415
  import { readdirSync, statSync, readFileSync as readFileSync3, existsSync as existsSync3, mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
1416
- import { join as join3, dirname as dirname2 } from "path";
1416
+ import { join as join3, dirname as dirname2, resolve, sep } from "path";
1417
1417
  import { fileURLToPath } from "url";
1418
1418
  var __filename = fileURLToPath(import.meta.url);
1419
1419
  var __dirname = dirname2(__filename);
@@ -1465,8 +1465,17 @@ function writeTemplates(targetDir, templates) {
1465
1465
  let written = 0;
1466
1466
  let skipped = 0;
1467
1467
  const errors = [];
1468
+ const resolvedTargetDir = resolve(targetDir);
1468
1469
  for (const template of templates) {
1469
1470
  const fullPath = join3(targetDir, template.relativePath);
1471
+ const resolvedFullPath = resolve(fullPath);
1472
+ if (!resolvedFullPath.startsWith(resolvedTargetDir + sep) && resolvedFullPath !== resolvedTargetDir) {
1473
+ errors.push({
1474
+ path: template.relativePath,
1475
+ error: "Path traversal detected - file path escapes target directory"
1476
+ });
1477
+ continue;
1478
+ }
1470
1479
  if (existsSync3(fullPath)) {
1471
1480
  skipped++;
1472
1481
  continue;
@@ -1494,7 +1503,7 @@ var initCommand = new Command("init").description("Initialize AIGILE in current
1494
1503
  "Module kind: library, service, ui, cli, other (for module profile)"
1495
1504
  ).option("--skip-templates", "Skip template file creation").option("-f, --force", "Reinitialize existing project").action(async (pathArg, options) => {
1496
1505
  const opts = getOutputOptions(initCommand);
1497
- const targetPath = resolve(pathArg ?? process.cwd());
1506
+ const targetPath = resolve2(pathArg ?? process.cwd());
1498
1507
  try {
1499
1508
  await initProject(targetPath, options, opts);
1500
1509
  } catch (err) {
@@ -7796,11 +7805,11 @@ uxJourneyCommand.command("delete").alias("rm").argument("<key>", "Journey key").
7796
7805
  init_connection();
7797
7806
  import { Command as Command19 } from "commander";
7798
7807
  import { existsSync as existsSync7 } from "fs";
7799
- import { resolve as resolve3, relative as relative4 } from "path";
7808
+ import { resolve as resolve4, relative as relative4 } from "path";
7800
7809
 
7801
7810
  // src/services/dependency-graph.ts
7802
7811
  init_connection();
7803
- import { resolve as resolve2, relative as relative3, dirname as dirname3 } from "path";
7812
+ import { resolve as resolve3, relative as relative3, dirname as dirname3 } from "path";
7804
7813
  function buildDependencyGraph(projectId) {
7805
7814
  const docs = queryAll(
7806
7815
  `SELECT id, path, meta_status, last_approved_at, last_modified_at, meta_dependencies
@@ -7835,7 +7844,7 @@ function buildDependencyGraph(projectId) {
7835
7844
  function resolveDocPath(fromPath, relativePath) {
7836
7845
  if (relativePath.startsWith("./") || relativePath.startsWith("../")) {
7837
7846
  const fromDir = dirname3(fromPath);
7838
- const resolved = resolve2(fromDir, relativePath);
7847
+ const resolved = resolve3(fromDir, relativePath);
7839
7848
  return relative3(".", resolved);
7840
7849
  }
7841
7850
  return relativePath;
@@ -8139,7 +8148,7 @@ async function approveDocument(cwd, filePath, options, opts) {
8139
8148
  if (!config?.project?.key) {
8140
8149
  throw new Error("AIGILE not initialized in this directory");
8141
8150
  }
8142
- const absolutePath = resolve3(cwd, filePath);
8151
+ const absolutePath = resolve4(cwd, filePath);
8143
8152
  if (!existsSync7(absolutePath)) {
8144
8153
  throw new Error(`File not found: ${filePath}`);
8145
8154
  }
@@ -8173,7 +8182,7 @@ async function approveDocument(cwd, filePath, options, opts) {
8173
8182
  blank();
8174
8183
  info(`Cascade approving ${cascadeResult.affectedDocs.length} dependents...`, opts);
8175
8184
  for (const depPath of cascadeResult.affectedDocs) {
8176
- const depAbsolute = resolve3(cwd, depPath);
8185
+ const depAbsolute = resolve4(cwd, depPath);
8177
8186
  const depContent = readFileSync8(depAbsolute, "utf-8");
8178
8187
  const updatedDep = updateFrontmatterContent(depContent, {
8179
8188
  status: "APPROVED",
@@ -8200,7 +8209,7 @@ async function acknowledgeDocument(cwd, filePath, opts) {
8200
8209
  if (!config?.project?.key) {
8201
8210
  throw new Error("AIGILE not initialized in this directory");
8202
8211
  }
8203
- const absolutePath = resolve3(cwd, filePath);
8212
+ const absolutePath = resolve4(cwd, filePath);
8204
8213
  if (!existsSync7(absolutePath)) {
8205
8214
  throw new Error(`File not found: ${filePath}`);
8206
8215
  }
@@ -8223,7 +8232,7 @@ async function markReady(cwd, filePath, opts) {
8223
8232
  if (!config?.project?.key) {
8224
8233
  throw new Error("AIGILE not initialized in this directory");
8225
8234
  }
8226
- const absolutePath = resolve3(cwd, filePath);
8235
+ const absolutePath = resolve4(cwd, filePath);
8227
8236
  if (!existsSync7(absolutePath)) {
8228
8237
  throw new Error(`File not found: ${filePath}`);
8229
8238
  }
@@ -8251,7 +8260,7 @@ async function markException(cwd, filePath, reason, opts) {
8251
8260
  if (!config?.project?.key) {
8252
8261
  throw new Error("AIGILE not initialized in this directory");
8253
8262
  }
8254
- const absolutePath = resolve3(cwd, filePath);
8263
+ const absolutePath = resolve4(cwd, filePath);
8255
8264
  if (!existsSync7(absolutePath)) {
8256
8265
  throw new Error(`File not found: ${filePath}`);
8257
8266
  }
@@ -8277,7 +8286,7 @@ async function markRefactoring(cwd, filePath, opts) {
8277
8286
  if (!config?.project?.key) {
8278
8287
  throw new Error("AIGILE not initialized in this directory");
8279
8288
  }
8280
- const absolutePath = resolve3(cwd, filePath);
8289
+ const absolutePath = resolve4(cwd, filePath);
8281
8290
  if (!existsSync7(absolutePath)) {
8282
8291
  throw new Error(`File not found: ${filePath}`);
8283
8292
  }
@@ -8302,7 +8311,7 @@ async function archiveDocument(cwd, filePath, opts) {
8302
8311
  if (!config?.project?.key) {
8303
8312
  throw new Error("AIGILE not initialized in this directory");
8304
8313
  }
8305
- const absolutePath = resolve3(cwd, filePath);
8314
+ const absolutePath = resolve4(cwd, filePath);
8306
8315
  if (!existsSync7(absolutePath)) {
8307
8316
  throw new Error(`File not found: ${filePath}`);
8308
8317
  }
@@ -8512,10 +8521,19 @@ var docCommand = new Command19("doc").description("Document integrity and status
8512
8521
  // src/commands/daemon.ts
8513
8522
  init_connection();
8514
8523
  import { Command as Command20 } from "commander";
8515
- import { existsSync as existsSync11, writeFileSync as writeFileSync7, unlinkSync, readFileSync as readFileSync11, mkdirSync as mkdirSync5, statSync as statSync5, renameSync, readdirSync as readdirSync3 } from "fs";
8524
+ import {
8525
+ existsSync as existsSync11,
8526
+ writeFileSync as writeFileSync7,
8527
+ unlinkSync,
8528
+ readFileSync as readFileSync11,
8529
+ mkdirSync as mkdirSync5,
8530
+ statSync as statSync5,
8531
+ renameSync,
8532
+ readdirSync as readdirSync3
8533
+ } from "fs";
8516
8534
  import { join as join12, dirname as dirname4 } from "path";
8517
8535
  import { homedir as homedir2, platform } from "os";
8518
- import { spawn, execSync as execSync2 } from "child_process";
8536
+ import { spawn, spawnSync, execSync as execSync2 } from "child_process";
8519
8537
  init_config();
8520
8538
 
8521
8539
  // src/services/daemon-manager.ts
@@ -8535,7 +8553,7 @@ init_config();
8535
8553
  // src/services/document-status-transitions.ts
8536
8554
  init_connection();
8537
8555
  import { writeFileSync as writeFileSync6, readFileSync as readFileSync9, existsSync as existsSync8 } from "fs";
8538
- import { resolve as resolve4 } from "path";
8556
+ import { resolve as resolve5 } from "path";
8539
8557
  import { createHash as createHash2 } from "crypto";
8540
8558
  async function handleDocumentEdit(projectId, docPath, absolutePath) {
8541
8559
  if (!existsSync8(absolutePath)) {
@@ -8633,7 +8651,7 @@ async function onFileChanged(projectId, projectPath, relativeDocPath) {
8633
8651
  if (!isAigileDoc(relativeDocPath)) {
8634
8652
  return;
8635
8653
  }
8636
- const absolutePath = resolve4(projectPath, relativeDocPath);
8654
+ const absolutePath = resolve5(projectPath, relativeDocPath);
8637
8655
  const transitioned = await handleDocumentEdit(
8638
8656
  projectId,
8639
8657
  relativeDocPath,
@@ -9441,7 +9459,11 @@ function cleanupOldLogs(logDir) {
9441
9459
  function generateLaunchAgentPlist() {
9442
9460
  const paths = getDaemonPaths();
9443
9461
  const nodePath = process.execPath;
9444
- const aigilePath = join12(dirname4(dirname4(import.meta.url.replace("file://", ""))), "bin", "aigile.js");
9462
+ const aigilePath = join12(
9463
+ dirname4(dirname4(import.meta.url.replace("file://", ""))),
9464
+ "bin",
9465
+ "aigile.js"
9466
+ );
9445
9467
  return `<?xml version="1.0" encoding="UTF-8"?>
9446
9468
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
9447
9469
  <plist version="1.0">
@@ -9476,7 +9498,11 @@ function generateLaunchAgentPlist() {
9476
9498
  function generateSystemdService() {
9477
9499
  const paths = getDaemonPaths();
9478
9500
  const nodePath = process.execPath;
9479
- const aigilePath = join12(dirname4(dirname4(import.meta.url.replace("file://", ""))), "bin", "aigile.js");
9501
+ const aigilePath = join12(
9502
+ dirname4(dirname4(import.meta.url.replace("file://", ""))),
9503
+ "bin",
9504
+ "aigile.js"
9505
+ );
9480
9506
  return `[Unit]
9481
9507
  Description=AIGILE File Watcher Daemon
9482
9508
  After=network.target
@@ -9495,7 +9521,9 @@ StandardError=append:${paths.logFile}
9495
9521
  [Install]
9496
9522
  WantedBy=default.target`;
9497
9523
  }
9498
- daemonCommand.command("install").description("Install daemon to start automatically on system boot (watches ALL registered projects)").action(() => {
9524
+ daemonCommand.command("install").description(
9525
+ "Install daemon to start automatically on system boot (watches ALL registered projects)"
9526
+ ).action(() => {
9499
9527
  const opts = getOutputOptions(daemonCommand);
9500
9528
  const paths = getDaemonPaths();
9501
9529
  if (PLATFORM === "darwin") {
@@ -9660,12 +9688,15 @@ daemonCommand.command("status").description("Show daemon status for ALL register
9660
9688
  let totalFiles = { allow: 0, unknown: 0, total: 0 };
9661
9689
  for (const project of projects) {
9662
9690
  const valid = existsSync11(project.path) && existsSync11(join12(project.path, ".aigile"));
9663
- const counts = queryAll(`
9691
+ const counts = queryAll(
9692
+ `
9664
9693
  SELECT COALESCE(monitoring_category, 'unknown') as monitoring_category, COUNT(*) as count
9665
9694
  FROM documents
9666
9695
  WHERE project_id = ? AND status != 'deleted'
9667
9696
  GROUP BY monitoring_category
9668
- `, [project.id]);
9697
+ `,
9698
+ [project.id]
9699
+ );
9669
9700
  let allow = 0;
9670
9701
  let unknown = 0;
9671
9702
  for (const row of counts) {
@@ -9689,28 +9720,32 @@ daemonCommand.command("status").description("Show daemon status for ALL register
9689
9720
  }
9690
9721
  const validCount = projectStats.filter((p) => p.valid).length;
9691
9722
  if (opts.json) {
9692
- console.log(JSON.stringify({
9693
- success: true,
9694
- data: {
9695
- running: status.running,
9696
- pid: status.pid ?? null,
9697
- platform: PLATFORM,
9698
- installed: PLATFORM === "darwin" ? paths.plist && existsSync11(paths.plist) : PLATFORM === "linux" ? paths.service && existsSync11(paths.service) : false,
9699
- projectCount: projects.length,
9700
- validProjectCount: validCount,
9701
- projects: projectStats,
9702
- totalFiles,
9703
- paths: {
9704
- database: getDbPath(),
9705
- pidFile: paths.pidFile,
9706
- logFile: paths.logFile
9723
+ console.log(
9724
+ JSON.stringify({
9725
+ success: true,
9726
+ data: {
9727
+ running: status.running,
9728
+ pid: status.pid ?? null,
9729
+ platform: PLATFORM,
9730
+ installed: PLATFORM === "darwin" ? paths.plist && existsSync11(paths.plist) : PLATFORM === "linux" ? paths.service && existsSync11(paths.service) : false,
9731
+ projectCount: projects.length,
9732
+ validProjectCount: validCount,
9733
+ projects: projectStats,
9734
+ totalFiles,
9735
+ paths: {
9736
+ database: getDbPath(),
9737
+ pidFile: paths.pidFile,
9738
+ logFile: paths.logFile
9739
+ }
9707
9740
  }
9708
- }
9709
- }));
9741
+ })
9742
+ );
9710
9743
  return;
9711
9744
  }
9712
9745
  console.log("\n\u{1F4CA} Daemon Status\n");
9713
- console.log(`\u251C\u2500\u2500 Running: ${status.running ? "\u2705 Yes" : "\u274C No"}${status.pid ? ` (PID: ${status.pid})` : ""}`);
9746
+ console.log(
9747
+ `\u251C\u2500\u2500 Running: ${status.running ? "\u2705 Yes" : "\u274C No"}${status.pid ? ` (PID: ${status.pid})` : ""}`
9748
+ );
9714
9749
  console.log(`\u251C\u2500\u2500 Platform: ${PLATFORM}`);
9715
9750
  const installed = PLATFORM === "darwin" ? paths.plist && existsSync11(paths.plist) : PLATFORM === "linux" ? paths.service && existsSync11(paths.service) : false;
9716
9751
  console.log(`\u251C\u2500\u2500 Installed: ${installed ? "\u2705 Yes" : "\u274C No"}`);
@@ -9733,7 +9768,9 @@ daemonCommand.command("status").description("Show daemon status for ALL register
9733
9768
  console.log(` \u2514\u2500\u2500 Log File: ${paths.logFile}`);
9734
9769
  console.log("");
9735
9770
  if (projectStats.some((p) => !p.valid)) {
9736
- console.log('\u26A0\uFE0F Some projects have invalid paths. Run "aigile project cleanup" to remove them.\n');
9771
+ console.log(
9772
+ '\u26A0\uFE0F Some projects have invalid paths. Run "aigile project cleanup" to remove them.\n'
9773
+ );
9737
9774
  }
9738
9775
  });
9739
9776
  function getRelativeTime(isoDate) {
@@ -9782,25 +9819,35 @@ daemonCommand.command("run").option("--skip-resync", "Skip initial resync on sta
9782
9819
  });
9783
9820
  rotateLogIfNeeded();
9784
9821
  writeFileSync7(paths.pidFile, String(process.pid));
9785
- console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Starting AIGILE daemon for all registered projects...`);
9786
- console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] PID: ${process.pid}, Node: ${process.version}, Platform: ${platform()}`);
9822
+ console.log(
9823
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] Starting AIGILE daemon for all registered projects...`
9824
+ );
9825
+ console.log(
9826
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] PID: ${process.pid}, Node: ${process.version}, Platform: ${platform()}`
9827
+ );
9787
9828
  const manager = getDaemonManager();
9788
9829
  if (!options.skipResync) {
9789
9830
  console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Performing initial resync for all projects...`);
9790
9831
  try {
9791
9832
  const results = await manager.resyncAll();
9792
9833
  const projectCount = Object.keys(results).length;
9793
- console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Resync complete: ${projectCount} projects synced`);
9834
+ console.log(
9835
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] Resync complete: ${projectCount} projects synced`
9836
+ );
9794
9837
  } catch (err) {
9795
9838
  console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] Resync warning: ${err}`);
9796
9839
  }
9797
9840
  }
9798
9841
  manager.on("sync", (event) => {
9799
9842
  const categoryStr = event.category ? ` [${event.category}]` : "";
9800
- console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] [${event.project}] Synced: ${event.type} ${event.path}${categoryStr}`);
9843
+ console.log(
9844
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] [${event.project}] Synced: ${event.type} ${event.path}${categoryStr}`
9845
+ );
9801
9846
  });
9802
9847
  manager.on("syncError", ({ project, event, error: err }) => {
9803
- console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] [${project}] Sync error: ${event.type} ${event.path} - ${err}`);
9848
+ console.error(
9849
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] [${project}] Sync error: ${event.type} ${event.path} - ${err}`
9850
+ );
9804
9851
  });
9805
9852
  manager.on("watcherError", ({ project, error: err }) => {
9806
9853
  console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] [${project}] Watcher error: ${err}`);
@@ -9811,7 +9858,9 @@ daemonCommand.command("run").option("--skip-resync", "Skip initial resync on sta
9811
9858
  isShuttingDown = true;
9812
9859
  console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Shutting down...`);
9813
9860
  const forceExitTimeout = setTimeout(() => {
9814
- console.error(`[${(/* @__PURE__ */ new Date()).toISOString()}] Shutdown timeout (${SHUTDOWN_TIMEOUT_MS}ms) - forcing exit`);
9861
+ console.error(
9862
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] Shutdown timeout (${SHUTDOWN_TIMEOUT_MS}ms) - forcing exit`
9863
+ );
9815
9864
  if (existsSync11(paths.pidFile)) {
9816
9865
  try {
9817
9866
  unlinkSync(paths.pidFile);
@@ -9834,15 +9883,20 @@ daemonCommand.command("run").option("--skip-resync", "Skip initial resync on sta
9834
9883
  };
9835
9884
  process.on("SIGTERM", shutdown);
9836
9885
  process.on("SIGINT", shutdown);
9837
- const logRotationInterval = setInterval(() => {
9838
- rotateLogIfNeeded();
9839
- }, 60 * 60 * 1e3);
9886
+ const logRotationInterval = setInterval(
9887
+ () => {
9888
+ rotateLogIfNeeded();
9889
+ },
9890
+ 60 * 60 * 1e3
9891
+ );
9840
9892
  process.on("exit", () => {
9841
9893
  clearInterval(logRotationInterval);
9842
9894
  });
9843
9895
  try {
9844
9896
  const status = await manager.start();
9845
- console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] Daemon started - watching ${status.watchingCount} projects`);
9897
+ console.log(
9898
+ `[${(/* @__PURE__ */ new Date()).toISOString()}] Daemon started - watching ${status.watchingCount} projects`
9899
+ );
9846
9900
  for (const p of status.projects) {
9847
9901
  if (p.watching) {
9848
9902
  console.log(`[${(/* @__PURE__ */ new Date()).toISOString()}] \u2713 ${p.key}: ${p.path}`);
@@ -9863,6 +9917,11 @@ daemonCommand.command("logs").option("-n, --lines <number>", "Number of lines to
9863
9917
  info("No log file found. Daemon may not have run yet.", opts);
9864
9918
  return;
9865
9919
  }
9920
+ const lines = parseInt(options.lines, 10);
9921
+ if (isNaN(lines) || lines < 1 || lines > 1e4) {
9922
+ error("Invalid lines parameter. Must be a number between 1 and 10000.", opts);
9923
+ return;
9924
+ }
9866
9925
  if (options.follow) {
9867
9926
  const tail = spawn("tail", ["-f", paths.logFile], {
9868
9927
  stdio: "inherit"
@@ -9873,8 +9932,14 @@ daemonCommand.command("logs").option("-n, --lines <number>", "Number of lines to
9873
9932
  });
9874
9933
  } else {
9875
9934
  try {
9876
- const output = execSync2(`tail -n ${options.lines} "${paths.logFile}"`, { encoding: "utf-8" });
9877
- console.log(output);
9935
+ const result = spawnSync("tail", ["-n", lines.toString(), paths.logFile], {
9936
+ encoding: "utf-8"
9937
+ });
9938
+ if (result.status === 0 && result.stdout) {
9939
+ console.log(result.stdout);
9940
+ } else {
9941
+ error("Failed to read log file", opts);
9942
+ }
9878
9943
  } catch {
9879
9944
  error("Failed to read log file", opts);
9880
9945
  }
@@ -9892,13 +9957,15 @@ daemonCommand.command("resync").option("--project <key>", "Resync only a specifi
9892
9957
  process.exit(1);
9893
9958
  }
9894
9959
  if (opts.json) {
9895
- console.log(JSON.stringify({
9896
- success: true,
9897
- data: {
9898
- project: options.project,
9899
- ...result
9900
- }
9901
- }));
9960
+ console.log(
9961
+ JSON.stringify({
9962
+ success: true,
9963
+ data: {
9964
+ project: options.project,
9965
+ ...result
9966
+ }
9967
+ })
9968
+ );
9902
9969
  } else {
9903
9970
  success(`Resync complete for ${options.project}:`, opts);
9904
9971
  console.log(` Allow: ${result.allow}`);
@@ -9917,13 +9984,15 @@ daemonCommand.command("resync").option("--project <key>", "Resync only a specifi
9917
9984
  const results = await manager.resyncAll();
9918
9985
  const projectKeys = Object.keys(results);
9919
9986
  if (opts.json) {
9920
- console.log(JSON.stringify({
9921
- success: true,
9922
- data: {
9923
- projectCount: projectKeys.length,
9924
- projects: results
9925
- }
9926
- }));
9987
+ console.log(
9988
+ JSON.stringify({
9989
+ success: true,
9990
+ data: {
9991
+ projectCount: projectKeys.length,
9992
+ projects: results
9993
+ }
9994
+ })
9995
+ );
9927
9996
  } else {
9928
9997
  success(`Resync complete: ${projectKeys.length} projects`, opts);
9929
9998
  for (const [key, result] of Object.entries(results)) {
@@ -9947,29 +10016,36 @@ daemonCommand.command("review").option("--list", "Just list unknown files withou
9947
10016
  error("Could not load project config.", opts);
9948
10017
  process.exit(1);
9949
10018
  }
9950
- const project = queryOne("SELECT id FROM projects WHERE key = ?", [config.project.key]);
10019
+ const project = queryOne("SELECT id FROM projects WHERE key = ?", [
10020
+ config.project.key
10021
+ ]);
9951
10022
  if (!project) {
9952
10023
  error(`Project "${config.project.key}" not found in database.`, opts);
9953
10024
  process.exit(1);
9954
10025
  }
9955
- const unknownFiles = queryAll(`
10026
+ const unknownFiles = queryAll(
10027
+ `
9956
10028
  SELECT id, path, extension, size_bytes, updated_at
9957
10029
  FROM documents
9958
10030
  WHERE project_id = ? AND monitoring_category = 'unknown' AND status != 'deleted'
9959
10031
  ORDER BY path
9960
- `, [project.id]);
10032
+ `,
10033
+ [project.id]
10034
+ );
9961
10035
  if (unknownFiles.length === 0) {
9962
10036
  success("No unknown files to review! All files are classified.", opts);
9963
10037
  return;
9964
10038
  }
9965
10039
  if (opts.json) {
9966
- console.log(JSON.stringify({
9967
- success: true,
9968
- data: {
9969
- count: unknownFiles.length,
9970
- files: unknownFiles
9971
- }
9972
- }));
10040
+ console.log(
10041
+ JSON.stringify({
10042
+ success: true,
10043
+ data: {
10044
+ count: unknownFiles.length,
10045
+ files: unknownFiles
10046
+ }
10047
+ })
10048
+ );
9973
10049
  return;
9974
10050
  }
9975
10051
  if (options.list) {
@@ -9991,14 +10067,18 @@ daemonCommand.command("review").option("--list", "Just list unknown files withou
9991
10067
  ],
9992
10068
  opts
9993
10069
  );
9994
- console.log('\nUse "aigile daemon allow <pattern>" or "aigile daemon deny <pattern>" to classify files.');
10070
+ console.log(
10071
+ '\nUse "aigile daemon allow <pattern>" or "aigile daemon deny <pattern>" to classify files.'
10072
+ );
9995
10073
  return;
9996
10074
  }
9997
10075
  console.log(`
9998
10076
  \u{1F4CB} Unknown Files (${unknownFiles.length} total)
9999
10077
  `);
10000
10078
  console.log('Run "aigile daemon review --list" to see all files.');
10001
- console.log('Use "aigile daemon allow <pattern>" or "aigile daemon deny <pattern>" to classify.\n');
10079
+ console.log(
10080
+ 'Use "aigile daemon allow <pattern>" or "aigile daemon deny <pattern>" to classify.\n'
10081
+ );
10002
10082
  const sample = unknownFiles.slice(0, 10);
10003
10083
  for (const file of sample) {
10004
10084
  console.log(` ${file.path} (.${file.extension || "no ext"})`);
@@ -10936,7 +11016,7 @@ init_connection();
10936
11016
  init_connection();
10937
11017
  import { Command as Command22 } from "commander";
10938
11018
  import { glob as glob2 } from "glob";
10939
- import { relative as relative7, resolve as resolve5 } from "path";
11019
+ import { relative as relative7, resolve as resolve6 } from "path";
10940
11020
  init_config();
10941
11021
  function safeParseArray(json) {
10942
11022
  if (!json) return [];
@@ -10983,7 +11063,7 @@ chunkCommand.command("create").argument("<id>", "Chunk ID (e.g., chunk-001)").op
10983
11063
  if (options.pattern) {
10984
11064
  for (const pattern of options.pattern) {
10985
11065
  const matches = await glob2(pattern, { cwd: projectRoot, nodir: true });
10986
- assignedFiles.push(...matches.map((f) => relative7(projectRoot, resolve5(projectRoot, f))));
11066
+ assignedFiles.push(...matches.map((f) => relative7(projectRoot, resolve6(projectRoot, f))));
10987
11067
  }
10988
11068
  }
10989
11069
  if (options.assign) {