@vladimir-ks/aigile 0.2.1 → 0.2.3

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.
@@ -893,7 +893,7 @@ var init_connection = __esm({
893
893
  import { Command as Command22 } from "commander";
894
894
 
895
895
  // src/index.ts
896
- var VERSION = "0.2.1";
896
+ var VERSION = true ? "0.2.3" : "0.0.0-dev";
897
897
 
898
898
  // src/bin/aigile.ts
899
899
  init_connection();
@@ -1825,8 +1825,14 @@ function detectGitContext(targetPath) {
1825
1825
  relativePath
1826
1826
  };
1827
1827
  }
1828
+ var VALID_PROFILES = ["full-repo", "subrepo", "module"];
1828
1829
  function determineProfile(context, options, opts) {
1829
1830
  if (options.profile) {
1831
+ if (!VALID_PROFILES.includes(options.profile)) {
1832
+ throw new Error(
1833
+ `Invalid profile "${options.profile}". Valid profiles: ${VALID_PROFILES.join(", ")}`
1834
+ );
1835
+ }
1830
1836
  return options.profile;
1831
1837
  }
1832
1838
  if (context.isSubmodule) {
@@ -1859,6 +1865,8 @@ function determineDbMode(profile, context, options) {
1859
1865
  case "module":
1860
1866
  const parentDbPath = findParentDb(context);
1861
1867
  return { mode: "shared", path: parentDbPath };
1868
+ default:
1869
+ return { mode: "local", path: ".aigile/aigile.db" };
1862
1870
  }
1863
1871
  }
1864
1872
  function findParentDb(context) {
@@ -2482,13 +2490,45 @@ epicCommand.command("transition").argument("<key>", "Epic key").argument("<statu
2482
2490
  run(`UPDATE epics SET status = ?, updated_at = datetime('now') WHERE key = ?`, [status, key]);
2483
2491
  success(`Epic "${key}" transitioned from "${epic.status}" to "${status}".`, opts);
2484
2492
  });
2485
- epicCommand.command("delete").alias("rm").argument("<key>", "Epic key").option("--force", "Delete without confirmation").description("Delete epic").action((key) => {
2493
+ epicCommand.command("delete").alias("rm").argument("<key>", "Epic key").option("--force", "Delete and orphan child stories").option("--cascade", "Delete with all child stories and their tasks").description("Delete epic").action((key, options) => {
2486
2494
  const opts = getOutputOptions(epicCommand);
2487
2495
  const epic = queryOne("SELECT id FROM epics WHERE key = ?", [key]);
2488
2496
  if (!epic) {
2489
2497
  error(`Epic "${key}" not found.`, opts);
2490
2498
  process.exit(1);
2491
2499
  }
2500
+ const childCount = queryOne(
2501
+ "SELECT COUNT(*) as count FROM user_stories WHERE epic_id = ?",
2502
+ [epic.id]
2503
+ );
2504
+ if (childCount && childCount.count > 0) {
2505
+ if (!options.force && !options.cascade) {
2506
+ error(
2507
+ `Cannot delete epic "${key}": has ${childCount.count} child story(s). Use --force to orphan children, or --cascade to delete them.`,
2508
+ opts
2509
+ );
2510
+ process.exit(1);
2511
+ }
2512
+ if (options.cascade) {
2513
+ const taskCount = queryOne(
2514
+ `SELECT COUNT(*) as count FROM tasks WHERE story_id IN
2515
+ (SELECT id FROM user_stories WHERE epic_id = ?)`,
2516
+ [epic.id]
2517
+ );
2518
+ warning(
2519
+ `Deleting ${childCount.count} child story(s) and ${taskCount?.count || 0} task(s)`,
2520
+ opts
2521
+ );
2522
+ run(
2523
+ `DELETE FROM tasks WHERE story_id IN (SELECT id FROM user_stories WHERE epic_id = ?)`,
2524
+ [epic.id]
2525
+ );
2526
+ run("DELETE FROM user_stories WHERE epic_id = ?", [epic.id]);
2527
+ } else {
2528
+ warning(`Orphaning ${childCount.count} child story(s)`, opts);
2529
+ run("UPDATE user_stories SET epic_id = NULL WHERE epic_id = ?", [epic.id]);
2530
+ }
2531
+ }
2492
2532
  run("DELETE FROM epics WHERE key = ?", [key]);
2493
2533
  success(`Epic "${key}" deleted.`, opts);
2494
2534
  });
@@ -2664,13 +2704,33 @@ storyCommand.command("update").argument("<key>", "Story key").option("-s, --summ
2664
2704
  run(`UPDATE user_stories SET ${updates.join(", ")} WHERE key = ?`, params);
2665
2705
  success(`Story "${key}" updated.`, opts);
2666
2706
  });
2667
- storyCommand.command("delete").alias("rm").argument("<key>", "Story key").option("--force", "Delete without confirmation").description("Delete story").action((key) => {
2707
+ storyCommand.command("delete").alias("rm").argument("<key>", "Story key").option("--force", "Delete and orphan child tasks").option("--cascade", "Delete with all child tasks").description("Delete story").action((key, options) => {
2668
2708
  const opts = getOutputOptions(storyCommand);
2669
2709
  const story = queryOne("SELECT id FROM user_stories WHERE key = ?", [key]);
2670
2710
  if (!story) {
2671
2711
  error(`Story "${key}" not found.`, opts);
2672
2712
  process.exit(1);
2673
2713
  }
2714
+ const childCount = queryOne(
2715
+ "SELECT COUNT(*) as count FROM tasks WHERE story_id = ?",
2716
+ [story.id]
2717
+ );
2718
+ if (childCount && childCount.count > 0) {
2719
+ if (!options.force && !options.cascade) {
2720
+ error(
2721
+ `Cannot delete story "${key}": has ${childCount.count} child task(s). Use --force to orphan children, or --cascade to delete them.`,
2722
+ opts
2723
+ );
2724
+ process.exit(1);
2725
+ }
2726
+ if (options.cascade) {
2727
+ warning(`Deleting ${childCount.count} child task(s)`, opts);
2728
+ run("DELETE FROM tasks WHERE story_id = ?", [story.id]);
2729
+ } else {
2730
+ warning(`Orphaning ${childCount.count} child task(s)`, opts);
2731
+ run("UPDATE tasks SET story_id = NULL WHERE story_id = ?", [story.id]);
2732
+ }
2733
+ }
2674
2734
  run("DELETE FROM user_stories WHERE key = ?", [key]);
2675
2735
  success(`Story "${key}" deleted.`, opts);
2676
2736
  });