zelari-code 2.44.0 → 2.45.1
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/README.md +22 -5
- package/dist/cli/companion/config.js +70 -9
- package/dist/cli/companion/config.js.map +1 -1
- package/dist/cli/companion/runManager.js +194 -9
- package/dist/cli/companion/runManager.js.map +1 -1
- package/dist/cli/companion/serve.js +223 -9
- package/dist/cli/companion/serve.js.map +1 -1
- package/dist/cli/main.bundled.js +618 -180
- package/dist/cli/main.bundled.js.map +3 -3
- package/dist/cli/serve/harnessClient.js +14 -0
- package/dist/cli/serve/harnessClient.js.map +1 -1
- package/dist/cli/slashHandlers/updater.js +10 -2
- package/dist/cli/slashHandlers/updater.js.map +1 -1
- package/dist/cli/toolRegistry.js +7 -0
- package/dist/cli/toolRegistry.js.map +1 -1
- package/dist/cli/tools/taskTool.js +10 -4
- package/dist/cli/tools/taskTool.js.map +1 -1
- package/dist/cli/updater.js +88 -3
- package/dist/cli/updater.js.map +1 -1
- package/dist/cli/utils/doctor.js +11 -0
- package/dist/cli/utils/doctor.js.map +1 -1
- package/dist/cli/utils/prereqChecks.js +2 -2
- package/dist/cli/utils/prereqChecks.js.map +1 -1
- package/package.json +5 -5
package/dist/cli/main.bundled.js
CHANGED
|
@@ -807,7 +807,7 @@ async function openBrowser(url2) {
|
|
|
807
807
|
return { bin: "xdg-open", args: [url2] };
|
|
808
808
|
}
|
|
809
809
|
})();
|
|
810
|
-
return new Promise((
|
|
810
|
+
return new Promise((resolve11, reject) => {
|
|
811
811
|
try {
|
|
812
812
|
const child = spawn19(cmd.bin, cmd.args, {
|
|
813
813
|
stdio: "ignore",
|
|
@@ -816,9 +816,9 @@ async function openBrowser(url2) {
|
|
|
816
816
|
child.on("error", (err) => reject(err));
|
|
817
817
|
child.on("spawn", () => {
|
|
818
818
|
child.unref();
|
|
819
|
-
|
|
819
|
+
resolve11();
|
|
820
820
|
});
|
|
821
|
-
setTimeout(() =>
|
|
821
|
+
setTimeout(() => resolve11(), 100);
|
|
822
822
|
} catch (err) {
|
|
823
823
|
reject(err);
|
|
824
824
|
}
|
|
@@ -867,7 +867,7 @@ async function waitForLoopbackCallback(options) {
|
|
|
867
867
|
const host = options.host ?? "127.0.0.1";
|
|
868
868
|
const timeoutMs2 = options.timeoutMs ?? 3e5;
|
|
869
869
|
const expectedPath = options.path.startsWith("/") ? options.path : `/${options.path}`;
|
|
870
|
-
return new Promise((
|
|
870
|
+
return new Promise((resolve11, reject) => {
|
|
871
871
|
let settled = false;
|
|
872
872
|
const server = createServer((req, res) => {
|
|
873
873
|
const url2 = new URL(req.url ?? "/", `http://${host}`);
|
|
@@ -896,7 +896,7 @@ async function waitForLoopbackCallback(options) {
|
|
|
896
896
|
clearTimeout(timer);
|
|
897
897
|
server.close(() => {
|
|
898
898
|
if (err) reject(err);
|
|
899
|
-
else
|
|
899
|
+
else resolve11(value ?? {});
|
|
900
900
|
});
|
|
901
901
|
};
|
|
902
902
|
server.on("error", (err) => finish2(void 0, err));
|
|
@@ -19086,7 +19086,7 @@ function createBashTool(spawnSeam) {
|
|
|
19086
19086
|
timeoutMs: 6e4,
|
|
19087
19087
|
inputSchema: BashArgsSchema,
|
|
19088
19088
|
execute: async (args, ctx) => {
|
|
19089
|
-
return new Promise((
|
|
19089
|
+
return new Promise((resolve11) => {
|
|
19090
19090
|
const start = Date.now();
|
|
19091
19091
|
const cwd = args.cwd ?? ctx.cwd;
|
|
19092
19092
|
const resolved = resolveShell();
|
|
@@ -19113,7 +19113,7 @@ function createBashTool(spawnSeam) {
|
|
|
19113
19113
|
if (spawnSeam) {
|
|
19114
19114
|
const seamResult = spawnSeam({ program, argv, cwd, env, signal: ctx.signal });
|
|
19115
19115
|
if (seamResult.outcome !== "spawned") {
|
|
19116
|
-
|
|
19116
|
+
resolve11(typedErr(seamResult.reason));
|
|
19117
19117
|
return;
|
|
19118
19118
|
}
|
|
19119
19119
|
child = seamResult.child;
|
|
@@ -19140,14 +19140,14 @@ function createBashTool(spawnSeam) {
|
|
|
19140
19140
|
});
|
|
19141
19141
|
const timer = setTimeout(() => {
|
|
19142
19142
|
child.kill("SIGTERM");
|
|
19143
|
-
|
|
19143
|
+
resolve11(typedErr(`Bash command timed out after ${args.timeoutMs}ms. If it was waiting for interactive input: stdin is closed \u2014 pass non-interactive flags or create the files directly instead of retrying.`));
|
|
19144
19144
|
}, args.timeoutMs);
|
|
19145
19145
|
child.on("close", (code) => {
|
|
19146
19146
|
clearTimeout(timer);
|
|
19147
19147
|
const cappedStdout = stdout.slice(0, maxBuffer);
|
|
19148
19148
|
const cappedStderr = stderr.slice(0, maxBuffer);
|
|
19149
19149
|
const interactive = INTERACTIVE_CANCEL_RE.test(cappedStdout) || INTERACTIVE_CANCEL_RE.test(cappedStderr);
|
|
19150
|
-
|
|
19150
|
+
resolve11(typedOk({
|
|
19151
19151
|
stdout: cappedStdout,
|
|
19152
19152
|
stderr: cappedStderr,
|
|
19153
19153
|
exitCode: code ?? -1,
|
|
@@ -19159,7 +19159,7 @@ function createBashTool(spawnSeam) {
|
|
|
19159
19159
|
});
|
|
19160
19160
|
child.on("error", (err) => {
|
|
19161
19161
|
clearTimeout(timer);
|
|
19162
|
-
|
|
19162
|
+
resolve11(typedErr(err.message));
|
|
19163
19163
|
});
|
|
19164
19164
|
});
|
|
19165
19165
|
}
|
|
@@ -22296,7 +22296,7 @@ var init_nodeProviders = __esm({
|
|
|
22296
22296
|
const isWindows = process.platform === "win32";
|
|
22297
22297
|
const file2 = isWindows ? "cmd.exe" : "/bin/sh";
|
|
22298
22298
|
const args = isWindows ? ["/d", "/s", "/c", command] : ["-c", command];
|
|
22299
|
-
return await new Promise((
|
|
22299
|
+
return await new Promise((resolve11) => {
|
|
22300
22300
|
const child = spawn2(file2, args, {
|
|
22301
22301
|
cwd,
|
|
22302
22302
|
shell: false,
|
|
@@ -22329,7 +22329,7 @@ var init_nodeProviders = __esm({
|
|
|
22329
22329
|
});
|
|
22330
22330
|
child.on("error", (err) => {
|
|
22331
22331
|
clearTimeout(timer);
|
|
22332
|
-
|
|
22332
|
+
resolve11({
|
|
22333
22333
|
exitCode: null,
|
|
22334
22334
|
stdout,
|
|
22335
22335
|
stderr: `${stderr}${err.message}`,
|
|
@@ -22339,7 +22339,7 @@ var init_nodeProviders = __esm({
|
|
|
22339
22339
|
});
|
|
22340
22340
|
child.on("close", (code) => {
|
|
22341
22341
|
clearTimeout(timer);
|
|
22342
|
-
|
|
22342
|
+
resolve11({ exitCode: code, stdout, stderr, durationMs: Date.now() - started, timedOut });
|
|
22343
22343
|
});
|
|
22344
22344
|
});
|
|
22345
22345
|
}
|
|
@@ -22417,7 +22417,7 @@ import path16 from "node:path";
|
|
|
22417
22417
|
import crypto2 from "node:crypto";
|
|
22418
22418
|
import { spawn as spawn3 } from "node:child_process";
|
|
22419
22419
|
async function git(cwd, args) {
|
|
22420
|
-
return await new Promise((
|
|
22420
|
+
return await new Promise((resolve11, reject) => {
|
|
22421
22421
|
const child = spawn3("git", args, { cwd, shell: false });
|
|
22422
22422
|
let stdout = "";
|
|
22423
22423
|
let stderr = "";
|
|
@@ -22426,7 +22426,7 @@ async function git(cwd, args) {
|
|
|
22426
22426
|
child.on("error", (err) => reject(err));
|
|
22427
22427
|
child.on("close", (code) => {
|
|
22428
22428
|
if (code === 0)
|
|
22429
|
-
|
|
22429
|
+
resolve11(stdout);
|
|
22430
22430
|
else
|
|
22431
22431
|
reject(new Error(`git ${args.join(" ")} failed (${code}): ${stderr.trim()}`));
|
|
22432
22432
|
});
|
|
@@ -30565,8 +30565,8 @@ function wrapLegacyStream(legacyStream, params, _messages, _tools) {
|
|
|
30565
30565
|
}
|
|
30566
30566
|
if (done)
|
|
30567
30567
|
break;
|
|
30568
|
-
await new Promise((
|
|
30569
|
-
resolveNext =
|
|
30568
|
+
await new Promise((resolve11) => {
|
|
30569
|
+
resolveNext = resolve11;
|
|
30570
30570
|
});
|
|
30571
30571
|
}
|
|
30572
30572
|
await promise2;
|
|
@@ -30699,11 +30699,11 @@ var init_sessionJsonl = __esm({
|
|
|
30699
30699
|
*/
|
|
30700
30700
|
scheduleFlush() {
|
|
30701
30701
|
if (this.pending.length > 0 && !this.flushDeferred) {
|
|
30702
|
-
let
|
|
30702
|
+
let resolve11;
|
|
30703
30703
|
const promise2 = new Promise((r) => {
|
|
30704
|
-
|
|
30704
|
+
resolve11 = r;
|
|
30705
30705
|
});
|
|
30706
|
-
this.flushDeferred = { promise: promise2, resolve:
|
|
30706
|
+
this.flushDeferred = { promise: promise2, resolve: resolve11 };
|
|
30707
30707
|
}
|
|
30708
30708
|
if (this.flushTimer === null && this.pending.length > 0) {
|
|
30709
30709
|
this.flushTimer = setTimeout(() => {
|
|
@@ -31010,7 +31010,7 @@ var init_lifecycleHookRunner = __esm({
|
|
|
31010
31010
|
}
|
|
31011
31011
|
/** Spawn `command`, write JSON payload to stdin, read stdout until close. */
|
|
31012
31012
|
execCommand(command, payload, timeoutMs2, cwd) {
|
|
31013
|
-
return new Promise((
|
|
31013
|
+
return new Promise((resolve11, reject) => {
|
|
31014
31014
|
const argv = splitHookCommandLine(command);
|
|
31015
31015
|
if (argv.length === 0) {
|
|
31016
31016
|
reject(new Error("empty hook command"));
|
|
@@ -31044,7 +31044,7 @@ var init_lifecycleHookRunner = __esm({
|
|
|
31044
31044
|
reject(new Error(`exited ${code}: ${stderr.trim().slice(0, 200)}`));
|
|
31045
31045
|
return;
|
|
31046
31046
|
}
|
|
31047
|
-
|
|
31047
|
+
resolve11(stdout);
|
|
31048
31048
|
});
|
|
31049
31049
|
child.stdin?.on("error", () => {
|
|
31050
31050
|
});
|
|
@@ -38898,7 +38898,7 @@ var CORE_VERSION;
|
|
|
38898
38898
|
var init_version = __esm({
|
|
38899
38899
|
"packages/core/dist/version.js"() {
|
|
38900
38900
|
"use strict";
|
|
38901
|
-
CORE_VERSION = "2.
|
|
38901
|
+
CORE_VERSION = "2.45.1";
|
|
38902
38902
|
}
|
|
38903
38903
|
});
|
|
38904
38904
|
|
|
@@ -40116,15 +40116,48 @@ __export(updater_exports, {
|
|
|
40116
40116
|
fetchLatestVersion: () => fetchLatestVersion,
|
|
40117
40117
|
getCurrentVersion: () => getCurrentVersion,
|
|
40118
40118
|
looksLikeBrokenShim: () => looksLikeBrokenShim,
|
|
40119
|
+
nonGlobalUpdateAdvisory: () => nonGlobalUpdateAdvisory,
|
|
40119
40120
|
performUpdate: () => performUpdate,
|
|
40120
40121
|
registryUrlForTag: () => registryUrlForTag,
|
|
40121
|
-
resolveBundledNpmCli: () => resolveBundledNpmCli
|
|
40122
|
+
resolveBundledNpmCli: () => resolveBundledNpmCli,
|
|
40123
|
+
resolveInstallKind: () => resolveInstallKind
|
|
40122
40124
|
});
|
|
40123
40125
|
import { createRequire } from "node:module";
|
|
40124
|
-
import { spawn as spawn6 } from "node:child_process";
|
|
40126
|
+
import { execSync, spawn as spawn6 } from "node:child_process";
|
|
40125
40127
|
import { existsSync as existsSync14 } from "node:fs";
|
|
40128
|
+
import os2 from "node:os";
|
|
40126
40129
|
import path32 from "node:path";
|
|
40127
40130
|
import { fileURLToPath } from "node:url";
|
|
40131
|
+
function getGlobalPrefix() {
|
|
40132
|
+
try {
|
|
40133
|
+
const out = execSync("npm prefix -g", {
|
|
40134
|
+
encoding: "utf8",
|
|
40135
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
40136
|
+
}).trim();
|
|
40137
|
+
return out || null;
|
|
40138
|
+
} catch {
|
|
40139
|
+
return null;
|
|
40140
|
+
}
|
|
40141
|
+
}
|
|
40142
|
+
function normalizeForMatch2(p3) {
|
|
40143
|
+
return path32.resolve(p3).replace(/\\/g, "/").replace(/\/+$/, "").toLowerCase();
|
|
40144
|
+
}
|
|
40145
|
+
function resolveInstallKind(npmPrefix = getGlobalPrefix(), packageRoot2 = PKG_ROOT) {
|
|
40146
|
+
const root = normalizeForMatch2(packageRoot2);
|
|
40147
|
+
const tmp = normalizeForMatch2(os2.tmpdir());
|
|
40148
|
+
const inTmp = tmp !== "" && (root === tmp || root.startsWith(`${tmp}/`));
|
|
40149
|
+
if (root.split("/").includes("_npx") || inTmp) return "npx";
|
|
40150
|
+
if (!npmPrefix) return "unknown";
|
|
40151
|
+
const prefix = normalizeForMatch2(npmPrefix);
|
|
40152
|
+
if (root === prefix || root.startsWith(`${prefix}/`)) return "global";
|
|
40153
|
+
return "local";
|
|
40154
|
+
}
|
|
40155
|
+
function nonGlobalUpdateAdvisory(kind2) {
|
|
40156
|
+
const where = kind2 === "npx" ? "was started via npx (from npm's cache)" : "is a local/source install";
|
|
40157
|
+
return `[update] this zelari-code ${where}, not a global install \u2014 self-update is disabled.
|
|
40158
|
+
update with: npx zelari-code@latest (always fetches the latest)
|
|
40159
|
+
or install persistently: npm install -g zelari-code (enables /update)`;
|
|
40160
|
+
}
|
|
40128
40161
|
function resolveBundledNpmCli(execPath = process.execPath) {
|
|
40129
40162
|
const dir = path32.dirname(execPath);
|
|
40130
40163
|
const candidates = [
|
|
@@ -40218,7 +40251,16 @@ async function checkForUpdate(fetcher = fetch, registryUrl) {
|
|
|
40218
40251
|
updateAvailable: cmp < 0
|
|
40219
40252
|
};
|
|
40220
40253
|
}
|
|
40221
|
-
async function performUpdate(packageName = "zelari-code", executor = spawn6, resolveNpmCli = resolveBundledNpmCli, channel) {
|
|
40254
|
+
async function performUpdate(packageName = "zelari-code", executor = spawn6, resolveNpmCli = resolveBundledNpmCli, channel, installKind = resolveInstallKind()) {
|
|
40255
|
+
if (installKind === "npx" || installKind === "local") {
|
|
40256
|
+
return {
|
|
40257
|
+
ok: false,
|
|
40258
|
+
output: nonGlobalUpdateAdvisory(installKind),
|
|
40259
|
+
error: "self-update skipped: non-global install",
|
|
40260
|
+
exitCode: null,
|
|
40261
|
+
installKind
|
|
40262
|
+
};
|
|
40263
|
+
}
|
|
40222
40264
|
const tag = channel ?? distTagForVersion(getCurrentVersion());
|
|
40223
40265
|
const args = ["install", "-g", `${packageName}@${tag}`];
|
|
40224
40266
|
const primary = await runNpm(executor, args, "shim");
|
|
@@ -40235,7 +40277,7 @@ ${fallback.output}`
|
|
|
40235
40277
|
return primary;
|
|
40236
40278
|
}
|
|
40237
40279
|
function runNpm(executor, args, mode, npmCliPath) {
|
|
40238
|
-
return new Promise((
|
|
40280
|
+
return new Promise((resolve11) => {
|
|
40239
40281
|
let stdout = "";
|
|
40240
40282
|
let stderr = "";
|
|
40241
40283
|
const stdio = ["ignore", "pipe", "pipe"];
|
|
@@ -40247,7 +40289,7 @@ function runNpm(executor, args, mode, npmCliPath) {
|
|
|
40247
40289
|
stderr += chunk.toString();
|
|
40248
40290
|
});
|
|
40249
40291
|
child.on("error", (err) => {
|
|
40250
|
-
|
|
40292
|
+
resolve11({
|
|
40251
40293
|
ok: false,
|
|
40252
40294
|
output: stdout + stderr,
|
|
40253
40295
|
error: err.message,
|
|
@@ -40256,7 +40298,7 @@ function runNpm(executor, args, mode, npmCliPath) {
|
|
|
40256
40298
|
});
|
|
40257
40299
|
child.on("close", (code) => {
|
|
40258
40300
|
const ok = code === 0;
|
|
40259
|
-
|
|
40301
|
+
resolve11({
|
|
40260
40302
|
ok,
|
|
40261
40303
|
output: stdout + stderr,
|
|
40262
40304
|
error: ok ? void 0 : `npm exited with code ${code}`,
|
|
@@ -40265,13 +40307,14 @@ function runNpm(executor, args, mode, npmCliPath) {
|
|
|
40265
40307
|
});
|
|
40266
40308
|
});
|
|
40267
40309
|
}
|
|
40268
|
-
var require2, __dirname2, REGISTRY_URL;
|
|
40310
|
+
var require2, __dirname2, PKG_ROOT, REGISTRY_URL;
|
|
40269
40311
|
var init_updater = __esm({
|
|
40270
40312
|
"src/cli/updater.ts"() {
|
|
40271
40313
|
"use strict";
|
|
40272
40314
|
init_cmdline();
|
|
40273
40315
|
require2 = createRequire(import.meta.url);
|
|
40274
40316
|
__dirname2 = path32.dirname(fileURLToPath(import.meta.url));
|
|
40317
|
+
PKG_ROOT = path32.resolve(__dirname2, "..", "..");
|
|
40275
40318
|
REGISTRY_URL = "https://registry.npmjs.org/zelari-code/latest";
|
|
40276
40319
|
}
|
|
40277
40320
|
});
|
|
@@ -42278,8 +42321,8 @@ var init_storage = __esm({
|
|
|
42278
42321
|
const prev2 = this.chains.get(key) ?? Promise.resolve();
|
|
42279
42322
|
let release = () => {
|
|
42280
42323
|
};
|
|
42281
|
-
const next = new Promise((
|
|
42282
|
-
release =
|
|
42324
|
+
const next = new Promise((resolve11) => {
|
|
42325
|
+
release = resolve11;
|
|
42283
42326
|
});
|
|
42284
42327
|
const chained = prev2.then(() => next);
|
|
42285
42328
|
this.chains.set(key, chained);
|
|
@@ -43075,14 +43118,14 @@ var init_engine2 = __esm({
|
|
|
43075
43118
|
parse: parseRuffJson
|
|
43076
43119
|
}
|
|
43077
43120
|
];
|
|
43078
|
-
defaultRunner = (cmd, args, opts) => new Promise((
|
|
43121
|
+
defaultRunner = (cmd, args, opts) => new Promise((resolve11) => {
|
|
43079
43122
|
let stdout = "";
|
|
43080
43123
|
let stderr = "";
|
|
43081
43124
|
let settled = false;
|
|
43082
43125
|
const done = (r) => {
|
|
43083
43126
|
if (settled) return;
|
|
43084
43127
|
settled = true;
|
|
43085
|
-
|
|
43128
|
+
resolve11(r);
|
|
43086
43129
|
};
|
|
43087
43130
|
let child;
|
|
43088
43131
|
try {
|
|
@@ -44137,7 +44180,7 @@ async function readChecks(cwd) {
|
|
|
44137
44180
|
}
|
|
44138
44181
|
}
|
|
44139
44182
|
function runShell(command, cwd, timeoutMs2, signal) {
|
|
44140
|
-
return new Promise((
|
|
44183
|
+
return new Promise((resolve11) => {
|
|
44141
44184
|
const isWin = process.platform === "win32";
|
|
44142
44185
|
const child = spawn8(isWin ? "cmd.exe" : "/bin/sh", isWin ? ["/c", command] : ["-c", command], {
|
|
44143
44186
|
cwd,
|
|
@@ -44151,7 +44194,7 @@ function runShell(command, cwd, timeoutMs2, signal) {
|
|
|
44151
44194
|
const finish2 = (exitCode) => {
|
|
44152
44195
|
if (settled) return;
|
|
44153
44196
|
settled = true;
|
|
44154
|
-
|
|
44197
|
+
resolve11({ exitCode, stdout, stderr });
|
|
44155
44198
|
};
|
|
44156
44199
|
const timer = setTimeout(() => {
|
|
44157
44200
|
try {
|
|
@@ -46862,8 +46905,8 @@ ${upstream}` : node.prompt,
|
|
|
46862
46905
|
if (ms <= 0) return promise2;
|
|
46863
46906
|
let timer;
|
|
46864
46907
|
const TIMED_OUT = Symbol("timeout");
|
|
46865
|
-
const timeout = new Promise((
|
|
46866
|
-
timer = setTimeout(() =>
|
|
46908
|
+
const timeout = new Promise((resolve11) => {
|
|
46909
|
+
timer = setTimeout(() => resolve11(TIMED_OUT), ms);
|
|
46867
46910
|
});
|
|
46868
46911
|
const raced = await Promise.race([promise2, timeout]).finally(() => {
|
|
46869
46912
|
if (timer) clearTimeout(timer);
|
|
@@ -46872,8 +46915,8 @@ ${upstream}` : node.prompt,
|
|
|
46872
46915
|
controller?.abort();
|
|
46873
46916
|
const graceMs = this.cancelGraceMs ?? resolveCancelGraceMs();
|
|
46874
46917
|
let graceTimer;
|
|
46875
|
-
const grace = new Promise((
|
|
46876
|
-
graceTimer = setTimeout(() =>
|
|
46918
|
+
const grace = new Promise((resolve11) => {
|
|
46919
|
+
graceTimer = setTimeout(() => resolve11(TIMED_OUT), graceMs);
|
|
46877
46920
|
});
|
|
46878
46921
|
const settled = await Promise.race([promise2, grace]).finally(() => {
|
|
46879
46922
|
if (graceTimer) clearTimeout(graceTimer);
|
|
@@ -47640,13 +47683,13 @@ ${findings || "(the reviewer reported FAIL without detail)"}`;
|
|
|
47640
47683
|
async function runAutoVerifyAfterGeneral(opts) {
|
|
47641
47684
|
const g = globalThis;
|
|
47642
47685
|
g.__zelariGeneralVerifyDebt = { description: opts.original.description };
|
|
47643
|
-
const emitVerifyPhase = (detail2, ok) => {
|
|
47686
|
+
const emitVerifyPhase = (detail2, ok, terminal) => {
|
|
47644
47687
|
const agentId = opts.general.agentId;
|
|
47645
47688
|
if (agentId) {
|
|
47646
47689
|
opts.deps.onTentacleEvent?.({
|
|
47647
47690
|
type: "agent_status",
|
|
47648
47691
|
agentId,
|
|
47649
|
-
status: "running",
|
|
47692
|
+
status: terminal ?? "running",
|
|
47650
47693
|
message: detail2,
|
|
47651
47694
|
id: randomUUID4(),
|
|
47652
47695
|
sessionId: opts.sessionId,
|
|
@@ -47714,6 +47757,7 @@ async function runAutoVerifyAfterGeneral(opts) {
|
|
|
47714
47757
|
detail: detail2,
|
|
47715
47758
|
ok: false
|
|
47716
47759
|
});
|
|
47760
|
+
emitVerifyPhase(`rework round ${round2} failed`, false, "failed");
|
|
47717
47761
|
return `
|
|
47718
47762
|
|
|
47719
47763
|
[kraken:auto-verify] verify FAIL \u2014 rework round ${round2} failed to run (${rework.error}). Work stays UNVERIFIED; strict done will close this turn blocked.`;
|
|
@@ -47725,14 +47769,15 @@ async function runAutoVerifyAfterGeneral(opts) {
|
|
|
47725
47769
|
}
|
|
47726
47770
|
if (verdict === "pass") {
|
|
47727
47771
|
g.__zelariGeneralVerifyDebt = null;
|
|
47728
|
-
emitVerifyPhase("verify PASS", true);
|
|
47772
|
+
emitVerifyPhase("verify PASS", true, "completed");
|
|
47729
47773
|
return `
|
|
47730
47774
|
|
|
47731
47775
|
[kraken:auto-verify] verify PASS \u2014 general\u21D2verify obligation satisfied.`;
|
|
47732
47776
|
}
|
|
47733
47777
|
emitVerifyPhase(
|
|
47734
47778
|
verdict === "fail" ? "verify FAIL" : verify.ok ? "verify unknown" : "verify failed",
|
|
47735
|
-
verdict === "fail" || !verify.ok ? false : void 0
|
|
47779
|
+
verdict === "fail" || !verify.ok ? false : void 0,
|
|
47780
|
+
"failed"
|
|
47736
47781
|
);
|
|
47737
47782
|
const detail = verdict === "fail" ? `verify FAIL unresolved (rework budget spent): ${findings || "no findings reported"}` : verify.ok ? "verify produced no parseable VERDICT \u2014 unverified" : `verify tentacle failed: ${verify.error}`;
|
|
47738
47783
|
g.__zelariGeneralVerifyDebt = { description: opts.original.description, detail };
|
|
@@ -50772,13 +50817,13 @@ async function scanTsbuildinfo(root) {
|
|
|
50772
50817
|
return found;
|
|
50773
50818
|
}
|
|
50774
50819
|
async function gitStatusPorcelain(root) {
|
|
50775
|
-
return new Promise((
|
|
50820
|
+
return new Promise((resolve11) => {
|
|
50776
50821
|
const child = spawn9("git", ["status", "--porcelain"], { cwd: root, shell: false });
|
|
50777
50822
|
let out = "";
|
|
50778
50823
|
child.stdout.on("data", (d) => out += d.toString());
|
|
50779
50824
|
child.stderr.on("data", (d) => out += d.toString());
|
|
50780
|
-
child.on("error", () =>
|
|
50781
|
-
child.on("close", (code) =>
|
|
50825
|
+
child.on("error", () => resolve11("<git-unavailable>"));
|
|
50826
|
+
child.on("close", (code) => resolve11(code === 0 ? out : `<git-exit-${code ?? "none"}>`));
|
|
50782
50827
|
});
|
|
50783
50828
|
}
|
|
50784
50829
|
async function fingerprintWorkspace(root) {
|
|
@@ -50826,7 +50871,7 @@ var init_inspectTypecheckSafety = __esm({
|
|
|
50826
50871
|
import { spawn as spawn10 } from "node:child_process";
|
|
50827
50872
|
import { createHash as createHash14 } from "node:crypto";
|
|
50828
50873
|
import { existsSync as existsSync30, promises as fs23 } from "node:fs";
|
|
50829
|
-
import
|
|
50874
|
+
import os3 from "node:os";
|
|
50830
50875
|
import path52 from "node:path";
|
|
50831
50876
|
function resolveNodeModuleBin(start, rel2) {
|
|
50832
50877
|
let dir = path52.resolve(start);
|
|
@@ -50912,7 +50957,7 @@ function buildInspectCommand(op, ctx) {
|
|
|
50912
50957
|
case "typecheck": {
|
|
50913
50958
|
const project = path52.resolve(ctx.cwd, op.project ?? "tsconfig.json");
|
|
50914
50959
|
const hash3 = createHash14("sha256").update(project).digest("hex").slice(0, 16);
|
|
50915
|
-
const tsBuildInfoFile = path52.join(
|
|
50960
|
+
const tsBuildInfoFile = path52.join(os3.tmpdir(), "zelari-inspect", `${hash3}.tsbuildinfo`);
|
|
50916
50961
|
return {
|
|
50917
50962
|
ok: true,
|
|
50918
50963
|
command: process.execPath,
|
|
@@ -50936,12 +50981,12 @@ function buildInspectCommand(op, ctx) {
|
|
|
50936
50981
|
}
|
|
50937
50982
|
}
|
|
50938
50983
|
function runSpawn(command, argv, opts) {
|
|
50939
|
-
return new Promise((
|
|
50984
|
+
return new Promise((resolve11) => {
|
|
50940
50985
|
let child;
|
|
50941
50986
|
try {
|
|
50942
50987
|
child = spawn10(command, argv, { cwd: opts.cwd, shell: false });
|
|
50943
50988
|
} catch (err) {
|
|
50944
|
-
|
|
50989
|
+
resolve11({ code: null, stdout: "", stderr: String(err), timedOut: false, spawnError: String(err) });
|
|
50945
50990
|
return;
|
|
50946
50991
|
}
|
|
50947
50992
|
let stdout = "";
|
|
@@ -50963,14 +51008,14 @@ function runSpawn(command, argv, opts) {
|
|
|
50963
51008
|
if (settled) return;
|
|
50964
51009
|
settled = true;
|
|
50965
51010
|
clearTimeout(timer);
|
|
50966
|
-
|
|
51011
|
+
resolve11({ code: null, stdout, stderr, timedOut, spawnError: err.message });
|
|
50967
51012
|
});
|
|
50968
51013
|
child.on("close", (code) => {
|
|
50969
51014
|
if (settled) return;
|
|
50970
51015
|
settled = true;
|
|
50971
51016
|
clearTimeout(timer);
|
|
50972
51017
|
opts.signal?.removeEventListener("abort", onAbort);
|
|
50973
|
-
|
|
51018
|
+
resolve11({ code, stdout, stderr, timedOut });
|
|
50974
51019
|
});
|
|
50975
51020
|
});
|
|
50976
51021
|
}
|
|
@@ -51255,7 +51300,7 @@ function createExecProcessTool(root, opts = {}) {
|
|
|
51255
51300
|
const msg = err instanceof SandboxViolationError ? err.message : String(err);
|
|
51256
51301
|
return typedErr(`[sandbox] ${msg}`);
|
|
51257
51302
|
}
|
|
51258
|
-
return new Promise((
|
|
51303
|
+
return new Promise((resolve11) => {
|
|
51259
51304
|
const start = Date.now();
|
|
51260
51305
|
const spec = { ...baseSpec, network: opts.resolveNetwork?.(input) ?? baseSpec.network };
|
|
51261
51306
|
const res = spawnJailed(spec, {
|
|
@@ -51267,11 +51312,11 @@ function createExecProcessTool(root, opts = {}) {
|
|
|
51267
51312
|
envExtras: { CI: process.env.CI ?? "1" }
|
|
51268
51313
|
});
|
|
51269
51314
|
if (res.outcome === "denied") {
|
|
51270
|
-
|
|
51315
|
+
resolve11(typedErr(res.reason));
|
|
51271
51316
|
return;
|
|
51272
51317
|
}
|
|
51273
51318
|
if (res.outcome === "failed") {
|
|
51274
|
-
|
|
51319
|
+
resolve11(typedErr(`exec_process could not launch ${input.program}: ${res.reason}`));
|
|
51275
51320
|
return;
|
|
51276
51321
|
}
|
|
51277
51322
|
const meta3 = res.notice ? { status: "complete", warnings: [`os-jail: ${res.notice}`] } : void 0;
|
|
@@ -51287,7 +51332,7 @@ function createExecProcessTool(root, opts = {}) {
|
|
|
51287
51332
|
const timeoutMs2 = typeof input.timeoutMs === "number" && input.timeoutMs > 0 ? input.timeoutMs : 3e4;
|
|
51288
51333
|
const timer = setTimeout(() => {
|
|
51289
51334
|
child.kill("SIGTERM");
|
|
51290
|
-
|
|
51335
|
+
resolve11(
|
|
51291
51336
|
typedErr(
|
|
51292
51337
|
`exec_process timed out after ${timeoutMs2}ms running: ${[input.program, ...argv].join(" ")}`
|
|
51293
51338
|
)
|
|
@@ -51295,11 +51340,11 @@ function createExecProcessTool(root, opts = {}) {
|
|
|
51295
51340
|
}, timeoutMs2);
|
|
51296
51341
|
child.on("error", (err) => {
|
|
51297
51342
|
clearTimeout(timer);
|
|
51298
|
-
|
|
51343
|
+
resolve11(typedErr(`exec_process could not launch ${input.program}: ${err.message}`));
|
|
51299
51344
|
});
|
|
51300
51345
|
child.on("close", (code) => {
|
|
51301
51346
|
clearTimeout(timer);
|
|
51302
|
-
|
|
51347
|
+
resolve11(
|
|
51303
51348
|
typedOk(
|
|
51304
51349
|
{
|
|
51305
51350
|
exitCode: code ?? -1,
|
|
@@ -51828,12 +51873,12 @@ var init_client = __esm({
|
|
|
51828
51873
|
if (this.closed) return Promise.reject(new Error("LSP transport is closed"));
|
|
51829
51874
|
const id3 = this.nextId++;
|
|
51830
51875
|
const msg = { jsonrpc: "2.0", id: id3, method, ...params !== void 0 ? { params } : {} };
|
|
51831
|
-
return new Promise((
|
|
51876
|
+
return new Promise((resolve11, reject) => {
|
|
51832
51877
|
const timer = setTimeout(() => {
|
|
51833
51878
|
this.pending.delete(id3);
|
|
51834
51879
|
reject(new Error(`LSP request "${method}" timed out after ${this.timeoutMs}ms`));
|
|
51835
51880
|
}, this.timeoutMs);
|
|
51836
|
-
this.pending.set(id3, { resolve:
|
|
51881
|
+
this.pending.set(id3, { resolve: resolve11, reject, timer });
|
|
51837
51882
|
this.transport.send(encodeMessage(msg));
|
|
51838
51883
|
});
|
|
51839
51884
|
}
|
|
@@ -52110,8 +52155,8 @@ var init_manager = __esm({
|
|
|
52110
52155
|
if (cached2 !== void 0) return cached2;
|
|
52111
52156
|
let resolveInit;
|
|
52112
52157
|
let rejectInit;
|
|
52113
|
-
const initialized = new Promise((
|
|
52114
|
-
resolveInit =
|
|
52158
|
+
const initialized = new Promise((resolve11, reject) => {
|
|
52159
|
+
resolveInit = resolve11;
|
|
52115
52160
|
rejectInit = reject;
|
|
52116
52161
|
});
|
|
52117
52162
|
let entry = null;
|
|
@@ -52636,14 +52681,14 @@ function resolveStreamTimeouts(capabilities) {
|
|
|
52636
52681
|
};
|
|
52637
52682
|
}
|
|
52638
52683
|
function abortableSleep(ms, signal) {
|
|
52639
|
-
return new Promise((
|
|
52640
|
-
if (signal?.aborted) return
|
|
52641
|
-
const t = setTimeout(
|
|
52684
|
+
return new Promise((resolve11) => {
|
|
52685
|
+
if (signal?.aborted) return resolve11();
|
|
52686
|
+
const t = setTimeout(resolve11, ms);
|
|
52642
52687
|
signal?.addEventListener(
|
|
52643
52688
|
"abort",
|
|
52644
52689
|
() => {
|
|
52645
52690
|
clearTimeout(t);
|
|
52646
|
-
|
|
52691
|
+
resolve11();
|
|
52647
52692
|
},
|
|
52648
52693
|
{ once: true }
|
|
52649
52694
|
);
|
|
@@ -53517,8 +53562,8 @@ async function runBrowserCheck(options, loader) {
|
|
|
53517
53562
|
const failedRequests = [];
|
|
53518
53563
|
const evaluateResults = [];
|
|
53519
53564
|
const base2 = { ok: false, consoleErrors, pageErrors, failedRequests };
|
|
53520
|
-
const
|
|
53521
|
-
const pw = await
|
|
53565
|
+
const resolve11 = loader ?? (() => loadPlaywright(options.cwd ?? process.cwd()));
|
|
53566
|
+
const pw = await resolve11();
|
|
53522
53567
|
if (!pw) {
|
|
53523
53568
|
return {
|
|
53524
53569
|
...base2,
|
|
@@ -53681,7 +53726,7 @@ var init_driver = __esm({
|
|
|
53681
53726
|
|
|
53682
53727
|
// src/cli/browser/tools.ts
|
|
53683
53728
|
import path58 from "node:path";
|
|
53684
|
-
import
|
|
53729
|
+
import os4 from "node:os";
|
|
53685
53730
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
53686
53731
|
async function loadImageBlock(filePath) {
|
|
53687
53732
|
try {
|
|
@@ -53708,7 +53753,7 @@ function createBrowserTool(deps = {}) {
|
|
|
53708
53753
|
}),
|
|
53709
53754
|
execute: async (args, ctx) => {
|
|
53710
53755
|
const a = args;
|
|
53711
|
-
const dir = deps.screenshotDir ??
|
|
53756
|
+
const dir = deps.screenshotDir ?? os4.tmpdir();
|
|
53712
53757
|
const screenshotPath = a.screenshot === false ? void 0 : path58.join(dir, `zelari-browser-${Date.now()}.png`);
|
|
53713
53758
|
const result = await runBrowserCheck(
|
|
53714
53759
|
{
|
|
@@ -54111,9 +54156,9 @@ exec node "$(dirname "$0")/askpass.cjs"
|
|
|
54111
54156
|
return sh;
|
|
54112
54157
|
}
|
|
54113
54158
|
function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
|
|
54114
|
-
return new Promise((
|
|
54159
|
+
return new Promise((resolve11) => {
|
|
54115
54160
|
if (target.auth === "password" && !getSshPassword(target.id)) {
|
|
54116
|
-
|
|
54161
|
+
resolve11({
|
|
54117
54162
|
code: 1,
|
|
54118
54163
|
stdout: "",
|
|
54119
54164
|
stderr: "No password stored for this target \u2014 edit target and set password"
|
|
@@ -54145,7 +54190,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
|
|
|
54145
54190
|
});
|
|
54146
54191
|
const timer = setTimeout(() => {
|
|
54147
54192
|
child.kill("SIGTERM");
|
|
54148
|
-
|
|
54193
|
+
resolve11({
|
|
54149
54194
|
code: 124,
|
|
54150
54195
|
stdout,
|
|
54151
54196
|
stderr: stderr + "\n[ssh] timeout"
|
|
@@ -54153,7 +54198,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
|
|
|
54153
54198
|
}, timeoutMs2);
|
|
54154
54199
|
child.on("error", (err) => {
|
|
54155
54200
|
clearTimeout(timer);
|
|
54156
|
-
|
|
54201
|
+
resolve11({
|
|
54157
54202
|
code: 127,
|
|
54158
54203
|
stdout,
|
|
54159
54204
|
stderr: err.message.includes("ENOENT") ? "ssh not found on PATH \u2014 install OpenSSH client" : err.message
|
|
@@ -54161,7 +54206,7 @@ function runSsh(target, remoteCommand, timeoutMs2 = 6e4) {
|
|
|
54161
54206
|
});
|
|
54162
54207
|
child.on("close", (code) => {
|
|
54163
54208
|
clearTimeout(timer);
|
|
54164
|
-
|
|
54209
|
+
resolve11({ code: code ?? 1, stdout, stderr });
|
|
54165
54210
|
});
|
|
54166
54211
|
});
|
|
54167
54212
|
}
|
|
@@ -54938,14 +54983,14 @@ function backoffDelay2(attempt, retryAfterHeader) {
|
|
|
54938
54983
|
return Math.min(BACKOFF_BASE_MS2 * 2 ** attempt, BACKOFF_CAP_MS2);
|
|
54939
54984
|
}
|
|
54940
54985
|
function abortableSleep2(ms, signal) {
|
|
54941
|
-
return new Promise((
|
|
54942
|
-
if (signal?.aborted) return
|
|
54943
|
-
const t = setTimeout(
|
|
54986
|
+
return new Promise((resolve11) => {
|
|
54987
|
+
if (signal?.aborted) return resolve11();
|
|
54988
|
+
const t = setTimeout(resolve11, ms);
|
|
54944
54989
|
signal?.addEventListener(
|
|
54945
54990
|
"abort",
|
|
54946
54991
|
() => {
|
|
54947
54992
|
clearTimeout(t);
|
|
54948
|
-
|
|
54993
|
+
resolve11();
|
|
54949
54994
|
},
|
|
54950
54995
|
{ once: true }
|
|
54951
54996
|
);
|
|
@@ -57035,6 +57080,9 @@ function wrapWithPermissions(original, policy, onAsk, agentLayers, precedence =
|
|
|
57035
57080
|
}
|
|
57036
57081
|
const claimHit = claims && claims.effect !== void 0 ? claims.matchedRules.find((x) => x.effect === claims.effect) : void 0;
|
|
57037
57082
|
const rulePrefix = contractRule ? `[contract] rule '${contractRule.match}'${contractRule.reason ? ` \u2014 ${contractRule.reason}` : ""}` : rule ? `[policy] rule '${rule.match}'${rule.reason ? ` \u2014 ${rule.reason}` : ""}` : claimHit ? `[policy] claim '${claimHit.match}'${claimHit.reason ? ` \u2014 ${claimHit.reason}` : ""}` : "";
|
|
57083
|
+
if (action === "ask" && activePermissionPreset() === "yolo") {
|
|
57084
|
+
action = "allow";
|
|
57085
|
+
}
|
|
57038
57086
|
if (action === "deny") {
|
|
57039
57087
|
return typedErr(`[permission] ${rulePrefix || decision.reason}`);
|
|
57040
57088
|
}
|
|
@@ -57565,12 +57613,12 @@ var init_metrics3 = __esm({
|
|
|
57565
57613
|
}
|
|
57566
57614
|
/** Append a single record synchronously (file I/O). */
|
|
57567
57615
|
append(rec) {
|
|
57568
|
-
return new Promise((
|
|
57616
|
+
return new Promise((resolve11, reject) => {
|
|
57569
57617
|
try {
|
|
57570
57618
|
this.maybeRotate();
|
|
57571
57619
|
const line = JSON.stringify(rec) + "\n";
|
|
57572
57620
|
appendFileSync3(this.file, line, { encoding: "utf-8" });
|
|
57573
|
-
|
|
57621
|
+
resolve11();
|
|
57574
57622
|
} catch (err) {
|
|
57575
57623
|
reject(err);
|
|
57576
57624
|
}
|
|
@@ -58955,8 +59003,8 @@ var init_sqliteRpc = __esm({
|
|
|
58955
59003
|
const worker = this.worker;
|
|
58956
59004
|
if (!worker) return Promise.reject(new Error("SQLite worker is not open."));
|
|
58957
59005
|
const id3 = this.nextId++;
|
|
58958
|
-
return new Promise((
|
|
58959
|
-
this.pending.set(id3, { resolve:
|
|
59006
|
+
return new Promise((resolve11, reject) => {
|
|
59007
|
+
this.pending.set(id3, { resolve: resolve11, reject });
|
|
58960
59008
|
worker.postMessage({ id: id3, operation, args });
|
|
58961
59009
|
});
|
|
58962
59010
|
}
|
|
@@ -58967,7 +59015,7 @@ var init_sqliteRpc = __esm({
|
|
|
58967
59015
|
return await this.request(operation, args);
|
|
58968
59016
|
} catch (error51) {
|
|
58969
59017
|
if (!isBusy(error51) || attempt >= 3) throw error51;
|
|
58970
|
-
await new Promise((
|
|
59018
|
+
await new Promise((resolve11) => setTimeout(resolve11, 25 * 2 ** attempt));
|
|
58971
59019
|
attempt += 1;
|
|
58972
59020
|
}
|
|
58973
59021
|
}
|
|
@@ -61886,13 +61934,13 @@ __export(claudeProvider_exports, {
|
|
|
61886
61934
|
});
|
|
61887
61935
|
import { spawn as spawn13 } from "node:child_process";
|
|
61888
61936
|
function waitForExit(child, timeoutMs2 = 2e3) {
|
|
61889
|
-
return new Promise((
|
|
61890
|
-
if (child.exitCode != null) return
|
|
61891
|
-
const timer = setTimeout(() =>
|
|
61937
|
+
return new Promise((resolve11) => {
|
|
61938
|
+
if (child.exitCode != null) return resolve11(child.exitCode);
|
|
61939
|
+
const timer = setTimeout(() => resolve11(child.exitCode ?? null), timeoutMs2);
|
|
61892
61940
|
timer.unref?.();
|
|
61893
61941
|
child.once("exit", (code) => {
|
|
61894
61942
|
clearTimeout(timer);
|
|
61895
|
-
|
|
61943
|
+
resolve11(code ?? null);
|
|
61896
61944
|
});
|
|
61897
61945
|
});
|
|
61898
61946
|
}
|
|
@@ -63807,7 +63855,7 @@ var init_mcpClient = __esm({
|
|
|
63807
63855
|
if (!transport && !child)
|
|
63808
63856
|
return Promise.reject(new Error(`[mcp:${this.serverName}] not started`));
|
|
63809
63857
|
const id3 = this.nextId++;
|
|
63810
|
-
return new Promise((
|
|
63858
|
+
return new Promise((resolve11, reject) => {
|
|
63811
63859
|
const timer = setTimeout(() => {
|
|
63812
63860
|
this.pending.delete(id3);
|
|
63813
63861
|
reject(
|
|
@@ -63816,7 +63864,7 @@ var init_mcpClient = __esm({
|
|
|
63816
63864
|
)
|
|
63817
63865
|
);
|
|
63818
63866
|
}, timeoutMs2);
|
|
63819
|
-
this.pending.set(id3, { resolve:
|
|
63867
|
+
this.pending.set(id3, { resolve: resolve11, reject, timer });
|
|
63820
63868
|
if (transport) {
|
|
63821
63869
|
void transport.send({ id: id3, method, params }, timeoutMs2);
|
|
63822
63870
|
} else {
|
|
@@ -67002,12 +67050,12 @@ function startPermissionBroker(socketPath, handlers, opts) {
|
|
|
67002
67050
|
});
|
|
67003
67051
|
}
|
|
67004
67052
|
}
|
|
67005
|
-
return new Promise((
|
|
67053
|
+
return new Promise((resolve11, reject) => {
|
|
67006
67054
|
const onError = (err) => reject(err);
|
|
67007
67055
|
server.once("error", onError);
|
|
67008
67056
|
server.listen(path104, () => {
|
|
67009
67057
|
server.removeListener("error", onError);
|
|
67010
|
-
|
|
67058
|
+
resolve11({
|
|
67011
67059
|
socketPath: path104,
|
|
67012
67060
|
stop: () => new Promise((res) => {
|
|
67013
67061
|
for (const s of sockets) s.destroy();
|
|
@@ -67035,7 +67083,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
67035
67083
|
const path104 = safeSocketPath(socketPath);
|
|
67036
67084
|
const requestTimeoutMs = opts?.requestTimeoutMs ?? PERMISSION_BROKER_DEFAULT_TIMEOUT_MS;
|
|
67037
67085
|
const connectTimeoutMs = opts?.connectTimeoutMs ?? PERMISSION_BROKER_DEFAULT_CONNECT_TIMEOUT_MS;
|
|
67038
|
-
return new Promise((
|
|
67086
|
+
return new Promise((resolve11, reject) => {
|
|
67039
67087
|
const socket = connect(path104);
|
|
67040
67088
|
let buffer = "";
|
|
67041
67089
|
let settled = false;
|
|
@@ -67088,7 +67136,7 @@ function requestBrokerAsk(socketPath, ask, opts) {
|
|
|
67088
67136
|
}
|
|
67089
67137
|
if (msg?.t === "answer" && msg.id === ask.id) {
|
|
67090
67138
|
const { t: _t, id: _id, ...answer } = msg;
|
|
67091
|
-
settle(() =>
|
|
67139
|
+
settle(() => resolve11(answer));
|
|
67092
67140
|
return;
|
|
67093
67141
|
}
|
|
67094
67142
|
}
|
|
@@ -67867,7 +67915,7 @@ __export(prereqChecks_exports, {
|
|
|
67867
67915
|
isWslBashPath: () => isWslBashPath2,
|
|
67868
67916
|
runPrereqChecks: () => runPrereqChecks
|
|
67869
67917
|
});
|
|
67870
|
-
import { execSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
67918
|
+
import { execSync as execSync2, spawnSync as spawnSync2 } from "node:child_process";
|
|
67871
67919
|
import { existsSync as existsSync54 } from "node:fs";
|
|
67872
67920
|
import { dirname as dirname13 } from "node:path";
|
|
67873
67921
|
function isWslBashPath2(p3) {
|
|
@@ -68027,7 +68075,7 @@ function probeTool(tool) {
|
|
|
68027
68075
|
}
|
|
68028
68076
|
} else if (process.platform === "win32") {
|
|
68029
68077
|
try {
|
|
68030
|
-
stdout =
|
|
68078
|
+
stdout = execSync2(`${tool} --version`, {
|
|
68031
68079
|
encoding: "utf8",
|
|
68032
68080
|
stdio: ["ignore", "pipe", "ignore"],
|
|
68033
68081
|
env
|
|
@@ -68036,7 +68084,7 @@ function probeTool(tool) {
|
|
|
68036
68084
|
}
|
|
68037
68085
|
} else {
|
|
68038
68086
|
try {
|
|
68039
|
-
stdout =
|
|
68087
|
+
stdout = execSync2(`${tool} --version`, {
|
|
68040
68088
|
encoding: "utf8",
|
|
68041
68089
|
stdio: ["ignore", "pipe", "ignore"],
|
|
68042
68090
|
env
|
|
@@ -68161,7 +68209,7 @@ function checkAgentBash() {
|
|
|
68161
68209
|
}
|
|
68162
68210
|
function checkMainNode() {
|
|
68163
68211
|
try {
|
|
68164
|
-
const raw =
|
|
68212
|
+
const raw = execSync2("node --version", {
|
|
68165
68213
|
encoding: "utf8",
|
|
68166
68214
|
stdio: ["ignore", "pipe", "ignore"]
|
|
68167
68215
|
}).trim();
|
|
@@ -68221,7 +68269,7 @@ var MIN_NODE_MAJOR, STANDARD_BASH_PATHS2, POWERSHELL_EXES2, STANDARD_POWERSHELL_
|
|
|
68221
68269
|
var init_prereqChecks = __esm({
|
|
68222
68270
|
"src/cli/utils/prereqChecks.ts"() {
|
|
68223
68271
|
"use strict";
|
|
68224
|
-
MIN_NODE_MAJOR =
|
|
68272
|
+
MIN_NODE_MAJOR = 20;
|
|
68225
68273
|
STANDARD_BASH_PATHS2 = [
|
|
68226
68274
|
"C:\\Program Files\\Git\\bin\\bash.exe",
|
|
68227
68275
|
"C:\\Program Files\\Git\\usr\\bin\\bash.exe",
|
|
@@ -74136,8 +74184,8 @@ async function startMemoryMcpServer(options) {
|
|
|
74136
74184
|
let stopped = false;
|
|
74137
74185
|
let finalizePromise;
|
|
74138
74186
|
let resolveClosed = () => void 0;
|
|
74139
|
-
const closed = new Promise((
|
|
74140
|
-
resolveClosed =
|
|
74187
|
+
const closed = new Promise((resolve11) => {
|
|
74188
|
+
resolveClosed = resolve11;
|
|
74141
74189
|
});
|
|
74142
74190
|
const adapter = new MemoryMcpAdapter({
|
|
74143
74191
|
service,
|
|
@@ -74284,8 +74332,8 @@ function startPermissionMcpServer(opts) {
|
|
|
74284
74332
|
});
|
|
74285
74333
|
let closedResolve = () => {
|
|
74286
74334
|
};
|
|
74287
|
-
const closed = new Promise((
|
|
74288
|
-
closedResolve =
|
|
74335
|
+
const closed = new Promise((resolve11) => {
|
|
74336
|
+
closedResolve = resolve11;
|
|
74289
74337
|
});
|
|
74290
74338
|
let stopped = false;
|
|
74291
74339
|
const send = (obj) => {
|
|
@@ -74541,9 +74589,10 @@ import {
|
|
|
74541
74589
|
existsSync as existsSync61,
|
|
74542
74590
|
mkdirSync as mkdirSync24,
|
|
74543
74591
|
readFileSync as readFileSync45,
|
|
74592
|
+
statSync as statSync10,
|
|
74544
74593
|
writeFileSync as writeFileSync26
|
|
74545
74594
|
} from "node:fs";
|
|
74546
|
-
import { join as join48 } from "node:path";
|
|
74595
|
+
import { join as join48, resolve as resolve9 } from "node:path";
|
|
74547
74596
|
import { createHash as createHash26, randomBytes as randomBytes7, timingSafeEqual } from "node:crypto";
|
|
74548
74597
|
function getZelariHome() {
|
|
74549
74598
|
return zelariHome();
|
|
@@ -74632,6 +74681,30 @@ function slugFromPath(p3) {
|
|
|
74632
74681
|
const base2 = p3.replace(/[/\\]+$/, "").split(/[/\\]/).pop() || "project";
|
|
74633
74682
|
return base2.toLowerCase().replace(/[^a-z0-9-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48) || "project";
|
|
74634
74683
|
}
|
|
74684
|
+
function resolveFsDirectory(rawPath) {
|
|
74685
|
+
const trimmed = rawPath.trim();
|
|
74686
|
+
if (!trimmed) return { ok: false, error: "cwd is required" };
|
|
74687
|
+
const norm = trimmed.replace(/\\/g, "/");
|
|
74688
|
+
const absolute = /^([a-zA-Z]:\/|\/)/.test(norm);
|
|
74689
|
+
if (!absolute || norm.split("/").includes("..")) {
|
|
74690
|
+
return {
|
|
74691
|
+
ok: false,
|
|
74692
|
+
error: `cwd must be an absolute path without '..': ${trimmed}`
|
|
74693
|
+
};
|
|
74694
|
+
}
|
|
74695
|
+
let stat8;
|
|
74696
|
+
try {
|
|
74697
|
+
stat8 = statSync10(trimmed);
|
|
74698
|
+
} catch {
|
|
74699
|
+
return { ok: false, error: `path not found: ${trimmed}` };
|
|
74700
|
+
}
|
|
74701
|
+
if (!stat8.isDirectory()) {
|
|
74702
|
+
return { ok: false, error: `not a directory: ${trimmed}` };
|
|
74703
|
+
}
|
|
74704
|
+
const abs = resolve9(trimmed);
|
|
74705
|
+
const slug = slugFromPath(abs);
|
|
74706
|
+
return { ok: true, project: { id: slug, name: slug, path: abs } };
|
|
74707
|
+
}
|
|
74635
74708
|
function mergeProjects(cfg, extraPaths) {
|
|
74636
74709
|
const byId = /* @__PURE__ */ new Map();
|
|
74637
74710
|
for (const p3 of cfg.projects) {
|
|
@@ -74653,24 +74726,24 @@ function mergeProjects(cfg, extraPaths) {
|
|
|
74653
74726
|
}
|
|
74654
74727
|
return [...byId.values()];
|
|
74655
74728
|
}
|
|
74656
|
-
function resolveProjectPath(projects, cwdOrId) {
|
|
74657
|
-
|
|
74729
|
+
function resolveProjectPath(projects, cwdOrId, opts = {}) {
|
|
74730
|
+
const key = String(cwdOrId ?? "").trim();
|
|
74731
|
+
if (!projects.length && !(opts.fullFs && key)) {
|
|
74658
74732
|
return {
|
|
74659
74733
|
ok: false,
|
|
74660
74734
|
error: "No projects configured. Pass --project <path> or edit ~/.zelari-code/companion.json"
|
|
74661
74735
|
};
|
|
74662
74736
|
}
|
|
74663
|
-
if (!
|
|
74664
|
-
return { ok: true, project: projects[0] };
|
|
74737
|
+
if (!key) {
|
|
74738
|
+
return { ok: true, project: projects[0], trusted: true };
|
|
74665
74739
|
}
|
|
74666
|
-
const key = String(cwdOrId).trim();
|
|
74667
74740
|
const byId = projects.find((p3) => p3.id === key || p3.name === key);
|
|
74668
|
-
if (byId) return { ok: true, project: byId };
|
|
74741
|
+
if (byId) return { ok: true, project: byId, trusted: true };
|
|
74669
74742
|
const norm = key.replace(/\\/g, "/").toLowerCase();
|
|
74670
74743
|
const byPath = projects.find(
|
|
74671
74744
|
(p3) => p3.path.replace(/\\/g, "/").toLowerCase() === norm
|
|
74672
74745
|
);
|
|
74673
|
-
if (byPath) return { ok: true, project: byPath };
|
|
74746
|
+
if (byPath) return { ok: true, project: byPath, trusted: true };
|
|
74674
74747
|
const under = projects.find((p3) => {
|
|
74675
74748
|
const root = p3.path.replace(/\\/g, "/").toLowerCase().replace(/\/$/, "");
|
|
74676
74749
|
return norm === root || norm.startsWith(root + "/");
|
|
@@ -74678,14 +74751,31 @@ function resolveProjectPath(projects, cwdOrId) {
|
|
|
74678
74751
|
if (under) {
|
|
74679
74752
|
return {
|
|
74680
74753
|
ok: true,
|
|
74681
|
-
project: { ...under, path: key }
|
|
74754
|
+
project: { ...under, path: key },
|
|
74755
|
+
trusted: true
|
|
74682
74756
|
};
|
|
74683
74757
|
}
|
|
74758
|
+
if (opts.fullFs) {
|
|
74759
|
+
const dir = resolveFsDirectory(key);
|
|
74760
|
+
if (dir.ok) return { ok: true, project: dir.project, trusted: false };
|
|
74761
|
+
return { ok: false, error: dir.error };
|
|
74762
|
+
}
|
|
74684
74763
|
return {
|
|
74685
74764
|
ok: false,
|
|
74686
74765
|
error: `cwd/project not in allowlist: ${key}. Allowed: ${projects.map((p3) => p3.id).join(", ")}`
|
|
74687
74766
|
};
|
|
74688
74767
|
}
|
|
74768
|
+
function isUnderRoots(rawPath, projects) {
|
|
74769
|
+
const norm = rawPath.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
|
|
74770
|
+
if (!norm || norm.split("/").includes("..")) return { ok: false };
|
|
74771
|
+
for (const p3 of projects) {
|
|
74772
|
+
const root = p3.path.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
|
|
74773
|
+
if (norm === root || norm.startsWith(root + "/")) {
|
|
74774
|
+
return { ok: true, root: p3, normalized: norm };
|
|
74775
|
+
}
|
|
74776
|
+
}
|
|
74777
|
+
return { ok: false };
|
|
74778
|
+
}
|
|
74689
74779
|
var DEFAULT_COMPANION_PORT, DEFAULT_COMPANION_BIND;
|
|
74690
74780
|
var init_config = __esm({
|
|
74691
74781
|
"src/cli/companion/config.ts"() {
|
|
@@ -74735,12 +74825,12 @@ function createServePermissionBridge(write, timeoutMs2 = 12e4) {
|
|
|
74735
74825
|
onPermissionAsk(payload) {
|
|
74736
74826
|
const requestId = `perm-${Date.now()}-${++seq}`;
|
|
74737
74827
|
const categories = payload.categories && payload.categories.length > 0 ? payload.categories : payload.category ? payload.category.split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
74738
|
-
return new Promise((
|
|
74828
|
+
return new Promise((resolve11) => {
|
|
74739
74829
|
const timer = setTimeout(() => {
|
|
74740
74830
|
settle(requestId, "deny", true);
|
|
74741
74831
|
}, timeoutMs2);
|
|
74742
74832
|
const sessionId2 = getCurrentHarnessSessionId();
|
|
74743
|
-
pending.set(requestId, { resolve:
|
|
74833
|
+
pending.set(requestId, { resolve: resolve11, timer, payload, sessionId: sessionId2 });
|
|
74744
74834
|
write(
|
|
74745
74835
|
JSON.stringify({
|
|
74746
74836
|
type: "permission.request",
|
|
@@ -74865,12 +74955,12 @@ function createServeAskUserBridge(write, timeoutMs2 = askUserTimeoutMs()) {
|
|
|
74865
74955
|
const choices = req.choices.map((c) => c.trim()).filter(Boolean);
|
|
74866
74956
|
if (choices.length < 2) return Promise.resolve(null);
|
|
74867
74957
|
const requestId = `ask-${Date.now()}-${++seq}`;
|
|
74868
|
-
return new Promise((
|
|
74958
|
+
return new Promise((resolve11) => {
|
|
74869
74959
|
const timer = setTimeout(() => {
|
|
74870
74960
|
settle(requestId, null, true);
|
|
74871
74961
|
}, timeoutMs2);
|
|
74872
74962
|
const sessionId2 = getCurrentHarnessSessionId();
|
|
74873
|
-
pending.set(requestId, { resolve:
|
|
74963
|
+
pending.set(requestId, { resolve: resolve11, timer, sessionId: sessionId2 });
|
|
74874
74964
|
write(
|
|
74875
74965
|
JSON.stringify({
|
|
74876
74966
|
type: "ask_user.request",
|
|
@@ -75374,8 +75464,8 @@ var init_harnessClient = __esm({
|
|
|
75374
75464
|
);
|
|
75375
75465
|
}
|
|
75376
75466
|
const id3 = this.nextId++;
|
|
75377
|
-
return new Promise((
|
|
75378
|
-
this.pending.set(id3, { resolve:
|
|
75467
|
+
return new Promise((resolve11, reject) => {
|
|
75468
|
+
this.pending.set(id3, { resolve: resolve11, reject });
|
|
75379
75469
|
this.transport.write(JSON.stringify({ id: id3, method, params }));
|
|
75380
75470
|
});
|
|
75381
75471
|
}
|
|
@@ -75401,6 +75491,18 @@ var init_harnessClient = __esm({
|
|
|
75401
75491
|
if (reason !== void 0) params["reason"] = reason;
|
|
75402
75492
|
return await this.request("session.cancel", params);
|
|
75403
75493
|
}
|
|
75494
|
+
/** t63: settle a permission.request (allow/deny/always-tool/always-category). */
|
|
75495
|
+
async permissionRespond(requestId, decision, sessionId2) {
|
|
75496
|
+
const params = { requestId, decision };
|
|
75497
|
+
if (sessionId2 !== void 0) params["sessionId"] = sessionId2;
|
|
75498
|
+
return await this.request("permission.respond", params);
|
|
75499
|
+
}
|
|
75500
|
+
/** t63: settle an ask_user.request (null = dismiss). */
|
|
75501
|
+
async askUserRespond(requestId, answer, sessionId2) {
|
|
75502
|
+
const params = { requestId, answer };
|
|
75503
|
+
if (sessionId2 !== void 0) params["sessionId"] = sessionId2;
|
|
75504
|
+
return await this.request("ask_user.respond", params);
|
|
75505
|
+
}
|
|
75404
75506
|
async disposeSession(sessionId2) {
|
|
75405
75507
|
await this.request("session.dispose", { sessionId: sessionId2 });
|
|
75406
75508
|
}
|
|
@@ -75430,6 +75532,9 @@ import { tmpdir as tmpdir4 } from "node:os";
|
|
|
75430
75532
|
function harnessServerMode() {
|
|
75431
75533
|
return process.env[HARNESS_SERVER_ENV] === "1";
|
|
75432
75534
|
}
|
|
75535
|
+
function isPermissionRequestEvent(ev) {
|
|
75536
|
+
return typeof ev === "object" && ev !== null && ev.type === "permission.request";
|
|
75537
|
+
}
|
|
75433
75538
|
var HARNESS_SERVER_ENV, RunManager;
|
|
75434
75539
|
var init_runManager = __esm({
|
|
75435
75540
|
"src/cli/companion/runManager.ts"() {
|
|
@@ -75487,6 +75592,13 @@ var init_runManager = __esm({
|
|
|
75487
75592
|
}
|
|
75488
75593
|
emit(ev) {
|
|
75489
75594
|
if (!this.active) return;
|
|
75595
|
+
if (this.active.permissionPreset === "yolo" && isPermissionRequestEvent(ev)) {
|
|
75596
|
+
const requestId = ev.requestId;
|
|
75597
|
+
if (typeof requestId === "string" && requestId.trim()) {
|
|
75598
|
+
void this.permissionRespond(this.active.run.id, requestId, "allow");
|
|
75599
|
+
return;
|
|
75600
|
+
}
|
|
75601
|
+
}
|
|
75490
75602
|
this.active.run.events.push(ev);
|
|
75491
75603
|
if (this.active.run.events.length > 5e3) {
|
|
75492
75604
|
this.active.run.events.splice(0, this.active.run.events.length - 4e3);
|
|
@@ -75498,7 +75610,7 @@ var init_runManager = __esm({
|
|
|
75498
75610
|
}
|
|
75499
75611
|
}
|
|
75500
75612
|
}
|
|
75501
|
-
start(args) {
|
|
75613
|
+
start(args, gate) {
|
|
75502
75614
|
if (this.active) {
|
|
75503
75615
|
return {
|
|
75504
75616
|
ok: false,
|
|
@@ -75520,9 +75632,79 @@ var init_runManager = __esm({
|
|
|
75520
75632
|
createdAt: Date.now(),
|
|
75521
75633
|
events: []
|
|
75522
75634
|
};
|
|
75635
|
+
if (gate?.awaitingTrust) {
|
|
75636
|
+
run.status = "awaiting_trust";
|
|
75637
|
+
this.active = {
|
|
75638
|
+
run,
|
|
75639
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
75640
|
+
trustArgs: args,
|
|
75641
|
+
trustMode: this.clientMode ? "harness" : "spawn",
|
|
75642
|
+
permissionPreset: args.permissionPreset
|
|
75643
|
+
};
|
|
75644
|
+
this.emit({
|
|
75645
|
+
type: "trust.pending",
|
|
75646
|
+
runId: id3,
|
|
75647
|
+
path: args.cwd,
|
|
75648
|
+
message: `[companion] run ${id3} awaiting desktop trust approval for ${args.cwd}`
|
|
75649
|
+
});
|
|
75650
|
+
return { ok: true, run, awaitingTrust: true };
|
|
75651
|
+
}
|
|
75523
75652
|
if (this.clientMode) {
|
|
75524
75653
|
return this.startViaHarness(run, args, mode, phase2);
|
|
75525
75654
|
}
|
|
75655
|
+
return this.launchSpawn(run, args);
|
|
75656
|
+
}
|
|
75657
|
+
/**
|
|
75658
|
+
* t66: desktop approved the parked run — launch it now, preserving the
|
|
75659
|
+
* listeners (phone SSE) attached while it was awaiting trust.
|
|
75660
|
+
*/
|
|
75661
|
+
releaseTrust() {
|
|
75662
|
+
const a = this.active;
|
|
75663
|
+
if (!a || a.run.status !== "awaiting_trust" || !a.trustArgs) {
|
|
75664
|
+
return { ok: false, error: "no run awaiting trust" };
|
|
75665
|
+
}
|
|
75666
|
+
const args = a.trustArgs;
|
|
75667
|
+
a.run.status = "running";
|
|
75668
|
+
this.emit({ type: "trust.settled", runId: a.run.id, approved: true });
|
|
75669
|
+
if (a.trustMode === "harness") {
|
|
75670
|
+
return this.startViaHarness(a.run, args, a.run.mode, a.run.phase);
|
|
75671
|
+
}
|
|
75672
|
+
return this.launchSpawn(a.run, args);
|
|
75673
|
+
}
|
|
75674
|
+
/** t66: desktop denied the parked run — fail it, fail-closed. */
|
|
75675
|
+
denyTrust(reason) {
|
|
75676
|
+
const a = this.active;
|
|
75677
|
+
if (!a || a.run.status !== "awaiting_trust") {
|
|
75678
|
+
return { ok: false, error: "no run awaiting trust" };
|
|
75679
|
+
}
|
|
75680
|
+
a.run.status = "error";
|
|
75681
|
+
a.run.error = reason;
|
|
75682
|
+
a.run.finishedAt = Date.now();
|
|
75683
|
+
this.emit({ type: "trust.settled", runId: a.run.id, approved: false });
|
|
75684
|
+
this.emit({
|
|
75685
|
+
type: "error",
|
|
75686
|
+
severity: "fatal",
|
|
75687
|
+
message: reason,
|
|
75688
|
+
code: "trust_denied"
|
|
75689
|
+
});
|
|
75690
|
+
this.emit({
|
|
75691
|
+
type: "run_finished",
|
|
75692
|
+
runId: a.run.id,
|
|
75693
|
+
status: "error",
|
|
75694
|
+
exitCode: null
|
|
75695
|
+
});
|
|
75696
|
+
this.finishActive();
|
|
75697
|
+
return { ok: true };
|
|
75698
|
+
}
|
|
75699
|
+
/** t66: current awaiting_trust run (if any) for GET /v1/trust/pending. */
|
|
75700
|
+
pendingTrust() {
|
|
75701
|
+
const a = this.active;
|
|
75702
|
+
if (!a || a.run.status !== "awaiting_trust") return null;
|
|
75703
|
+
return { runId: a.run.id, path: a.run.cwd };
|
|
75704
|
+
}
|
|
75705
|
+
/** t66: spawn-path launch, extracted from start() so releaseTrust can
|
|
75706
|
+
* launch a parked run. Preserves parked listeners (same run id). */
|
|
75707
|
+
launchSpawn(run, args) {
|
|
75526
75708
|
const cliEntry = process.argv[1];
|
|
75527
75709
|
if (!cliEntry) {
|
|
75528
75710
|
return { ok: false, error: "Cannot resolve CLI entry (process.argv[1])" };
|
|
@@ -75531,13 +75713,13 @@ var init_runManager = __esm({
|
|
|
75531
75713
|
cliEntry,
|
|
75532
75714
|
"--headless",
|
|
75533
75715
|
"--task",
|
|
75534
|
-
prompt,
|
|
75716
|
+
run.prompt,
|
|
75535
75717
|
"--output",
|
|
75536
75718
|
"json",
|
|
75537
75719
|
"--mode",
|
|
75538
|
-
mode === "council" || mode === "zelari" ? mode : "kraken",
|
|
75720
|
+
run.mode === "council" || run.mode === "zelari" ? run.mode : "kraken",
|
|
75539
75721
|
"--phase",
|
|
75540
|
-
|
|
75722
|
+
run.phase === "plan" ? "plan" : "build"
|
|
75541
75723
|
];
|
|
75542
75724
|
if (args.provider?.trim()) {
|
|
75543
75725
|
argv.push("--provider", args.provider.trim());
|
|
@@ -75545,9 +75727,14 @@ var init_runManager = __esm({
|
|
|
75545
75727
|
if (args.model?.trim()) {
|
|
75546
75728
|
argv.push("--model", args.model.trim());
|
|
75547
75729
|
}
|
|
75730
|
+
if (args.strictDone === true) argv.push("--strict-done");
|
|
75731
|
+
else if (args.strictDone === false) argv.push("--no-strict-done");
|
|
75732
|
+
if (args.permissionPreset) {
|
|
75733
|
+
argv.push("--permissions", args.permissionPreset);
|
|
75734
|
+
}
|
|
75548
75735
|
let historyFile;
|
|
75549
75736
|
if (args.history && Array.isArray(args.history) && args.history.length > 0) {
|
|
75550
|
-
historyFile = join49(tmpdir4(), `zelari-companion-hist-${
|
|
75737
|
+
historyFile = join49(tmpdir4(), `zelari-companion-hist-${run.id}.json`);
|
|
75551
75738
|
try {
|
|
75552
75739
|
writeFileSync27(historyFile, JSON.stringify(args.history), "utf8");
|
|
75553
75740
|
argv.push("--history-file", historyFile);
|
|
@@ -75561,15 +75748,26 @@ var init_runManager = __esm({
|
|
|
75561
75748
|
...process.env,
|
|
75562
75749
|
ZELARI_SKIP_PREFLIGHT: "1",
|
|
75563
75750
|
ANATHEMA_DEV: "1",
|
|
75564
|
-
FORCE_COLOR: "0"
|
|
75751
|
+
FORCE_COLOR: "0",
|
|
75752
|
+
// t65: belt-and-suspenders — the long-lived headless child reads the
|
|
75753
|
+
// preset straight from env even if it never re-parses --permissions;
|
|
75754
|
+
// mirrors main.ts's --permissions → ZELARI_PERMISSION_PRESET promotion.
|
|
75755
|
+
...args.permissionPreset ? { ZELARI_PERMISSION_PRESET: args.permissionPreset } : {}
|
|
75565
75756
|
},
|
|
75566
75757
|
stdio: ["ignore", "pipe", "pipe"],
|
|
75567
75758
|
windowsHide: true
|
|
75568
75759
|
});
|
|
75569
|
-
this.active
|
|
75760
|
+
const parked = this.active?.run.id === run.id ? this.active : null;
|
|
75761
|
+
this.active = {
|
|
75762
|
+
run,
|
|
75763
|
+
child,
|
|
75764
|
+
listeners: parked?.listeners ?? /* @__PURE__ */ new Set(),
|
|
75765
|
+
historyFile,
|
|
75766
|
+
permissionPreset: args.permissionPreset
|
|
75767
|
+
};
|
|
75570
75768
|
this.emit({
|
|
75571
75769
|
type: "log",
|
|
75572
|
-
message: `[companion] run ${
|
|
75770
|
+
message: `[companion] run ${run.id} started mode=${run.mode} phase=${run.phase} cwd=${args.cwd}`
|
|
75573
75771
|
});
|
|
75574
75772
|
if (child.stdout) {
|
|
75575
75773
|
const rl = createInterface4({ input: child.stdout });
|
|
@@ -75616,7 +75814,7 @@ var init_runManager = __esm({
|
|
|
75616
75814
|
}
|
|
75617
75815
|
this.emit({
|
|
75618
75816
|
type: "run_finished",
|
|
75619
|
-
runId:
|
|
75817
|
+
runId: run.id,
|
|
75620
75818
|
status: run.status,
|
|
75621
75819
|
exitCode: code
|
|
75622
75820
|
});
|
|
@@ -75631,7 +75829,12 @@ var init_runManager = __esm({
|
|
|
75631
75829
|
* reports through the usual run status + emit path.
|
|
75632
75830
|
*/
|
|
75633
75831
|
startViaHarness(run, args, mode, phase2) {
|
|
75634
|
-
this.active
|
|
75832
|
+
const parked = this.active?.run.id === run.id ? this.active : null;
|
|
75833
|
+
this.active = {
|
|
75834
|
+
run,
|
|
75835
|
+
listeners: parked?.listeners ?? /* @__PURE__ */ new Set(),
|
|
75836
|
+
permissionPreset: args.permissionPreset
|
|
75837
|
+
};
|
|
75635
75838
|
this.emit({
|
|
75636
75839
|
type: "log",
|
|
75637
75840
|
message: `[companion] run ${run.id} started mode=${mode} phase=${phase2} cwd=${args.cwd}`
|
|
@@ -75679,6 +75882,9 @@ var init_runManager = __esm({
|
|
|
75679
75882
|
if (Array.isArray(args.history) && args.history.length > 0) {
|
|
75680
75883
|
turnInput["history"] = args.history;
|
|
75681
75884
|
}
|
|
75885
|
+
if (args.permissionPreset) turnInput["permissionPreset"] = args.permissionPreset;
|
|
75886
|
+
if (args.strictDone !== void 0) turnInput["strictDone"] = args.strictDone;
|
|
75887
|
+
if (args.verifyPack !== void 0) turnInput["verifyPack"] = args.verifyPack;
|
|
75682
75888
|
const result = await client.runTurn(sessionId2, turnInput);
|
|
75683
75889
|
const stillOwner = this.active?.run.id === run.id;
|
|
75684
75890
|
if (stillOwner && run.status === "running") {
|
|
@@ -75779,6 +75985,51 @@ var init_runManager = __esm({
|
|
|
75779
75985
|
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
75780
75986
|
}
|
|
75781
75987
|
}
|
|
75988
|
+
/** t63: settle a permission.request on the active client-mode run. */
|
|
75989
|
+
async permissionRespond(runId, requestId, decision) {
|
|
75990
|
+
if (!this.active) return { ok: false, error: "No active run" };
|
|
75991
|
+
if (runId && this.active.run.id !== runId) {
|
|
75992
|
+
return { ok: false, error: `Run ${runId} is not active` };
|
|
75993
|
+
}
|
|
75994
|
+
const id3 = requestId?.trim();
|
|
75995
|
+
if (!id3) return { ok: false, error: "requestId is required" };
|
|
75996
|
+
if (!this.active.harnessSessionId || !this.harnessClient) {
|
|
75997
|
+
return {
|
|
75998
|
+
ok: false,
|
|
75999
|
+
error: `permission respond requires harness server mode (${HARNESS_SERVER_ENV}=1)`
|
|
76000
|
+
};
|
|
76001
|
+
}
|
|
76002
|
+
try {
|
|
76003
|
+
const result = await this.harnessClient.permissionRespond(id3, decision);
|
|
76004
|
+
return { ok: true, result };
|
|
76005
|
+
} catch (err) {
|
|
76006
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
76007
|
+
}
|
|
76008
|
+
}
|
|
76009
|
+
/** t63: settle an ask_user.request (answer null = dismiss). */
|
|
76010
|
+
async askUserRespond(runId, requestId, answer) {
|
|
76011
|
+
if (!this.active) return { ok: false, error: "No active run" };
|
|
76012
|
+
if (runId && this.active.run.id !== runId) {
|
|
76013
|
+
return { ok: false, error: `Run ${runId} is not active` };
|
|
76014
|
+
}
|
|
76015
|
+
const id3 = requestId?.trim();
|
|
76016
|
+
if (!id3) return { ok: false, error: "requestId is required" };
|
|
76017
|
+
if (answer != null && typeof answer !== "string") {
|
|
76018
|
+
return { ok: false, error: "answer must be a string or null" };
|
|
76019
|
+
}
|
|
76020
|
+
if (!this.active.harnessSessionId || !this.harnessClient) {
|
|
76021
|
+
return {
|
|
76022
|
+
ok: false,
|
|
76023
|
+
error: `ask respond requires harness server mode (${HARNESS_SERVER_ENV}=1)`
|
|
76024
|
+
};
|
|
76025
|
+
}
|
|
76026
|
+
try {
|
|
76027
|
+
const result = await this.harnessClient.askUserRespond(id3, answer);
|
|
76028
|
+
return { ok: true, result };
|
|
76029
|
+
} catch (err) {
|
|
76030
|
+
return { ok: false, error: err instanceof Error ? err.message : String(err) };
|
|
76031
|
+
}
|
|
76032
|
+
}
|
|
75782
76033
|
cancel(runId) {
|
|
75783
76034
|
if (!this.active) {
|
|
75784
76035
|
return { ok: false, error: "No active run" };
|
|
@@ -75870,8 +76121,8 @@ __export(serve_exports, {
|
|
|
75870
76121
|
runCompanionServe: () => runCompanionServe
|
|
75871
76122
|
});
|
|
75872
76123
|
import { createServer as createServer3 } from "node:http";
|
|
75873
|
-
import { existsSync as existsSync62 } from "node:fs";
|
|
75874
|
-
import { resolve as
|
|
76124
|
+
import { existsSync as existsSync62, readdirSync as readdirSync13 } from "node:fs";
|
|
76125
|
+
import { join as join50, resolve as resolve10 } from "node:path";
|
|
75875
76126
|
function readBody(req, max = 2e6) {
|
|
75876
76127
|
return new Promise((resolveBody, reject) => {
|
|
75877
76128
|
const chunks = [];
|
|
@@ -75918,7 +76169,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
75918
76169
|
const { token, created } = loadOrCreateToken(opts.token);
|
|
75919
76170
|
let projects = mergeProjects(fileCfg, opts.projects ?? []);
|
|
75920
76171
|
projects = projects.filter((p3) => {
|
|
75921
|
-
const abs =
|
|
76172
|
+
const abs = resolve10(p3.path);
|
|
75922
76173
|
if (!existsSync62(abs)) {
|
|
75923
76174
|
process.stderr.write(
|
|
75924
76175
|
`[zelari-code serve] skip missing project path: ${p3.path}
|
|
@@ -75938,7 +76189,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
75938
76189
|
});
|
|
75939
76190
|
}
|
|
75940
76191
|
if (projects.length === 0) {
|
|
75941
|
-
const cwd =
|
|
76192
|
+
const cwd = resolve10(process.cwd());
|
|
75942
76193
|
projects = [
|
|
75943
76194
|
{
|
|
75944
76195
|
id: "default",
|
|
@@ -75954,6 +76205,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
75954
76205
|
);
|
|
75955
76206
|
}
|
|
75956
76207
|
const runs = new RunManager();
|
|
76208
|
+
const fsFull = (opts.fsMode ?? "full") === "full";
|
|
75957
76209
|
const allowedOrigins = [
|
|
75958
76210
|
...loopbackOrigins(port),
|
|
75959
76211
|
...parseAllowedOrigins(process.env[COMPANION_ALLOWED_ORIGINS_ENV])
|
|
@@ -75995,6 +76247,65 @@ async function runCompanionServe(opts = {}) {
|
|
|
75995
76247
|
sendJson2(res, 200, { ok: true, ...snap });
|
|
75996
76248
|
return;
|
|
75997
76249
|
}
|
|
76250
|
+
if (req.method === "GET" && path104 === "/v1/fs") {
|
|
76251
|
+
const listFsRootsInline = () => {
|
|
76252
|
+
if (process.platform === "win32") {
|
|
76253
|
+
const roots = [];
|
|
76254
|
+
for (let code = 65; code <= 90; code++) {
|
|
76255
|
+
const letter = String.fromCharCode(code);
|
|
76256
|
+
const drive = `${letter}:\\`;
|
|
76257
|
+
if (existsSync62(drive)) {
|
|
76258
|
+
roots.push({
|
|
76259
|
+
id: `fs-${letter.toLowerCase()}`,
|
|
76260
|
+
name: drive,
|
|
76261
|
+
path: drive
|
|
76262
|
+
});
|
|
76263
|
+
}
|
|
76264
|
+
}
|
|
76265
|
+
return roots;
|
|
76266
|
+
}
|
|
76267
|
+
return [{ id: "fs-root", name: "/", path: "/" }];
|
|
76268
|
+
};
|
|
76269
|
+
const rawParam = url2.searchParams.get("path")?.trim() ?? "";
|
|
76270
|
+
if (!rawParam) {
|
|
76271
|
+
sendJson2(res, 200, {
|
|
76272
|
+
ok: true,
|
|
76273
|
+
roots: fsFull ? listFsRootsInline() : projects,
|
|
76274
|
+
entries: []
|
|
76275
|
+
});
|
|
76276
|
+
return;
|
|
76277
|
+
}
|
|
76278
|
+
const norm = rawParam.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
76279
|
+
const absolute = /^([a-zA-Z]:\/|\/)/.test(norm);
|
|
76280
|
+
const allowed = fsFull && absolute && !norm.split("/").includes("..") ? true : isUnderRoots(rawParam, projects).ok;
|
|
76281
|
+
if (!allowed) {
|
|
76282
|
+
sendJson2(res, 403, { ok: false, error: "path outside allowed roots" });
|
|
76283
|
+
return;
|
|
76284
|
+
}
|
|
76285
|
+
if (!existsSync62(rawParam)) {
|
|
76286
|
+
sendJson2(res, 404, { ok: false, error: "path not found" });
|
|
76287
|
+
return;
|
|
76288
|
+
}
|
|
76289
|
+
const dirs = readdirSync13(rawParam, { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).sort((a, b) => a.name.localeCompare(b.name));
|
|
76290
|
+
const slash = norm.lastIndexOf("/");
|
|
76291
|
+
let parent = slash > 0 ? norm.slice(0, slash) : null;
|
|
76292
|
+
const rootHit = isUnderRoots(rawParam, projects);
|
|
76293
|
+
if (rootHit.ok) {
|
|
76294
|
+
const rootNorm = rootHit.root.path.replace(/\\/g, "/").toLowerCase().replace(/\/+$/, "");
|
|
76295
|
+
if (rootHit.normalized === rootNorm) parent = null;
|
|
76296
|
+
}
|
|
76297
|
+
sendJson2(res, 200, {
|
|
76298
|
+
ok: true,
|
|
76299
|
+
path: rawParam,
|
|
76300
|
+
parent,
|
|
76301
|
+
entries: dirs.map((d) => ({
|
|
76302
|
+
name: d.name,
|
|
76303
|
+
path: join50(rawParam, d.name),
|
|
76304
|
+
dir: true
|
|
76305
|
+
}))
|
|
76306
|
+
});
|
|
76307
|
+
return;
|
|
76308
|
+
}
|
|
75998
76309
|
if (req.method === "GET" && path104 === "/v1/projects") {
|
|
75999
76310
|
sendJson2(res, 200, {
|
|
76000
76311
|
ok: true,
|
|
@@ -76037,27 +76348,37 @@ async function runCompanionServe(opts = {}) {
|
|
|
76037
76348
|
const mode = String(body.mode ?? "kraken");
|
|
76038
76349
|
const phase2 = String(body.phase ?? "build");
|
|
76039
76350
|
const cwdArg = body.cwd != null ? String(body.cwd) : body.projectId != null ? String(body.projectId) : null;
|
|
76040
|
-
const resolved = resolveProjectPath(projects, cwdArg);
|
|
76351
|
+
const resolved = resolveProjectPath(projects, cwdArg, { fullFs: fsFull });
|
|
76041
76352
|
if (!resolved.ok) {
|
|
76042
76353
|
sendJson2(res, 400, { ok: false, error: resolved.error });
|
|
76043
76354
|
return;
|
|
76044
76355
|
}
|
|
76045
76356
|
const history2 = Array.isArray(body.history) ? body.history : void 0;
|
|
76046
|
-
const
|
|
76357
|
+
const presetRaw = typeof body.permissionPreset === "string" ? body.permissionPreset.trim().toLowerCase() : "";
|
|
76358
|
+
const permissionPreset = ["standard", "strict", "yolo"].includes(presetRaw) ? presetRaw : void 0;
|
|
76359
|
+
const strictDone = typeof body.strictDone === "boolean" ? body.strictDone : void 0;
|
|
76360
|
+
const verifyPack = typeof body.verifyPack === "boolean" ? body.verifyPack : void 0;
|
|
76361
|
+
const startArgs = {
|
|
76047
76362
|
prompt,
|
|
76048
76363
|
mode,
|
|
76049
76364
|
phase: phase2,
|
|
76050
76365
|
cwd: resolved.project.path,
|
|
76051
76366
|
provider: body.provider != null ? String(body.provider) : void 0,
|
|
76052
76367
|
model: body.model != null ? String(body.model) : void 0,
|
|
76053
|
-
history: history2
|
|
76054
|
-
|
|
76368
|
+
history: history2,
|
|
76369
|
+
permissionPreset,
|
|
76370
|
+
strictDone,
|
|
76371
|
+
verifyPack
|
|
76372
|
+
};
|
|
76373
|
+
const gate = fsFull && !resolved.trusted ? { awaitingTrust: true } : void 0;
|
|
76374
|
+
const result = runs.start(startArgs, gate);
|
|
76055
76375
|
if (!result.ok) {
|
|
76056
76376
|
sendJson2(res, 409, { ok: false, error: result.error });
|
|
76057
76377
|
return;
|
|
76058
76378
|
}
|
|
76059
76379
|
sendJson2(res, 201, {
|
|
76060
76380
|
ok: true,
|
|
76381
|
+
awaitingTrust: gate ? true : void 0,
|
|
76061
76382
|
run: {
|
|
76062
76383
|
id: result.run.id,
|
|
76063
76384
|
status: result.run.status,
|
|
@@ -76068,10 +76389,57 @@ async function runCompanionServe(opts = {}) {
|
|
|
76068
76389
|
},
|
|
76069
76390
|
eventsUrl: `/v1/runs/${result.run.id}/events`,
|
|
76070
76391
|
cancelUrl: `/v1/runs/${result.run.id}/cancel`,
|
|
76071
|
-
steerUrl: `/v1/runs/${result.run.id}/steer
|
|
76392
|
+
steerUrl: `/v1/runs/${result.run.id}/steer`,
|
|
76393
|
+
permissionUrl: `/v1/runs/${result.run.id}/permission`,
|
|
76394
|
+
askUrl: `/v1/runs/${result.run.id}/ask`
|
|
76072
76395
|
});
|
|
76073
76396
|
return;
|
|
76074
76397
|
}
|
|
76398
|
+
if (req.method === "POST" && path104 === "/v1/trust") {
|
|
76399
|
+
const raw = await readBody(req);
|
|
76400
|
+
let body = {};
|
|
76401
|
+
try {
|
|
76402
|
+
body = raw ? JSON.parse(raw) : {};
|
|
76403
|
+
} catch {
|
|
76404
|
+
sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
|
|
76405
|
+
return;
|
|
76406
|
+
}
|
|
76407
|
+
const runId = typeof body.runId === "string" ? body.runId.trim() : "";
|
|
76408
|
+
if (!runId) {
|
|
76409
|
+
sendJson2(res, 400, { ok: false, error: "runId is required" });
|
|
76410
|
+
return;
|
|
76411
|
+
}
|
|
76412
|
+
const current = runs.pendingTrust();
|
|
76413
|
+
if (!current || current.runId !== runId) {
|
|
76414
|
+
sendJson2(res, 409, { ok: false, error: "no such awaiting_trust run" });
|
|
76415
|
+
return;
|
|
76416
|
+
}
|
|
76417
|
+
if (body.approve === true) {
|
|
76418
|
+
projects = mergeProjects({ ...fileCfg, projects }, [current.path]);
|
|
76419
|
+
try {
|
|
76420
|
+
saveCompanionConfig({ ...fileCfg, bind, port, projects });
|
|
76421
|
+
} catch {
|
|
76422
|
+
}
|
|
76423
|
+
const released = runs.releaseTrust();
|
|
76424
|
+
if (!released.ok) {
|
|
76425
|
+
sendJson2(res, 409, { ok: false, error: released.error });
|
|
76426
|
+
return;
|
|
76427
|
+
}
|
|
76428
|
+
sendJson2(res, 200, { ok: true, approved: runId, path: current.path });
|
|
76429
|
+
return;
|
|
76430
|
+
}
|
|
76431
|
+
const denied = runs.denyTrust("Trust negato sul desktop");
|
|
76432
|
+
if (!denied.ok) {
|
|
76433
|
+
sendJson2(res, 409, { ok: false, error: denied.error });
|
|
76434
|
+
return;
|
|
76435
|
+
}
|
|
76436
|
+
sendJson2(res, 200, { ok: true, denied: runId });
|
|
76437
|
+
return;
|
|
76438
|
+
}
|
|
76439
|
+
if (req.method === "GET" && path104 === "/v1/trust/pending") {
|
|
76440
|
+
sendJson2(res, 200, { ok: true, pending: runs.pendingTrust() });
|
|
76441
|
+
return;
|
|
76442
|
+
}
|
|
76075
76443
|
const eventsMatch = /^\/v1\/runs\/([^/]+)\/events$/.exec(path104);
|
|
76076
76444
|
if (req.method === "GET" && eventsMatch) {
|
|
76077
76445
|
const runId = eventsMatch[1];
|
|
@@ -76099,7 +76467,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
76099
76467
|
}
|
|
76100
76468
|
};
|
|
76101
76469
|
const unsub = runs.subscribe(runId, writeEv);
|
|
76102
|
-
if (run.status !== "running" && run.status !== "queued") {
|
|
76470
|
+
if (run.status !== "running" && run.status !== "queued" && run.status !== "awaiting_trust") {
|
|
76103
76471
|
writeEv({
|
|
76104
76472
|
type: "run_finished",
|
|
76105
76473
|
runId,
|
|
@@ -76125,7 +76493,7 @@ async function runCompanionServe(opts = {}) {
|
|
|
76125
76493
|
req.on("close", onClose);
|
|
76126
76494
|
const check2 = setInterval(() => {
|
|
76127
76495
|
const r = runs.getRun(runId);
|
|
76128
|
-
if (!r || r.status !== "running" && r.status !== "queued") {
|
|
76496
|
+
if (!r || r.status !== "running" && r.status !== "queued" && r.status !== "awaiting_trust") {
|
|
76129
76497
|
clearInterval(check2);
|
|
76130
76498
|
clearInterval(heartbeat);
|
|
76131
76499
|
unsub();
|
|
@@ -76172,6 +76540,53 @@ async function runCompanionServe(opts = {}) {
|
|
|
76172
76540
|
sendJson2(res, 200, { ok: true, steered: runId, result: result.result });
|
|
76173
76541
|
return;
|
|
76174
76542
|
}
|
|
76543
|
+
const askMatch = /^\/v1\/runs\/([^/]+)\/(permission|ask)$/.exec(path104);
|
|
76544
|
+
if (req.method === "POST" && askMatch) {
|
|
76545
|
+
const runId = askMatch[1];
|
|
76546
|
+
const kind2 = askMatch[2];
|
|
76547
|
+
const raw = await readBody(req);
|
|
76548
|
+
let body = {};
|
|
76549
|
+
try {
|
|
76550
|
+
body = raw ? JSON.parse(raw) : {};
|
|
76551
|
+
} catch {
|
|
76552
|
+
sendJson2(res, 400, { ok: false, error: "invalid JSON body" });
|
|
76553
|
+
return;
|
|
76554
|
+
}
|
|
76555
|
+
const requestId = typeof body.requestId === "string" ? body.requestId.trim() : "";
|
|
76556
|
+
if (!requestId) {
|
|
76557
|
+
sendJson2(res, 400, { ok: false, error: "requestId is required" });
|
|
76558
|
+
return;
|
|
76559
|
+
}
|
|
76560
|
+
if (kind2 === "permission") {
|
|
76561
|
+
const decision = typeof body.decision === "string" ? body.decision.trim() : "";
|
|
76562
|
+
if (!["allow", "deny", "always-tool", "always-category"].includes(decision)) {
|
|
76563
|
+
sendJson2(res, 400, {
|
|
76564
|
+
ok: false,
|
|
76565
|
+
error: "decision must be allow|deny|always-tool|always-category"
|
|
76566
|
+
});
|
|
76567
|
+
return;
|
|
76568
|
+
}
|
|
76569
|
+
const result2 = await runs.permissionRespond(runId, requestId, decision);
|
|
76570
|
+
if (!result2.ok) {
|
|
76571
|
+
sendJson2(res, 404, { ok: false, error: result2.error });
|
|
76572
|
+
return;
|
|
76573
|
+
}
|
|
76574
|
+
sendJson2(res, 200, { ok: true, runId, requestId, result: result2.result });
|
|
76575
|
+
return;
|
|
76576
|
+
}
|
|
76577
|
+
const answer = body.answer == null ? null : typeof body.answer === "string" ? body.answer : void 0;
|
|
76578
|
+
if (answer === void 0) {
|
|
76579
|
+
sendJson2(res, 400, { ok: false, error: "answer must be a string or null" });
|
|
76580
|
+
return;
|
|
76581
|
+
}
|
|
76582
|
+
const result = await runs.askUserRespond(runId, requestId, answer);
|
|
76583
|
+
if (!result.ok) {
|
|
76584
|
+
sendJson2(res, 404, { ok: false, error: result.error });
|
|
76585
|
+
return;
|
|
76586
|
+
}
|
|
76587
|
+
sendJson2(res, 200, { ok: true, runId, requestId, result: result.result });
|
|
76588
|
+
return;
|
|
76589
|
+
}
|
|
76175
76590
|
sendJson2(res, 404, { ok: false, error: "not found" });
|
|
76176
76591
|
} catch (err) {
|
|
76177
76592
|
sendJson2(res, 500, {
|
|
@@ -76247,12 +76662,14 @@ function parseServeFlags(argv) {
|
|
|
76247
76662
|
}
|
|
76248
76663
|
const portRaw = get("--port");
|
|
76249
76664
|
const port = portRaw ? Number.parseInt(portRaw, 10) : void 0;
|
|
76665
|
+
const fsRaw = get("--fs");
|
|
76250
76666
|
return {
|
|
76251
76667
|
bind: get("--bind"),
|
|
76252
76668
|
port: Number.isFinite(port) ? port : void 0,
|
|
76253
76669
|
token: get("--token"),
|
|
76254
76670
|
projects,
|
|
76255
|
-
persistProjects: argv.includes("--save-projects")
|
|
76671
|
+
persistProjects: argv.includes("--save-projects"),
|
|
76672
|
+
fsMode: fsRaw === "allowlist" ? "allowlist" : fsRaw === "full" ? "full" : void 0
|
|
76256
76673
|
};
|
|
76257
76674
|
}
|
|
76258
76675
|
var init_serve = __esm({
|
|
@@ -76313,8 +76730,8 @@ __export(doctor_exports, {
|
|
|
76313
76730
|
firstBlockingRed: () => firstBlockingRed,
|
|
76314
76731
|
runDoctor: () => runDoctor
|
|
76315
76732
|
});
|
|
76316
|
-
import { execSync as
|
|
76317
|
-
import { existsSync as existsSync63, readFileSync as readFileSync46, readlinkSync, statSync as
|
|
76733
|
+
import { execSync as execSync3 } from "node:child_process";
|
|
76734
|
+
import { existsSync as existsSync63, readFileSync as readFileSync46, readlinkSync, statSync as statSync11 } from "node:fs";
|
|
76318
76735
|
import { createRequire as createRequire3 } from "node:module";
|
|
76319
76736
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
76320
76737
|
import path100 from "node:path";
|
|
@@ -76337,7 +76754,7 @@ function findPackageRoot(start) {
|
|
|
76337
76754
|
}
|
|
76338
76755
|
function tryExec(cmd) {
|
|
76339
76756
|
try {
|
|
76340
|
-
return
|
|
76757
|
+
return execSync3(cmd, {
|
|
76341
76758
|
encoding: "utf8",
|
|
76342
76759
|
stdio: ["ignore", "pipe", "ignore"]
|
|
76343
76760
|
}).trim();
|
|
@@ -76353,7 +76770,7 @@ function readPackageJson4() {
|
|
|
76353
76770
|
return null;
|
|
76354
76771
|
}
|
|
76355
76772
|
}
|
|
76356
|
-
function
|
|
76773
|
+
function getGlobalPrefix2() {
|
|
76357
76774
|
const fromNpm = tryExec("npm prefix -g");
|
|
76358
76775
|
if (fromNpm) return fromNpm;
|
|
76359
76776
|
return (process.env.npm_config_prefix || process.env.NPM_CONFIG_PREFIX || "").trim();
|
|
@@ -76362,7 +76779,7 @@ function isSourceCheckout() {
|
|
|
76362
76779
|
return existsSync63(path100.join(packageRoot, "src", "cli", "main.ts")) && existsSync63(path100.join(packageRoot, "apps", "desktop", "package.json"));
|
|
76363
76780
|
}
|
|
76364
76781
|
function checkShim(pkgName) {
|
|
76365
|
-
const prefix =
|
|
76782
|
+
const prefix = getGlobalPrefix2();
|
|
76366
76783
|
if (!prefix) {
|
|
76367
76784
|
return WARN("npm global prefix not detectable (run inside an npm context)");
|
|
76368
76785
|
}
|
|
@@ -76378,13 +76795,21 @@ function checkShim(pkgName) {
|
|
|
76378
76795
|
optional: npm install -g ${pkgName}@latest --force`
|
|
76379
76796
|
);
|
|
76380
76797
|
}
|
|
76798
|
+
const installKind = resolveInstallKind();
|
|
76799
|
+
if (installKind === "npx" || installKind === "local") {
|
|
76800
|
+
return WARN(
|
|
76801
|
+
`non-global install (${installKind}) \u2014 no global shim at ${shimPath}
|
|
76802
|
+
PATH/shim expectations do not apply to an npx or local run
|
|
76803
|
+
for a persistent install: npm install -g ${pkgName}@latest`
|
|
76804
|
+
);
|
|
76805
|
+
}
|
|
76381
76806
|
return FAIL(
|
|
76382
76807
|
`shim not found at ${shimPath}
|
|
76383
76808
|
fix: npm install -g ${pkgName}@latest --force`
|
|
76384
76809
|
);
|
|
76385
76810
|
}
|
|
76386
76811
|
try {
|
|
76387
|
-
const st =
|
|
76812
|
+
const st = statSync11(shimPath);
|
|
76388
76813
|
if (isWin) {
|
|
76389
76814
|
const content = readFileSync46(shimPath, "utf8");
|
|
76390
76815
|
if (content.includes(`${pkgName}\\bin\\`) || content.includes(`${pkgName}/bin/`)) {
|
|
@@ -76455,7 +76880,7 @@ function checkBundle() {
|
|
|
76455
76880
|
);
|
|
76456
76881
|
}
|
|
76457
76882
|
try {
|
|
76458
|
-
const st =
|
|
76883
|
+
const st = statSync11(bundle);
|
|
76459
76884
|
return OK(`bundle OK (${(st.size / 1024 / 1024).toFixed(2)} MB)`);
|
|
76460
76885
|
} catch (err) {
|
|
76461
76886
|
return FAIL(
|
|
@@ -76485,7 +76910,7 @@ function checkRuntimeDeps() {
|
|
|
76485
76910
|
);
|
|
76486
76911
|
}
|
|
76487
76912
|
function checkPath() {
|
|
76488
|
-
const prefix =
|
|
76913
|
+
const prefix = getGlobalPrefix2();
|
|
76489
76914
|
if (!prefix) return WARN("npm global prefix not detectable");
|
|
76490
76915
|
const pathSep = process.platform === "win32" ? ";" : ":";
|
|
76491
76916
|
const pathDirs = (process.env.PATH || "").split(pathSep);
|
|
@@ -76703,7 +77128,7 @@ async function runDoctor() {
|
|
|
76703
77128
|
console.log(`zelari-code doctor (v${pkg?.version ?? "unknown"})`);
|
|
76704
77129
|
console.log("platform:", process.platform, process.arch);
|
|
76705
77130
|
console.log("node: ", process.version);
|
|
76706
|
-
console.log("prefix: ",
|
|
77131
|
+
console.log("prefix: ", getGlobalPrefix2() || "(unknown)");
|
|
76707
77132
|
console.log("root: ", packageRoot);
|
|
76708
77133
|
console.log("");
|
|
76709
77134
|
let criticalFails = 0;
|
|
@@ -76744,6 +77169,7 @@ var init_doctor = __esm({
|
|
|
76744
77169
|
init_prereqChecks();
|
|
76745
77170
|
init_metrics3();
|
|
76746
77171
|
init_contextGrowthSummary();
|
|
77172
|
+
init_updater();
|
|
76747
77173
|
require3 = createRequire3(import.meta.url);
|
|
76748
77174
|
__dirname3 = path100.dirname(fileURLToPath3(import.meta.url));
|
|
76749
77175
|
packageRoot = findPackageRoot(__dirname3);
|
|
@@ -76771,7 +77197,7 @@ __export(fixPath_exports, {
|
|
|
76771
77197
|
repairWindowsUserPath: () => repairWindowsUserPath
|
|
76772
77198
|
});
|
|
76773
77199
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
76774
|
-
function
|
|
77200
|
+
function getGlobalPrefix3() {
|
|
76775
77201
|
try {
|
|
76776
77202
|
const fromNpm = spawnSync3("npm", ["prefix", "-g"], {
|
|
76777
77203
|
encoding: "utf8",
|
|
@@ -76796,7 +77222,7 @@ function powershell(script) {
|
|
|
76796
77222
|
}
|
|
76797
77223
|
}
|
|
76798
77224
|
function repairWindowsUserPath() {
|
|
76799
|
-
const prefix =
|
|
77225
|
+
const prefix = getGlobalPrefix3();
|
|
76800
77226
|
if (!prefix) {
|
|
76801
77227
|
return {
|
|
76802
77228
|
ok: false,
|
|
@@ -77206,7 +77632,7 @@ __export(inspect_exports, {
|
|
|
77206
77632
|
runInspect: () => runInspect
|
|
77207
77633
|
});
|
|
77208
77634
|
import path103 from "node:path";
|
|
77209
|
-
import { existsSync as existsSync66, readFileSync as readFileSync48, readdirSync as
|
|
77635
|
+
import { existsSync as existsSync66, readFileSync as readFileSync48, readdirSync as readdirSync14 } from "node:fs";
|
|
77210
77636
|
async function collectInspectReport(cwd = process.cwd()) {
|
|
77211
77637
|
ensureBuiltinSkillsLoadedSync();
|
|
77212
77638
|
const snap = listSkillsSnapshot(cwd);
|
|
@@ -77275,7 +77701,7 @@ async function collectInspectReport(cwd = process.cwd()) {
|
|
|
77275
77701
|
}
|
|
77276
77702
|
function listJsonFiles(dir) {
|
|
77277
77703
|
try {
|
|
77278
|
-
return
|
|
77704
|
+
return readdirSync14(dir).filter((f) => f.endsWith(".json")).sort();
|
|
77279
77705
|
} catch {
|
|
77280
77706
|
return [];
|
|
77281
77707
|
}
|
|
@@ -77742,12 +78168,12 @@ function mergeChanges(unstaged, staged, untrackedPaths) {
|
|
|
77742
78168
|
return [...byPath.values()].sort((a, b) => churn(b) - churn(a));
|
|
77743
78169
|
}
|
|
77744
78170
|
function runGit(args, cwd) {
|
|
77745
|
-
return new Promise((
|
|
78171
|
+
return new Promise((resolve11, reject) => {
|
|
77746
78172
|
execFile(
|
|
77747
78173
|
"git",
|
|
77748
78174
|
args,
|
|
77749
78175
|
{ cwd, timeout: 5e3, windowsHide: true, maxBuffer: 4 * 1024 * 1024 },
|
|
77750
|
-
(err, stdout) => err ? reject(err) :
|
|
78176
|
+
(err, stdout) => err ? reject(err) : resolve11(stdout)
|
|
77751
78177
|
);
|
|
77752
78178
|
});
|
|
77753
78179
|
}
|
|
@@ -80326,7 +80752,7 @@ init_toolPermissions();
|
|
|
80326
80752
|
init_askUserTimeout();
|
|
80327
80753
|
function createPermissionAskHandler(opts) {
|
|
80328
80754
|
const { setPicker: setPicker2, appendSystem: appendSystem2 } = opts;
|
|
80329
|
-
return (req) => new Promise((
|
|
80755
|
+
return (req) => new Promise((resolve11) => {
|
|
80330
80756
|
const cats = req.categories;
|
|
80331
80757
|
const catLabel = cats.length === 1 ? cats[0] : cats.join("+") || "action";
|
|
80332
80758
|
const title = `Allow tool "${req.toolName}"?`;
|
|
@@ -80352,7 +80778,7 @@ ${detail}${note}${claimsBlock}
|
|
|
80352
80778
|
cancelAskTimeout();
|
|
80353
80779
|
setPicker2(null);
|
|
80354
80780
|
if (note2) appendSystem2?.(note2, Date.now());
|
|
80355
|
-
|
|
80781
|
+
resolve11(ok);
|
|
80356
80782
|
};
|
|
80357
80783
|
cancelAskTimeout = armPickerTimeout(
|
|
80358
80784
|
() => finish2(
|
|
@@ -80551,10 +80977,10 @@ function useChatTurn(params) {
|
|
|
80551
80977
|
}
|
|
80552
80978
|
} catch {
|
|
80553
80979
|
}
|
|
80554
|
-
const onAskUser = setPicker2 ? (req) => new Promise((
|
|
80980
|
+
const onAskUser = setPicker2 ? (req) => new Promise((resolve11) => {
|
|
80555
80981
|
const choices = req.choices ?? [];
|
|
80556
80982
|
if (choices.length < 2) {
|
|
80557
|
-
|
|
80983
|
+
resolve11(null);
|
|
80558
80984
|
return;
|
|
80559
80985
|
}
|
|
80560
80986
|
setLastClarification({
|
|
@@ -80578,7 +81004,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
80578
81004
|
settled = true;
|
|
80579
81005
|
cancelAskTimeout();
|
|
80580
81006
|
setPicker2(null);
|
|
80581
|
-
|
|
81007
|
+
resolve11(value);
|
|
80582
81008
|
};
|
|
80583
81009
|
cancelAskTimeout = armPickerTimeout(
|
|
80584
81010
|
() => {
|
|
@@ -81524,10 +81950,10 @@ async function dispatchCouncilPromptImpl(text, deps, overrides = {}) {
|
|
|
81524
81950
|
const { composeProjectContext: composeProjectContext2 } = await Promise.resolve().then(() => (init_composeContext(), composeContext_exports));
|
|
81525
81951
|
const { FeedbackStore: FeedbackStore2 } = await Promise.resolve().then(() => (init_councilFeedback(), councilFeedback_exports));
|
|
81526
81952
|
const workPhase = getPhase();
|
|
81527
|
-
const onAskUserCouncil = setPicker2 ? (req) => new Promise((
|
|
81953
|
+
const onAskUserCouncil = setPicker2 ? (req) => new Promise((resolve11) => {
|
|
81528
81954
|
const choices = req.choices ?? [];
|
|
81529
81955
|
if (choices.length < 2) {
|
|
81530
|
-
|
|
81956
|
+
resolve11(null);
|
|
81531
81957
|
return;
|
|
81532
81958
|
}
|
|
81533
81959
|
setLastClarification({
|
|
@@ -81551,7 +81977,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
81551
81977
|
settled = true;
|
|
81552
81978
|
cancelAskTimeout();
|
|
81553
81979
|
setPicker2(null);
|
|
81554
|
-
|
|
81980
|
+
resolve11(value);
|
|
81555
81981
|
};
|
|
81556
81982
|
cancelAskTimeout = armPickerTimeout(
|
|
81557
81983
|
() => {
|
|
@@ -81733,10 +82159,10 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
81733
82159
|
appendSystem(setMessages, message, Date.now());
|
|
81734
82160
|
},
|
|
81735
82161
|
// v1.8.0: pause council when a member asks a structured question.
|
|
81736
|
-
onClarification: setPicker2 ? (req) => new Promise((
|
|
82162
|
+
onClarification: setPicker2 ? (req) => new Promise((resolve11) => {
|
|
81737
82163
|
const choices = req.choices ?? [];
|
|
81738
82164
|
if (choices.length < 2) {
|
|
81739
|
-
|
|
82165
|
+
resolve11(null);
|
|
81740
82166
|
return;
|
|
81741
82167
|
}
|
|
81742
82168
|
setLastClarification({
|
|
@@ -81757,7 +82183,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il membro riprende dop
|
|
|
81757
82183
|
if (settled) return;
|
|
81758
82184
|
settled = true;
|
|
81759
82185
|
setPicker2(null);
|
|
81760
|
-
|
|
82186
|
+
resolve11(value);
|
|
81761
82187
|
};
|
|
81762
82188
|
setPicker2({
|
|
81763
82189
|
kind: "clarification",
|
|
@@ -82415,10 +82841,10 @@ function usePermissionBroker(opts) {
|
|
|
82415
82841
|
setPicker: setPicker2,
|
|
82416
82842
|
appendSystem: (msg, at) => appendSystem(setMessages, msg, at ?? Date.now())
|
|
82417
82843
|
});
|
|
82418
|
-
const onQuestion = (req) => new Promise((
|
|
82844
|
+
const onQuestion = (req) => new Promise((resolve11) => {
|
|
82419
82845
|
const choices = (req.choices ?? []).map((c) => String(c).trim()).filter((c) => c.length > 0);
|
|
82420
82846
|
if (choices.length < 2) {
|
|
82421
|
-
|
|
82847
|
+
resolve11(null);
|
|
82422
82848
|
return;
|
|
82423
82849
|
}
|
|
82424
82850
|
let settled = false;
|
|
@@ -82428,7 +82854,7 @@ function usePermissionBroker(opts) {
|
|
|
82428
82854
|
settled = true;
|
|
82429
82855
|
cancelWaitTimeout?.();
|
|
82430
82856
|
setPicker2(null);
|
|
82431
|
-
|
|
82857
|
+
resolve11(value);
|
|
82432
82858
|
};
|
|
82433
82859
|
const waitTimeoutMs = askUserTimeoutMs();
|
|
82434
82860
|
cancelWaitTimeout = armPickerTimeout(() => {
|
|
@@ -84682,7 +85108,8 @@ async function handleUpdateCheck(ctx) {
|
|
|
84682
85108
|
appendSystem(
|
|
84683
85109
|
ctx.setMessages,
|
|
84684
85110
|
`[update] \u{1F195} zelari-code ${info.latestVersion} available (current: ${info.currentVersion})
|
|
84685
|
-
Run \`/update --yes\` to install
|
|
85111
|
+
Run \`/update --yes\` to install (global installs only).
|
|
85112
|
+
On npx/local installs, update with \`npx zelari-code@latest\` \u2014 you'll need to restart manually after.`
|
|
84686
85113
|
);
|
|
84687
85114
|
} else {
|
|
84688
85115
|
appendSystem(
|
|
@@ -84699,7 +85126,18 @@ async function handleUpdateCheck(ctx) {
|
|
|
84699
85126
|
}
|
|
84700
85127
|
async function handleUpdatePerform(ctx) {
|
|
84701
85128
|
try {
|
|
84702
|
-
const {
|
|
85129
|
+
const {
|
|
85130
|
+
performUpdate: performUpdate2,
|
|
85131
|
+
resolveInstallKind: resolveInstallKind2,
|
|
85132
|
+
nonGlobalUpdateAdvisory: nonGlobalUpdateAdvisory2,
|
|
85133
|
+
distTagForVersion: distTagForVersion2,
|
|
85134
|
+
getCurrentVersion: getCurrentVersion2
|
|
85135
|
+
} = await Promise.resolve().then(() => (init_updater(), updater_exports));
|
|
85136
|
+
const kind2 = resolveInstallKind2();
|
|
85137
|
+
if (kind2 === "npx" || kind2 === "local") {
|
|
85138
|
+
appendSystem(ctx.setMessages, nonGlobalUpdateAdvisory2(kind2));
|
|
85139
|
+
return;
|
|
85140
|
+
}
|
|
84703
85141
|
const tag = distTagForVersion2(getCurrentVersion2());
|
|
84704
85142
|
appendSystem(
|
|
84705
85143
|
ctx.setMessages,
|
|
@@ -84806,7 +85244,7 @@ ${browsers.output}` : "") + (browsers.ok ? "" : `
|
|
|
84806
85244
|
return result;
|
|
84807
85245
|
}
|
|
84808
85246
|
function runPlaywrightInstallChromium(cwd, executor) {
|
|
84809
|
-
return new Promise((
|
|
85247
|
+
return new Promise((resolve11) => {
|
|
84810
85248
|
let stdout = "";
|
|
84811
85249
|
let stderr = "";
|
|
84812
85250
|
const stdio = ["ignore", "pipe", "pipe"];
|
|
@@ -84819,7 +85257,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
|
|
|
84819
85257
|
stderr += chunk.toString();
|
|
84820
85258
|
});
|
|
84821
85259
|
child.on("error", (err) => {
|
|
84822
|
-
|
|
85260
|
+
resolve11({
|
|
84823
85261
|
ok: false,
|
|
84824
85262
|
output: stdout + stderr,
|
|
84825
85263
|
error: err.message,
|
|
@@ -84828,7 +85266,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
|
|
|
84828
85266
|
});
|
|
84829
85267
|
child.on("close", (code) => {
|
|
84830
85268
|
const ok = code === 0;
|
|
84831
|
-
|
|
85269
|
+
resolve11({
|
|
84832
85270
|
ok,
|
|
84833
85271
|
output: stdout + stderr,
|
|
84834
85272
|
exitCode: code,
|
|
@@ -84838,7 +85276,7 @@ function runPlaywrightInstallChromium(cwd, executor) {
|
|
|
84838
85276
|
});
|
|
84839
85277
|
}
|
|
84840
85278
|
function runNpm2(executor, args, cwd, mode, npmCliPath) {
|
|
84841
|
-
return new Promise((
|
|
85279
|
+
return new Promise((resolve11) => {
|
|
84842
85280
|
let stdout = "";
|
|
84843
85281
|
let stderr = "";
|
|
84844
85282
|
const stdio = ["ignore", "pipe", "pipe"];
|
|
@@ -84850,7 +85288,7 @@ function runNpm2(executor, args, cwd, mode, npmCliPath) {
|
|
|
84850
85288
|
stderr += chunk.toString();
|
|
84851
85289
|
});
|
|
84852
85290
|
child.on("error", (err) => {
|
|
84853
|
-
|
|
85291
|
+
resolve11({
|
|
84854
85292
|
ok: false,
|
|
84855
85293
|
output: stdout + stderr,
|
|
84856
85294
|
error: err.message,
|
|
@@ -84859,7 +85297,7 @@ function runNpm2(executor, args, cwd, mode, npmCliPath) {
|
|
|
84859
85297
|
});
|
|
84860
85298
|
child.on("close", (code) => {
|
|
84861
85299
|
const ok = code === 0;
|
|
84862
|
-
|
|
85300
|
+
resolve11({
|
|
84863
85301
|
ok,
|
|
84864
85302
|
output: stdout + stderr,
|
|
84865
85303
|
exitCode: code,
|
|
@@ -87323,7 +87761,7 @@ function runPreflight() {
|
|
|
87323
87761
|
}
|
|
87324
87762
|
async function backgroundUpdateCheck() {
|
|
87325
87763
|
if (process.env.ANATHEMA_DEV === "1") return;
|
|
87326
|
-
await new Promise((
|
|
87764
|
+
await new Promise((resolve11) => setTimeout(resolve11, 3e3));
|
|
87327
87765
|
try {
|
|
87328
87766
|
const { checkForUpdate: checkForUpdate2 } = await Promise.resolve().then(() => (init_updater(), updater_exports));
|
|
87329
87767
|
const info = await checkForUpdate2();
|
|
@@ -88124,7 +88562,7 @@ function main() {
|
|
|
88124
88562
|
closeMcpClients2();
|
|
88125
88563
|
} catch {
|
|
88126
88564
|
}
|
|
88127
|
-
await new Promise((
|
|
88565
|
+
await new Promise((resolve11) => setImmediate(resolve11));
|
|
88128
88566
|
process.exit(code);
|
|
88129
88567
|
}).catch(async (err) => {
|
|
88130
88568
|
console.error(
|