@hacksmith/doraval 0.2.44 → 0.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/bin/doraval.js +195 -100
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
# doraval
|
|
2
2
|
|
|
3
|
-
The context engineering toolkit for coding
|
|
3
|
+
The context engineering toolkit for coding agent orchestrators.
|
|
4
4
|
|
|
5
|
-
If you'
|
|
5
|
+
If you're a senior engineer handing skills to new team members, a company publishing AI resources, or anyone who wants agents (and humans) to succeed on the first attempt instead of after days of debugging — this is for you.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
**The orchestrator problem:** Give 10 new engineers (or agents) a skill and only 3/10 succeed on the first try. 4/10 take hours. 7/10 take a day. 10/10 take days.
|
|
8
|
+
|
|
9
|
+
doraval helps you **left-shift success** — validate, scaffold, and manage context so the first attempt works across Claude, Cursor, Codex, Copilot, and whatever comes next.
|
|
10
|
+
|
|
11
|
+
> **Quick start (left-shift success in < 2 minutes):**
|
|
8
12
|
> ```bash
|
|
9
13
|
> # macOS
|
|
10
14
|
> brew install saif-shines/tap/doraval
|
|
@@ -14,7 +18,7 @@ If you've ever shipped a Claude Code skill that stopped firing after a refactor,
|
|
|
14
18
|
> npx @hacksmith/doraval validate .
|
|
15
19
|
> ```
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
Validate before you hand a skill to a new engineer or publish it. It auto-detects issues across agents and tells you what's broken.
|
|
18
22
|
|
|
19
23
|
## Install
|
|
20
24
|
|
|
@@ -144,6 +148,17 @@ doraval journal update # pull latest from remote
|
|
|
144
148
|
|
|
145
149
|
Requires the GitHub CLI (`gh`). Journal lives in a private GitHub repo you control.
|
|
146
150
|
|
|
151
|
+
### `ui` — Local dashboard (avoid typing repetitive commands)
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
doraval ui # start the web dashboard (opens browser)
|
|
155
|
+
doraval ui --port 4921 # different port
|
|
156
|
+
doraval ui --status # check if running + show URL
|
|
157
|
+
doraval ui --force # force restart
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Re-running `doraval ui` is now idempotent (uses PID tracking). Use `--force` to restart.
|
|
161
|
+
|
|
147
162
|
doraval update # self-update doraval to the latest version
|
|
148
163
|
doraval claude new # interactive wizard for skills/plugins (follows official table)
|
|
149
164
|
|
package/bin/doraval.js
CHANGED
|
@@ -599,7 +599,7 @@ var init_dist = __esm(() => {
|
|
|
599
599
|
var require_package = __commonJS((exports, module) => {
|
|
600
600
|
module.exports = {
|
|
601
601
|
name: "@hacksmith/doraval",
|
|
602
|
-
version: "0.2.
|
|
602
|
+
version: "0.2.46",
|
|
603
603
|
author: "Saif",
|
|
604
604
|
repository: {
|
|
605
605
|
type: "git",
|
|
@@ -612,7 +612,7 @@ var require_package = __commonJS((exports, module) => {
|
|
|
612
612
|
doraval: "bin/doraval-wrapper.js",
|
|
613
613
|
dora: "bin/doraval-wrapper.js"
|
|
614
614
|
},
|
|
615
|
-
description: "The context engineering toolkit for coding
|
|
615
|
+
description: "The context engineering toolkit for coding agent orchestrators",
|
|
616
616
|
engines: {
|
|
617
617
|
bun: ">=1.2.0",
|
|
618
618
|
node: ">=14.18.0"
|
|
@@ -4367,7 +4367,7 @@ var exports_ui = {};
|
|
|
4367
4367
|
__export(exports_ui, {
|
|
4368
4368
|
default: () => ui_default
|
|
4369
4369
|
});
|
|
4370
|
-
import { existsSync as existsSync19, readdirSync as readdirSync9 } from "fs";
|
|
4370
|
+
import { existsSync as existsSync19, readdirSync as readdirSync9, writeFileSync as writeFileSync6, unlinkSync as unlinkSync2, readFileSync as readFileSync2 } from "fs";
|
|
4371
4371
|
import { join as join18 } from "path";
|
|
4372
4372
|
import { spawn } from "child_process";
|
|
4373
4373
|
function slugify2(title) {
|
|
@@ -4457,6 +4457,34 @@ async function killPort(port) {
|
|
|
4457
4457
|
await new Promise((r) => setTimeout(r, 400));
|
|
4458
4458
|
} catch {}
|
|
4459
4459
|
}
|
|
4460
|
+
function readPid(p) {
|
|
4461
|
+
const file = getPidFile(p);
|
|
4462
|
+
if (!existsSync19(file))
|
|
4463
|
+
return null;
|
|
4464
|
+
try {
|
|
4465
|
+
const raw = readFileSync2(file, "utf8").trim();
|
|
4466
|
+
const pid = parseInt(raw, 10);
|
|
4467
|
+
if (isNaN(pid))
|
|
4468
|
+
return null;
|
|
4469
|
+
process.kill(pid, 0);
|
|
4470
|
+
return pid;
|
|
4471
|
+
} catch {
|
|
4472
|
+
try {
|
|
4473
|
+
unlinkSync2(file);
|
|
4474
|
+
} catch {}
|
|
4475
|
+
return null;
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
function writePid(pid, p) {
|
|
4479
|
+
ensureDoravalDirs();
|
|
4480
|
+
writeFileSync6(getPidFile(p), String(pid) + `
|
|
4481
|
+
`);
|
|
4482
|
+
}
|
|
4483
|
+
function removePid(p) {
|
|
4484
|
+
try {
|
|
4485
|
+
unlinkSync2(getPidFile(p));
|
|
4486
|
+
} catch {}
|
|
4487
|
+
}
|
|
4460
4488
|
async function getDashboardHtml() {
|
|
4461
4489
|
const isSource = import.meta.url.includes("/src/");
|
|
4462
4490
|
const htmlPath = isSource ? new URL("../../ui/index.html", import.meta.url) : new URL("./ui/index.html", import.meta.url);
|
|
@@ -4467,7 +4495,7 @@ async function getDashboardHtml() {
|
|
|
4467
4495
|
return `<!doctype html><meta charset="utf-8"><body style="font-family:monospace;background:#111;color:#ddd;padding:2rem"><h1>doraval ui</h1><p>Dashboard HTML missing.</p><pre>${String(err)}</pre></body>`;
|
|
4468
4496
|
}
|
|
4469
4497
|
}
|
|
4470
|
-
var import_picocolors16, DEFAULT_PORT = 3737, ui_default;
|
|
4498
|
+
var import_picocolors16, DEFAULT_PORT = 3737, getPidFile = (p) => join18(getDoravalDir(), `ui.${p}.pid`), ui_default;
|
|
4471
4499
|
var init_ui = __esm(() => {
|
|
4472
4500
|
init_journal_config();
|
|
4473
4501
|
init_journal_parse();
|
|
@@ -4479,7 +4507,42 @@ var init_ui = __esm(() => {
|
|
|
4479
4507
|
const port = Number(args.port) || DEFAULT_PORT;
|
|
4480
4508
|
const host = args.host || "127.0.0.1";
|
|
4481
4509
|
const shouldOpen = args.open !== false;
|
|
4482
|
-
|
|
4510
|
+
const showStatusOnly = !!args.status;
|
|
4511
|
+
const force = !!args.force;
|
|
4512
|
+
ensureDoravalDirs();
|
|
4513
|
+
const existingPid = readPid(port);
|
|
4514
|
+
if (showStatusOnly) {
|
|
4515
|
+
if (existingPid) {
|
|
4516
|
+
const url2 = `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`;
|
|
4517
|
+
console.error(` Dashboard running (pid ${existingPid})`);
|
|
4518
|
+
console.error(` URL: ${import_picocolors16.default.underline(import_picocolors16.default.cyan(url2))}`);
|
|
4519
|
+
} else {
|
|
4520
|
+
console.error(` No dashboard running.`);
|
|
4521
|
+
}
|
|
4522
|
+
return;
|
|
4523
|
+
}
|
|
4524
|
+
if (existingPid && !force) {
|
|
4525
|
+
const url2 = `http://${host === "0.0.0.0" ? "localhost" : host}:${port}`;
|
|
4526
|
+
console.error(` Dashboard already running (pid ${existingPid}).`);
|
|
4527
|
+
console.error(` URL: ${import_picocolors16.default.underline(import_picocolors16.default.cyan(url2))}`);
|
|
4528
|
+
if (shouldOpen && process.stdout.isTTY) {
|
|
4529
|
+
try {
|
|
4530
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
4531
|
+
spawn(opener, [url2], { stdio: "ignore", detached: true }).unref();
|
|
4532
|
+
} catch {}
|
|
4533
|
+
}
|
|
4534
|
+
return;
|
|
4535
|
+
}
|
|
4536
|
+
if (existingPid && force) {
|
|
4537
|
+
console.error(` Force restarting (killing pid ${existingPid})...`);
|
|
4538
|
+
try {
|
|
4539
|
+
process.kill(existingPid, "SIGTERM");
|
|
4540
|
+
} catch {}
|
|
4541
|
+
await new Promise((r) => setTimeout(r, 400));
|
|
4542
|
+
removePid(port);
|
|
4543
|
+
} else if (!existingPid) {
|
|
4544
|
+
await killPort(port);
|
|
4545
|
+
}
|
|
4483
4546
|
const config = await readConfig();
|
|
4484
4547
|
let project = resolveProjectName(config) ?? undefined;
|
|
4485
4548
|
if (project) {
|
|
@@ -4489,105 +4552,113 @@ var init_ui = __esm(() => {
|
|
|
4489
4552
|
project = undefined;
|
|
4490
4553
|
}
|
|
4491
4554
|
}
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
const
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
return Response.json({
|
|
4505
|
-
project: project || null,
|
|
4506
|
-
doravalDir: getJournalsDir(),
|
|
4507
|
-
hasConfig: !!config,
|
|
4508
|
-
repo: config?.journal?.repo ?? null
|
|
4509
|
-
});
|
|
4510
|
-
}
|
|
4511
|
-
if (url2.pathname === "/api/entries") {
|
|
4512
|
-
const { committed, staged } = await loadAllEntries(project || null);
|
|
4513
|
-
return Response.json({ project, committed, staged });
|
|
4514
|
-
}
|
|
4515
|
-
if (url2.pathname === "/api/context") {
|
|
4516
|
-
const { committed, staged } = await loadAllEntries(project || null);
|
|
4517
|
-
const all = [...staged, ...committed].filter((e) => (e.status || "active") === "active");
|
|
4518
|
-
const text = generateJournalContext(all, project || null, { minPushback: 1 });
|
|
4519
|
-
return Response.json({ text, project });
|
|
4520
|
-
}
|
|
4521
|
-
if (url2.pathname === "/api/hooks/status" && req.method === "GET") {
|
|
4522
|
-
const localPath = getLocalHooksPath();
|
|
4523
|
-
const globalPath = getGlobalSettingsPath();
|
|
4524
|
-
const localHas = hasHook(await readJson(localPath));
|
|
4525
|
-
const globalHas = hasHook(await readJson(globalPath));
|
|
4526
|
-
return Response.json({
|
|
4527
|
-
local: { enabled: localHas, path: localPath },
|
|
4528
|
-
global: { enabled: globalHas, path: globalPath }
|
|
4529
|
-
});
|
|
4530
|
-
}
|
|
4531
|
-
if (url2.pathname === "/api/hooks/enable" && req.method === "POST") {
|
|
4532
|
-
const body = await req.json().catch(() => ({}));
|
|
4533
|
-
const useGlobal = !!body.global;
|
|
4534
|
-
const target = useGlobal ? getGlobalSettingsPath() : getLocalHooksPath();
|
|
4535
|
-
const res = await addHook(target);
|
|
4536
|
-
return Response.json(res);
|
|
4537
|
-
}
|
|
4538
|
-
if (url2.pathname === "/api/hooks/disable" && req.method === "POST") {
|
|
4539
|
-
const body = await req.json().catch(() => ({}));
|
|
4540
|
-
const useGlobal = !!body.global;
|
|
4541
|
-
const target = useGlobal ? getGlobalSettingsPath() : getLocalHooksPath();
|
|
4542
|
-
const res = await removeHook(target);
|
|
4543
|
-
return Response.json(res);
|
|
4544
|
-
}
|
|
4545
|
-
if (url2.pathname === "/api/add" && req.method === "POST") {
|
|
4546
|
-
if (!project) {
|
|
4547
|
-
return Response.json({ error: "No project configured. Run dora init or dora journal init first." }, { status: 400 });
|
|
4555
|
+
let server;
|
|
4556
|
+
try {
|
|
4557
|
+
server = Bun.serve({
|
|
4558
|
+
port,
|
|
4559
|
+
hostname: host,
|
|
4560
|
+
async fetch(req) {
|
|
4561
|
+
const url2 = new URL(req.url);
|
|
4562
|
+
if (url2.pathname === "/" || url2.pathname === "/index.html") {
|
|
4563
|
+
const html = await getDashboardHtml();
|
|
4564
|
+
return new Response(html, {
|
|
4565
|
+
headers: { "content-type": "text/html; charset=utf-8" }
|
|
4566
|
+
});
|
|
4548
4567
|
}
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
return Response.json({ ok: true, ...result });
|
|
4557
|
-
} catch (e) {
|
|
4558
|
-
return Response.json({ error: e.message }, { status: 500 });
|
|
4568
|
+
if (url2.pathname === "/api/status") {
|
|
4569
|
+
return Response.json({
|
|
4570
|
+
project: project || null,
|
|
4571
|
+
doravalDir: getJournalsDir(),
|
|
4572
|
+
hasConfig: !!config,
|
|
4573
|
+
repo: config?.journal?.repo ?? null
|
|
4574
|
+
});
|
|
4559
4575
|
}
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4576
|
+
if (url2.pathname === "/api/entries") {
|
|
4577
|
+
const { committed, staged } = await loadAllEntries(project || null);
|
|
4578
|
+
return Response.json({ project, committed, staged });
|
|
4579
|
+
}
|
|
4580
|
+
if (url2.pathname === "/api/context") {
|
|
4581
|
+
const { committed, staged } = await loadAllEntries(project || null);
|
|
4582
|
+
const all = [...staged, ...committed].filter((e) => (e.status || "active") === "active");
|
|
4583
|
+
const text = generateJournalContext(all, project || null, { minPushback: 1 });
|
|
4584
|
+
return Response.json({ text, project });
|
|
4568
4585
|
}
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4586
|
+
if (url2.pathname === "/api/hooks/status" && req.method === "GET") {
|
|
4587
|
+
const localPath = getLocalHooksPath();
|
|
4588
|
+
const globalPath = getGlobalSettingsPath();
|
|
4589
|
+
const localHas = hasHook(await readJson(localPath));
|
|
4590
|
+
const globalHas = hasHook(await readJson(globalPath));
|
|
4591
|
+
return Response.json({
|
|
4592
|
+
local: { enabled: localHas, path: localPath },
|
|
4593
|
+
global: { enabled: globalHas, path: globalPath }
|
|
4594
|
+
});
|
|
4573
4595
|
}
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4596
|
+
if (url2.pathname === "/api/hooks/enable" && req.method === "POST") {
|
|
4597
|
+
const body = await req.json().catch(() => ({}));
|
|
4598
|
+
const useGlobal = !!body.global;
|
|
4599
|
+
const target = useGlobal ? getGlobalSettingsPath() : getLocalHooksPath();
|
|
4600
|
+
const res = await addHook(target);
|
|
4601
|
+
return Response.json(res);
|
|
4602
|
+
}
|
|
4603
|
+
if (url2.pathname === "/api/hooks/disable" && req.method === "POST") {
|
|
4604
|
+
const body = await req.json().catch(() => ({}));
|
|
4605
|
+
const useGlobal = !!body.global;
|
|
4606
|
+
const target = useGlobal ? getGlobalSettingsPath() : getLocalHooksPath();
|
|
4607
|
+
const res = await removeHook(target);
|
|
4608
|
+
return Response.json(res);
|
|
4609
|
+
}
|
|
4610
|
+
if (url2.pathname === "/api/add" && req.method === "POST") {
|
|
4611
|
+
if (!project) {
|
|
4612
|
+
return Response.json({ error: "No project configured. Run dora init or dora journal init first." }, { status: 400 });
|
|
4613
|
+
}
|
|
4614
|
+
const body = await req.json();
|
|
4615
|
+
const title = String(body.title || "Untitled decision").trim();
|
|
4616
|
+
const pushback = Number(body.pushback ?? 4);
|
|
4617
|
+
const tags = Array.isArray(body.tags) ? body.tags.map((t) => String(t).trim()).filter(Boolean) : [];
|
|
4618
|
+
const rationale = String(body.rationale || title).trim();
|
|
4577
4619
|
try {
|
|
4578
|
-
await
|
|
4579
|
-
|
|
4580
|
-
|
|
4620
|
+
const result = await writePendingEntry(project, { title, pushback, tags, rationale });
|
|
4621
|
+
return Response.json({ ok: true, ...result });
|
|
4622
|
+
} catch (e) {
|
|
4623
|
+
return Response.json({ error: e.message }, { status: 500 });
|
|
4624
|
+
}
|
|
4581
4625
|
}
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4626
|
+
if (url2.pathname === "/api/refresh" && req.method === "POST") {
|
|
4627
|
+
const { committed, staged } = await loadAllEntries(project || null);
|
|
4628
|
+
return Response.json({ ok: true, committed, staged });
|
|
4629
|
+
}
|
|
4630
|
+
if (url2.pathname === "/api/delete-staged" && req.method === "POST") {
|
|
4631
|
+
if (!project) {
|
|
4632
|
+
return Response.json({ error: "No project" }, { status: 400 });
|
|
4633
|
+
}
|
|
4634
|
+
const body = await req.json().catch(() => ({}));
|
|
4635
|
+
const filename = body.filename;
|
|
4636
|
+
if (!filename) {
|
|
4637
|
+
return Response.json({ error: "filename required" }, { status: 400 });
|
|
4638
|
+
}
|
|
4639
|
+
const pdir = getPendingProjectDir(project);
|
|
4640
|
+
const filePath = join18(pdir, filename);
|
|
4641
|
+
if (existsSync19(filePath)) {
|
|
4642
|
+
try {
|
|
4643
|
+
await Bun.file(filePath).unlink();
|
|
4644
|
+
} catch {}
|
|
4645
|
+
return Response.json({ ok: true });
|
|
4646
|
+
}
|
|
4647
|
+
return Response.json({ error: "not found" }, { status: 404 });
|
|
4648
|
+
}
|
|
4649
|
+
if (url2.pathname.startsWith("/api/")) {
|
|
4650
|
+
return Response.json({ error: "Not found" }, { status: 404 });
|
|
4651
|
+
}
|
|
4652
|
+
return new Response("Not found", { status: 404 });
|
|
4586
4653
|
}
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4654
|
+
});
|
|
4655
|
+
} catch (err) {
|
|
4656
|
+
removePid(port);
|
|
4657
|
+
console.error(` Failed to start dashboard on port ${port}: ${err?.message || err}`);
|
|
4658
|
+
process.exit(1);
|
|
4659
|
+
}
|
|
4590
4660
|
const url = `http://${host === "0.0.0.0" ? "localhost" : host}:${server.port}`;
|
|
4661
|
+
writePid(process.pid, port);
|
|
4591
4662
|
const msg = `
|
|
4592
4663
|
${import_picocolors16.default.blue("\u25C9")} dora local dashboard
|
|
4593
4664
|
${import_picocolors16.default.dim("Project:")} ${project ? import_picocolors16.default.white(project) : import_picocolors16.default.yellow("none (run dora init)")}
|
|
@@ -4604,12 +4675,15 @@ var init_ui = __esm(() => {
|
|
|
4604
4675
|
console.error(import_picocolors16.default.dim(` Could not auto-open. Visit ${url}`));
|
|
4605
4676
|
}
|
|
4606
4677
|
}
|
|
4607
|
-
|
|
4678
|
+
const cleanup = () => {
|
|
4679
|
+
removePid(port);
|
|
4608
4680
|
console.error(`
|
|
4609
4681
|
Stopping dashboard...`);
|
|
4610
4682
|
server.stop();
|
|
4611
4683
|
process.exit(0);
|
|
4612
|
-
}
|
|
4684
|
+
};
|
|
4685
|
+
process.on("SIGINT", cleanup);
|
|
4686
|
+
process.on("SIGTERM", cleanup);
|
|
4613
4687
|
}
|
|
4614
4688
|
};
|
|
4615
4689
|
});
|
|
@@ -7733,7 +7807,7 @@ var exports_completion = {};
|
|
|
7733
7807
|
__export(exports_completion, {
|
|
7734
7808
|
default: () => completion_default
|
|
7735
7809
|
});
|
|
7736
|
-
var commands, subCommands, completion_default;
|
|
7810
|
+
var commands, uiFlags, subCommands, completion_default;
|
|
7737
7811
|
var init_completion = __esm(() => {
|
|
7738
7812
|
init_dist();
|
|
7739
7813
|
commands = [
|
|
@@ -7750,6 +7824,7 @@ var init_completion = __esm(() => {
|
|
|
7750
7824
|
"cursor",
|
|
7751
7825
|
"copilot"
|
|
7752
7826
|
];
|
|
7827
|
+
uiFlags = ["--port", "--open", "--no-open", "--host", "--status", "--force"];
|
|
7753
7828
|
subCommands = {
|
|
7754
7829
|
skill: ["validate", "drift", "judge"],
|
|
7755
7830
|
journal: ["init", "list", "context", "hook", "update", "add", "sync"],
|
|
@@ -7788,6 +7863,7 @@ _doraval_completions() {
|
|
|
7788
7863
|
skill) COMPREPLY=( $(compgen -W "${subCommands.skill.join(" ")}" -- "$cur") ) ;;
|
|
7789
7864
|
journal) COMPREPLY=( $(compgen -W "${subCommands.journal.join(" ")}" -- "$cur") ) ;;
|
|
7790
7865
|
hook) COMPREPLY=( $(compgen -W "${subCommands.hook.join(" ")}" -- "$cur") ) ;;
|
|
7866
|
+
ui) COMPREPLY=( $(compgen -W "${uiFlags.join(" ")}" -- "$cur") ) ;;
|
|
7791
7867
|
claude|codex|cursor|copilot) COMPREPLY=( $(compgen -W "${subCommands.claude.join(" ")}" -- "$cur") ) ;;
|
|
7792
7868
|
esac
|
|
7793
7869
|
fi
|
|
@@ -7820,6 +7896,9 @@ _doraval() {
|
|
|
7820
7896
|
hook)
|
|
7821
7897
|
_describe 'subcommand' (enable disable status)
|
|
7822
7898
|
;;
|
|
7899
|
+
ui)
|
|
7900
|
+
_describe 'flag' (${uiFlags})
|
|
7901
|
+
;;
|
|
7823
7902
|
claude|codex|cursor|copilot)
|
|
7824
7903
|
_describe 'subcommand' (new bump)
|
|
7825
7904
|
;;
|
|
@@ -7838,6 +7917,12 @@ complete -c doraval -n '__fish_use_subcommand' -a 'validate init bump update pro
|
|
|
7838
7917
|
complete -c doraval -n '__fish_seen_subcommand_from skill' -a 'validate drift judge'
|
|
7839
7918
|
complete -c doraval -n '__fish_seen_subcommand_from journal' -a 'init list context hook update add sync'
|
|
7840
7919
|
complete -c doraval -n '__fish_seen_subcommand_from hook' -a 'enable disable status'
|
|
7920
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l port -d 'Port'
|
|
7921
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l open -d 'Open browser'
|
|
7922
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l no-open -d 'Do not open browser'
|
|
7923
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l host -d 'Host'
|
|
7924
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l status -d 'Show status only'
|
|
7925
|
+
complete -c doraval -n '__fish_seen_subcommand_from ui' -l force -d 'Force restart'
|
|
7841
7926
|
complete -c doraval -n '__fish_seen_subcommand_from claude codex cursor copilot' -a 'new bump'
|
|
7842
7927
|
`);
|
|
7843
7928
|
} else {
|
|
@@ -7975,6 +8060,16 @@ var ui2 = defineCommand({
|
|
|
7975
8060
|
type: "string",
|
|
7976
8061
|
description: "Host to bind (default 127.0.0.1 for local only)",
|
|
7977
8062
|
default: "127.0.0.1"
|
|
8063
|
+
},
|
|
8064
|
+
status: {
|
|
8065
|
+
type: "boolean",
|
|
8066
|
+
description: "Check if a dashboard is running and print its URL (no start)",
|
|
8067
|
+
default: false
|
|
8068
|
+
},
|
|
8069
|
+
force: {
|
|
8070
|
+
type: "boolean",
|
|
8071
|
+
description: "Force start/restart even if one is already running",
|
|
8072
|
+
default: false
|
|
7978
8073
|
}
|
|
7979
8074
|
},
|
|
7980
8075
|
async run({ args }) {
|
|
@@ -7997,7 +8092,7 @@ var main = defineCommand({
|
|
|
7997
8092
|
meta: {
|
|
7998
8093
|
name: "doraval",
|
|
7999
8094
|
version: import__package.default.version,
|
|
8000
|
-
description: "The context engineering toolkit for coding
|
|
8095
|
+
description: "The context engineering toolkit for coding agent orchestrators"
|
|
8001
8096
|
},
|
|
8002
8097
|
subCommands: {
|
|
8003
8098
|
validate: () => Promise.resolve().then(() => (init_validate_top(), exports_validate_top)).then((m) => m.default),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hacksmith/doraval",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.46",
|
|
4
4
|
"author": "Saif",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"doraval": "bin/doraval-wrapper.js",
|
|
14
14
|
"dora": "bin/doraval-wrapper.js"
|
|
15
15
|
},
|
|
16
|
-
"description": "The context engineering toolkit for coding
|
|
16
|
+
"description": "The context engineering toolkit for coding agent orchestrators",
|
|
17
17
|
"engines": {
|
|
18
18
|
"bun": ">=1.2.0",
|
|
19
19
|
"node": ">=14.18.0"
|