@enruana/claude-orka 0.7.3 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/cli.js +119 -31
  2. package/dist/electron/main/main.js +232 -27
  3. package/dist/electron/main/main.js.map +1 -1
  4. package/dist/electron/preload/preload.js +31 -22
  5. package/dist/electron/preload/preload.js.map +1 -1
  6. package/dist/electron/renderer/assets/main-C9VElgAd.js +66 -0
  7. package/dist/electron/renderer/index.html +1 -1
  8. package/dist/src/cli/commands/fork.js +1 -1
  9. package/dist/src/cli/commands/fork.js.map +1 -1
  10. package/dist/src/cli/commands/session.d.ts.map +1 -1
  11. package/dist/src/cli/commands/session.js +5 -3
  12. package/dist/src/cli/commands/session.js.map +1 -1
  13. package/dist/src/cli/utils/output.d.ts.map +1 -1
  14. package/dist/src/cli/utils/output.js +13 -10
  15. package/dist/src/cli/utils/output.js.map +1 -1
  16. package/dist/src/core/ClaudeOrka.d.ts +10 -0
  17. package/dist/src/core/ClaudeOrka.d.ts.map +1 -1
  18. package/dist/src/core/ClaudeOrka.js +12 -0
  19. package/dist/src/core/ClaudeOrka.js.map +1 -1
  20. package/dist/src/core/SessionManager.d.ts +10 -0
  21. package/dist/src/core/SessionManager.d.ts.map +1 -1
  22. package/dist/src/core/SessionManager.js +27 -3
  23. package/dist/src/core/SessionManager.js.map +1 -1
  24. package/dist/src/core/StateManager.d.ts +5 -0
  25. package/dist/src/core/StateManager.d.ts.map +1 -1
  26. package/dist/src/core/StateManager.js +49 -0
  27. package/dist/src/core/StateManager.js.map +1 -1
  28. package/dist/src/models/Session.d.ts +9 -0
  29. package/dist/src/models/Session.d.ts.map +1 -1
  30. package/dist/src/utils/tmux.d.ts +1 -1
  31. package/dist/src/utils/tmux.d.ts.map +1 -1
  32. package/dist/src/utils/tmux.js +9 -5
  33. package/dist/src/utils/tmux.js.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/electron/renderer/assets/main-CcTQJJH_.js +0 -66
package/dist/cli.js CHANGED
@@ -3,12 +3,13 @@
3
3
  // src/cli/index.ts
4
4
  import { Command } from "commander";
5
5
  import { readFileSync } from "fs";
6
- import { fileURLToPath as fileURLToPath3 } from "url";
6
+ import { fileURLToPath as fileURLToPath4 } from "url";
7
7
  import { dirname as dirname3, join as join2 } from "path";
8
8
 
9
9
  // src/core/StateManager.ts
10
10
  import path4 from "path";
11
11
  import fs4 from "fs-extra";
12
+ import { fileURLToPath as fileURLToPath2 } from "url";
12
13
 
13
14
  // src/utils/tmux.ts
14
15
  import execa from "execa";
@@ -101,7 +102,7 @@ var TmuxCommands = class {
101
102
  logger.debug(`Creating tmux session: ${name} at ${projectPath}`);
102
103
  await execa("tmux", ["new-session", "-d", "-s", name, "-c", projectPath]);
103
104
  logger.info(`Tmux session created: ${name}`);
104
- await this.applyOrkaTheme(name);
105
+ await this.applyOrkaTheme(name, projectPath);
105
106
  } catch (error) {
106
107
  throw new TmuxError(
107
108
  `Failed to create tmux session: ${name}`,
@@ -113,14 +114,19 @@ var TmuxCommands = class {
113
114
  /**
114
115
  * Apply Claude-Orka custom tmux theme to a session
115
116
  */
116
- static async applyOrkaTheme(sessionName) {
117
+ static async applyOrkaTheme(sessionName, projectPath) {
117
118
  try {
118
119
  const possiblePaths = [
120
+ // PRIORITY 1: Project-local theme (copied during orka init)
121
+ ...projectPath ? [path2.join(projectPath, ".claude-orka", ".tmux.orka.conf")] : [],
122
+ // PRIORITY 2: Current working directory project
123
+ path2.join(process.cwd(), ".claude-orka", ".tmux.orka.conf"),
124
+ // FALLBACK: Package installation paths
119
125
  // When installed globally via npm (dist/ -> package root)
120
126
  path2.join(__dirname, "../.tmux.orka.conf"),
121
127
  // When running from source (src/utils/ -> package root)
122
128
  path2.join(__dirname, "../../.tmux.orka.conf"),
123
- // When running from current working directory
129
+ // When running from current working directory (legacy)
124
130
  path2.join(process.cwd(), ".tmux.orka.conf")
125
131
  ];
126
132
  logger.debug(`Looking for Orka theme config. __dirname: ${__dirname}`);
@@ -502,6 +508,8 @@ async function listClaudeSessions(projectPath, limit = 20) {
502
508
  }
503
509
 
504
510
  // src/core/StateManager.ts
511
+ var __filename2 = fileURLToPath2(import.meta.url);
512
+ var __dirname2 = path4.dirname(__filename2);
505
513
  var StateManager = class {
506
514
  projectPath;
507
515
  orkaDir;
@@ -518,6 +526,7 @@ var StateManager = class {
518
526
  async initialize() {
519
527
  logger.debug("Initializing StateManager");
520
528
  await this.ensureDirectories();
529
+ await this.copyThemeConfig();
521
530
  if (!await fs4.pathExists(this.statePath)) {
522
531
  logger.info("Creating initial state.json");
523
532
  const initialState = {
@@ -530,6 +539,46 @@ var StateManager = class {
530
539
  }
531
540
  logger.info("StateManager initialized");
532
541
  }
542
+ /**
543
+ * Copy tmux theme config to project's .claude-orka directory
544
+ * This ensures the theme persists across system restarts
545
+ */
546
+ async copyThemeConfig() {
547
+ const destPath = path4.join(this.orkaDir, ".tmux.orka.conf");
548
+ if (await fs4.pathExists(destPath)) {
549
+ logger.debug("Theme config already exists in project");
550
+ return;
551
+ }
552
+ const possibleSources = [
553
+ // When running from dist/ (bundled CLI)
554
+ path4.join(__dirname2, "../.tmux.orka.conf"),
555
+ // When running from src/core/ (development)
556
+ path4.join(__dirname2, "../../.tmux.orka.conf"),
557
+ // Fallback: look in node_modules (when used as dependency)
558
+ path4.join(__dirname2, "../../../.tmux.orka.conf")
559
+ ];
560
+ logger.debug(`Looking for tmux theme. __dirname: ${__dirname2}`);
561
+ let sourcePath = null;
562
+ for (const p of possibleSources) {
563
+ const resolved = path4.resolve(p);
564
+ const exists = await fs4.pathExists(resolved);
565
+ logger.debug(` Checking ${resolved}: ${exists ? "EXISTS" : "not found"}`);
566
+ if (exists) {
567
+ sourcePath = resolved;
568
+ break;
569
+ }
570
+ }
571
+ if (!sourcePath) {
572
+ logger.warn("Could not find tmux theme source file to copy");
573
+ return;
574
+ }
575
+ try {
576
+ await fs4.copy(sourcePath, destPath);
577
+ logger.info(`Tmux theme copied to ${destPath}`);
578
+ } catch (error) {
579
+ logger.warn(`Failed to copy tmux theme: ${error.message}`);
580
+ }
581
+ }
533
582
  /**
534
583
  * Create directory structure
535
584
  */
@@ -810,13 +859,13 @@ var StateManager = class {
810
859
  // src/core/SessionManager.ts
811
860
  import { v4 as uuidv4 } from "uuid";
812
861
  import path5 from "path";
813
- import { fileURLToPath as fileURLToPath2 } from "url";
862
+ import { fileURLToPath as fileURLToPath3 } from "url";
814
863
  import { dirname as dirname2 } from "path";
815
864
  import fs5 from "fs-extra";
816
865
  import { spawn } from "child_process";
817
866
  import execa2 from "execa";
818
- var __filename2 = fileURLToPath2(import.meta.url);
819
- var __dirname2 = dirname2(__filename2);
867
+ var __filename3 = fileURLToPath3(import.meta.url);
868
+ var __dirname3 = dirname2(__filename3);
820
869
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
821
870
  var SessionManager = class {
822
871
  stateManager;
@@ -925,7 +974,7 @@ var SessionManager = class {
925
974
  }
926
975
  logger.info(`Tmux session not found, recovering from Claude session...`);
927
976
  await TmuxCommands.createSession(tmuxSessionId, this.projectPath);
928
- await TmuxCommands.applyOrkaTheme(tmuxSessionId);
977
+ await TmuxCommands.applyOrkaTheme(tmuxSessionId, this.projectPath);
929
978
  if (openTerminal) {
930
979
  await TmuxCommands.openTerminalWindow(tmuxSessionId);
931
980
  }
@@ -942,7 +991,8 @@ var SessionManager = class {
942
991
  session.status = "active";
943
992
  session.lastActivity = (/* @__PURE__ */ new Date()).toISOString();
944
993
  await this.stateManager.replaceSession(session);
945
- const forksToRestore = session.forks.filter((f) => f.status !== "merged");
994
+ const forks = session.forks || [];
995
+ const forksToRestore = forks.filter((f) => f.status === "active" || f.status === "saved");
946
996
  if (forksToRestore.length > 0) {
947
997
  logger.info(`Restoring ${forksToRestore.length} fork(s)...`);
948
998
  for (const fork of forksToRestore) {
@@ -1337,6 +1387,27 @@ Analyze the content and help me integrate the changes and learnings from the for
1337
1387
  return await this.generateForkExport(sessionId, forkId);
1338
1388
  }
1339
1389
  // ==========================================
1390
+ // UI METHODS
1391
+ // ==========================================
1392
+ /**
1393
+ * Save node position for UI persistence
1394
+ * @param sessionId Session ID
1395
+ * @param nodeId Node ID ('main' or fork id)
1396
+ * @param position Position {x, y}
1397
+ */
1398
+ async saveNodePosition(sessionId, nodeId, position) {
1399
+ const session = await this.getSession(sessionId);
1400
+ if (!session) {
1401
+ throw new Error(`Session ${sessionId} not found`);
1402
+ }
1403
+ if (!session.nodePositions) {
1404
+ session.nodePositions = {};
1405
+ }
1406
+ session.nodePositions[nodeId] = position;
1407
+ await this.stateManager.replaceSession(session);
1408
+ logger.debug(`Node position saved: ${nodeId} -> (${position.x}, ${position.y})`);
1409
+ }
1410
+ // ==========================================
1340
1411
  // HELPERS PRIVADOS
1341
1412
  // ==========================================
1342
1413
  /**
@@ -1390,11 +1461,11 @@ Analyze the content and help me integrate the changes and learnings from the for
1390
1461
  }
1391
1462
  const possiblePaths = [
1392
1463
  // Via CLI (bundled): dist -> ./electron/main/main.js
1393
- path5.join(__dirname2, "./electron/main/main.js"),
1464
+ path5.join(__dirname3, "./electron/main/main.js"),
1394
1465
  // Via SDK: dist/src/core -> ../../electron/main/main.js
1395
- path5.join(__dirname2, "../../electron/main/main.js"),
1466
+ path5.join(__dirname3, "../../electron/main/main.js"),
1396
1467
  // Development: src/core -> ../../dist/electron/main/main.js
1397
- path5.join(__dirname2, "../../dist/electron/main/main.js")
1468
+ path5.join(__dirname3, "../../dist/electron/main/main.js")
1398
1469
  ];
1399
1470
  let mainPath = null;
1400
1471
  for (const p of possiblePaths) {
@@ -1408,7 +1479,7 @@ Analyze the content and help me integrate the changes and learnings from the for
1408
1479
  if (!mainPath) {
1409
1480
  const resolvedPaths = possiblePaths.map((p) => path5.resolve(p));
1410
1481
  logger.warn(`Electron main.js not found. Tried paths: ${resolvedPaths.join(", ")}`);
1411
- logger.warn(`Current __dirname: ${__dirname2}`);
1482
+ logger.warn(`Current __dirname: ${__dirname3}`);
1412
1483
  logger.warn("Skipping UI launch");
1413
1484
  return;
1414
1485
  }
@@ -1685,6 +1756,18 @@ var ClaudeOrka = class {
1685
1756
  await this.exportAndMerge(sessionId, forkId);
1686
1757
  await this.closeFork(sessionId, forkId);
1687
1758
  }
1759
+ // ==========================================
1760
+ // UI METHODS
1761
+ // ==========================================
1762
+ /**
1763
+ * Save node position for UI persistence
1764
+ * @param sessionId Session ID
1765
+ * @param nodeId Node ID ('main' or fork id)
1766
+ * @param position Position {x, y}
1767
+ */
1768
+ async saveNodePosition(sessionId, nodeId, position) {
1769
+ await this.sessionManager.saveNodePosition(sessionId, nodeId, position);
1770
+ }
1688
1771
  };
1689
1772
 
1690
1773
  // src/cli/utils/output.ts
@@ -1744,16 +1827,17 @@ ${statusEmoji} ${chalk.bold(session.name)}`);
1744
1827
  if (session.status === "active") {
1745
1828
  console.log(` ${chalk.gray("Tmux Session:")} ${session.tmuxSessionId}`);
1746
1829
  }
1747
- if (session.forks.length > 0) {
1748
- console.log(` ${chalk.gray("Forks:")} ${session.forks.length}`);
1830
+ const forks = session.forks || [];
1831
+ if (forks.length > 0) {
1832
+ console.log(` ${chalk.gray("Forks:")} ${forks.length}`);
1749
1833
  console.log(
1750
- ` ${chalk.green("Active:")} ${session.forks.filter((f) => f.status === "active").length}`
1834
+ ` ${chalk.green("Active:")} ${forks.filter((f) => f.status === "active").length}`
1751
1835
  );
1752
1836
  console.log(
1753
- ` ${chalk.yellow("Saved:")} ${session.forks.filter((f) => f.status === "saved").length}`
1837
+ ` ${chalk.yellow("Saved:")} ${forks.filter((f) => f.status === "saved").length}`
1754
1838
  );
1755
1839
  console.log(
1756
- ` ${chalk.blue("Merged:")} ${session.forks.filter((f) => f.status === "merged").length}`
1840
+ ` ${chalk.blue("Merged:")} ${forks.filter((f) => f.status === "merged").length}`
1757
1841
  );
1758
1842
  }
1759
1843
  }
@@ -1801,9 +1885,10 @@ ${statusEmoji} ${chalk.bold(session.name)}`);
1801
1885
  });
1802
1886
  for (const session of sessions) {
1803
1887
  const statusColor = session.status === "active" ? chalk.green : chalk.yellow;
1804
- const activeForks = session.forks.filter((f) => f.status === "active").length;
1805
- const savedForks = session.forks.filter((f) => f.status === "saved").length;
1806
- const mergedForks = session.forks.filter((f) => f.status === "merged").length;
1888
+ const forks = session.forks || [];
1889
+ const activeForks = forks.filter((f) => f.status === "active").length;
1890
+ const savedForks = forks.filter((f) => f.status === "saved").length;
1891
+ const mergedForks = forks.filter((f) => f.status === "merged").length;
1807
1892
  table.push([
1808
1893
  session.name,
1809
1894
  statusColor(session.status),
@@ -1881,10 +1966,11 @@ ${statusEmoji} ${chalk.bold(session.name)}`);
1881
1966
  console.log(
1882
1967
  ` ${chalk.green("Active:")} ${session.activeForks} | ${chalk.yellow("Saved:")} ${session.savedForks} | ${chalk.blue("Merged:")} ${session.mergedForks}`
1883
1968
  );
1884
- if (session.forks.length > 0) {
1969
+ const sessionForks = session.forks || [];
1970
+ if (sessionForks.length > 0) {
1885
1971
  console.log(`
1886
1972
  ${chalk.bold("Forks:")}`);
1887
- for (const fork of session.forks) {
1973
+ for (const fork of sessionForks) {
1888
1974
  const forkEmoji = fork.status === "active" ? "\u2713" : fork.status === "merged" ? "\u{1F500}" : "\u{1F4BE}";
1889
1975
  const forkColor = fork.status === "active" ? chalk.green : fork.status === "merged" ? chalk.blue : chalk.yellow;
1890
1976
  console.log(`
@@ -2014,7 +2100,8 @@ async function selectSession(sessions) {
2014
2100
  sessions.forEach((session, index2) => {
2015
2101
  const statusColor = session.status === "active" ? chalk3.green : chalk3.yellow;
2016
2102
  const status = statusColor(`[${session.status}]`);
2017
- const forkCount = session.forks.length > 0 ? chalk3.gray(` (${session.forks.length} forks)`) : "";
2103
+ const forks = session.forks || [];
2104
+ const forkCount = forks.length > 0 ? chalk3.gray(` (${forks.length} forks)`) : "";
2018
2105
  console.log(` ${chalk3.bold(index2 + 1)}. ${session.name || "Unnamed"} ${status}${forkCount}`);
2019
2106
  console.log(chalk3.gray(` ID: ${session.id.slice(0, 8)}...`));
2020
2107
  console.log();
@@ -2163,9 +2250,10 @@ function sessionCommand(program2) {
2163
2250
  Output.json(session2);
2164
2251
  } else {
2165
2252
  Output.session(session2);
2166
- if (session2.forks.length > 0) {
2253
+ const sessionForks = session2.forks || [];
2254
+ if (sessionForks.length > 0) {
2167
2255
  Output.section("\n\u{1F33F} Forks:");
2168
- for (const fork of session2.forks) {
2256
+ for (const fork of sessionForks) {
2169
2257
  Output.fork(fork);
2170
2258
  }
2171
2259
  }
@@ -2287,7 +2375,7 @@ function forkCommand(program2) {
2287
2375
  Output.error(`Session not found: ${sessionId}`);
2288
2376
  process.exit(1);
2289
2377
  }
2290
- let forks = session.forks;
2378
+ let forks = session.forks || [];
2291
2379
  if (options.status) {
2292
2380
  forks = forks.filter((f) => f.status === options.status);
2293
2381
  }
@@ -2846,13 +2934,13 @@ async function checkClaudeCLI() {
2846
2934
  }
2847
2935
 
2848
2936
  // src/cli/index.ts
2849
- var __filename3 = fileURLToPath3(import.meta.url);
2850
- var __dirname3 = dirname3(__filename3);
2851
- var packageJsonPath = join2(__dirname3, "../package.json");
2937
+ var __filename4 = fileURLToPath4(import.meta.url);
2938
+ var __dirname4 = dirname3(__filename4);
2939
+ var packageJsonPath = join2(__dirname4, "../package.json");
2852
2940
  try {
2853
2941
  readFileSync(packageJsonPath, "utf-8");
2854
2942
  } catch {
2855
- packageJsonPath = join2(__dirname3, "../../package.json");
2943
+ packageJsonPath = join2(__dirname4, "../../package.json");
2856
2944
  }
2857
2945
  var packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
2858
2946
  var version = packageJson.version;