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