@askexenow/exe-os 0.8.49 → 0.8.50
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/bin/cli.js +273 -212
- package/dist/bin/update.js +80 -22
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -6096,6 +6096,159 @@ var init_setup_wizard = __esm({
|
|
|
6096
6096
|
}
|
|
6097
6097
|
});
|
|
6098
6098
|
|
|
6099
|
+
// src/lib/update-check.ts
|
|
6100
|
+
import { execSync as execSync3 } from "child_process";
|
|
6101
|
+
import { readFileSync as readFileSync9 } from "fs";
|
|
6102
|
+
import path14 from "path";
|
|
6103
|
+
function getLocalVersion(packageRoot) {
|
|
6104
|
+
const pkgPath = path14.join(packageRoot, "package.json");
|
|
6105
|
+
const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
|
|
6106
|
+
return pkg.version;
|
|
6107
|
+
}
|
|
6108
|
+
function getRemoteVersion() {
|
|
6109
|
+
try {
|
|
6110
|
+
const output = execSync3("npm view @askexenow/exe-os version", {
|
|
6111
|
+
encoding: "utf-8",
|
|
6112
|
+
timeout: 15e3,
|
|
6113
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
6114
|
+
});
|
|
6115
|
+
return output.trim();
|
|
6116
|
+
} catch {
|
|
6117
|
+
return null;
|
|
6118
|
+
}
|
|
6119
|
+
}
|
|
6120
|
+
function checkForUpdate(packageRoot) {
|
|
6121
|
+
const localVersion = getLocalVersion(packageRoot);
|
|
6122
|
+
const remoteVersion = getRemoteVersion();
|
|
6123
|
+
if (!remoteVersion) {
|
|
6124
|
+
return {
|
|
6125
|
+
updateAvailable: false,
|
|
6126
|
+
localVersion,
|
|
6127
|
+
error: "Could not reach npm registry or package not published yet"
|
|
6128
|
+
};
|
|
6129
|
+
}
|
|
6130
|
+
if (remoteVersion === localVersion) {
|
|
6131
|
+
return { updateAvailable: false, localVersion, remoteVersion };
|
|
6132
|
+
}
|
|
6133
|
+
return { updateAvailable: true, localVersion, remoteVersion };
|
|
6134
|
+
}
|
|
6135
|
+
var init_update_check = __esm({
|
|
6136
|
+
"src/lib/update-check.ts"() {
|
|
6137
|
+
"use strict";
|
|
6138
|
+
}
|
|
6139
|
+
});
|
|
6140
|
+
|
|
6141
|
+
// src/bin/update.ts
|
|
6142
|
+
var update_exports = {};
|
|
6143
|
+
__export(update_exports, {
|
|
6144
|
+
checkForUpdate: () => checkForUpdate,
|
|
6145
|
+
getLocalVersion: () => getLocalVersion,
|
|
6146
|
+
getRemoteVersion: () => getRemoteVersion,
|
|
6147
|
+
runUpdate: () => runUpdate
|
|
6148
|
+
});
|
|
6149
|
+
import { execSync as execSync4 } from "child_process";
|
|
6150
|
+
import { createInterface as createInterface3 } from "readline";
|
|
6151
|
+
async function runUpdate(cliArgs) {
|
|
6152
|
+
const args2 = cliArgs ?? process.argv.slice(2);
|
|
6153
|
+
const autoMode = args2.includes("--auto") || args2.includes("-y");
|
|
6154
|
+
const checkOnly = args2.includes("--check");
|
|
6155
|
+
const packageRoot = new URL("../..", import.meta.url).pathname;
|
|
6156
|
+
const result = checkForUpdate(packageRoot);
|
|
6157
|
+
if (result.error) {
|
|
6158
|
+
console.error(`\u26A0\uFE0F ${result.error}`);
|
|
6159
|
+
process.exit(0);
|
|
6160
|
+
}
|
|
6161
|
+
if (checkOnly) {
|
|
6162
|
+
if (result.updateAvailable) {
|
|
6163
|
+
console.log(`Update available: v${result.localVersion} \u2192 v${result.remoteVersion}`);
|
|
6164
|
+
} else {
|
|
6165
|
+
console.log(`\u2705 exe-os is up to date (v${result.localVersion})`);
|
|
6166
|
+
}
|
|
6167
|
+
process.exit(0);
|
|
6168
|
+
}
|
|
6169
|
+
if (!result.updateAvailable) {
|
|
6170
|
+
console.log(`\u2705 exe-os is up to date (v${result.localVersion})`);
|
|
6171
|
+
process.exit(0);
|
|
6172
|
+
}
|
|
6173
|
+
console.log(`
|
|
6174
|
+
\u{1F4E6} Update available: v${result.localVersion} \u2192 v${result.remoteVersion}
|
|
6175
|
+
`);
|
|
6176
|
+
let proceed = autoMode;
|
|
6177
|
+
if (!proceed) {
|
|
6178
|
+
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
6179
|
+
const answer = await new Promise((resolve) => {
|
|
6180
|
+
rl.question("Install update? (Y/n) ", resolve);
|
|
6181
|
+
});
|
|
6182
|
+
rl.close();
|
|
6183
|
+
proceed = answer.toLowerCase() !== "n";
|
|
6184
|
+
}
|
|
6185
|
+
if (!proceed) {
|
|
6186
|
+
console.log("Update skipped.");
|
|
6187
|
+
process.exit(0);
|
|
6188
|
+
}
|
|
6189
|
+
console.log("\n\u{1F9F9} Clearing npm cache...");
|
|
6190
|
+
try {
|
|
6191
|
+
execSync4("npm cache clean --force", { stdio: "pipe" });
|
|
6192
|
+
console.log(" Done");
|
|
6193
|
+
} catch {
|
|
6194
|
+
console.log(" Skipped (non-critical)");
|
|
6195
|
+
}
|
|
6196
|
+
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
6197
|
+
try {
|
|
6198
|
+
execSync4("npm install -g @askexenow/exe-os@latest", {
|
|
6199
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
6200
|
+
timeout: 12e4
|
|
6201
|
+
});
|
|
6202
|
+
} catch (err) {
|
|
6203
|
+
console.error("\n\u274C Update failed.");
|
|
6204
|
+
console.error(" Try manually: npm install -g @askexenow/exe-os@latest");
|
|
6205
|
+
if (err instanceof Error && err.message) {
|
|
6206
|
+
console.error(` Error: ${err.message.split("\n")[0]}`);
|
|
6207
|
+
}
|
|
6208
|
+
process.exit(1);
|
|
6209
|
+
}
|
|
6210
|
+
let newVersion;
|
|
6211
|
+
try {
|
|
6212
|
+
newVersion = getLocalVersion(packageRoot);
|
|
6213
|
+
} catch {
|
|
6214
|
+
try {
|
|
6215
|
+
const out = execSync4("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
|
|
6216
|
+
const match = out.match(/@askexenow\/exe-os@(\S+)/);
|
|
6217
|
+
newVersion = match?.[1] ?? "unknown";
|
|
6218
|
+
} catch {
|
|
6219
|
+
newVersion = "unknown";
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
6222
|
+
const remoteVersion = result.remoteVersion;
|
|
6223
|
+
if (newVersion === remoteVersion) {
|
|
6224
|
+
console.log(`
|
|
6225
|
+
\u2705 Updated to v${newVersion}`);
|
|
6226
|
+
} else if (newVersion !== result.localVersion) {
|
|
6227
|
+
console.log(`
|
|
6228
|
+
\u2705 Updated to v${newVersion} (latest: v${remoteVersion})`);
|
|
6229
|
+
} else {
|
|
6230
|
+
console.log(`
|
|
6231
|
+
\u26A0\uFE0F Version unchanged (v${newVersion}). npm cache may be stale.`);
|
|
6232
|
+
console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
|
|
6233
|
+
}
|
|
6234
|
+
console.log(" Hooks re-wired, daemon restarted automatically.");
|
|
6235
|
+
console.log("\n\u{1F680} Ready. Start your COO session to use the new version.\n");
|
|
6236
|
+
}
|
|
6237
|
+
var init_update = __esm({
|
|
6238
|
+
"src/bin/update.ts"() {
|
|
6239
|
+
"use strict";
|
|
6240
|
+
init_is_main();
|
|
6241
|
+
init_update_check();
|
|
6242
|
+
init_update_check();
|
|
6243
|
+
if (isMainModule(import.meta.url)) {
|
|
6244
|
+
runUpdate().catch((err) => {
|
|
6245
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
6246
|
+
process.exit(1);
|
|
6247
|
+
});
|
|
6248
|
+
}
|
|
6249
|
+
}
|
|
6250
|
+
});
|
|
6251
|
+
|
|
6099
6252
|
// node_modules/es-toolkit/dist/function/debounce.mjs
|
|
6100
6253
|
function debounce(func, debounceMs, { signal, edges } = {}) {
|
|
6101
6254
|
let pendingThis = void 0;
|
|
@@ -12558,13 +12711,13 @@ __export(tmux_status_exports, {
|
|
|
12558
12711
|
parseActivity: () => parseActivity,
|
|
12559
12712
|
parseContextPercentage: () => parseContextPercentage
|
|
12560
12713
|
});
|
|
12561
|
-
import { execSync as
|
|
12714
|
+
import { execSync as execSync5 } from "child_process";
|
|
12562
12715
|
function inTmux() {
|
|
12563
12716
|
if (process.env.TMUX || process.env.TMUX_PANE) return true;
|
|
12564
12717
|
const term = process.env.TERM ?? "";
|
|
12565
12718
|
if (term.startsWith("tmux") || term.startsWith("screen")) return true;
|
|
12566
12719
|
try {
|
|
12567
|
-
|
|
12720
|
+
execSync5("tmux display-message -p '#{session_name}' 2>/dev/null", {
|
|
12568
12721
|
encoding: "utf8",
|
|
12569
12722
|
timeout: 2e3
|
|
12570
12723
|
});
|
|
@@ -12574,12 +12727,12 @@ function inTmux() {
|
|
|
12574
12727
|
try {
|
|
12575
12728
|
let pid = process.ppid;
|
|
12576
12729
|
for (let depth = 0; depth < 8 && pid > 1; depth++) {
|
|
12577
|
-
const comm =
|
|
12730
|
+
const comm = execSync5(`ps -p ${pid} -o comm= 2>/dev/null`, {
|
|
12578
12731
|
encoding: "utf8",
|
|
12579
12732
|
timeout: 1e3
|
|
12580
12733
|
}).trim();
|
|
12581
12734
|
if (/tmux/.test(comm)) return true;
|
|
12582
|
-
const ppid =
|
|
12735
|
+
const ppid = execSync5(`ps -p ${pid} -o ppid= 2>/dev/null`, {
|
|
12583
12736
|
encoding: "utf8",
|
|
12584
12737
|
timeout: 1e3
|
|
12585
12738
|
}).trim();
|
|
@@ -12592,7 +12745,7 @@ function inTmux() {
|
|
|
12592
12745
|
}
|
|
12593
12746
|
function listTmuxSessions() {
|
|
12594
12747
|
try {
|
|
12595
|
-
const out =
|
|
12748
|
+
const out = execSync5("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
12596
12749
|
encoding: "utf8",
|
|
12597
12750
|
timeout: 3e3
|
|
12598
12751
|
});
|
|
@@ -12603,7 +12756,7 @@ function listTmuxSessions() {
|
|
|
12603
12756
|
}
|
|
12604
12757
|
function capturePaneLines(windowName, lines = 10) {
|
|
12605
12758
|
try {
|
|
12606
|
-
const out =
|
|
12759
|
+
const out = execSync5(
|
|
12607
12760
|
`tmux capture-pane -t ${JSON.stringify(windowName)} -p 2>/dev/null | tail -${lines}`,
|
|
12608
12761
|
{ encoding: "utf8", timeout: 3e3 }
|
|
12609
12762
|
);
|
|
@@ -12614,7 +12767,7 @@ function capturePaneLines(windowName, lines = 10) {
|
|
|
12614
12767
|
}
|
|
12615
12768
|
function getPaneCwd(windowName) {
|
|
12616
12769
|
try {
|
|
12617
|
-
const out =
|
|
12770
|
+
const out = execSync5(
|
|
12618
12771
|
`tmux display-message -t ${JSON.stringify(windowName)} -p '#{pane_current_path}' 2>/dev/null`,
|
|
12619
12772
|
{ encoding: "utf8", timeout: 3e3 }
|
|
12620
12773
|
);
|
|
@@ -12625,7 +12778,7 @@ function getPaneCwd(windowName) {
|
|
|
12625
12778
|
}
|
|
12626
12779
|
function projectFromPath(dir) {
|
|
12627
12780
|
try {
|
|
12628
|
-
const root =
|
|
12781
|
+
const root = execSync5("git -C " + JSON.stringify(dir) + " rev-parse --show-toplevel 2>/dev/null", {
|
|
12629
12782
|
encoding: "utf8",
|
|
12630
12783
|
timeout: 3e3
|
|
12631
12784
|
}).trim();
|
|
@@ -12694,7 +12847,7 @@ function getEmployeeStatuses(employeeNames) {
|
|
|
12694
12847
|
}
|
|
12695
12848
|
let paneAlive = true;
|
|
12696
12849
|
try {
|
|
12697
|
-
const paneStatus =
|
|
12850
|
+
const paneStatus = execSync5(
|
|
12698
12851
|
`tmux list-panes -t ${JSON.stringify(sessionName)} -F '#{pane_dead}' 2>/dev/null`,
|
|
12699
12852
|
{ encoding: "utf8", timeout: 3e3 }
|
|
12700
12853
|
).trim();
|
|
@@ -14894,10 +15047,10 @@ var init_hooks = __esm({
|
|
|
14894
15047
|
});
|
|
14895
15048
|
|
|
14896
15049
|
// src/runtime/safety-checks.ts
|
|
14897
|
-
import
|
|
15050
|
+
import path15 from "path";
|
|
14898
15051
|
import os6 from "os";
|
|
14899
15052
|
function checkPathSafety(filePath) {
|
|
14900
|
-
const resolved =
|
|
15053
|
+
const resolved = path15.resolve(filePath);
|
|
14901
15054
|
for (const { pattern, reason } of BYPASS_IMMUNE_PATTERNS) {
|
|
14902
15055
|
const matches = typeof pattern === "function" ? pattern(resolved) : pattern.test(resolved);
|
|
14903
15056
|
if (matches) {
|
|
@@ -14907,7 +15060,7 @@ function checkPathSafety(filePath) {
|
|
|
14907
15060
|
return { safe: true, bypassImmune: true };
|
|
14908
15061
|
}
|
|
14909
15062
|
function checkReadPathSafety(filePath) {
|
|
14910
|
-
const resolved =
|
|
15063
|
+
const resolved = path15.resolve(filePath);
|
|
14911
15064
|
const credPatterns = BYPASS_IMMUNE_PATTERNS.filter(
|
|
14912
15065
|
(p) => typeof p.pattern !== "function" && (p.reason.includes("secrets") || p.reason.includes("Private key") || p.reason.includes("Credential"))
|
|
14913
15066
|
);
|
|
@@ -14933,11 +15086,11 @@ var init_safety_checks = __esm({
|
|
|
14933
15086
|
reason: "Git config can set hooks and command execution"
|
|
14934
15087
|
},
|
|
14935
15088
|
{
|
|
14936
|
-
pattern: (p) => p.startsWith(
|
|
15089
|
+
pattern: (p) => p.startsWith(path15.join(HOME, ".claude")),
|
|
14937
15090
|
reason: "Claude configuration files are protected"
|
|
14938
15091
|
},
|
|
14939
15092
|
{
|
|
14940
|
-
pattern: (p) => p.startsWith(
|
|
15093
|
+
pattern: (p) => p.startsWith(path15.join(HOME, ".exe-os")),
|
|
14941
15094
|
reason: "exe-os configuration files are protected"
|
|
14942
15095
|
},
|
|
14943
15096
|
{
|
|
@@ -14954,7 +15107,7 @@ var init_safety_checks = __esm({
|
|
|
14954
15107
|
},
|
|
14955
15108
|
{
|
|
14956
15109
|
pattern: (p) => {
|
|
14957
|
-
const name =
|
|
15110
|
+
const name = path15.basename(p);
|
|
14958
15111
|
return [".bashrc", ".zshrc", ".profile", ".bash_profile", ".zprofile", ".zshenv"].includes(name);
|
|
14959
15112
|
},
|
|
14960
15113
|
reason: "Shell configuration files can execute arbitrary code on login"
|
|
@@ -14981,7 +15134,7 @@ __export(file_read_exports, {
|
|
|
14981
15134
|
FileReadTool: () => FileReadTool
|
|
14982
15135
|
});
|
|
14983
15136
|
import fs3 from "fs/promises";
|
|
14984
|
-
import
|
|
15137
|
+
import path16 from "path";
|
|
14985
15138
|
import { z } from "zod";
|
|
14986
15139
|
function isBinary(buf) {
|
|
14987
15140
|
for (let i = 0; i < buf.length; i++) {
|
|
@@ -15017,7 +15170,7 @@ var init_file_read = __esm({
|
|
|
15017
15170
|
return { behavior: "allow" };
|
|
15018
15171
|
},
|
|
15019
15172
|
async call(input, context) {
|
|
15020
|
-
const filePath =
|
|
15173
|
+
const filePath = path16.isAbsolute(input.file_path) ? input.file_path : path16.resolve(context.cwd, input.file_path);
|
|
15021
15174
|
let stat2;
|
|
15022
15175
|
try {
|
|
15023
15176
|
stat2 = await fs3.stat(filePath);
|
|
@@ -15057,7 +15210,7 @@ __export(glob_exports, {
|
|
|
15057
15210
|
GlobTool: () => GlobTool
|
|
15058
15211
|
});
|
|
15059
15212
|
import fs4 from "fs/promises";
|
|
15060
|
-
import
|
|
15213
|
+
import path17 from "path";
|
|
15061
15214
|
import { z as z2 } from "zod";
|
|
15062
15215
|
async function walkDir(dir, maxDepth = 10) {
|
|
15063
15216
|
const results = [];
|
|
@@ -15073,7 +15226,7 @@ async function walkDir(dir, maxDepth = 10) {
|
|
|
15073
15226
|
if (entry.isDirectory() && (entry.name === "node_modules" || entry.name === ".git")) {
|
|
15074
15227
|
continue;
|
|
15075
15228
|
}
|
|
15076
|
-
const fullPath =
|
|
15229
|
+
const fullPath = path17.join(current, entry.name);
|
|
15077
15230
|
if (entry.isDirectory()) {
|
|
15078
15231
|
await walk(fullPath, depth + 1);
|
|
15079
15232
|
} else {
|
|
@@ -15107,11 +15260,11 @@ var init_glob = __esm({
|
|
|
15107
15260
|
inputSchema: inputSchema2,
|
|
15108
15261
|
isReadOnly: true,
|
|
15109
15262
|
async call(input, context) {
|
|
15110
|
-
const baseDir = input.path ?
|
|
15263
|
+
const baseDir = input.path ? path17.isAbsolute(input.path) ? input.path : path17.resolve(context.cwd, input.path) : context.cwd;
|
|
15111
15264
|
try {
|
|
15112
15265
|
const entries = await walkDir(baseDir);
|
|
15113
15266
|
const matched = entries.filter(
|
|
15114
|
-
(e) => simpleGlobMatch(
|
|
15267
|
+
(e) => simpleGlobMatch(path17.relative(baseDir, e.path), input.pattern)
|
|
15115
15268
|
);
|
|
15116
15269
|
matched.sort((a, b) => b.mtime - a.mtime);
|
|
15117
15270
|
if (matched.length === 0) {
|
|
@@ -15137,7 +15290,7 @@ __export(grep_exports, {
|
|
|
15137
15290
|
});
|
|
15138
15291
|
import { spawn as spawn2 } from "child_process";
|
|
15139
15292
|
import fs5 from "fs/promises";
|
|
15140
|
-
import
|
|
15293
|
+
import path18 from "path";
|
|
15141
15294
|
import { z as z3 } from "zod";
|
|
15142
15295
|
function runRipgrep(input, searchPath, context) {
|
|
15143
15296
|
return new Promise((resolve, reject) => {
|
|
@@ -15191,7 +15344,7 @@ async function nodeGrep(input, searchPath) {
|
|
|
15191
15344
|
}
|
|
15192
15345
|
for (const entry of entries) {
|
|
15193
15346
|
if (entry.name === "node_modules" || entry.name === ".git") continue;
|
|
15194
|
-
const fullPath =
|
|
15347
|
+
const fullPath = path18.join(dir, entry.name);
|
|
15195
15348
|
if (entry.isDirectory()) {
|
|
15196
15349
|
await walk(fullPath);
|
|
15197
15350
|
} else {
|
|
@@ -15237,7 +15390,7 @@ var init_grep = __esm({
|
|
|
15237
15390
|
inputSchema: inputSchema3,
|
|
15238
15391
|
isReadOnly: true,
|
|
15239
15392
|
async call(input, context) {
|
|
15240
|
-
const searchPath = input.path ?
|
|
15393
|
+
const searchPath = input.path ? path18.isAbsolute(input.path) ? input.path : path18.resolve(context.cwd, input.path) : context.cwd;
|
|
15241
15394
|
try {
|
|
15242
15395
|
const result = await runRipgrep(input, searchPath, context);
|
|
15243
15396
|
return result;
|
|
@@ -15262,7 +15415,7 @@ __export(file_write_exports, {
|
|
|
15262
15415
|
FileWriteTool: () => FileWriteTool
|
|
15263
15416
|
});
|
|
15264
15417
|
import fs6 from "fs/promises";
|
|
15265
|
-
import
|
|
15418
|
+
import path19 from "path";
|
|
15266
15419
|
import { z as z4 } from "zod";
|
|
15267
15420
|
var inputSchema4, FileWriteTool;
|
|
15268
15421
|
var init_file_write = __esm({
|
|
@@ -15290,8 +15443,8 @@ var init_file_write = __esm({
|
|
|
15290
15443
|
return { behavior: "allow" };
|
|
15291
15444
|
},
|
|
15292
15445
|
async call(input, context) {
|
|
15293
|
-
const filePath =
|
|
15294
|
-
const dir =
|
|
15446
|
+
const filePath = path19.isAbsolute(input.file_path) ? input.file_path : path19.resolve(context.cwd, input.file_path);
|
|
15447
|
+
const dir = path19.dirname(filePath);
|
|
15295
15448
|
await fs6.mkdir(dir, { recursive: true });
|
|
15296
15449
|
await fs6.writeFile(filePath, input.content, "utf-8");
|
|
15297
15450
|
return {
|
|
@@ -15309,7 +15462,7 @@ __export(file_edit_exports, {
|
|
|
15309
15462
|
FileEditTool: () => FileEditTool
|
|
15310
15463
|
});
|
|
15311
15464
|
import fs7 from "fs/promises";
|
|
15312
|
-
import
|
|
15465
|
+
import path20 from "path";
|
|
15313
15466
|
import { z as z5 } from "zod";
|
|
15314
15467
|
function countOccurrences(haystack, needle) {
|
|
15315
15468
|
let count = 0;
|
|
@@ -15350,7 +15503,7 @@ var init_file_edit = __esm({
|
|
|
15350
15503
|
return { behavior: "allow" };
|
|
15351
15504
|
},
|
|
15352
15505
|
async call(input, context) {
|
|
15353
|
-
const filePath =
|
|
15506
|
+
const filePath = path20.isAbsolute(input.file_path) ? input.file_path : path20.resolve(context.cwd, input.file_path);
|
|
15354
15507
|
let content;
|
|
15355
15508
|
try {
|
|
15356
15509
|
content = await fs7.readFile(filePath, "utf-8");
|
|
@@ -15596,12 +15749,12 @@ __export(session_registry_exports, {
|
|
|
15596
15749
|
pruneStaleSessions: () => pruneStaleSessions,
|
|
15597
15750
|
registerSession: () => registerSession
|
|
15598
15751
|
});
|
|
15599
|
-
import { readFileSync as
|
|
15600
|
-
import { execSync as
|
|
15601
|
-
import
|
|
15752
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, existsSync as existsSync14 } from "fs";
|
|
15753
|
+
import { execSync as execSync6 } from "child_process";
|
|
15754
|
+
import path21 from "path";
|
|
15602
15755
|
import os7 from "os";
|
|
15603
15756
|
function registerSession(entry) {
|
|
15604
|
-
const dir =
|
|
15757
|
+
const dir = path21.dirname(REGISTRY_PATH);
|
|
15605
15758
|
if (!existsSync14(dir)) {
|
|
15606
15759
|
mkdirSync6(dir, { recursive: true });
|
|
15607
15760
|
}
|
|
@@ -15616,7 +15769,7 @@ function registerSession(entry) {
|
|
|
15616
15769
|
}
|
|
15617
15770
|
function listSessions() {
|
|
15618
15771
|
try {
|
|
15619
|
-
const raw =
|
|
15772
|
+
const raw = readFileSync11(REGISTRY_PATH, "utf8");
|
|
15620
15773
|
return JSON.parse(raw);
|
|
15621
15774
|
} catch {
|
|
15622
15775
|
return [];
|
|
@@ -15627,7 +15780,7 @@ function pruneStaleSessions() {
|
|
|
15627
15780
|
if (sessions.length === 0) return 0;
|
|
15628
15781
|
let liveSessions = [];
|
|
15629
15782
|
try {
|
|
15630
|
-
liveSessions =
|
|
15783
|
+
liveSessions = execSync6("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
15631
15784
|
encoding: "utf8"
|
|
15632
15785
|
}).trim().split("\n").filter(Boolean);
|
|
15633
15786
|
} catch {
|
|
@@ -15645,14 +15798,14 @@ var REGISTRY_PATH;
|
|
|
15645
15798
|
var init_session_registry = __esm({
|
|
15646
15799
|
"src/lib/session-registry.ts"() {
|
|
15647
15800
|
"use strict";
|
|
15648
|
-
REGISTRY_PATH =
|
|
15801
|
+
REGISTRY_PATH = path21.join(os7.homedir(), ".exe-os", "session-registry.json");
|
|
15649
15802
|
}
|
|
15650
15803
|
});
|
|
15651
15804
|
|
|
15652
15805
|
// src/tui/views/CommandCenter.tsx
|
|
15653
15806
|
import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
15654
15807
|
import TextInput from "ink-text-input";
|
|
15655
|
-
import
|
|
15808
|
+
import path22 from "path";
|
|
15656
15809
|
import { homedir as homedir3 } from "os";
|
|
15657
15810
|
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
15658
15811
|
function CommandCenterView({
|
|
@@ -15893,7 +16046,7 @@ function CommandCenterView({
|
|
|
15893
16046
|
const demoEntries = DEMO_PROJECTS.map((p) => ({
|
|
15894
16047
|
projectName: p.projectName,
|
|
15895
16048
|
exeSession: p.exeSession,
|
|
15896
|
-
projectDir:
|
|
16049
|
+
projectDir: path22.join(homedir3(), p.projectName),
|
|
15897
16050
|
employeeCount: p.employees.length,
|
|
15898
16051
|
activeCount: p.employees.filter((e) => e.status === "active").length,
|
|
15899
16052
|
memoryCount: p.employees.length * 4e3,
|
|
@@ -16463,13 +16616,13 @@ var init_task_router = __esm({
|
|
|
16463
16616
|
});
|
|
16464
16617
|
|
|
16465
16618
|
// src/lib/session-key.ts
|
|
16466
|
-
import { execSync as
|
|
16619
|
+
import { execSync as execSync7 } from "child_process";
|
|
16467
16620
|
function getSessionKey() {
|
|
16468
16621
|
if (_cached) return _cached;
|
|
16469
16622
|
let pid = process.ppid;
|
|
16470
16623
|
for (let i = 0; i < 10; i++) {
|
|
16471
16624
|
try {
|
|
16472
|
-
const info =
|
|
16625
|
+
const info = execSync7(`ps -p ${pid} -o ppid=,comm=`, {
|
|
16473
16626
|
encoding: "utf8",
|
|
16474
16627
|
timeout: 2e3
|
|
16475
16628
|
}).trim();
|
|
@@ -16613,14 +16766,14 @@ var init_transport = __esm({
|
|
|
16613
16766
|
});
|
|
16614
16767
|
|
|
16615
16768
|
// src/lib/cc-agent-support.ts
|
|
16616
|
-
import { execSync as
|
|
16769
|
+
import { execSync as execSync8 } from "child_process";
|
|
16617
16770
|
function _resetCcAgentSupportCache() {
|
|
16618
16771
|
_cachedSupport = null;
|
|
16619
16772
|
}
|
|
16620
16773
|
function claudeSupportsAgentFlag() {
|
|
16621
16774
|
if (_cachedSupport !== null) return _cachedSupport;
|
|
16622
16775
|
try {
|
|
16623
|
-
const helpOutput =
|
|
16776
|
+
const helpOutput = execSync8("claude --help 2>&1", {
|
|
16624
16777
|
encoding: "utf-8",
|
|
16625
16778
|
timeout: 5e3
|
|
16626
16779
|
});
|
|
@@ -16663,17 +16816,17 @@ var init_provider_table = __esm({
|
|
|
16663
16816
|
});
|
|
16664
16817
|
|
|
16665
16818
|
// src/lib/intercom-queue.ts
|
|
16666
|
-
import { readFileSync as
|
|
16667
|
-
import
|
|
16819
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, renameSync as renameSync4, existsSync as existsSync15, mkdirSync as mkdirSync7 } from "fs";
|
|
16820
|
+
import path23 from "path";
|
|
16668
16821
|
import os8 from "os";
|
|
16669
16822
|
function ensureDir2() {
|
|
16670
|
-
const dir =
|
|
16823
|
+
const dir = path23.dirname(QUEUE_PATH);
|
|
16671
16824
|
if (!existsSync15(dir)) mkdirSync7(dir, { recursive: true });
|
|
16672
16825
|
}
|
|
16673
16826
|
function readQueue() {
|
|
16674
16827
|
try {
|
|
16675
16828
|
if (!existsSync15(QUEUE_PATH)) return [];
|
|
16676
|
-
return JSON.parse(
|
|
16829
|
+
return JSON.parse(readFileSync12(QUEUE_PATH, "utf8"));
|
|
16677
16830
|
} catch {
|
|
16678
16831
|
return [];
|
|
16679
16832
|
}
|
|
@@ -16705,19 +16858,19 @@ var QUEUE_PATH, TTL_MS, INTERCOM_LOG;
|
|
|
16705
16858
|
var init_intercom_queue = __esm({
|
|
16706
16859
|
"src/lib/intercom-queue.ts"() {
|
|
16707
16860
|
"use strict";
|
|
16708
|
-
QUEUE_PATH =
|
|
16861
|
+
QUEUE_PATH = path23.join(os8.homedir(), ".exe-os", "intercom-queue.json");
|
|
16709
16862
|
TTL_MS = 60 * 60 * 1e3;
|
|
16710
|
-
INTERCOM_LOG =
|
|
16863
|
+
INTERCOM_LOG = path23.join(os8.homedir(), ".exe-os", "intercom.log");
|
|
16711
16864
|
}
|
|
16712
16865
|
});
|
|
16713
16866
|
|
|
16714
16867
|
// src/lib/plan-limits.ts
|
|
16715
|
-
import { readFileSync as
|
|
16716
|
-
import
|
|
16868
|
+
import { readFileSync as readFileSync13, existsSync as existsSync16 } from "fs";
|
|
16869
|
+
import path24 from "path";
|
|
16717
16870
|
function getLicenseSync() {
|
|
16718
16871
|
try {
|
|
16719
16872
|
if (!existsSync16(CACHE_PATH2)) return freeLicense();
|
|
16720
|
-
const raw = JSON.parse(
|
|
16873
|
+
const raw = JSON.parse(readFileSync13(CACHE_PATH2, "utf8"));
|
|
16721
16874
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
16722
16875
|
const parts = raw.token.split(".");
|
|
16723
16876
|
if (parts.length !== 3) return freeLicense();
|
|
@@ -16756,7 +16909,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
16756
16909
|
let count = 0;
|
|
16757
16910
|
try {
|
|
16758
16911
|
if (existsSync16(filePath)) {
|
|
16759
|
-
const raw =
|
|
16912
|
+
const raw = readFileSync13(filePath, "utf8");
|
|
16760
16913
|
const employees = JSON.parse(raw);
|
|
16761
16914
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
16762
16915
|
}
|
|
@@ -16785,16 +16938,16 @@ var init_plan_limits = __esm({
|
|
|
16785
16938
|
this.name = "PlanLimitError";
|
|
16786
16939
|
}
|
|
16787
16940
|
};
|
|
16788
|
-
CACHE_PATH2 =
|
|
16941
|
+
CACHE_PATH2 = path24.join(EXE_AI_DIR, "license-cache.json");
|
|
16789
16942
|
}
|
|
16790
16943
|
});
|
|
16791
16944
|
|
|
16792
16945
|
// src/lib/notifications.ts
|
|
16793
16946
|
import crypto4 from "crypto";
|
|
16794
|
-
import
|
|
16947
|
+
import path25 from "path";
|
|
16795
16948
|
import os9 from "os";
|
|
16796
16949
|
import {
|
|
16797
|
-
readFileSync as
|
|
16950
|
+
readFileSync as readFileSync14,
|
|
16798
16951
|
readdirSync as readdirSync3,
|
|
16799
16952
|
unlinkSync as unlinkSync5,
|
|
16800
16953
|
existsSync as existsSync17,
|
|
@@ -16877,10 +17030,10 @@ var init_session_kill_telemetry = __esm({
|
|
|
16877
17030
|
|
|
16878
17031
|
// src/lib/tasks-crud.ts
|
|
16879
17032
|
import crypto6 from "crypto";
|
|
16880
|
-
import
|
|
16881
|
-
import { execSync as
|
|
17033
|
+
import path26 from "path";
|
|
17034
|
+
import { execSync as execSync9 } from "child_process";
|
|
16882
17035
|
import { mkdir as mkdir6, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
16883
|
-
import { existsSync as existsSync18, readFileSync as
|
|
17036
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15 } from "fs";
|
|
16884
17037
|
async function writeCheckpoint(input) {
|
|
16885
17038
|
const client = getClient();
|
|
16886
17039
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -17010,8 +17163,8 @@ async function createTaskCore(input) {
|
|
|
17010
17163
|
}
|
|
17011
17164
|
if (input.baseDir) {
|
|
17012
17165
|
try {
|
|
17013
|
-
await mkdir6(
|
|
17014
|
-
await mkdir6(
|
|
17166
|
+
await mkdir6(path26.join(input.baseDir, "exe", "output"), { recursive: true });
|
|
17167
|
+
await mkdir6(path26.join(input.baseDir, "exe", "research"), { recursive: true });
|
|
17015
17168
|
await ensureArchitectureDoc(input.baseDir, input.projectName);
|
|
17016
17169
|
await ensureGitignoreExe(input.baseDir);
|
|
17017
17170
|
} catch {
|
|
@@ -17127,12 +17280,12 @@ function checkStaleCompletion(taskContext, taskCreatedAt) {
|
|
|
17127
17280
|
if (!DELEGATION_KEYWORDS.test(taskContext)) return null;
|
|
17128
17281
|
try {
|
|
17129
17282
|
const since = new Date(taskCreatedAt).toISOString();
|
|
17130
|
-
const branch =
|
|
17283
|
+
const branch = execSync9(
|
|
17131
17284
|
"git rev-parse --abbrev-ref HEAD 2>/dev/null",
|
|
17132
17285
|
{ encoding: "utf8", timeout: 3e3 }
|
|
17133
17286
|
).trim();
|
|
17134
17287
|
const branchArg = branch && branch !== "HEAD" ? branch : "";
|
|
17135
|
-
const commitCount =
|
|
17288
|
+
const commitCount = execSync9(
|
|
17136
17289
|
`git log --oneline --since="${since}" ${branchArg} 2>/dev/null | wc -l`,
|
|
17137
17290
|
{ encoding: "utf8", timeout: 5e3 }
|
|
17138
17291
|
).trim();
|
|
@@ -17235,7 +17388,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
17235
17388
|
return { taskFile, assignedTo, assignedBy, taskSlug };
|
|
17236
17389
|
}
|
|
17237
17390
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
17238
|
-
const archPath =
|
|
17391
|
+
const archPath = path26.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
17239
17392
|
try {
|
|
17240
17393
|
if (existsSync18(archPath)) return;
|
|
17241
17394
|
const template = [
|
|
@@ -17270,10 +17423,10 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
17270
17423
|
}
|
|
17271
17424
|
}
|
|
17272
17425
|
async function ensureGitignoreExe(baseDir) {
|
|
17273
|
-
const gitignorePath =
|
|
17426
|
+
const gitignorePath = path26.join(baseDir, ".gitignore");
|
|
17274
17427
|
try {
|
|
17275
17428
|
if (existsSync18(gitignorePath)) {
|
|
17276
|
-
const content =
|
|
17429
|
+
const content = readFileSync15(gitignorePath, "utf-8");
|
|
17277
17430
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
17278
17431
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
17279
17432
|
} else {
|
|
@@ -17293,7 +17446,7 @@ var init_tasks_crud = __esm({
|
|
|
17293
17446
|
});
|
|
17294
17447
|
|
|
17295
17448
|
// src/lib/tasks-review.ts
|
|
17296
|
-
import
|
|
17449
|
+
import path27 from "path";
|
|
17297
17450
|
import { existsSync as existsSync19, readdirSync as readdirSync4, unlinkSync as unlinkSync6 } from "fs";
|
|
17298
17451
|
async function countPendingReviews() {
|
|
17299
17452
|
const client = getClient();
|
|
@@ -17442,11 +17595,11 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
17442
17595
|
);
|
|
17443
17596
|
}
|
|
17444
17597
|
try {
|
|
17445
|
-
const cacheDir =
|
|
17598
|
+
const cacheDir = path27.join(EXE_AI_DIR, "session-cache");
|
|
17446
17599
|
if (existsSync19(cacheDir)) {
|
|
17447
17600
|
for (const f of readdirSync4(cacheDir)) {
|
|
17448
17601
|
if (f.startsWith("review-notified-")) {
|
|
17449
|
-
unlinkSync6(
|
|
17602
|
+
unlinkSync6(path27.join(cacheDir, f));
|
|
17450
17603
|
}
|
|
17451
17604
|
}
|
|
17452
17605
|
}
|
|
@@ -17468,7 +17621,7 @@ var init_tasks_review = __esm({
|
|
|
17468
17621
|
});
|
|
17469
17622
|
|
|
17470
17623
|
// src/lib/tasks-chain.ts
|
|
17471
|
-
import
|
|
17624
|
+
import path28 from "path";
|
|
17472
17625
|
import { readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
|
|
17473
17626
|
async function cascadeUnblock(taskId, baseDir, now) {
|
|
17474
17627
|
const client = getClient();
|
|
@@ -17484,7 +17637,7 @@ async function cascadeUnblock(taskId, baseDir, now) {
|
|
|
17484
17637
|
});
|
|
17485
17638
|
for (const ur of unblockedRows.rows) {
|
|
17486
17639
|
try {
|
|
17487
|
-
const ubFile =
|
|
17640
|
+
const ubFile = path28.join(baseDir, String(ur.task_file));
|
|
17488
17641
|
let ubContent = await readFile5(ubFile, "utf-8");
|
|
17489
17642
|
ubContent = ubContent.replace(/\*\*Status:\*\* blocked/, "**Status:** open");
|
|
17490
17643
|
ubContent = ubContent.replace(/\n\*\*Blocked by:\*\*.*\n/, "\n");
|
|
@@ -17549,34 +17702,34 @@ var init_tasks_chain = __esm({
|
|
|
17549
17702
|
});
|
|
17550
17703
|
|
|
17551
17704
|
// src/lib/project-name.ts
|
|
17552
|
-
import { execSync as
|
|
17553
|
-
import
|
|
17705
|
+
import { execSync as execSync10 } from "child_process";
|
|
17706
|
+
import path29 from "path";
|
|
17554
17707
|
function getProjectName(cwd2) {
|
|
17555
17708
|
const dir = cwd2 ?? process.cwd();
|
|
17556
17709
|
if (_cached2 && _cachedCwd === dir) return _cached2;
|
|
17557
17710
|
try {
|
|
17558
17711
|
let repoRoot;
|
|
17559
17712
|
try {
|
|
17560
|
-
const gitCommonDir =
|
|
17713
|
+
const gitCommonDir = execSync10("git rev-parse --path-format=absolute --git-common-dir", {
|
|
17561
17714
|
cwd: dir,
|
|
17562
17715
|
encoding: "utf8",
|
|
17563
17716
|
timeout: 2e3,
|
|
17564
17717
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17565
17718
|
}).trim();
|
|
17566
|
-
repoRoot =
|
|
17719
|
+
repoRoot = path29.dirname(gitCommonDir);
|
|
17567
17720
|
} catch {
|
|
17568
|
-
repoRoot =
|
|
17721
|
+
repoRoot = execSync10("git rev-parse --show-toplevel", {
|
|
17569
17722
|
cwd: dir,
|
|
17570
17723
|
encoding: "utf8",
|
|
17571
17724
|
timeout: 2e3,
|
|
17572
17725
|
stdio: ["pipe", "pipe", "pipe"]
|
|
17573
17726
|
}).trim();
|
|
17574
17727
|
}
|
|
17575
|
-
_cached2 =
|
|
17728
|
+
_cached2 = path29.basename(repoRoot);
|
|
17576
17729
|
_cachedCwd = dir;
|
|
17577
17730
|
return _cached2;
|
|
17578
17731
|
} catch {
|
|
17579
|
-
_cached2 =
|
|
17732
|
+
_cached2 = path29.basename(dir);
|
|
17580
17733
|
_cachedCwd = dir;
|
|
17581
17734
|
return _cached2;
|
|
17582
17735
|
}
|
|
@@ -18048,7 +18201,7 @@ __export(tasks_exports, {
|
|
|
18048
18201
|
updateTaskStatus: () => updateTaskStatus,
|
|
18049
18202
|
writeCheckpoint: () => writeCheckpoint
|
|
18050
18203
|
});
|
|
18051
|
-
import
|
|
18204
|
+
import path30 from "path";
|
|
18052
18205
|
import { writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, unlinkSync as unlinkSync7 } from "fs";
|
|
18053
18206
|
async function createTask(input) {
|
|
18054
18207
|
const result = await createTaskCore(input);
|
|
@@ -18068,8 +18221,8 @@ async function updateTask(input) {
|
|
|
18068
18221
|
const { row, taskFile, now, taskId } = await updateTaskStatus(input);
|
|
18069
18222
|
try {
|
|
18070
18223
|
const agent = String(row.assigned_to);
|
|
18071
|
-
const cacheDir =
|
|
18072
|
-
const cachePath =
|
|
18224
|
+
const cacheDir = path30.join(EXE_AI_DIR, "session-cache");
|
|
18225
|
+
const cachePath = path30.join(cacheDir, `current-task-${agent}.json`);
|
|
18073
18226
|
if (input.status === "in_progress") {
|
|
18074
18227
|
mkdirSync8(cacheDir, { recursive: true });
|
|
18075
18228
|
writeFileSync7(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
@@ -18512,14 +18665,14 @@ __export(tmux_routing_exports, {
|
|
|
18512
18665
|
spawnEmployee: () => spawnEmployee,
|
|
18513
18666
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
18514
18667
|
});
|
|
18515
|
-
import { execFileSync as execFileSync3, execSync as
|
|
18516
|
-
import { readFileSync as
|
|
18517
|
-
import
|
|
18668
|
+
import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
|
|
18669
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync8, mkdirSync as mkdirSync9, existsSync as existsSync20, appendFileSync } from "fs";
|
|
18670
|
+
import path31 from "path";
|
|
18518
18671
|
import os10 from "os";
|
|
18519
18672
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
18520
18673
|
import { unlinkSync as unlinkSync8 } from "fs";
|
|
18521
18674
|
function spawnLockPath(sessionName) {
|
|
18522
|
-
return
|
|
18675
|
+
return path31.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
18523
18676
|
}
|
|
18524
18677
|
function isProcessAlive(pid) {
|
|
18525
18678
|
try {
|
|
@@ -18536,7 +18689,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
18536
18689
|
const lockFile = spawnLockPath(sessionName);
|
|
18537
18690
|
if (existsSync20(lockFile)) {
|
|
18538
18691
|
try {
|
|
18539
|
-
const lock = JSON.parse(
|
|
18692
|
+
const lock = JSON.parse(readFileSync16(lockFile, "utf8"));
|
|
18540
18693
|
const age = Date.now() - lock.timestamp;
|
|
18541
18694
|
if (isProcessAlive(lock.pid) && age < 6e4) {
|
|
18542
18695
|
return false;
|
|
@@ -18556,8 +18709,8 @@ function releaseSpawnLock2(sessionName) {
|
|
|
18556
18709
|
function resolveBehaviorsExporterScript() {
|
|
18557
18710
|
try {
|
|
18558
18711
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18559
|
-
const scriptPath =
|
|
18560
|
-
|
|
18712
|
+
const scriptPath = path31.join(
|
|
18713
|
+
path31.dirname(thisFile),
|
|
18561
18714
|
"..",
|
|
18562
18715
|
"bin",
|
|
18563
18716
|
"exe-export-behaviors.js"
|
|
@@ -18627,7 +18780,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18627
18780
|
mkdirSync9(SESSION_CACHE, { recursive: true });
|
|
18628
18781
|
}
|
|
18629
18782
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
18630
|
-
const filePath =
|
|
18783
|
+
const filePath = path31.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
18631
18784
|
writeFileSync8(filePath, JSON.stringify({
|
|
18632
18785
|
parentExe: rootExe,
|
|
18633
18786
|
dispatchedBy: dispatchedBy || rootExe,
|
|
@@ -18636,7 +18789,7 @@ function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
|
18636
18789
|
}
|
|
18637
18790
|
function getParentExe(sessionKey) {
|
|
18638
18791
|
try {
|
|
18639
|
-
const data = JSON.parse(
|
|
18792
|
+
const data = JSON.parse(readFileSync16(path31.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`), "utf8"));
|
|
18640
18793
|
return data.parentExe || null;
|
|
18641
18794
|
} catch {
|
|
18642
18795
|
return null;
|
|
@@ -18644,8 +18797,8 @@ function getParentExe(sessionKey) {
|
|
|
18644
18797
|
}
|
|
18645
18798
|
function getDispatchedBy(sessionKey) {
|
|
18646
18799
|
try {
|
|
18647
|
-
const data = JSON.parse(
|
|
18648
|
-
|
|
18800
|
+
const data = JSON.parse(readFileSync16(
|
|
18801
|
+
path31.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`),
|
|
18649
18802
|
"utf8"
|
|
18650
18803
|
));
|
|
18651
18804
|
return data.dispatchedBy ?? data.parentExe ?? null;
|
|
@@ -18707,7 +18860,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
18707
18860
|
function readDebounceState() {
|
|
18708
18861
|
try {
|
|
18709
18862
|
if (!existsSync20(DEBOUNCE_FILE)) return {};
|
|
18710
|
-
return JSON.parse(
|
|
18863
|
+
return JSON.parse(readFileSync16(DEBOUNCE_FILE, "utf8"));
|
|
18711
18864
|
} catch {
|
|
18712
18865
|
return {};
|
|
18713
18866
|
}
|
|
@@ -18904,8 +19057,8 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18904
19057
|
const transport = getTransport();
|
|
18905
19058
|
const sessionName = employeeSessionName(employeeName, exeSession, opts?.instance);
|
|
18906
19059
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
18907
|
-
const logDir =
|
|
18908
|
-
const logFile =
|
|
19060
|
+
const logDir = path31.join(os10.homedir(), ".exe-os", "session-logs");
|
|
19061
|
+
const logFile = path31.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
18909
19062
|
if (!existsSync20(logDir)) {
|
|
18910
19063
|
mkdirSync9(logDir, { recursive: true });
|
|
18911
19064
|
}
|
|
@@ -18913,17 +19066,17 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18913
19066
|
let cleanupSuffix = "";
|
|
18914
19067
|
try {
|
|
18915
19068
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
18916
|
-
const cleanupScript =
|
|
19069
|
+
const cleanupScript = path31.join(path31.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
18917
19070
|
if (existsSync20(cleanupScript)) {
|
|
18918
19071
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
18919
19072
|
}
|
|
18920
19073
|
} catch {
|
|
18921
19074
|
}
|
|
18922
19075
|
try {
|
|
18923
|
-
const claudeJsonPath =
|
|
19076
|
+
const claudeJsonPath = path31.join(os10.homedir(), ".claude.json");
|
|
18924
19077
|
let claudeJson = {};
|
|
18925
19078
|
try {
|
|
18926
|
-
claudeJson = JSON.parse(
|
|
19079
|
+
claudeJson = JSON.parse(readFileSync16(claudeJsonPath, "utf8"));
|
|
18927
19080
|
} catch {
|
|
18928
19081
|
}
|
|
18929
19082
|
if (!claudeJson.projects) claudeJson.projects = {};
|
|
@@ -18935,13 +19088,13 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18935
19088
|
} catch {
|
|
18936
19089
|
}
|
|
18937
19090
|
try {
|
|
18938
|
-
const settingsDir =
|
|
19091
|
+
const settingsDir = path31.join(os10.homedir(), ".claude", "projects");
|
|
18939
19092
|
const normalizedKey = (opts?.cwd ?? projectDir).replace(/\//g, "-").replace(/^-/, "");
|
|
18940
|
-
const projSettingsDir =
|
|
18941
|
-
const settingsPath =
|
|
19093
|
+
const projSettingsDir = path31.join(settingsDir, normalizedKey);
|
|
19094
|
+
const settingsPath = path31.join(projSettingsDir, "settings.json");
|
|
18942
19095
|
let settings = {};
|
|
18943
19096
|
try {
|
|
18944
|
-
settings = JSON.parse(
|
|
19097
|
+
settings = JSON.parse(readFileSync16(settingsPath, "utf8"));
|
|
18945
19098
|
} catch {
|
|
18946
19099
|
}
|
|
18947
19100
|
const perms = settings.permissions ?? {};
|
|
@@ -18982,7 +19135,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18982
19135
|
let behaviorsFlag = "";
|
|
18983
19136
|
let legacyFallbackWarned = false;
|
|
18984
19137
|
if (!useExeAgent && !useBinSymlink) {
|
|
18985
|
-
const identityPath2 =
|
|
19138
|
+
const identityPath2 = path31.join(
|
|
18986
19139
|
os10.homedir(),
|
|
18987
19140
|
".exe-os",
|
|
18988
19141
|
"identity",
|
|
@@ -18998,7 +19151,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
18998
19151
|
}
|
|
18999
19152
|
const behaviorsFile = exportBehaviorsSync(
|
|
19000
19153
|
employeeName,
|
|
19001
|
-
|
|
19154
|
+
path31.basename(spawnCwd),
|
|
19002
19155
|
sessionName
|
|
19003
19156
|
);
|
|
19004
19157
|
if (behaviorsFile) {
|
|
@@ -19013,9 +19166,9 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
19013
19166
|
}
|
|
19014
19167
|
let sessionContextFlag = "";
|
|
19015
19168
|
try {
|
|
19016
|
-
const ctxDir =
|
|
19169
|
+
const ctxDir = path31.join(os10.homedir(), ".exe-os", "session-cache");
|
|
19017
19170
|
mkdirSync9(ctxDir, { recursive: true });
|
|
19018
|
-
const ctxFile =
|
|
19171
|
+
const ctxFile = path31.join(ctxDir, `session-context-${sessionName}.md`);
|
|
19019
19172
|
const ctxContent = [
|
|
19020
19173
|
`## Session Context`,
|
|
19021
19174
|
`You are running in tmux session: ${sessionName}.`,
|
|
@@ -19060,7 +19213,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
19060
19213
|
transport.pipeLog(sessionName, logFile);
|
|
19061
19214
|
try {
|
|
19062
19215
|
const mySession = getMySession();
|
|
19063
|
-
const dispatchInfo =
|
|
19216
|
+
const dispatchInfo = path31.join(SESSION_CACHE, `dispatch-info-${sessionName}.json`);
|
|
19064
19217
|
writeFileSync8(dispatchInfo, JSON.stringify({
|
|
19065
19218
|
dispatchedBy: mySession,
|
|
19066
19219
|
rootExe: exeSession,
|
|
@@ -19072,7 +19225,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
19072
19225
|
let booted = false;
|
|
19073
19226
|
for (let i = 0; i < 30; i++) {
|
|
19074
19227
|
try {
|
|
19075
|
-
|
|
19228
|
+
execSync11("sleep 0.5");
|
|
19076
19229
|
} catch {
|
|
19077
19230
|
}
|
|
19078
19231
|
try {
|
|
@@ -19124,14 +19277,14 @@ var init_tmux_routing = __esm({
|
|
|
19124
19277
|
init_provider_table();
|
|
19125
19278
|
init_intercom_queue();
|
|
19126
19279
|
init_plan_limits();
|
|
19127
|
-
SPAWN_LOCK_DIR =
|
|
19128
|
-
SESSION_CACHE =
|
|
19280
|
+
SPAWN_LOCK_DIR = path31.join(os10.homedir(), ".exe-os", "spawn-locks");
|
|
19281
|
+
SESSION_CACHE = path31.join(os10.homedir(), ".exe-os", "session-cache");
|
|
19129
19282
|
BEHAVIORS_EXPORT_TIMEOUT_MS = 1e4;
|
|
19130
19283
|
VALID_SESSION_NAME = /^[a-z]+-exe\d+$|^[a-z]+\d+-exe\d+$/;
|
|
19131
19284
|
VERIFY_PANE_LINES = 200;
|
|
19132
19285
|
INTERCOM_DEBOUNCE_MS = 3e4;
|
|
19133
|
-
INTERCOM_LOG2 =
|
|
19134
|
-
DEBOUNCE_FILE =
|
|
19286
|
+
INTERCOM_LOG2 = path31.join(os10.homedir(), ".exe-os", "intercom.log");
|
|
19287
|
+
DEBOUNCE_FILE = path31.join(SESSION_CACHE, "intercom-debounce.json");
|
|
19135
19288
|
DEBOUNCE_CLEANUP_AGE_MS = 5 * 60 * 1e3;
|
|
19136
19289
|
BUSY_PATTERN = /[✻✽✶✳·].*…|Running…/;
|
|
19137
19290
|
}
|
|
@@ -19519,7 +19672,7 @@ var init_useOrchestrator = __esm({
|
|
|
19519
19672
|
|
|
19520
19673
|
// src/tui/views/Sessions.tsx
|
|
19521
19674
|
import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
19522
|
-
import
|
|
19675
|
+
import path32 from "path";
|
|
19523
19676
|
import { homedir as homedir4 } from "os";
|
|
19524
19677
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
19525
19678
|
function SessionsView({
|
|
@@ -19554,7 +19707,7 @@ function SessionsView({
|
|
|
19554
19707
|
if (demo) {
|
|
19555
19708
|
setProjects(DEMO_PROJECTS.map((p) => ({
|
|
19556
19709
|
...p,
|
|
19557
|
-
projectDir:
|
|
19710
|
+
projectDir: path32.join(homedir4(), p.projectName),
|
|
19558
19711
|
employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
|
|
19559
19712
|
})));
|
|
19560
19713
|
return;
|
|
@@ -21147,10 +21300,10 @@ var init_Gateway = __esm({
|
|
|
21147
21300
|
});
|
|
21148
21301
|
|
|
21149
21302
|
// src/tui/utils/agent-status.ts
|
|
21150
|
-
import { execSync as
|
|
21303
|
+
import { execSync as execSync12 } from "child_process";
|
|
21151
21304
|
function getAgentStatus(agentId) {
|
|
21152
21305
|
try {
|
|
21153
|
-
const sessions =
|
|
21306
|
+
const sessions = execSync12("tmux list-sessions -F '#{session_name}' 2>/dev/null", {
|
|
21154
21307
|
encoding: "utf8",
|
|
21155
21308
|
timeout: 2e3
|
|
21156
21309
|
}).trim().split("\n");
|
|
@@ -21161,7 +21314,7 @@ function getAgentStatus(agentId) {
|
|
|
21161
21314
|
return /^\d?-/.test(suffix) || /^\d+$/.test(suffix);
|
|
21162
21315
|
});
|
|
21163
21316
|
if (!agentSession) return { label: "offline", color: "gray" };
|
|
21164
|
-
const pane =
|
|
21317
|
+
const pane = execSync12(`tmux capture-pane -t "${agentSession}" -p 2>/dev/null | tail -3`, {
|
|
21165
21318
|
encoding: "utf8",
|
|
21166
21319
|
timeout: 2e3
|
|
21167
21320
|
});
|
|
@@ -22739,101 +22892,6 @@ var init_App2 = __esm({
|
|
|
22739
22892
|
}
|
|
22740
22893
|
});
|
|
22741
22894
|
|
|
22742
|
-
// src/lib/update-check.ts
|
|
22743
|
-
import { execSync as execSync11 } from "child_process";
|
|
22744
|
-
import { readFileSync as readFileSync16 } from "fs";
|
|
22745
|
-
import path32 from "path";
|
|
22746
|
-
function getLocalVersion(packageRoot) {
|
|
22747
|
-
const pkgPath = path32.join(packageRoot, "package.json");
|
|
22748
|
-
const pkg = JSON.parse(readFileSync16(pkgPath, "utf-8"));
|
|
22749
|
-
return pkg.version;
|
|
22750
|
-
}
|
|
22751
|
-
function getRemoteVersion() {
|
|
22752
|
-
try {
|
|
22753
|
-
const output = execSync11("npm view @askexenow/exe-os version", {
|
|
22754
|
-
encoding: "utf-8",
|
|
22755
|
-
timeout: 15e3,
|
|
22756
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
22757
|
-
});
|
|
22758
|
-
return output.trim();
|
|
22759
|
-
} catch {
|
|
22760
|
-
return null;
|
|
22761
|
-
}
|
|
22762
|
-
}
|
|
22763
|
-
function checkForUpdate(packageRoot) {
|
|
22764
|
-
const localVersion = getLocalVersion(packageRoot);
|
|
22765
|
-
const remoteVersion = getRemoteVersion();
|
|
22766
|
-
if (!remoteVersion) {
|
|
22767
|
-
return {
|
|
22768
|
-
updateAvailable: false,
|
|
22769
|
-
localVersion,
|
|
22770
|
-
error: "Could not reach npm registry or package not published yet"
|
|
22771
|
-
};
|
|
22772
|
-
}
|
|
22773
|
-
if (remoteVersion === localVersion) {
|
|
22774
|
-
return { updateAvailable: false, localVersion, remoteVersion };
|
|
22775
|
-
}
|
|
22776
|
-
return { updateAvailable: true, localVersion, remoteVersion };
|
|
22777
|
-
}
|
|
22778
|
-
var init_update_check = __esm({
|
|
22779
|
-
"src/lib/update-check.ts"() {
|
|
22780
|
-
"use strict";
|
|
22781
|
-
}
|
|
22782
|
-
});
|
|
22783
|
-
|
|
22784
|
-
// src/bin/update.ts
|
|
22785
|
-
var update_exports = {};
|
|
22786
|
-
__export(update_exports, {
|
|
22787
|
-
checkForUpdate: () => checkForUpdate,
|
|
22788
|
-
getLocalVersion: () => getLocalVersion,
|
|
22789
|
-
getRemoteVersion: () => getRemoteVersion
|
|
22790
|
-
});
|
|
22791
|
-
import { execSync as execSync12 } from "child_process";
|
|
22792
|
-
import { createInterface as createInterface3 } from "readline";
|
|
22793
|
-
var init_update = __esm({
|
|
22794
|
-
async "src/bin/update.ts"() {
|
|
22795
|
-
"use strict";
|
|
22796
|
-
init_is_main();
|
|
22797
|
-
init_update_check();
|
|
22798
|
-
init_update_check();
|
|
22799
|
-
if (isMainModule(import.meta.url)) {
|
|
22800
|
-
const packageRoot = new URL("../..", import.meta.url).pathname;
|
|
22801
|
-
const result = checkForUpdate(packageRoot);
|
|
22802
|
-
if (result.error) {
|
|
22803
|
-
console.error(result.error);
|
|
22804
|
-
process.exit(0);
|
|
22805
|
-
}
|
|
22806
|
-
if (!result.updateAvailable) {
|
|
22807
|
-
console.log(`exe-os is up to date (v${result.localVersion})`);
|
|
22808
|
-
process.exit(0);
|
|
22809
|
-
}
|
|
22810
|
-
console.log(
|
|
22811
|
-
`Update available: v${result.localVersion} -> v${result.remoteVersion}`
|
|
22812
|
-
);
|
|
22813
|
-
console.log("");
|
|
22814
|
-
const rl = createInterface3({ input: process.stdin, output: process.stdout });
|
|
22815
|
-
const answer = await new Promise((resolve) => {
|
|
22816
|
-
rl.question("Install update? (y/N) ", resolve);
|
|
22817
|
-
});
|
|
22818
|
-
rl.close();
|
|
22819
|
-
if (answer.toLowerCase() === "y") {
|
|
22820
|
-
console.log("Updating...");
|
|
22821
|
-
try {
|
|
22822
|
-
execSync12("npm install -g @askexenow/exe-os@latest", { stdio: "inherit" });
|
|
22823
|
-
console.log("Update complete!");
|
|
22824
|
-
} catch {
|
|
22825
|
-
console.error(
|
|
22826
|
-
"Update failed. Try running manually: npx exe-os --global"
|
|
22827
|
-
);
|
|
22828
|
-
process.exit(1);
|
|
22829
|
-
}
|
|
22830
|
-
} else {
|
|
22831
|
-
console.log("Update skipped.");
|
|
22832
|
-
}
|
|
22833
|
-
}
|
|
22834
|
-
}
|
|
22835
|
-
});
|
|
22836
|
-
|
|
22837
22895
|
// src/bin/cli.ts
|
|
22838
22896
|
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync9, readdirSync as readdirSync5, rmSync } from "fs";
|
|
22839
22897
|
import path33 from "path";
|
|
@@ -22892,6 +22950,9 @@ if (args.includes("--global")) {
|
|
|
22892
22950
|
} else if (args[0] === "setup" || args[0] === "-setup" || args[0] === "--setup") {
|
|
22893
22951
|
const { runSetupWizard: runSetupWizard2 } = await Promise.resolve().then(() => (init_setup_wizard(), setup_wizard_exports));
|
|
22894
22952
|
await runSetupWizard2({ skipModel: args.includes("--skip-model") });
|
|
22953
|
+
} else if (args[0] === "update") {
|
|
22954
|
+
const { runUpdate: runUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
|
|
22955
|
+
await runUpdate2(args.slice(1));
|
|
22895
22956
|
} else {
|
|
22896
22957
|
checkForUpdateOnBoot().catch(() => {
|
|
22897
22958
|
});
|
|
@@ -23217,7 +23278,7 @@ async function checkForUpdateOnBoot() {
|
|
|
23217
23278
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
23218
23279
|
const config = await loadConfig2();
|
|
23219
23280
|
if (!config.autoUpdate.checkOnBoot) return;
|
|
23220
|
-
const { checkForUpdate: checkForUpdate2 } = await
|
|
23281
|
+
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_update(), update_exports));
|
|
23221
23282
|
const packageRoot = path33.resolve(
|
|
23222
23283
|
new URL("../..", import.meta.url).pathname
|
|
23223
23284
|
);
|
package/dist/bin/update.js
CHANGED
|
@@ -56,43 +56,101 @@ function checkForUpdate(packageRoot) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// src/bin/update.ts
|
|
59
|
-
|
|
59
|
+
async function runUpdate(cliArgs) {
|
|
60
|
+
const args = cliArgs ?? process.argv.slice(2);
|
|
61
|
+
const autoMode = args.includes("--auto") || args.includes("-y");
|
|
62
|
+
const checkOnly = args.includes("--check");
|
|
60
63
|
const packageRoot = new URL("../..", import.meta.url).pathname;
|
|
61
64
|
const result = checkForUpdate(packageRoot);
|
|
62
65
|
if (result.error) {
|
|
63
|
-
console.error(result.error);
|
|
66
|
+
console.error(`\u26A0\uFE0F ${result.error}`);
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
if (checkOnly) {
|
|
70
|
+
if (result.updateAvailable) {
|
|
71
|
+
console.log(`Update available: v${result.localVersion} \u2192 v${result.remoteVersion}`);
|
|
72
|
+
} else {
|
|
73
|
+
console.log(`\u2705 exe-os is up to date (v${result.localVersion})`);
|
|
74
|
+
}
|
|
64
75
|
process.exit(0);
|
|
65
76
|
}
|
|
66
77
|
if (!result.updateAvailable) {
|
|
67
|
-
console.log(
|
|
78
|
+
console.log(`\u2705 exe-os is up to date (v${result.localVersion})`);
|
|
68
79
|
process.exit(0);
|
|
69
80
|
}
|
|
70
|
-
console.log(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
console.log(`
|
|
82
|
+
\u{1F4E6} Update available: v${result.localVersion} \u2192 v${result.remoteVersion}
|
|
83
|
+
`);
|
|
84
|
+
let proceed = autoMode;
|
|
85
|
+
if (!proceed) {
|
|
86
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
87
|
+
const answer = await new Promise((resolve) => {
|
|
88
|
+
rl.question("Install update? (Y/n) ", resolve);
|
|
89
|
+
});
|
|
90
|
+
rl.close();
|
|
91
|
+
proceed = answer.toLowerCase() !== "n";
|
|
92
|
+
}
|
|
93
|
+
if (!proceed) {
|
|
94
|
+
console.log("Update skipped.");
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
console.log("\n\u{1F9F9} Clearing npm cache...");
|
|
98
|
+
try {
|
|
99
|
+
execSync2("npm cache clean --force", { stdio: "pipe" });
|
|
100
|
+
console.log(" Done");
|
|
101
|
+
} catch {
|
|
102
|
+
console.log(" Skipped (non-critical)");
|
|
103
|
+
}
|
|
104
|
+
console.log("\u{1F4E5} Installing @askexenow/exe-os@latest...");
|
|
105
|
+
try {
|
|
106
|
+
execSync2("npm install -g @askexenow/exe-os@latest", {
|
|
107
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
108
|
+
timeout: 12e4
|
|
109
|
+
});
|
|
110
|
+
} catch (err) {
|
|
111
|
+
console.error("\n\u274C Update failed.");
|
|
112
|
+
console.error(" Try manually: npm install -g @askexenow/exe-os@latest");
|
|
113
|
+
if (err instanceof Error && err.message) {
|
|
114
|
+
console.error(` Error: ${err.message.split("\n")[0]}`);
|
|
115
|
+
}
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
let newVersion;
|
|
119
|
+
try {
|
|
120
|
+
newVersion = getLocalVersion(packageRoot);
|
|
121
|
+
} catch {
|
|
81
122
|
try {
|
|
82
|
-
execSync2("npm
|
|
83
|
-
|
|
123
|
+
const out = execSync2("npm list -g @askexenow/exe-os --depth=0 2>/dev/null", { encoding: "utf8" });
|
|
124
|
+
const match = out.match(/@askexenow\/exe-os@(\S+)/);
|
|
125
|
+
newVersion = match?.[1] ?? "unknown";
|
|
84
126
|
} catch {
|
|
85
|
-
|
|
86
|
-
"Update failed. Try running manually: npx exe-os --global"
|
|
87
|
-
);
|
|
88
|
-
process.exit(1);
|
|
127
|
+
newVersion = "unknown";
|
|
89
128
|
}
|
|
129
|
+
}
|
|
130
|
+
const remoteVersion = result.remoteVersion;
|
|
131
|
+
if (newVersion === remoteVersion) {
|
|
132
|
+
console.log(`
|
|
133
|
+
\u2705 Updated to v${newVersion}`);
|
|
134
|
+
} else if (newVersion !== result.localVersion) {
|
|
135
|
+
console.log(`
|
|
136
|
+
\u2705 Updated to v${newVersion} (latest: v${remoteVersion})`);
|
|
90
137
|
} else {
|
|
91
|
-
console.log(
|
|
138
|
+
console.log(`
|
|
139
|
+
\u26A0\uFE0F Version unchanged (v${newVersion}). npm cache may be stale.`);
|
|
140
|
+
console.log(" Try: npm cache clean --force && npm install -g @askexenow/exe-os@latest");
|
|
92
141
|
}
|
|
142
|
+
console.log(" Hooks re-wired, daemon restarted automatically.");
|
|
143
|
+
console.log("\n\u{1F680} Ready. Start your COO session to use the new version.\n");
|
|
144
|
+
}
|
|
145
|
+
if (isMainModule(import.meta.url)) {
|
|
146
|
+
runUpdate().catch((err) => {
|
|
147
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
148
|
+
process.exit(1);
|
|
149
|
+
});
|
|
93
150
|
}
|
|
94
151
|
export {
|
|
95
152
|
checkForUpdate,
|
|
96
153
|
getLocalVersion,
|
|
97
|
-
getRemoteVersion
|
|
154
|
+
getRemoteVersion,
|
|
155
|
+
runUpdate
|
|
98
156
|
};
|
package/package.json
CHANGED