@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.
- package/dist/cli.js +119 -31
- package/dist/electron/main/main.js +232 -27
- package/dist/electron/main/main.js.map +1 -1
- package/dist/electron/preload/preload.js +31 -22
- package/dist/electron/preload/preload.js.map +1 -1
- package/dist/electron/renderer/assets/main-C9VElgAd.js +66 -0
- package/dist/electron/renderer/index.html +1 -1
- package/dist/src/cli/commands/fork.js +1 -1
- package/dist/src/cli/commands/fork.js.map +1 -1
- package/dist/src/cli/commands/session.d.ts.map +1 -1
- package/dist/src/cli/commands/session.js +5 -3
- package/dist/src/cli/commands/session.js.map +1 -1
- package/dist/src/cli/utils/output.d.ts.map +1 -1
- package/dist/src/cli/utils/output.js +13 -10
- package/dist/src/cli/utils/output.js.map +1 -1
- package/dist/src/core/ClaudeOrka.d.ts +10 -0
- package/dist/src/core/ClaudeOrka.d.ts.map +1 -1
- package/dist/src/core/ClaudeOrka.js +12 -0
- package/dist/src/core/ClaudeOrka.js.map +1 -1
- package/dist/src/core/SessionManager.d.ts +10 -0
- package/dist/src/core/SessionManager.d.ts.map +1 -1
- package/dist/src/core/SessionManager.js +27 -3
- package/dist/src/core/SessionManager.js.map +1 -1
- package/dist/src/core/StateManager.d.ts +5 -0
- package/dist/src/core/StateManager.d.ts.map +1 -1
- package/dist/src/core/StateManager.js +49 -0
- package/dist/src/core/StateManager.js.map +1 -1
- package/dist/src/models/Session.d.ts +9 -0
- package/dist/src/models/Session.d.ts.map +1 -1
- package/dist/src/utils/tmux.d.ts +1 -1
- package/dist/src/utils/tmux.d.ts.map +1 -1
- package/dist/src/utils/tmux.js +9 -5
- package/dist/src/utils/tmux.js.map +1 -1
- package/package.json +1 -1
- 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
|
|
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
|
|
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
|
|
819
|
-
var
|
|
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
|
|
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(
|
|
1464
|
+
path5.join(__dirname3, "./electron/main/main.js"),
|
|
1394
1465
|
// Via SDK: dist/src/core -> ../../electron/main/main.js
|
|
1395
|
-
path5.join(
|
|
1466
|
+
path5.join(__dirname3, "../../electron/main/main.js"),
|
|
1396
1467
|
// Development: src/core -> ../../dist/electron/main/main.js
|
|
1397
|
-
path5.join(
|
|
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: ${
|
|
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
|
-
|
|
1748
|
-
|
|
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:")} ${
|
|
1834
|
+
` ${chalk.green("Active:")} ${forks.filter((f) => f.status === "active").length}`
|
|
1751
1835
|
);
|
|
1752
1836
|
console.log(
|
|
1753
|
-
` ${chalk.yellow("Saved:")} ${
|
|
1837
|
+
` ${chalk.yellow("Saved:")} ${forks.filter((f) => f.status === "saved").length}`
|
|
1754
1838
|
);
|
|
1755
1839
|
console.log(
|
|
1756
|
-
` ${chalk.blue("Merged:")} ${
|
|
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
|
|
1805
|
-
const
|
|
1806
|
-
const
|
|
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
|
-
|
|
1969
|
+
const sessionForks = session.forks || [];
|
|
1970
|
+
if (sessionForks.length > 0) {
|
|
1885
1971
|
console.log(`
|
|
1886
1972
|
${chalk.bold("Forks:")}`);
|
|
1887
|
-
for (const fork of
|
|
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
|
|
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
|
-
|
|
2253
|
+
const sessionForks = session2.forks || [];
|
|
2254
|
+
if (sessionForks.length > 0) {
|
|
2167
2255
|
Output.section("\n\u{1F33F} Forks:");
|
|
2168
|
-
for (const fork of
|
|
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
|
|
2850
|
-
var
|
|
2851
|
-
var packageJsonPath = join2(
|
|
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(
|
|
2943
|
+
packageJsonPath = join2(__dirname4, "../../package.json");
|
|
2856
2944
|
}
|
|
2857
2945
|
var packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
2858
2946
|
var version = packageJson.version;
|