@ordewell/core 0.4.20 → 0.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-QJ63PD5K.mjs → chunk-MKUTJDT2.mjs} +2 -1
- package/dist/chunk-MKUTJDT2.mjs.map +1 -0
- package/dist/index.d.mts +14 -2
- package/dist/index.d.ts +14 -2
- package/dist/index.js +317 -127
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +310 -121
- package/dist/index.mjs.map +1 -1
- package/dist/parsing.js +1 -0
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-QJ63PD5K.mjs.map +0 -1
package/dist/index.js
CHANGED
|
@@ -4340,6 +4340,7 @@ function resolveTaskMode(emittedMode, runnerId, runnerModes, autonomousDefault =
|
|
|
4340
4340
|
if (!runnerModes) return rawMode === "plan" ? "plan" : "build";
|
|
4341
4341
|
const modes = runnerModes[runnerId];
|
|
4342
4342
|
if (!modes || modes.length === 0) return rawMode;
|
|
4343
|
+
if (!emittedMode) return resolveDefaultMode(modes, autonomousDefault) ?? "build";
|
|
4343
4344
|
const validIds = new Set(modes.map((m) => m.id));
|
|
4344
4345
|
if (rawMode === "build" || validIds.has(rawMode)) {
|
|
4345
4346
|
if (rawMode === "plan" || rawMode === "build") return rawMode;
|
|
@@ -6671,9 +6672,9 @@ function summarizeToolCall(tool, argsJson, toolLabel) {
|
|
|
6671
6672
|
const scope = args.include ? ` in ${args.include}` : "";
|
|
6672
6673
|
return `grep ${ellipsize(String(args.pattern), 40)}${scope}${mode}`;
|
|
6673
6674
|
}
|
|
6674
|
-
const
|
|
6675
|
-
if (
|
|
6676
|
-
const basename = String(
|
|
6675
|
+
const path21 = args.filePath || args.file_path || args.path;
|
|
6676
|
+
if (path21) {
|
|
6677
|
+
const basename = String(path21).split("/").pop() || String(path21);
|
|
6677
6678
|
return `${display} ${basename}`;
|
|
6678
6679
|
}
|
|
6679
6680
|
if (args.pattern) {
|
|
@@ -8058,6 +8059,19 @@ function renderTerminalOutput(raw) {
|
|
|
8058
8059
|
}
|
|
8059
8060
|
var MARKER_SCAN_TAIL = 16384;
|
|
8060
8061
|
var IDLE_TIMEOUT_MS = 6e4;
|
|
8062
|
+
function renderCleanCapture(raw, doneToken) {
|
|
8063
|
+
const rendered = renderTerminalOutput(raw).replace(/[\s─-▟]+$/gm, "");
|
|
8064
|
+
if (!doneToken) return rendered.trim();
|
|
8065
|
+
const lines = rendered.split("\n");
|
|
8066
|
+
const flat = (s) => flattenTerminalOutput(s);
|
|
8067
|
+
for (let i = 0; i < lines.length; i++) {
|
|
8068
|
+
const own = flat(lines[i]).includes(doneToken);
|
|
8069
|
+
if (own) return lines.slice(0, i).join("\n").trim();
|
|
8070
|
+
const window = flat(lines[i]) + (i + 1 < lines.length ? flat(lines[i + 1]) : "");
|
|
8071
|
+
if (window.includes(doneToken)) return lines.slice(0, i + 1).join("\n").trim();
|
|
8072
|
+
}
|
|
8073
|
+
return rendered.trim();
|
|
8074
|
+
}
|
|
8061
8075
|
var VerdictEngine = class {
|
|
8062
8076
|
markerSeen = /* @__PURE__ */ new Set();
|
|
8063
8077
|
buffers = /* @__PURE__ */ new Map();
|
|
@@ -8285,6 +8299,167 @@ ${line}
|
|
|
8285
8299
|
}
|
|
8286
8300
|
};
|
|
8287
8301
|
|
|
8302
|
+
// src/services/transcriptCapture.ts
|
|
8303
|
+
var import_fs = require("fs");
|
|
8304
|
+
var os2 = __toESM(require("os"));
|
|
8305
|
+
var path4 = __toESM(require("path"));
|
|
8306
|
+
function homeDir() {
|
|
8307
|
+
return process.env.HOME || os2.homedir();
|
|
8308
|
+
}
|
|
8309
|
+
async function readFinalAssistantText(query, maxChars = 4e3) {
|
|
8310
|
+
try {
|
|
8311
|
+
if (query.runner === "claude-code") return claudeFinal(query, maxChars);
|
|
8312
|
+
if (query.runner === "opencode") return await opencodeFinal(query, maxChars);
|
|
8313
|
+
if (query.runner === "codex") return codexFinal(query, maxChars);
|
|
8314
|
+
} catch {
|
|
8315
|
+
}
|
|
8316
|
+
return null;
|
|
8317
|
+
}
|
|
8318
|
+
function claudeFinal(query, maxChars) {
|
|
8319
|
+
const munged = query.cwd.replaceAll("/", "-").replaceAll("_", "-");
|
|
8320
|
+
const dir = path4.join(homeDir(), ".claude", "projects", munged);
|
|
8321
|
+
if (!(0, import_fs.existsSync)(dir)) return null;
|
|
8322
|
+
const cutoff = query.startedAt ? Date.parse(query.startedAt) : 0;
|
|
8323
|
+
const candidates = (0, import_fs.readdirSync)(dir).filter((f) => f.endsWith(".jsonl")).map((f) => path4.join(dir, f)).filter((f) => cutoff ? (0, import_fs.statSync)(f).mtimeMs >= cutoff - 5e3 : true).sort((a, b) => (0, import_fs.statSync)(b).mtimeMs - (0, import_fs.statSync)(a).mtimeMs);
|
|
8324
|
+
for (const file of candidates) {
|
|
8325
|
+
const text = claudeLastAssistant(file);
|
|
8326
|
+
if (text) return clamp(text, maxChars);
|
|
8327
|
+
}
|
|
8328
|
+
return null;
|
|
8329
|
+
}
|
|
8330
|
+
function claudeLastAssistant(file) {
|
|
8331
|
+
let last = null;
|
|
8332
|
+
let buf = "";
|
|
8333
|
+
const fd = (0, import_fs.statSync)(file);
|
|
8334
|
+
const start = Math.max(0, fd.size - 512 * 1024);
|
|
8335
|
+
buf = (0, import_fs.readFileSync)(file, { encoding: "utf8" }).toString();
|
|
8336
|
+
if (start > 0) buf = buf.slice(buf.indexOf("\n", Math.min(start, buf.length - 1)) + 1);
|
|
8337
|
+
for (const line of buf.split("\n")) {
|
|
8338
|
+
if (!line.trim()) continue;
|
|
8339
|
+
let rec;
|
|
8340
|
+
try {
|
|
8341
|
+
rec = JSON.parse(line);
|
|
8342
|
+
} catch {
|
|
8343
|
+
continue;
|
|
8344
|
+
}
|
|
8345
|
+
if (rec.type !== "assistant" || rec.isSidechain) continue;
|
|
8346
|
+
const content = rec.message?.content;
|
|
8347
|
+
if (!Array.isArray(content)) continue;
|
|
8348
|
+
const texts = content.filter((b) => typeof b === "object" && b !== null && b.type === "text").map((b) => b.text).join("\n").trim();
|
|
8349
|
+
if (texts) last = texts;
|
|
8350
|
+
}
|
|
8351
|
+
return last;
|
|
8352
|
+
}
|
|
8353
|
+
async function opencodeFinal(query, maxChars) {
|
|
8354
|
+
let DatabaseSync;
|
|
8355
|
+
try {
|
|
8356
|
+
({ DatabaseSync } = await import("sqlite"));
|
|
8357
|
+
} catch {
|
|
8358
|
+
return null;
|
|
8359
|
+
}
|
|
8360
|
+
const dbPath = path4.join(homeDir(), ".local", "share", "opencode", "opencode.db");
|
|
8361
|
+
if (!(0, import_fs.existsSync)(dbPath)) return null;
|
|
8362
|
+
let db;
|
|
8363
|
+
try {
|
|
8364
|
+
db = new DatabaseSync(dbPath, { open: true });
|
|
8365
|
+
} catch {
|
|
8366
|
+
return null;
|
|
8367
|
+
}
|
|
8368
|
+
try {
|
|
8369
|
+
const cutoff = query.startedAt ? Date.parse(query.startedAt) : 0;
|
|
8370
|
+
const rows = db.prepare(
|
|
8371
|
+
`select s.id, s.time_updated from session s
|
|
8372
|
+
join project p on p.id = s.project_id
|
|
8373
|
+
where s.directory = ?
|
|
8374
|
+
order by s.time_updated desc limit 5`
|
|
8375
|
+
).all(query.cwd);
|
|
8376
|
+
for (const row of rows) {
|
|
8377
|
+
if (cutoff && row.time_updated < cutoff - 5e3) continue;
|
|
8378
|
+
const parts = db.prepare(
|
|
8379
|
+
`select pt.data from part pt
|
|
8380
|
+
join message m on m.id = pt.message_id
|
|
8381
|
+
where m.session_id = ? and m.data like '%"role":"assistant"%'
|
|
8382
|
+
order by pt.id asc`
|
|
8383
|
+
).all(row.id);
|
|
8384
|
+
let text = null;
|
|
8385
|
+
for (const p of parts) {
|
|
8386
|
+
try {
|
|
8387
|
+
const d = JSON.parse(p.data);
|
|
8388
|
+
if (d.type === "text" && d.text && d.text.trim()) text = d.text.trim();
|
|
8389
|
+
} catch {
|
|
8390
|
+
continue;
|
|
8391
|
+
}
|
|
8392
|
+
}
|
|
8393
|
+
if (text) return clamp(text, maxChars);
|
|
8394
|
+
}
|
|
8395
|
+
return null;
|
|
8396
|
+
} catch {
|
|
8397
|
+
return null;
|
|
8398
|
+
} finally {
|
|
8399
|
+
try {
|
|
8400
|
+
db.close();
|
|
8401
|
+
} catch {
|
|
8402
|
+
}
|
|
8403
|
+
}
|
|
8404
|
+
}
|
|
8405
|
+
function codexFinal(query, maxChars) {
|
|
8406
|
+
const root = path4.join(homeDir(), ".codex", "sessions");
|
|
8407
|
+
if (!(0, import_fs.existsSync)(root)) return null;
|
|
8408
|
+
const cutoff = query.startedAt ? Date.parse(query.startedAt) : 0;
|
|
8409
|
+
const files = [];
|
|
8410
|
+
const stack = [root];
|
|
8411
|
+
while (stack.length) {
|
|
8412
|
+
const dir = stack.pop();
|
|
8413
|
+
let entries;
|
|
8414
|
+
try {
|
|
8415
|
+
entries = (0, import_fs.readdirSync)(dir);
|
|
8416
|
+
} catch {
|
|
8417
|
+
continue;
|
|
8418
|
+
}
|
|
8419
|
+
for (const e of entries) {
|
|
8420
|
+
const full = path4.join(dir, e);
|
|
8421
|
+
let st;
|
|
8422
|
+
try {
|
|
8423
|
+
st = (0, import_fs.statSync)(full);
|
|
8424
|
+
} catch {
|
|
8425
|
+
continue;
|
|
8426
|
+
}
|
|
8427
|
+
if (st.isDirectory()) stack.push(full);
|
|
8428
|
+
else if (e.startsWith("rollout-") && e.endsWith(".jsonl") && (!cutoff || st.mtimeMs >= cutoff - 5e3)) files.push(full);
|
|
8429
|
+
}
|
|
8430
|
+
}
|
|
8431
|
+
files.sort((a, b) => (0, import_fs.statSync)(b).mtimeMs - (0, import_fs.statSync)(a).mtimeMs);
|
|
8432
|
+
for (const file of files.slice(0, 10)) {
|
|
8433
|
+
const text = codexLastAssistant(file, query.cwd);
|
|
8434
|
+
if (text) return clamp(text, maxChars);
|
|
8435
|
+
}
|
|
8436
|
+
return null;
|
|
8437
|
+
}
|
|
8438
|
+
function codexLastAssistant(file, cwd) {
|
|
8439
|
+
const raw = (0, import_fs.readFileSync)(file, "utf8");
|
|
8440
|
+
const lines = raw.split("\n").filter((l) => l.trim());
|
|
8441
|
+
let sawCwd = false;
|
|
8442
|
+
let last = null;
|
|
8443
|
+
for (const line of lines) {
|
|
8444
|
+
let rec;
|
|
8445
|
+
try {
|
|
8446
|
+
rec = JSON.parse(line);
|
|
8447
|
+
} catch {
|
|
8448
|
+
continue;
|
|
8449
|
+
}
|
|
8450
|
+
if (rec.type === "session_meta" && rec.payload?.cwd === cwd) sawCwd = true;
|
|
8451
|
+
if (rec.type !== "response_item") continue;
|
|
8452
|
+
const p = rec.payload;
|
|
8453
|
+
if (p?.role !== "assistant" || p.type !== "message") continue;
|
|
8454
|
+
const texts = (Array.isArray(p.content) ? p.content : []).map((c) => typeof c === "object" && c !== null && c.text || "").join("\n").trim();
|
|
8455
|
+
if (texts) last = texts;
|
|
8456
|
+
}
|
|
8457
|
+
return sawCwd ? last : null;
|
|
8458
|
+
}
|
|
8459
|
+
function clamp(text, maxChars) {
|
|
8460
|
+
return text.length <= maxChars ? text : text.slice(-maxChars);
|
|
8461
|
+
}
|
|
8462
|
+
|
|
8288
8463
|
// src/services/PlanStore.ts
|
|
8289
8464
|
var PlanStore = class {
|
|
8290
8465
|
_planTasks = [];
|
|
@@ -8666,6 +8841,11 @@ var TaskOrchestrator = class {
|
|
|
8666
8841
|
workspaceRootFn = () => process.cwd();
|
|
8667
8842
|
observers = [];
|
|
8668
8843
|
tddEnabled = () => false;
|
|
8844
|
+
/**
|
|
8845
|
+
* Spawn context per active task, for locating the agent's own session
|
|
8846
|
+
* transcript at verdict time (issue #16). Cleared with the session entry.
|
|
8847
|
+
*/
|
|
8848
|
+
taskSpawnContext = /* @__PURE__ */ new Map();
|
|
8669
8849
|
/** Advisory silence timestamp for a task's live runner, or null if not idle. */
|
|
8670
8850
|
getIdleSince(taskId) {
|
|
8671
8851
|
return this.verifier.getIdleSince(taskId);
|
|
@@ -8828,6 +9008,8 @@ var TaskOrchestrator = class {
|
|
|
8828
9008
|
const task = this.store.get(taskId);
|
|
8829
9009
|
if (!task) return;
|
|
8830
9010
|
this.activeTaskSessions.delete(taskId);
|
|
9011
|
+
const spawnContext = this.taskSpawnContext.get(taskId);
|
|
9012
|
+
this.taskSpawnContext.delete(taskId);
|
|
8831
9013
|
console.error(`[TaskOrchestrator] Task #${task.order} "${task.title}" verdict=${verdict.outcome}`);
|
|
8832
9014
|
console.error(`[TaskOrchestrator] Runner: ${task.assignedRunner}, Model: ${task.assignedModel?.modelId ?? "default"}`);
|
|
8833
9015
|
console.error(`[TaskOrchestrator] Prompt preview: ${(task.prompt ?? "").slice(0, 200)}`);
|
|
@@ -8838,6 +9020,10 @@ ${output.slice(-3e3)}`);
|
|
|
8838
9020
|
console.error(`[TaskOrchestrator] Output: (empty \u2014 no stdout/stderr captured)`);
|
|
8839
9021
|
}
|
|
8840
9022
|
this.store.setTaskVerdict(taskId, verdict);
|
|
9023
|
+
const doneToken = `<<<ORDEWELL_DONE_${task.completionMarker}>>>`;
|
|
9024
|
+
const transcript = spawnContext ? await readFinalAssistantText(spawnContext) : null;
|
|
9025
|
+
const cleaned = transcript ?? renderCleanCapture(output, doneToken);
|
|
9026
|
+
const effective = cleaned.length > 0 ? cleaned : output;
|
|
8841
9027
|
if (verdict.outcome === "pass") {
|
|
8842
9028
|
this.store.markCompleted(taskId);
|
|
8843
9029
|
this.notifications.info(`Task "${task.title}" completed.`);
|
|
@@ -8847,7 +9033,7 @@ ${output.slice(-3e3)}`);
|
|
|
8847
9033
|
this.planStatus = "approved";
|
|
8848
9034
|
this.notifications.error(`Task "${task.title}" failed verification: ${verdict.reason}`);
|
|
8849
9035
|
}
|
|
8850
|
-
this.store.setTaskOutputSummary(taskId, summarizeOutput(verdict.reason,
|
|
9036
|
+
this.store.setTaskOutputSummary(taskId, summarizeOutput(verdict.reason, effective));
|
|
8851
9037
|
this.logAndArchive(task, verdict);
|
|
8852
9038
|
this.emit("onTaskChanged");
|
|
8853
9039
|
if (!this.running) {
|
|
@@ -9087,6 +9273,8 @@ ${output.slice(-3e3)}`);
|
|
|
9087
9273
|
try {
|
|
9088
9274
|
const cwd = this.workspaceRootFn();
|
|
9089
9275
|
const runner = this.store.resolveTaskRunner(task);
|
|
9276
|
+
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
9277
|
+
this.taskSpawnContext.set(task.id, { runner, cwd, startedAt });
|
|
9090
9278
|
const finalPrompt = composeAugmentedPrompt(task, this.store.planTasks, {
|
|
9091
9279
|
planMapEnabled: this.config.planMapEnabled,
|
|
9092
9280
|
tddEnabled: this.tddEnabled()
|
|
@@ -9251,7 +9439,7 @@ ${errors.map((e) => `- ${e}`).join("\n")}`
|
|
|
9251
9439
|
};
|
|
9252
9440
|
|
|
9253
9441
|
// src/services/ModelDiscovery.ts
|
|
9254
|
-
var
|
|
9442
|
+
var path8 = __toESM(require("path"));
|
|
9255
9443
|
var import_child_process3 = require("child_process");
|
|
9256
9444
|
var import_util2 = require("util");
|
|
9257
9445
|
var fsSync3 = __toESM(require("fs"));
|
|
@@ -9260,8 +9448,8 @@ var osMod = __toESM(require("os"));
|
|
|
9260
9448
|
// src/utils/shellPath.ts
|
|
9261
9449
|
var import_child_process = require("child_process");
|
|
9262
9450
|
var import_util = require("util");
|
|
9263
|
-
var
|
|
9264
|
-
var
|
|
9451
|
+
var os3 = __toESM(require("os"));
|
|
9452
|
+
var path5 = __toESM(require("path"));
|
|
9265
9453
|
var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
9266
9454
|
var LOGIN_SHELL_TIMEOUT_MS = 5e3;
|
|
9267
9455
|
var PATH_MARKER = "__ORDEWELL_PATH__";
|
|
@@ -9270,42 +9458,42 @@ var defaultExec = async (command, options) => {
|
|
|
9270
9458
|
return { stdout: String(stdout) };
|
|
9271
9459
|
};
|
|
9272
9460
|
function posixBinDirs() {
|
|
9273
|
-
const home =
|
|
9461
|
+
const home = os3.homedir();
|
|
9274
9462
|
return [
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
|
|
9463
|
+
path5.join(home, ".local", "bin"),
|
|
9464
|
+
path5.join(home, ".opencode", "bin"),
|
|
9465
|
+
path5.join(home, ".claude", "bin"),
|
|
9466
|
+
path5.join(home, ".bun", "bin"),
|
|
9467
|
+
path5.join(home, ".volta", "bin"),
|
|
9468
|
+
path5.join(home, ".npm-global", "bin"),
|
|
9469
|
+
path5.join(home, "bin"),
|
|
9282
9470
|
"/usr/local/bin",
|
|
9283
9471
|
"/opt/homebrew/bin"
|
|
9284
9472
|
];
|
|
9285
9473
|
}
|
|
9286
9474
|
function windowsBinDirs(env, home) {
|
|
9287
|
-
const
|
|
9288
|
-
const under = (base, ...parts) => base ? [
|
|
9475
|
+
const join20 = (...parts) => path5.win32.join(...parts);
|
|
9476
|
+
const under = (base, ...parts) => base ? [join20(base, ...parts)] : [];
|
|
9289
9477
|
const appData = env.APPDATA;
|
|
9290
9478
|
const localAppData = env.LOCALAPPDATA;
|
|
9291
9479
|
const programData = env.ProgramData;
|
|
9292
9480
|
return [
|
|
9293
9481
|
// Native per-user installers, PowerShell-driven and otherwise.
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9482
|
+
join20(home, ".local", "bin"),
|
|
9483
|
+
join20(home, ".opencode", "bin"),
|
|
9484
|
+
join20(home, ".claude", "bin"),
|
|
9485
|
+
join20(home, ".codex", "bin"),
|
|
9298
9486
|
...under(localAppData, "Programs", "claude"),
|
|
9299
9487
|
// Node package managers. npm's global prefix is `%APPDATA%\npm`; the
|
|
9300
9488
|
// literal spelling is kept as a fallback for a host that does not export
|
|
9301
9489
|
// APPDATA (a service account, a stripped CI container).
|
|
9302
9490
|
...under(appData, "npm"),
|
|
9303
|
-
|
|
9491
|
+
join20(home, "AppData", "Roaming", "npm"),
|
|
9304
9492
|
...under(localAppData, "pnpm"),
|
|
9305
9493
|
...under(localAppData, "Yarn", "bin"),
|
|
9306
|
-
|
|
9494
|
+
join20(home, ".bun", "bin"),
|
|
9307
9495
|
// Windows package managers.
|
|
9308
|
-
|
|
9496
|
+
join20(home, "scoop", "shims"),
|
|
9309
9497
|
...under(env.SCOOP, "shims"),
|
|
9310
9498
|
...under(env.SCOOP_GLOBAL ?? programData, "scoop", "shims"),
|
|
9311
9499
|
...under(programData, "chocolatey", "bin"),
|
|
@@ -9315,13 +9503,13 @@ function windowsBinDirs(env, home) {
|
|
|
9315
9503
|
...under(localAppData, "Microsoft", "WindowsApps"),
|
|
9316
9504
|
// Version managers. Volta's Windows home is not the POSIX `~/.volta`.
|
|
9317
9505
|
...under(localAppData, "Volta", "bin"),
|
|
9318
|
-
|
|
9506
|
+
join20(home, ".volta", "bin")
|
|
9319
9507
|
];
|
|
9320
9508
|
}
|
|
9321
9509
|
function wellKnownBinDirs(deps = {}) {
|
|
9322
9510
|
const platform = deps.platform ?? process.platform;
|
|
9323
9511
|
if (platform !== "win32") return posixBinDirs();
|
|
9324
|
-
return [...new Set(windowsBinDirs(deps.env ?? process.env, deps.home ??
|
|
9512
|
+
return [...new Set(windowsBinDirs(deps.env ?? process.env, deps.home ?? os3.homedir()))];
|
|
9325
9513
|
}
|
|
9326
9514
|
async function loginShellPath(execImpl) {
|
|
9327
9515
|
if (process.platform === "win32") return null;
|
|
@@ -9344,14 +9532,14 @@ function augmentedPath(execImpl = defaultExec) {
|
|
|
9344
9532
|
const segments = [];
|
|
9345
9533
|
const push = (p) => {
|
|
9346
9534
|
if (!p) return;
|
|
9347
|
-
for (const seg of p.split(
|
|
9535
|
+
for (const seg of p.split(path5.delimiter)) {
|
|
9348
9536
|
if (seg && !segments.includes(seg)) segments.push(seg);
|
|
9349
9537
|
}
|
|
9350
9538
|
};
|
|
9351
9539
|
push(process.env.PATH);
|
|
9352
9540
|
push(await loginShellPath(execImpl));
|
|
9353
9541
|
for (const dir of wellKnownBinDirs()) push(dir);
|
|
9354
|
-
return segments.join(
|
|
9542
|
+
return segments.join(path5.delimiter);
|
|
9355
9543
|
})();
|
|
9356
9544
|
}
|
|
9357
9545
|
return cachedPath;
|
|
@@ -9373,17 +9561,17 @@ function withPath(base, resolvedPath, overrides = {}) {
|
|
|
9373
9561
|
|
|
9374
9562
|
// src/utils/globalDataDir.ts
|
|
9375
9563
|
var fs = __toESM(require("fs"));
|
|
9376
|
-
var
|
|
9377
|
-
var
|
|
9564
|
+
var path6 = __toESM(require("path"));
|
|
9565
|
+
var os4 = __toESM(require("os"));
|
|
9378
9566
|
function globalDataDir() {
|
|
9379
|
-
return
|
|
9567
|
+
return path6.join(os4.homedir(), ".ordewell");
|
|
9380
9568
|
}
|
|
9381
9569
|
function copyDirSync(src, dest) {
|
|
9382
9570
|
fs.mkdirSync(dest, { recursive: true });
|
|
9383
9571
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
9384
9572
|
for (const entry of entries) {
|
|
9385
|
-
const srcPath =
|
|
9386
|
-
const destPath =
|
|
9573
|
+
const srcPath = path6.join(src, entry.name);
|
|
9574
|
+
const destPath = path6.join(dest, entry.name);
|
|
9387
9575
|
if (entry.isDirectory()) {
|
|
9388
9576
|
copyDirSync(srcPath, destPath);
|
|
9389
9577
|
} else {
|
|
@@ -9395,12 +9583,12 @@ var migrated = false;
|
|
|
9395
9583
|
function migrateOldConfigDir() {
|
|
9396
9584
|
if (migrated) return;
|
|
9397
9585
|
migrated = true;
|
|
9398
|
-
const oldDir =
|
|
9586
|
+
const oldDir = path6.join(os4.homedir(), ".config", "ordewell");
|
|
9399
9587
|
if (!fs.existsSync(oldDir)) return;
|
|
9400
9588
|
const newDir = globalDataDir();
|
|
9401
9589
|
const liftFile = (name) => {
|
|
9402
|
-
const oldFile =
|
|
9403
|
-
const newFile =
|
|
9590
|
+
const oldFile = path6.join(oldDir, name);
|
|
9591
|
+
const newFile = path6.join(newDir, name);
|
|
9404
9592
|
if (fs.existsSync(oldFile) && !fs.existsSync(newFile)) {
|
|
9405
9593
|
fs.mkdirSync(newDir, { recursive: true });
|
|
9406
9594
|
fs.copyFileSync(oldFile, newFile);
|
|
@@ -9408,8 +9596,8 @@ function migrateOldConfigDir() {
|
|
|
9408
9596
|
};
|
|
9409
9597
|
liftFile("settings.json");
|
|
9410
9598
|
liftFile(".env");
|
|
9411
|
-
const oldPlugins =
|
|
9412
|
-
const newPlugins =
|
|
9599
|
+
const oldPlugins = path6.join(oldDir, "plugins");
|
|
9600
|
+
const newPlugins = path6.join(newDir, "plugins");
|
|
9413
9601
|
if (fs.existsSync(oldPlugins) && !fs.existsSync(newPlugins)) {
|
|
9414
9602
|
copyDirSync(oldPlugins, newPlugins);
|
|
9415
9603
|
}
|
|
@@ -9417,7 +9605,7 @@ function migrateOldConfigDir() {
|
|
|
9417
9605
|
|
|
9418
9606
|
// src/utils/launch.ts
|
|
9419
9607
|
var fsSync2 = __toESM(require("fs"));
|
|
9420
|
-
var
|
|
9608
|
+
var path7 = __toESM(require("path"));
|
|
9421
9609
|
|
|
9422
9610
|
// src/utils/shell.ts
|
|
9423
9611
|
var ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]|\r/g;
|
|
@@ -9446,7 +9634,7 @@ var CMD_EXE_MAX_COMMAND_LINE = 8191;
|
|
|
9446
9634
|
var WINDOWS_MAX_COMMAND_LINE = 32767;
|
|
9447
9635
|
function defaultPowerShell() {
|
|
9448
9636
|
const root = process.env.SystemRoot || process.env.windir;
|
|
9449
|
-
return root ?
|
|
9637
|
+
return root ? path7.win32.join(root, "System32", "WindowsPowerShell", "v1.0", "powershell.exe") : "powershell.exe";
|
|
9450
9638
|
}
|
|
9451
9639
|
var POWERSHELL_FLAGS = ["-NoLogo", "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", "-File"];
|
|
9452
9640
|
var CommandLineTooLongError = class extends Error {
|
|
@@ -9498,7 +9686,7 @@ Searched: ${searchedPath || "(empty PATH)"}`);
|
|
|
9498
9686
|
};
|
|
9499
9687
|
function isResolvableOnPosixPath(command, PATH, exists) {
|
|
9500
9688
|
if (command.includes("/")) return exists(command);
|
|
9501
|
-
return PATH.split(
|
|
9689
|
+
return PATH.split(path7.delimiter).map((d) => d.trim()).filter(Boolean).some((dir) => exists(path7.join(dir, command)));
|
|
9502
9690
|
}
|
|
9503
9691
|
function isExecutableResolved(command, plan, PATH, deps = {}) {
|
|
9504
9692
|
if ((deps.platform ?? process.platform) === "win32") return plan.file !== command;
|
|
@@ -9538,9 +9726,9 @@ function cmdArgs(line) {
|
|
|
9538
9726
|
return ["/d", "/s", "/c", `"${line}"`];
|
|
9539
9727
|
}
|
|
9540
9728
|
function candidateExtensions(command, pathExt) {
|
|
9541
|
-
const declared = pathExt.split(
|
|
9729
|
+
const declared = pathExt.split(path7.win32.delimiter).map((e) => e.trim().toLowerCase()).filter(Boolean);
|
|
9542
9730
|
const known = /* @__PURE__ */ new Set([...DIRECT_EXTENSIONS, ...BATCH_EXTENSIONS, ...POWERSHELL_EXTENSIONS, ...declared]);
|
|
9543
|
-
const ext =
|
|
9731
|
+
const ext = path7.win32.extname(command).toLowerCase();
|
|
9544
9732
|
if (ext && known.has(ext)) {
|
|
9545
9733
|
const route = BATCH_EXTENSIONS.includes(ext) ? "cmd" : POWERSHELL_EXTENSIONS.includes(ext) ? "powershell" : "direct";
|
|
9546
9734
|
return { direct: [], cmd: [], powershell: [], [route]: [""] };
|
|
@@ -9561,13 +9749,13 @@ async function findWindowsExecutables(command, deps) {
|
|
|
9561
9749
|
const exists = deps.exists ?? defaultExists2;
|
|
9562
9750
|
const pathExt = (deps.pathExt ?? (() => process.env.PATHEXT ?? ""))();
|
|
9563
9751
|
const byRoute = candidateExtensions(command, pathExt);
|
|
9564
|
-
const dirs =
|
|
9565
|
-
const base =
|
|
9752
|
+
const dirs = path7.win32.basename(command) !== command ? [path7.win32.dirname(path7.win32.resolve(command))] : (await (deps.resolvePath ?? augmentedPath)() || "").split(path7.win32.delimiter).map((d) => d.trim().replace(/^"|"$/g, "")).filter(Boolean);
|
|
9753
|
+
const base = path7.win32.basename(command);
|
|
9566
9754
|
const found = [];
|
|
9567
9755
|
for (const route of ROUTES) {
|
|
9568
9756
|
outer: for (const ext of byRoute[route]) {
|
|
9569
9757
|
for (const dir of dirs) {
|
|
9570
|
-
const candidate =
|
|
9758
|
+
const candidate = path7.win32.join(dir, `${base}${ext}`);
|
|
9571
9759
|
if (exists(candidate)) {
|
|
9572
9760
|
found.push({ file: candidate, route });
|
|
9573
9761
|
break outer;
|
|
@@ -9747,7 +9935,7 @@ function geminiDiscoveryCacheKey(apiKey) {
|
|
|
9747
9935
|
return {
|
|
9748
9936
|
key: `gemini-models:${hash}`,
|
|
9749
9937
|
dir,
|
|
9750
|
-
file:
|
|
9938
|
+
file: path8.join(dir, `gemini_models_${hash}.json`)
|
|
9751
9939
|
};
|
|
9752
9940
|
}
|
|
9753
9941
|
function readGeminiCache(apiKey) {
|
|
@@ -10271,7 +10459,7 @@ var ModelDiscovery = class {
|
|
|
10271
10459
|
|
|
10272
10460
|
// src/services/ModelCatalog.ts
|
|
10273
10461
|
var fs2 = __toESM(require("fs"));
|
|
10274
|
-
var
|
|
10462
|
+
var path9 = __toESM(require("path"));
|
|
10275
10463
|
var CACHE_KEY = "model-catalog";
|
|
10276
10464
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
10277
10465
|
function storageKey(baseUrl) {
|
|
@@ -10323,7 +10511,7 @@ var ModelCatalog = class {
|
|
|
10323
10511
|
const url = (baseUrl || "https://openrouter.ai/api/v1").replace(/\/+$/, "");
|
|
10324
10512
|
const key = storageKey(url);
|
|
10325
10513
|
const cacheDir = globalCacheDir();
|
|
10326
|
-
const cacheFile =
|
|
10514
|
+
const cacheFile = path9.join(cacheDir, `${key.replace(/[:/]/g, "_")}.json`);
|
|
10327
10515
|
if (fs2.existsSync(cacheFile)) fs2.rmSync(cacheFile);
|
|
10328
10516
|
} catch {
|
|
10329
10517
|
}
|
|
@@ -10331,7 +10519,7 @@ var ModelCatalog = class {
|
|
|
10331
10519
|
static readCache(key) {
|
|
10332
10520
|
try {
|
|
10333
10521
|
const cacheDir = globalCacheDir();
|
|
10334
|
-
const cacheFile =
|
|
10522
|
+
const cacheFile = path9.join(cacheDir, `${key.replace(/[:/]/g, "_")}.json`);
|
|
10335
10523
|
if (!fs2.existsSync(cacheFile)) return null;
|
|
10336
10524
|
const raw = fs2.readFileSync(cacheFile, "utf8");
|
|
10337
10525
|
const data = JSON.parse(raw);
|
|
@@ -10345,7 +10533,7 @@ var ModelCatalog = class {
|
|
|
10345
10533
|
try {
|
|
10346
10534
|
const cacheDir = globalCacheDir();
|
|
10347
10535
|
fs2.mkdirSync(cacheDir, { recursive: true });
|
|
10348
|
-
const cacheFile =
|
|
10536
|
+
const cacheFile = path9.join(cacheDir, `${key.replace(/[:/]/g, "_")}.json`);
|
|
10349
10537
|
fs2.writeFileSync(
|
|
10350
10538
|
cacheFile,
|
|
10351
10539
|
JSON.stringify({ models, cachedAt: Date.now() }, null, 2)
|
|
@@ -10786,7 +10974,7 @@ var import_child_process5 = require("child_process");
|
|
|
10786
10974
|
|
|
10787
10975
|
// src/utils/workspace.ts
|
|
10788
10976
|
var fs3 = __toESM(require("fs"));
|
|
10789
|
-
var
|
|
10977
|
+
var path10 = __toESM(require("path"));
|
|
10790
10978
|
var WorkspaceNotFoundError = class extends Error {
|
|
10791
10979
|
constructor(workspace) {
|
|
10792
10980
|
super(`Workspace "${workspace}" does not exist.`);
|
|
@@ -10842,7 +11030,7 @@ function assertWorkspaceIsProject(workspace, deps = {}) {
|
|
|
10842
11030
|
throw new WorkspaceNotAProjectError(workspace);
|
|
10843
11031
|
}
|
|
10844
11032
|
const hasMarker = [...PROJECT_MARKER_DIRS, ...PROJECT_MARKER_FILES].some(
|
|
10845
|
-
(marker2) => exists(
|
|
11033
|
+
(marker2) => exists(path10.join(resolved, marker2))
|
|
10846
11034
|
);
|
|
10847
11035
|
if (!hasMarker) throw new WorkspaceNotAProjectError(workspace);
|
|
10848
11036
|
}
|
|
@@ -11874,14 +12062,14 @@ ${part.text}` : part.text });
|
|
|
11874
12062
|
}
|
|
11875
12063
|
}
|
|
11876
12064
|
}
|
|
11877
|
-
async json(method,
|
|
11878
|
-
const response = await this.deps.fetch(`${this.baseUrl}${
|
|
12065
|
+
async json(method, path21, body, signal) {
|
|
12066
|
+
const response = await this.deps.fetch(`${this.baseUrl}${path21}`, {
|
|
11879
12067
|
method,
|
|
11880
12068
|
headers: { "content-type": "application/json" },
|
|
11881
12069
|
...body === void 0 ? {} : { body: JSON.stringify(body) },
|
|
11882
12070
|
...signal ? { signal } : {}
|
|
11883
12071
|
});
|
|
11884
|
-
if (!response.ok) throw new Error(`${method} ${
|
|
12072
|
+
if (!response.ok) throw new Error(`${method} ${path21} failed: ${response.status} ${response.statusText}`);
|
|
11885
12073
|
return await response.json().catch(() => null);
|
|
11886
12074
|
}
|
|
11887
12075
|
nativeSessionId() {
|
|
@@ -12649,7 +12837,7 @@ function runnerAssignment(catalog, current) {
|
|
|
12649
12837
|
changes.thinkingEffort = thinkingEffort;
|
|
12650
12838
|
}
|
|
12651
12839
|
if (catalog.modes.length > 0) {
|
|
12652
|
-
changes.taskMode = catalog.modes.some((m) => m.id === current?.taskMode) ? current.taskMode : catalog.modes[0].id;
|
|
12840
|
+
changes.taskMode = catalog.modes.some((m) => m.id === current?.taskMode) ? current.taskMode : catalog.defaultMode ?? catalog.modes[0].id;
|
|
12653
12841
|
}
|
|
12654
12842
|
return changes;
|
|
12655
12843
|
}
|
|
@@ -12661,18 +12849,18 @@ function retargetTaskRunner(task, runner, catalog) {
|
|
|
12661
12849
|
|
|
12662
12850
|
// src/services/SkillsService.ts
|
|
12663
12851
|
var fs4 = __toESM(require("fs"));
|
|
12664
|
-
var
|
|
12852
|
+
var path12 = __toESM(require("path"));
|
|
12665
12853
|
|
|
12666
12854
|
// src/services/builtinSkills.ts
|
|
12667
|
-
var
|
|
12855
|
+
var path11 = __toESM(require("path"));
|
|
12668
12856
|
var import_url = require("url");
|
|
12669
12857
|
var import_meta = {};
|
|
12670
12858
|
function builtinSkillsDir() {
|
|
12671
|
-
const dir = typeof __dirname !== "undefined" && __dirname ? __dirname :
|
|
12859
|
+
const dir = typeof __dirname !== "undefined" && __dirname ? __dirname : path11.dirname((0, import_url.fileURLToPath)(
|
|
12672
12860
|
// @ts-expect-error - import.meta is only valid under an ESM module setting
|
|
12673
12861
|
import_meta.url
|
|
12674
12862
|
));
|
|
12675
|
-
return
|
|
12863
|
+
return path11.join(dir, "..", "skills");
|
|
12676
12864
|
}
|
|
12677
12865
|
|
|
12678
12866
|
// src/services/SkillsService.ts
|
|
@@ -12711,8 +12899,8 @@ function copyDirSync2(src, dest) {
|
|
|
12711
12899
|
fs4.mkdirSync(dest, { recursive: true });
|
|
12712
12900
|
const entries = fs4.readdirSync(src, { withFileTypes: true });
|
|
12713
12901
|
for (const entry of entries) {
|
|
12714
|
-
const srcPath =
|
|
12715
|
-
const destPath =
|
|
12902
|
+
const srcPath = path12.join(src, entry.name);
|
|
12903
|
+
const destPath = path12.join(dest, entry.name);
|
|
12716
12904
|
if (entry.isDirectory()) copyDirSync2(srcPath, destPath);
|
|
12717
12905
|
else fs4.copyFileSync(srcPath, destPath);
|
|
12718
12906
|
}
|
|
@@ -12723,7 +12911,7 @@ function readDir(dir, source) {
|
|
|
12723
12911
|
const skills = [];
|
|
12724
12912
|
for (const entry of entries) {
|
|
12725
12913
|
if (!entry.isDirectory()) continue;
|
|
12726
|
-
const skillFile =
|
|
12914
|
+
const skillFile = path12.join(dir, entry.name, "SKILL.md");
|
|
12727
12915
|
if (!fs4.existsSync(skillFile)) continue;
|
|
12728
12916
|
const parsed = parseSkillFile(skillFile, entry.name, source);
|
|
12729
12917
|
if (parsed) skills.push(parsed);
|
|
@@ -12736,17 +12924,17 @@ var SkillsService = class {
|
|
|
12736
12924
|
}
|
|
12737
12925
|
workspaceRoot;
|
|
12738
12926
|
localDir() {
|
|
12739
|
-
return this.workspaceRoot ?
|
|
12927
|
+
return this.workspaceRoot ? path12.join(this.workspaceRoot, ".ordewell", "skills") : void 0;
|
|
12740
12928
|
}
|
|
12741
12929
|
globalDir() {
|
|
12742
|
-
return
|
|
12930
|
+
return path12.join(globalDataDir(), "skills");
|
|
12743
12931
|
}
|
|
12744
12932
|
seed(name) {
|
|
12745
|
-
const dest =
|
|
12933
|
+
const dest = path12.join(this.globalDir(), name);
|
|
12746
12934
|
if (fs4.existsSync(dest)) return false;
|
|
12747
12935
|
let srcDir;
|
|
12748
12936
|
try {
|
|
12749
|
-
srcDir =
|
|
12937
|
+
srcDir = path12.join(builtinSkillsDir(), name);
|
|
12750
12938
|
} catch (err) {
|
|
12751
12939
|
console.warn(`Could not locate built-in skills dir: ${String(err)}`);
|
|
12752
12940
|
return false;
|
|
@@ -12772,7 +12960,7 @@ var SkillsService = class {
|
|
|
12772
12960
|
if (entries.length !== 1 || entries[0].name !== "SKILL.md" || !entries[0].isFile()) return false;
|
|
12773
12961
|
let raw;
|
|
12774
12962
|
try {
|
|
12775
|
-
raw = fs4.readFileSync(
|
|
12963
|
+
raw = fs4.readFileSync(path12.join(dir, "SKILL.md"), "utf8");
|
|
12776
12964
|
} catch {
|
|
12777
12965
|
return false;
|
|
12778
12966
|
}
|
|
@@ -12789,7 +12977,7 @@ var SkillsService = class {
|
|
|
12789
12977
|
}
|
|
12790
12978
|
pruneRetired() {
|
|
12791
12979
|
for (const name of RETIRED_BUILTIN_SKILL_NAMES) {
|
|
12792
|
-
const dest =
|
|
12980
|
+
const dest = path12.join(this.globalDir(), name);
|
|
12793
12981
|
if (!fs4.existsSync(dest)) continue;
|
|
12794
12982
|
if (!this.isUnmodifiedRetiredSeed(dest, name)) continue;
|
|
12795
12983
|
try {
|
|
@@ -12804,10 +12992,10 @@ var SkillsService = class {
|
|
|
12804
12992
|
if (BUILTIN_SKILL_NAMES.includes(name)) this.seed(name);
|
|
12805
12993
|
const localDir = this.localDir();
|
|
12806
12994
|
if (localDir) {
|
|
12807
|
-
const localFile =
|
|
12995
|
+
const localFile = path12.join(localDir, name, "SKILL.md");
|
|
12808
12996
|
if (fs4.existsSync(localFile)) return parseSkillFile(localFile, name, "local");
|
|
12809
12997
|
}
|
|
12810
|
-
const globalFile =
|
|
12998
|
+
const globalFile = path12.join(this.globalDir(), name, "SKILL.md");
|
|
12811
12999
|
if (fs4.existsSync(globalFile)) return parseSkillFile(globalFile, name, "global");
|
|
12812
13000
|
return void 0;
|
|
12813
13001
|
}
|
|
@@ -12889,11 +13077,11 @@ function truncateCheckpointSummary(summary) {
|
|
|
12889
13077
|
|
|
12890
13078
|
// src/utils/sessionStore.ts
|
|
12891
13079
|
var fs6 = __toESM(require("fs"));
|
|
12892
|
-
var
|
|
13080
|
+
var path14 = __toESM(require("path"));
|
|
12893
13081
|
|
|
12894
13082
|
// src/utils/fsHelpers.ts
|
|
12895
13083
|
var fs5 = __toESM(require("fs"));
|
|
12896
|
-
var
|
|
13084
|
+
var path13 = __toESM(require("path"));
|
|
12897
13085
|
var STATE_DIR = ".ordewell";
|
|
12898
13086
|
function ensureDir(dir) {
|
|
12899
13087
|
if (!fs5.existsSync(dir)) {
|
|
@@ -12901,14 +13089,14 @@ function ensureDir(dir) {
|
|
|
12901
13089
|
}
|
|
12902
13090
|
}
|
|
12903
13091
|
function getStateDir(baseDir) {
|
|
12904
|
-
return
|
|
13092
|
+
return path13.join(baseDir ?? process.cwd(), STATE_DIR);
|
|
12905
13093
|
}
|
|
12906
13094
|
var IGNORE_FILE = ".gitignore";
|
|
12907
13095
|
function ensureStateDirIgnored(baseDir) {
|
|
12908
13096
|
const dir = getStateDir(baseDir);
|
|
12909
13097
|
ensureDir(dir);
|
|
12910
13098
|
try {
|
|
12911
|
-
fs5.writeFileSync(
|
|
13099
|
+
fs5.writeFileSync(path13.join(dir, IGNORE_FILE), "*\n", { flag: "wx" });
|
|
12912
13100
|
} catch (err) {
|
|
12913
13101
|
if (err.code !== "EEXIST") throw err;
|
|
12914
13102
|
}
|
|
@@ -12923,7 +13111,7 @@ function mintSessionId() {
|
|
|
12923
13111
|
// src/utils/sessionStore.ts
|
|
12924
13112
|
var SESSIONS_SUBDIR = "sessions";
|
|
12925
13113
|
function getSessionsDir(baseDir) {
|
|
12926
|
-
return
|
|
13114
|
+
return path14.join(getStateDir(baseDir), SESSIONS_SUBDIR);
|
|
12927
13115
|
}
|
|
12928
13116
|
var REJECTION_MESSAGE = "This session was created with an older version of Ordewell. Please re-plan.";
|
|
12929
13117
|
function hasScalarRunner(parsed) {
|
|
@@ -12958,7 +13146,7 @@ function saveSession(plan, goal, baseDir, id) {
|
|
|
12958
13146
|
plan: JSON.parse(JSON.stringify(plan))
|
|
12959
13147
|
};
|
|
12960
13148
|
const filename = sessionFilename(meta);
|
|
12961
|
-
const filePath =
|
|
13149
|
+
const filePath = path14.join(sessionsDir, filename);
|
|
12962
13150
|
fs6.writeFileSync(filePath, JSON.stringify(session, null, 2));
|
|
12963
13151
|
return meta;
|
|
12964
13152
|
}
|
|
@@ -12968,7 +13156,7 @@ function listSessions(baseDir, logger = defaultLogger) {
|
|
|
12968
13156
|
const files = fs6.readdirSync(sessionsDir).filter((f) => f.endsWith(".json"));
|
|
12969
13157
|
return files.map((f) => {
|
|
12970
13158
|
try {
|
|
12971
|
-
const raw = fs6.readFileSync(
|
|
13159
|
+
const raw = fs6.readFileSync(path14.join(sessionsDir, f), "utf-8");
|
|
12972
13160
|
const parsed = JSON.parse(raw);
|
|
12973
13161
|
if (hasScalarRunner(parsed)) {
|
|
12974
13162
|
logger.warn("sessionStore", `session file ${f}: ${REJECTION_MESSAGE}`);
|
|
@@ -12986,7 +13174,7 @@ function findSessionFile(sessionsDir, sessionId, logger) {
|
|
|
12986
13174
|
const files = fs6.readdirSync(sessionsDir).filter((f) => f.endsWith(".json"));
|
|
12987
13175
|
for (const f of files) {
|
|
12988
13176
|
try {
|
|
12989
|
-
const raw = fs6.readFileSync(
|
|
13177
|
+
const raw = fs6.readFileSync(path14.join(sessionsDir, f), "utf-8");
|
|
12990
13178
|
const session = JSON.parse(raw);
|
|
12991
13179
|
if (session.meta.id === sessionId) return f;
|
|
12992
13180
|
} catch (err) {
|
|
@@ -13001,7 +13189,7 @@ function loadSession(sessionId, baseDir, logger = defaultLogger) {
|
|
|
13001
13189
|
try {
|
|
13002
13190
|
const file = findSessionFile(sessionsDir, sessionId, logger);
|
|
13003
13191
|
if (file) {
|
|
13004
|
-
const raw = fs6.readFileSync(
|
|
13192
|
+
const raw = fs6.readFileSync(path14.join(sessionsDir, file), "utf-8");
|
|
13005
13193
|
const parsed = JSON.parse(raw);
|
|
13006
13194
|
if (hasScalarRunner(parsed)) {
|
|
13007
13195
|
logger.warn("sessionStore", `session file ${file}: ${REJECTION_MESSAGE}`);
|
|
@@ -13035,7 +13223,7 @@ function deleteSession(sessionId, baseDir, logger = defaultLogger) {
|
|
|
13035
13223
|
try {
|
|
13036
13224
|
const file = findSessionFile(sessionsDir, sessionId, logger);
|
|
13037
13225
|
if (file) {
|
|
13038
|
-
fs6.unlinkSync(
|
|
13226
|
+
fs6.unlinkSync(path14.join(sessionsDir, file));
|
|
13039
13227
|
return true;
|
|
13040
13228
|
}
|
|
13041
13229
|
} catch (err) {
|
|
@@ -13046,7 +13234,7 @@ function deleteSession(sessionId, baseDir, logger = defaultLogger) {
|
|
|
13046
13234
|
|
|
13047
13235
|
// src/utils/prdStore.ts
|
|
13048
13236
|
var fs7 = __toESM(require("fs"));
|
|
13049
|
-
var
|
|
13237
|
+
var path15 = __toESM(require("path"));
|
|
13050
13238
|
var PRD_BLOCK_RE = /<!--\s*ORDEWELL_PRD_START\s+slug="([^"]+)"\s*-->\s*([\s\S]*?)\s*<!--\s*ORDEWELL_PRD_END\s*-->/;
|
|
13051
13239
|
function extractPrdBlock(text) {
|
|
13052
13240
|
const match = PRD_BLOCK_RE.exec(text);
|
|
@@ -13060,9 +13248,9 @@ function sanitizeSlug(raw) {
|
|
|
13060
13248
|
return raw.toLowerCase().replace(/[^a-z0-9-_]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 80);
|
|
13061
13249
|
}
|
|
13062
13250
|
function savePrdMarkdown(workspace, slug2, markdown) {
|
|
13063
|
-
const dir =
|
|
13251
|
+
const dir = path15.join(workspace, ".scratch", sanitizeSlug(slug2));
|
|
13064
13252
|
fs7.mkdirSync(dir, { recursive: true });
|
|
13065
|
-
const file =
|
|
13253
|
+
const file = path15.join(dir, "PRD.md");
|
|
13066
13254
|
fs7.writeFileSync(file, markdown.endsWith("\n") ? markdown : markdown + "\n", "utf8");
|
|
13067
13255
|
return file;
|
|
13068
13256
|
}
|
|
@@ -14089,9 +14277,11 @@ Execution is RUNNING${locked.length ? ` \u2014 these tasks are locked: ${locked.
|
|
|
14089
14277
|
}
|
|
14090
14278
|
/** What a runner offers, as {@link runnerAssignment} needs it. Spawns the runner's CLI to list models. */
|
|
14091
14279
|
async catalogFor(runner) {
|
|
14280
|
+
const modes = this.runnerModesFor([runner])[runner];
|
|
14092
14281
|
return {
|
|
14093
14282
|
models: (await this.modelResolver.modelsForRunners([runner]))[runner] ?? [],
|
|
14094
|
-
modes
|
|
14283
|
+
modes,
|
|
14284
|
+
defaultMode: resolveDefaultMode(modes, this.config.autonomousMode)
|
|
14095
14285
|
};
|
|
14096
14286
|
}
|
|
14097
14287
|
/**
|
|
@@ -14779,7 +14969,7 @@ var import_child_process8 = require("child_process");
|
|
|
14779
14969
|
var import_util4 = require("util");
|
|
14780
14970
|
var import_os = require("os");
|
|
14781
14971
|
var import_path = require("path");
|
|
14782
|
-
var
|
|
14972
|
+
var import_fs2 = require("fs");
|
|
14783
14973
|
|
|
14784
14974
|
// src/utils/tmux.ts
|
|
14785
14975
|
var import_child_process7 = require("child_process");
|
|
@@ -14872,7 +15062,7 @@ var TmuxSession = class extends AbstractTerminalSession {
|
|
|
14872
15062
|
* lets the user keep poking at a finished task's terminal.
|
|
14873
15063
|
*/
|
|
14874
15064
|
async start(command, args, cwd, env) {
|
|
14875
|
-
(0,
|
|
15065
|
+
(0, import_fs2.writeFileSync)(this.logPath, "");
|
|
14876
15066
|
const envAssignments = Object.entries(env ?? {}).map(([k, v]) => `${k}=${posixShellQuote(v)}`).join(" ");
|
|
14877
15067
|
const inner = [command, ...args].map(posixShellQuote).join(" ");
|
|
14878
15068
|
const prefix = envAssignments ? `env ${envAssignments} ` : "";
|
|
@@ -14886,7 +15076,7 @@ var TmuxSession = class extends AbstractTerminalSession {
|
|
|
14886
15076
|
if (this.exited) return;
|
|
14887
15077
|
let content;
|
|
14888
15078
|
try {
|
|
14889
|
-
content = (0,
|
|
15079
|
+
content = (0, import_fs2.existsSync)(this.logPath) ? (0, import_fs2.readFileSync)(this.logPath, "utf8") : "";
|
|
14890
15080
|
} catch {
|
|
14891
15081
|
return;
|
|
14892
15082
|
}
|
|
@@ -14913,7 +15103,7 @@ var TmuxSession = class extends AbstractTerminalSession {
|
|
|
14913
15103
|
this.tmux(["pipe-pane", "-t", this.target]).catch(() => {
|
|
14914
15104
|
});
|
|
14915
15105
|
try {
|
|
14916
|
-
(0,
|
|
15106
|
+
(0, import_fs2.unlinkSync)(this.logPath);
|
|
14917
15107
|
} catch {
|
|
14918
15108
|
}
|
|
14919
15109
|
this.baseHandleExit(code);
|
|
@@ -15078,7 +15268,7 @@ var TmuxRunner = class extends AbstractRunner {
|
|
|
15078
15268
|
|
|
15079
15269
|
// src/utils/daemonToken.ts
|
|
15080
15270
|
var import_crypto2 = require("crypto");
|
|
15081
|
-
var
|
|
15271
|
+
var import_fs3 = require("fs");
|
|
15082
15272
|
var import_path2 = require("path");
|
|
15083
15273
|
var BEARER_PREFIX = "bearer ";
|
|
15084
15274
|
var DAEMON_TOKEN_SUBPROTOCOL_PREFIX = "ordewell.token.";
|
|
@@ -15092,22 +15282,22 @@ function daemonTokenPath(port) {
|
|
|
15092
15282
|
function mintDaemonToken(port) {
|
|
15093
15283
|
const token = (0, import_crypto2.randomBytes)(32).toString("base64url");
|
|
15094
15284
|
const file = daemonTokenPath(port);
|
|
15095
|
-
(0,
|
|
15285
|
+
(0, import_fs3.mkdirSync)(configDir(), { recursive: true });
|
|
15096
15286
|
try {
|
|
15097
|
-
(0,
|
|
15287
|
+
(0, import_fs3.unlinkSync)(file);
|
|
15098
15288
|
} catch {
|
|
15099
15289
|
}
|
|
15100
|
-
const fd = (0,
|
|
15290
|
+
const fd = (0, import_fs3.openSync)(file, "wx", 384);
|
|
15101
15291
|
try {
|
|
15102
|
-
(0,
|
|
15292
|
+
(0, import_fs3.writeSync)(fd, token);
|
|
15103
15293
|
} finally {
|
|
15104
|
-
(0,
|
|
15294
|
+
(0, import_fs3.closeSync)(fd);
|
|
15105
15295
|
}
|
|
15106
15296
|
return { token, file };
|
|
15107
15297
|
}
|
|
15108
15298
|
function readDaemonToken(port) {
|
|
15109
15299
|
try {
|
|
15110
|
-
const token = (0,
|
|
15300
|
+
const token = (0, import_fs3.readFileSync)(daemonTokenPath(port), "utf8").trim();
|
|
15111
15301
|
return token === "" ? void 0 : token;
|
|
15112
15302
|
} catch {
|
|
15113
15303
|
return void 0;
|
|
@@ -15115,7 +15305,7 @@ function readDaemonToken(port) {
|
|
|
15115
15305
|
}
|
|
15116
15306
|
function clearDaemonToken(port) {
|
|
15117
15307
|
try {
|
|
15118
|
-
(0,
|
|
15308
|
+
(0, import_fs3.unlinkSync)(daemonTokenPath(port));
|
|
15119
15309
|
} catch {
|
|
15120
15310
|
}
|
|
15121
15311
|
}
|
|
@@ -15149,17 +15339,17 @@ function tokensMatch(presented, expected) {
|
|
|
15149
15339
|
|
|
15150
15340
|
// src/plugins/RunnerRegistry.ts
|
|
15151
15341
|
var fs9 = __toESM(require("fs"));
|
|
15152
|
-
var
|
|
15153
|
-
var
|
|
15342
|
+
var path18 = __toESM(require("path"));
|
|
15343
|
+
var os5 = __toESM(require("os"));
|
|
15154
15344
|
var import_child_process9 = require("child_process");
|
|
15155
15345
|
var import_crypto3 = require("crypto");
|
|
15156
15346
|
|
|
15157
15347
|
// src/plugins/FsPluginStore.ts
|
|
15158
15348
|
var fs8 = __toESM(require("fs"));
|
|
15159
|
-
var
|
|
15349
|
+
var path17 = __toESM(require("path"));
|
|
15160
15350
|
|
|
15161
15351
|
// src/plugins/pluginNames.ts
|
|
15162
|
-
var
|
|
15352
|
+
var path16 = __toESM(require("path"));
|
|
15163
15353
|
var PLUGIN_NAME_PATTERN = /^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/;
|
|
15164
15354
|
var MAX_PLUGIN_NAME_LENGTH = 64;
|
|
15165
15355
|
function isPlainPluginName(name) {
|
|
@@ -15174,10 +15364,10 @@ function assertPlainPluginName(name) {
|
|
|
15174
15364
|
}
|
|
15175
15365
|
function resolvePluginInstallDir(pluginsDir, name) {
|
|
15176
15366
|
assertPlainPluginName(name);
|
|
15177
|
-
const root =
|
|
15178
|
-
const dest =
|
|
15179
|
-
const relative3 =
|
|
15180
|
-
if (relative3 !== name || relative3 === "" ||
|
|
15367
|
+
const root = path16.resolve(pluginsDir);
|
|
15368
|
+
const dest = path16.resolve(root, name);
|
|
15369
|
+
const relative3 = path16.relative(root, dest);
|
|
15370
|
+
if (relative3 !== name || relative3 === "" || path16.isAbsolute(relative3)) {
|
|
15181
15371
|
throw new Error(`Plugin install path escapes the plugins directory: ${JSON.stringify(name)}`);
|
|
15182
15372
|
}
|
|
15183
15373
|
return dest;
|
|
@@ -15192,10 +15382,10 @@ function isValidManifest(obj) {
|
|
|
15192
15382
|
|
|
15193
15383
|
// src/plugins/FsPluginStore.ts
|
|
15194
15384
|
function userPluginsDir() {
|
|
15195
|
-
return
|
|
15385
|
+
return path17.join(globalDataDir(), "plugins");
|
|
15196
15386
|
}
|
|
15197
15387
|
function loadManifestFromDir(dir) {
|
|
15198
|
-
const manifestPath =
|
|
15388
|
+
const manifestPath = path17.join(dir, "manifest.json");
|
|
15199
15389
|
if (!fs8.existsSync(manifestPath)) return null;
|
|
15200
15390
|
try {
|
|
15201
15391
|
const raw = fs8.readFileSync(manifestPath, "utf8");
|
|
@@ -15210,8 +15400,8 @@ function copyDirSync3(src, dest) {
|
|
|
15210
15400
|
ensureDir(dest);
|
|
15211
15401
|
const entries = fs8.readdirSync(src, { withFileTypes: true });
|
|
15212
15402
|
for (const entry of entries) {
|
|
15213
|
-
const srcPath =
|
|
15214
|
-
const destPath =
|
|
15403
|
+
const srcPath = path17.join(src, entry.name);
|
|
15404
|
+
const destPath = path17.join(dest, entry.name);
|
|
15215
15405
|
if (entry.isDirectory()) {
|
|
15216
15406
|
copyDirSync3(srcPath, destPath);
|
|
15217
15407
|
} else {
|
|
@@ -15223,7 +15413,7 @@ function rmDirSync(dir) {
|
|
|
15223
15413
|
if (!fs8.existsSync(dir)) return;
|
|
15224
15414
|
const entries = fs8.readdirSync(dir, { withFileTypes: true });
|
|
15225
15415
|
for (const entry of entries) {
|
|
15226
|
-
const p =
|
|
15416
|
+
const p = path17.join(dir, entry.name);
|
|
15227
15417
|
if (entry.isDirectory()) {
|
|
15228
15418
|
rmDirSync(p);
|
|
15229
15419
|
} else {
|
|
@@ -15276,11 +15466,11 @@ var FsPluginStore = class {
|
|
|
15276
15466
|
return null;
|
|
15277
15467
|
}
|
|
15278
15468
|
}
|
|
15279
|
-
dirExists(
|
|
15280
|
-
return fs8.existsSync(
|
|
15469
|
+
dirExists(path21) {
|
|
15470
|
+
return fs8.existsSync(path21) && fs8.statSync(path21).isDirectory();
|
|
15281
15471
|
}
|
|
15282
|
-
exists(
|
|
15283
|
-
return fs8.existsSync(
|
|
15472
|
+
exists(path21) {
|
|
15473
|
+
return fs8.existsSync(path21);
|
|
15284
15474
|
}
|
|
15285
15475
|
};
|
|
15286
15476
|
|
|
@@ -15712,7 +15902,7 @@ var RunnerRegistry = class {
|
|
|
15712
15902
|
return entry?.source === "builtin";
|
|
15713
15903
|
}
|
|
15714
15904
|
installFromPath(sourcePath) {
|
|
15715
|
-
const absPath =
|
|
15905
|
+
const absPath = path18.resolve(sourcePath);
|
|
15716
15906
|
if (!this.store.dirExists(absPath)) {
|
|
15717
15907
|
throw new Error(`Plugin source must be a directory: ${absPath}`);
|
|
15718
15908
|
}
|
|
@@ -15724,7 +15914,7 @@ var RunnerRegistry = class {
|
|
|
15724
15914
|
}
|
|
15725
15915
|
installFromGit(url) {
|
|
15726
15916
|
const validated = assertInstallablePluginUrl(url);
|
|
15727
|
-
const tmpDir =
|
|
15917
|
+
const tmpDir = path18.join(os5.tmpdir(), `ordewell-plugin-${(0, import_crypto3.randomBytes)(12).toString("hex")}`);
|
|
15728
15918
|
this.store.ensureDir(tmpDir);
|
|
15729
15919
|
try {
|
|
15730
15920
|
try {
|
|
@@ -15737,7 +15927,7 @@ var RunnerRegistry = class {
|
|
|
15737
15927
|
const hasManifest = contents.some((f) => f === "manifest.json");
|
|
15738
15928
|
let sourceDir = tmpDir;
|
|
15739
15929
|
if (!hasManifest) {
|
|
15740
|
-
const onlyEntry = contents.length === 1 ?
|
|
15930
|
+
const onlyEntry = contents.length === 1 ? path18.join(tmpDir, contents[0]) : void 0;
|
|
15741
15931
|
if (!onlyEntry || !this.store.dirExists(onlyEntry)) {
|
|
15742
15932
|
throw new Error(`No manifest.json found in repository: ${validated.toString()}`);
|
|
15743
15933
|
}
|
|
@@ -15785,7 +15975,7 @@ var RunnerRegistry = class {
|
|
|
15785
15975
|
}
|
|
15786
15976
|
createSkeleton(name, outputDir) {
|
|
15787
15977
|
assertPlainPluginName(name);
|
|
15788
|
-
const dir =
|
|
15978
|
+
const dir = path18.resolve(outputDir, name);
|
|
15789
15979
|
this.store.ensureDir(dir);
|
|
15790
15980
|
const manifest = {
|
|
15791
15981
|
name,
|
|
@@ -15817,8 +16007,8 @@ var RunnerRegistry = class {
|
|
|
15817
16007
|
]
|
|
15818
16008
|
}
|
|
15819
16009
|
};
|
|
15820
|
-
this.store.writeFile(
|
|
15821
|
-
const runSh =
|
|
16010
|
+
this.store.writeFile(path18.join(dir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n");
|
|
16011
|
+
const runSh = path18.join(dir, "run.sh");
|
|
15822
16012
|
const scriptContent = `#!/usr/bin/env bash
|
|
15823
16013
|
# Custom runner script for ${name}
|
|
15824
16014
|
# Receives:
|
|
@@ -15851,14 +16041,14 @@ function fsChmodSync(fpath, mode) {
|
|
|
15851
16041
|
|
|
15852
16042
|
// src/utils/stateStore.ts
|
|
15853
16043
|
var fs10 = __toESM(require("fs"));
|
|
15854
|
-
var
|
|
16044
|
+
var path19 = __toESM(require("path"));
|
|
15855
16045
|
var STATE_FILE = "state.json";
|
|
15856
16046
|
function getStatePath(baseDir) {
|
|
15857
|
-
return
|
|
16047
|
+
return path19.join(getStateDir(baseDir), STATE_FILE);
|
|
15858
16048
|
}
|
|
15859
16049
|
function saveState(plan, baseDir) {
|
|
15860
16050
|
const statePath = getStatePath(baseDir ?? process.cwd());
|
|
15861
|
-
ensureDir(
|
|
16051
|
+
ensureDir(path19.dirname(statePath));
|
|
15862
16052
|
plan.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
15863
16053
|
fs10.writeFileSync(statePath, JSON.stringify(plan, null, 2));
|
|
15864
16054
|
}
|
|
@@ -15891,7 +16081,7 @@ function stateExists(baseDir) {
|
|
|
15891
16081
|
|
|
15892
16082
|
// src/services/SettingsService.ts
|
|
15893
16083
|
var fs11 = __toESM(require("fs"));
|
|
15894
|
-
var
|
|
16084
|
+
var path20 = __toESM(require("path"));
|
|
15895
16085
|
var DEFAULTS = {
|
|
15896
16086
|
tdd: { enabled: true },
|
|
15897
16087
|
verification: { enabled: false }
|
|
@@ -15899,7 +16089,7 @@ var DEFAULTS = {
|
|
|
15899
16089
|
function getSettingsPath() {
|
|
15900
16090
|
const override = process.env.ORDEWELL_SETTINGS_PATH;
|
|
15901
16091
|
if (override && override.trim()) return override.trim();
|
|
15902
|
-
return
|
|
16092
|
+
return path20.join(globalDataDir(), "settings.json");
|
|
15903
16093
|
}
|
|
15904
16094
|
function readPlannerModels(raw) {
|
|
15905
16095
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
@@ -16027,7 +16217,7 @@ var SettingsService = class {
|
|
|
16027
16217
|
return { ...DEFAULTS, tdd: { ...DEFAULTS.tdd }, verification: { ...DEFAULTS.verification } };
|
|
16028
16218
|
}
|
|
16029
16219
|
persist() {
|
|
16030
|
-
const dir =
|
|
16220
|
+
const dir = path20.dirname(this.filePath);
|
|
16031
16221
|
if (!fs11.existsSync(dir)) {
|
|
16032
16222
|
fs11.mkdirSync(dir, { recursive: true });
|
|
16033
16223
|
}
|