@hacksmith/doraval 0.2.16 → 0.2.19
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 +1 -0
- package/bin/doraval.js +368 -219
- package/package.json +2 -1
package/bin/doraval.js
CHANGED
|
@@ -698,8 +698,8 @@ function parseFrontmatter(raw) {
|
|
|
698
698
|
if (!match) {
|
|
699
699
|
return { data: {}, content: raw };
|
|
700
700
|
}
|
|
701
|
-
const data = YAML.parse(match[1]);
|
|
702
|
-
return { data
|
|
701
|
+
const data = YAML.parse(match[1]) ?? {};
|
|
702
|
+
return { data, content: match[2] ?? "" };
|
|
703
703
|
}
|
|
704
704
|
var FRONTMATTER_RE;
|
|
705
705
|
var init_frontmatter = __esm(() => {
|
|
@@ -1216,33 +1216,19 @@ function hasGhCli() {
|
|
|
1216
1216
|
});
|
|
1217
1217
|
return result.exitCode === 0;
|
|
1218
1218
|
}
|
|
1219
|
-
function
|
|
1219
|
+
function ensureGhCli() {
|
|
1220
1220
|
if (hasGhCli())
|
|
1221
|
-
return;
|
|
1222
|
-
|
|
1223
|
-
`);
|
|
1224
|
-
ui.info(` doraval uses ${import_picocolors4.default.bold("gh")} to fetch and sync journal files with GitHub.
|
|
1225
|
-
`);
|
|
1226
|
-
ui.info(` Install it:
|
|
1227
|
-
`);
|
|
1228
|
-
ui.info(` macOS: ${import_picocolors4.default.dim("brew install gh")}`);
|
|
1229
|
-
ui.info(` Linux: ${import_picocolors4.default.dim("https://github.com/cli/cli/blob/trunk/docs/install_linux.md")}`);
|
|
1230
|
-
ui.info(` Windows: ${import_picocolors4.default.dim("winget install --id GitHub.cli")}
|
|
1231
|
-
`);
|
|
1232
|
-
ui.info(` Then authenticate: ${import_picocolors4.default.dim("gh auth login")}
|
|
1233
|
-
`);
|
|
1234
|
-
process.exit(1);
|
|
1221
|
+
return { ok: true, value: true };
|
|
1222
|
+
return { ok: false, error: "GH_CLI_MISSING" };
|
|
1235
1223
|
}
|
|
1236
1224
|
function fetchRemoteJournalFile(repo, path) {
|
|
1237
1225
|
const result = spawnSync(["gh", "api", `repos/${repo}/contents/${path}`, "--jq", "{sha, content, encoding}"], { stdout: "pipe", stderr: "pipe" });
|
|
1238
1226
|
if (result.exitCode !== 0) {
|
|
1239
1227
|
const stderr = result.stderr.toString();
|
|
1240
1228
|
if (stderr.includes("404") || stderr.includes("Not Found")) {
|
|
1241
|
-
return
|
|
1229
|
+
return { ok: false, error: "not found", isNotFound: true };
|
|
1242
1230
|
}
|
|
1243
|
-
|
|
1244
|
-
ui.info(stderr);
|
|
1245
|
-
process.exit(1);
|
|
1231
|
+
return { ok: false, error: stderr };
|
|
1246
1232
|
}
|
|
1247
1233
|
try {
|
|
1248
1234
|
const parsed = JSON.parse(result.stdout.toString());
|
|
@@ -1253,38 +1239,42 @@ function fetchRemoteJournalFile(repo, path) {
|
|
|
1253
1239
|
decoded = parsed.content;
|
|
1254
1240
|
}
|
|
1255
1241
|
return {
|
|
1256
|
-
|
|
1257
|
-
|
|
1242
|
+
ok: true,
|
|
1243
|
+
value: {
|
|
1244
|
+
content: decoded,
|
|
1245
|
+
sha: parsed.sha
|
|
1246
|
+
}
|
|
1258
1247
|
};
|
|
1259
1248
|
} catch {
|
|
1260
|
-
|
|
1261
|
-
process.exit(1);
|
|
1249
|
+
return { ok: false, error: `Unexpected response when fetching ${path} from ${repo}` };
|
|
1262
1250
|
}
|
|
1263
1251
|
}
|
|
1264
1252
|
async function refreshLocalJournalFile(repo, remotePath, localPath) {
|
|
1265
|
-
const
|
|
1266
|
-
if (!
|
|
1267
|
-
|
|
1253
|
+
const res = fetchRemoteJournalFile(repo, remotePath);
|
|
1254
|
+
if (!res.ok) {
|
|
1255
|
+
if (res.isNotFound) {
|
|
1256
|
+
return { ok: true, value: false };
|
|
1257
|
+
}
|
|
1258
|
+
return { ok: false, error: res.error };
|
|
1268
1259
|
}
|
|
1260
|
+
const remote = res.value;
|
|
1269
1261
|
await Bun.write(localPath, remote.content);
|
|
1270
|
-
return true;
|
|
1262
|
+
return { ok: true, value: true };
|
|
1271
1263
|
}
|
|
1272
1264
|
function getRemoteJournalFileMeta(repo, path) {
|
|
1273
1265
|
const result = spawnSync(["gh", "api", `repos/${repo}/contents/${path}`, "--jq", "{sha, content, encoding}"], { stdout: "pipe", stderr: "pipe" });
|
|
1274
1266
|
if (result.exitCode !== 0) {
|
|
1275
1267
|
const stderr = result.stderr.toString();
|
|
1276
1268
|
if (stderr.includes("404") || stderr.includes("Not Found")) {
|
|
1277
|
-
return
|
|
1269
|
+
return { ok: false, error: "not found", isNotFound: true };
|
|
1278
1270
|
}
|
|
1279
|
-
|
|
1280
|
-
ui.info(stderr);
|
|
1281
|
-
process.exit(1);
|
|
1271
|
+
return { ok: false, error: stderr };
|
|
1282
1272
|
}
|
|
1283
1273
|
try {
|
|
1284
|
-
|
|
1274
|
+
const parsed = JSON.parse(result.stdout.toString());
|
|
1275
|
+
return { ok: true, value: parsed };
|
|
1285
1276
|
} catch {
|
|
1286
|
-
|
|
1287
|
-
process.exit(1);
|
|
1277
|
+
return { ok: false, error: `Unexpected response when fetching ${path} from ${repo}` };
|
|
1288
1278
|
}
|
|
1289
1279
|
}
|
|
1290
1280
|
function getGitRemoteOwner() {
|
|
@@ -1313,23 +1303,19 @@ function repoExists(repo) {
|
|
|
1313
1303
|
const result = spawnSync(["gh", "api", `repos/${repo}`, "--jq", ".full_name"], { stdout: "pipe", stderr: "pipe" });
|
|
1314
1304
|
return result.exitCode === 0 && result.stdout.toString().trim().length > 0;
|
|
1315
1305
|
}
|
|
1316
|
-
var
|
|
1317
|
-
var init_journal_remote = __esm(() => {
|
|
1318
|
-
init_out();
|
|
1319
|
-
import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
1320
|
-
});
|
|
1306
|
+
var init_journal_remote = () => {};
|
|
1321
1307
|
|
|
1322
1308
|
// src/cli/prompt.ts
|
|
1323
1309
|
function prompt(label, fallback) {
|
|
1324
|
-
process.stderr.write(`${label} ${
|
|
1310
|
+
process.stderr.write(`${label} ${import_picocolors4.default.dim(`(${fallback})`)} `);
|
|
1325
1311
|
const buf = new Uint8Array(1024);
|
|
1326
1312
|
const n = __require("fs").readSync(0, buf);
|
|
1327
1313
|
const input = new TextDecoder().decode(buf.subarray(0, n)).trim();
|
|
1328
1314
|
return input || fallback;
|
|
1329
1315
|
}
|
|
1330
|
-
var
|
|
1316
|
+
var import_picocolors4;
|
|
1331
1317
|
var init_prompt = __esm(() => {
|
|
1332
|
-
|
|
1318
|
+
import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
1333
1319
|
});
|
|
1334
1320
|
|
|
1335
1321
|
// src/cli/commands/journal/init.ts
|
|
@@ -1338,14 +1324,14 @@ __export(exports_init, {
|
|
|
1338
1324
|
default: () => init_default
|
|
1339
1325
|
});
|
|
1340
1326
|
import { basename, join as join2 } from "path";
|
|
1341
|
-
var
|
|
1327
|
+
var import_picocolors5, init_default;
|
|
1342
1328
|
var init_init = __esm(() => {
|
|
1343
1329
|
init_dist();
|
|
1344
1330
|
init_out();
|
|
1345
1331
|
init_journal_config();
|
|
1346
1332
|
init_journal_remote();
|
|
1347
1333
|
init_prompt();
|
|
1348
|
-
|
|
1334
|
+
import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
1349
1335
|
init_default = defineCommand({
|
|
1350
1336
|
meta: {
|
|
1351
1337
|
name: "init",
|
|
@@ -1370,9 +1356,24 @@ var init_init = __esm(() => {
|
|
|
1370
1356
|
},
|
|
1371
1357
|
async run({ args }) {
|
|
1372
1358
|
ui.write(`
|
|
1373
|
-
${
|
|
1359
|
+
${import_picocolors5.default.bold(import_picocolors5.default.white("dora journal init"))} (or top-level ${import_picocolors5.default.dim(import_picocolors5.default.gray("dora init"))}) \u2014 Set up your journal
|
|
1360
|
+
`);
|
|
1361
|
+
const ghCheck = ensureGhCli();
|
|
1362
|
+
if (!ghCheck.ok) {
|
|
1363
|
+
ui.write(` ${import_picocolors5.default.red("\u2717")} ${import_picocolors5.default.white("The GitHub CLI (")}${import_picocolors5.default.bold("gh")}${import_picocolors5.default.white(") is not installed.")}
|
|
1364
|
+
`);
|
|
1365
|
+
ui.write(` doraval uses ${import_picocolors5.default.bold("gh")} to fetch and sync journal files with GitHub.
|
|
1366
|
+
`);
|
|
1367
|
+
ui.write(` Install it:
|
|
1374
1368
|
`);
|
|
1375
|
-
|
|
1369
|
+
ui.write(` macOS: ${import_picocolors5.default.dim("brew install gh")}`);
|
|
1370
|
+
ui.write(` Linux: ${import_picocolors5.default.dim("https://github.com/cli/cli/blob/trunk/docs/install_linux.md")}`);
|
|
1371
|
+
ui.write(` Windows: ${import_picocolors5.default.dim("winget install --id GitHub.cli")}
|
|
1372
|
+
`);
|
|
1373
|
+
ui.write(` Then authenticate: ${import_picocolors5.default.dim("gh auth login")}
|
|
1374
|
+
`);
|
|
1375
|
+
process.exit(1);
|
|
1376
|
+
}
|
|
1376
1377
|
let repo = args.repo || process.env.DORAVAL_JOURNAL_REPO;
|
|
1377
1378
|
if (!repo) {
|
|
1378
1379
|
const gitOwner = getGitRemoteOwner();
|
|
@@ -1382,28 +1383,28 @@ var init_init = __esm(() => {
|
|
|
1382
1383
|
if (gitOwner) {
|
|
1383
1384
|
defaultRepo = `${gitOwner}/${gitOwner}.md`;
|
|
1384
1385
|
if (ghLogin && ghLogin !== gitOwner) {
|
|
1385
|
-
sourceNote = ` ${
|
|
1386
|
+
sourceNote = ` ${import_picocolors5.default.dim("(from git remote; your active gh account is " + ghLogin + ")")}
|
|
1386
1387
|
`;
|
|
1387
1388
|
} else {
|
|
1388
|
-
sourceNote = ` ${
|
|
1389
|
+
sourceNote = ` ${import_picocolors5.default.dim("(from git remote)")}
|
|
1389
1390
|
`;
|
|
1390
1391
|
}
|
|
1391
1392
|
} else if (ghLogin) {
|
|
1392
1393
|
defaultRepo = `${ghLogin}/${ghLogin}.md`;
|
|
1393
|
-
sourceNote = ` ${
|
|
1394
|
+
sourceNote = ` ${import_picocolors5.default.dim("(from your active gh account)")}
|
|
1394
1395
|
`;
|
|
1395
1396
|
} else {
|
|
1396
|
-
ui.write(` ${
|
|
1397
|
+
ui.write(` ${import_picocolors5.default.yellow("\u26A0")} Not logged in to GitHub. Run ${import_picocolors5.default.dim("gh auth login")} first.
|
|
1397
1398
|
`);
|
|
1398
1399
|
process.exit(1);
|
|
1399
1400
|
}
|
|
1400
1401
|
const existingConfig = await readConfig();
|
|
1401
1402
|
if (existingConfig?.journal.repo) {
|
|
1402
1403
|
defaultRepo = existingConfig.journal.repo;
|
|
1403
|
-
sourceNote = ` ${
|
|
1404
|
+
sourceNote = ` ${import_picocolors5.default.dim("(from your previous journal setup)")}
|
|
1404
1405
|
`;
|
|
1405
1406
|
}
|
|
1406
|
-
ui.write(` Journal repo ${
|
|
1407
|
+
ui.write(` Journal repo ${import_picocolors5.default.dim(import_picocolors5.default.gray("(owner/name)"))}`);
|
|
1407
1408
|
if (sourceNote)
|
|
1408
1409
|
ui.write(sourceNote);
|
|
1409
1410
|
repo = prompt(" >", defaultRepo);
|
|
@@ -1415,13 +1416,13 @@ var init_init = __esm(() => {
|
|
|
1415
1416
|
}
|
|
1416
1417
|
project = sanitizeProjectName(project);
|
|
1417
1418
|
if (!repoExists(repo)) {
|
|
1418
|
-
ui.write(` ${
|
|
1419
|
+
ui.write(` ${import_picocolors5.default.red("\u2717")} Repository ${import_picocolors5.default.bold(import_picocolors5.default.white(repo))} not found on GitHub.
|
|
1419
1420
|
`);
|
|
1420
1421
|
ui.write(` Create it first:
|
|
1421
1422
|
`);
|
|
1422
|
-
ui.write(` ${
|
|
1423
|
+
ui.write(` ${import_picocolors5.default.dim(`gh repo create ${repo} --private --description "Personal journal for agent decisions"`)}
|
|
1423
1424
|
`);
|
|
1424
|
-
ui.write(` The repo should be private. doraval will populate it on first ${
|
|
1425
|
+
ui.write(` The repo should be private. doraval will populate it on first ${import_picocolors5.default.dim("dora journal sync")}.
|
|
1425
1426
|
`);
|
|
1426
1427
|
process.exit(1);
|
|
1427
1428
|
}
|
|
@@ -1429,14 +1430,14 @@ var init_init = __esm(() => {
|
|
|
1429
1430
|
const alreadyRegistered = existing?.journal.projects[project];
|
|
1430
1431
|
const isRefresh = alreadyRegistered && args.refresh;
|
|
1431
1432
|
if (alreadyRegistered && !isRefresh) {
|
|
1432
|
-
ui.write(` ${
|
|
1433
|
+
ui.write(` ${import_picocolors5.default.yellow("\u26A0")} Project ${import_picocolors5.default.bold(import_picocolors5.default.white(project))} is already registered.
|
|
1433
1434
|
`);
|
|
1434
|
-
ui.write(` Repo: ${
|
|
1435
|
-
ui.write(` Remote: ${existing.journal.projects[project]
|
|
1435
|
+
ui.write(` Repo: ${import_picocolors5.default.gray(existing.journal.repo)}`);
|
|
1436
|
+
ui.write(` Remote: ${existing.journal.projects[project]?.remote_path}
|
|
1436
1437
|
`);
|
|
1437
|
-
ui.write(` To refresh local files, run: ${
|
|
1438
|
+
ui.write(` To refresh local files, run: ${import_picocolors5.default.dim(import_picocolors5.default.gray(`dora journal update`))}
|
|
1438
1439
|
` + ` (init --refresh still works for compatibility.)
|
|
1439
|
-
` + ` Or remove the project from ${
|
|
1440
|
+
` + ` Or remove the project from ${import_picocolors5.default.dim(import_picocolors5.default.gray("~/.doraval/config.yml"))} to fully re-initialize.
|
|
1440
1441
|
`);
|
|
1441
1442
|
process.exit(0);
|
|
1442
1443
|
}
|
|
@@ -1454,24 +1455,48 @@ var init_init = __esm(() => {
|
|
|
1454
1455
|
};
|
|
1455
1456
|
ensureDoravalDirs();
|
|
1456
1457
|
const actionLabel = isRefresh ? "Refreshing" : "Fetching";
|
|
1457
|
-
ui.write(` ${
|
|
1458
|
+
ui.write(` ${import_picocolors5.default.dim(import_picocolors5.default.gray(`${actionLabel} journal files from`))} ${import_picocolors5.default.gray(effectiveRepo)}${import_picocolors5.default.dim(import_picocolors5.default.gray("..."))}
|
|
1458
1459
|
`);
|
|
1459
1460
|
const globalDest = join2(journalsDir, "global.md");
|
|
1460
|
-
const
|
|
1461
|
+
const refreshGlobalRes = await refreshLocalJournalFile(effectiveRepo, "global.md", globalDest);
|
|
1462
|
+
let wroteGlobal;
|
|
1463
|
+
if (!refreshGlobalRes.ok) {
|
|
1464
|
+
if (refreshGlobalRes.isNotFound) {
|
|
1465
|
+
wroteGlobal = false;
|
|
1466
|
+
} else {
|
|
1467
|
+
ui.write(` ${import_picocolors5.default.red("\u2717")} Failed to fetch global.md from ${effectiveRepo}:`);
|
|
1468
|
+
ui.write(refreshGlobalRes.error);
|
|
1469
|
+
process.exit(1);
|
|
1470
|
+
}
|
|
1471
|
+
} else {
|
|
1472
|
+
wroteGlobal = refreshGlobalRes.value;
|
|
1473
|
+
}
|
|
1461
1474
|
if (wroteGlobal) {
|
|
1462
|
-
ui.write(` ${
|
|
1475
|
+
ui.write(` ${import_picocolors5.default.green("\u2713")} global.md`);
|
|
1463
1476
|
} else {
|
|
1464
|
-
ui.write(` ${
|
|
1477
|
+
ui.write(` ${import_picocolors5.default.dim("\xB7")} global.md ${import_picocolors5.default.dim("(not found \u2014 will be created on first sync)")}`);
|
|
1465
1478
|
await Bun.write(globalDest, `# Global Journal
|
|
1466
1479
|
|
|
1467
1480
|
Cross-project principles.
|
|
1468
1481
|
`);
|
|
1469
1482
|
}
|
|
1470
|
-
const
|
|
1483
|
+
const refreshProjectRes = await refreshLocalJournalFile(effectiveRepo, remotePath, localPath);
|
|
1484
|
+
let wroteProject;
|
|
1485
|
+
if (!refreshProjectRes.ok) {
|
|
1486
|
+
if (refreshProjectRes.isNotFound) {
|
|
1487
|
+
wroteProject = false;
|
|
1488
|
+
} else {
|
|
1489
|
+
ui.write(` ${import_picocolors5.default.red("\u2717")} Failed to fetch ${remotePath} from ${effectiveRepo}:`);
|
|
1490
|
+
ui.write(refreshProjectRes.error);
|
|
1491
|
+
process.exit(1);
|
|
1492
|
+
}
|
|
1493
|
+
} else {
|
|
1494
|
+
wroteProject = refreshProjectRes.value;
|
|
1495
|
+
}
|
|
1471
1496
|
if (wroteProject) {
|
|
1472
|
-
ui.write(` ${
|
|
1497
|
+
ui.write(` ${import_picocolors5.default.green("\u2713")} ${remotePath}`);
|
|
1473
1498
|
} else {
|
|
1474
|
-
ui.write(` ${
|
|
1499
|
+
ui.write(` ${import_picocolors5.default.dim("\xB7")} ${remotePath} ${import_picocolors5.default.dim("(not found \u2014 will be created on first sync)")}`);
|
|
1475
1500
|
await Bun.write(localPath, `# ${project} Journal
|
|
1476
1501
|
|
|
1477
1502
|
Project-specific decisions.
|
|
@@ -1479,13 +1504,13 @@ Project-specific decisions.
|
|
|
1479
1504
|
}
|
|
1480
1505
|
await writeConfig(config);
|
|
1481
1506
|
ui.write(`
|
|
1482
|
-
${
|
|
1507
|
+
${import_picocolors5.default.green("\u2713")} Project ${import_picocolors5.default.bold(import_picocolors5.default.white(project))} registered to ${import_picocolors5.default.bold(import_picocolors5.default.white(repo))}.
|
|
1483
1508
|
`);
|
|
1484
|
-
ui.write(` Config: ${
|
|
1485
|
-
ui.write(` Journals: ${
|
|
1486
|
-
ui.write(` Pending: ${
|
|
1509
|
+
ui.write(` Config: ${import_picocolors5.default.dim(import_picocolors5.default.gray("~/.doraval/config.yml"))}`);
|
|
1510
|
+
ui.write(` Journals: ${import_picocolors5.default.dim(import_picocolors5.default.gray("~/.doraval/journals/"))}`);
|
|
1511
|
+
ui.write(` Pending: ${import_picocolors5.default.dim(import_picocolors5.default.gray("~/.doraval/pending/"))}
|
|
1487
1512
|
`);
|
|
1488
|
-
ui.write(` Use ${
|
|
1513
|
+
ui.write(` Use ${import_picocolors5.default.dim(import_picocolors5.default.gray("dora journal add"))} to propose decisions and ${import_picocolors5.default.dim(import_picocolors5.default.gray("dora journal list"))} to view them.
|
|
1489
1514
|
`);
|
|
1490
1515
|
process.exit(0);
|
|
1491
1516
|
}
|
|
@@ -1536,8 +1561,8 @@ function parseJournalEntriesWithWarnings(raw) {
|
|
|
1536
1561
|
const pushback = Number(meta.pushback);
|
|
1537
1562
|
const tags = Array.isArray(meta.tags) ? meta.tags : Array.isArray(meta.scope) ? meta.scope : [];
|
|
1538
1563
|
const author = typeof meta.author === "string" ? meta.author : "human";
|
|
1539
|
-
const date = typeof meta.date === "string" ? meta.date : "";
|
|
1540
|
-
const status = meta.status || "active";
|
|
1564
|
+
const date = (typeof meta.date === "string" ? meta.date : "") ?? "";
|
|
1565
|
+
const status = (meta.status || "active") ?? "active";
|
|
1541
1566
|
const superseded_by = typeof meta.superseded_by === "string" ? meta.superseded_by : undefined;
|
|
1542
1567
|
entries.push({
|
|
1543
1568
|
title,
|
|
@@ -1561,13 +1586,13 @@ __export(exports_list, {
|
|
|
1561
1586
|
});
|
|
1562
1587
|
import { existsSync as existsSync4, readdirSync } from "fs";
|
|
1563
1588
|
import { join as join3 } from "path";
|
|
1564
|
-
var
|
|
1589
|
+
var import_picocolors6, list_default;
|
|
1565
1590
|
var init_list = __esm(() => {
|
|
1566
1591
|
init_dist();
|
|
1567
1592
|
init_out();
|
|
1568
1593
|
init_journal_config();
|
|
1569
1594
|
init_journal_parse();
|
|
1570
|
-
|
|
1595
|
+
import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
1571
1596
|
list_default = defineCommand({
|
|
1572
1597
|
meta: {
|
|
1573
1598
|
name: "list",
|
|
@@ -1601,9 +1626,9 @@ var init_list = __esm(() => {
|
|
|
1601
1626
|
project = sanitizeProjectName(project);
|
|
1602
1627
|
}
|
|
1603
1628
|
if (!project) {
|
|
1604
|
-
ui.write(`${
|
|
1629
|
+
ui.write(`${import_picocolors6.default.yellow("\u26A0")} ${import_picocolors6.default.yellow("No project mapping found.")}
|
|
1605
1630
|
|
|
1606
|
-
` + `Run ${
|
|
1631
|
+
` + `Run ${import_picocolors6.default.dim(import_picocolors6.default.gray("dora init"))} (or ${import_picocolors6.default.dim(import_picocolors6.default.gray("doraval journal init"))}) first, or pass ${import_picocolors6.default.dim(import_picocolors6.default.gray("--project <name>"))}.`);
|
|
1607
1632
|
process.exit(1);
|
|
1608
1633
|
}
|
|
1609
1634
|
const journalRepo = config?.journal.repo ?? "(unknown)";
|
|
@@ -1640,7 +1665,7 @@ var init_list = __esm(() => {
|
|
|
1640
1665
|
return;
|
|
1641
1666
|
}
|
|
1642
1667
|
ui.write(`
|
|
1643
|
-
${
|
|
1668
|
+
${import_picocolors6.default.bold(import_picocolors6.default.white("dora journal list"))} \u2014 ${import_picocolors6.default.white(project)} ${import_picocolors6.default.dim(import_picocolors6.default.gray(`(from ${journalRepo})`))}
|
|
1644
1669
|
`);
|
|
1645
1670
|
const hasStaged = staged.length > 0;
|
|
1646
1671
|
const hasCommitted = allEntries.length > 0;
|
|
@@ -1654,46 +1679,46 @@ var init_list = __esm(() => {
|
|
|
1654
1679
|
}
|
|
1655
1680
|
if (dups.length > 0) {
|
|
1656
1681
|
const uniqueDups = [...new Set(dups)];
|
|
1657
|
-
ui.write(` ${
|
|
1682
|
+
ui.write(` ${import_picocolors6.default.yellow("\u26A0")} ${import_picocolors6.default.yellow("Duplicate titles in this view (clean in your journal repo + update):")} ${uniqueDups.map((t) => import_picocolors6.default.yellow(`"${t}"`)).join(", ")}
|
|
1658
1683
|
`);
|
|
1659
1684
|
}
|
|
1660
1685
|
if (!hasStaged && !hasCommitted) {
|
|
1661
|
-
ui.write(` ${
|
|
1686
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray("No active entries found for"))} ${import_picocolors6.default.bold(import_picocolors6.default.white(project))}.
|
|
1662
1687
|
`);
|
|
1663
|
-
ui.write(` Journal repo: ${
|
|
1664
|
-
ui.write(` Local file: ${
|
|
1688
|
+
ui.write(` Journal repo: ${import_picocolors6.default.dim(import_picocolors6.default.gray(journalRepo))}`);
|
|
1689
|
+
ui.write(` Local file: ${import_picocolors6.default.dim(import_picocolors6.default.gray(projectFile))}
|
|
1665
1690
|
`);
|
|
1666
|
-
ui.write(` ${
|
|
1667
|
-
` + ` Use ${
|
|
1668
|
-
` + ` They will be staged locally until you run ${
|
|
1691
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray("This is normal for a freshly initialized project."))}
|
|
1692
|
+
` + ` Use ${import_picocolors6.default.dim(import_picocolors6.default.gray("dora journal add"))} to propose decisions.
|
|
1693
|
+
` + ` They will be staged locally until you run ${import_picocolors6.default.dim(import_picocolors6.default.gray("dora journal sync"))}.
|
|
1669
1694
|
`);
|
|
1670
|
-
ui.write(` If you expect content, try: ${
|
|
1695
|
+
ui.write(` If you expect content, try: ${import_picocolors6.default.dim(import_picocolors6.default.gray(`dora journal update`))}
|
|
1671
1696
|
`);
|
|
1672
1697
|
return;
|
|
1673
1698
|
}
|
|
1674
1699
|
function printEntry(entry) {
|
|
1675
1700
|
const pb = entry.pushback ?? 0;
|
|
1676
|
-
let pbColor =
|
|
1701
|
+
let pbColor = import_picocolors6.default.green;
|
|
1677
1702
|
if (pb >= 7)
|
|
1678
|
-
pbColor =
|
|
1703
|
+
pbColor = import_picocolors6.default.red;
|
|
1679
1704
|
else if (pb >= 4)
|
|
1680
|
-
pbColor =
|
|
1681
|
-
const tagsStr = (entry.tags || []).join(", ") ||
|
|
1682
|
-
const statusNote = entry.status !== "active" ?
|
|
1683
|
-
const stagedNote = entry._staged ?
|
|
1684
|
-
ui.write(` ${pbColor(String(pb).padStart(2))} ${
|
|
1685
|
-
ui.write(` ${
|
|
1686
|
-
const by = entry.author?.startsWith("agent:") ?
|
|
1687
|
-
ui.write(` ${
|
|
1705
|
+
pbColor = import_picocolors6.default.yellow;
|
|
1706
|
+
const tagsStr = (entry.tags || []).join(", ") || import_picocolors6.default.dim("(none)");
|
|
1707
|
+
const statusNote = entry.status !== "active" ? import_picocolors6.default.dim(` [${entry.status}]`) : "";
|
|
1708
|
+
const stagedNote = entry._staged ? import_picocolors6.default.dim(" (staged)") : "";
|
|
1709
|
+
ui.write(` ${pbColor(String(pb).padStart(2))} ${import_picocolors6.default.bold(import_picocolors6.default.white(entry.title))}${statusNote}${stagedNote}`);
|
|
1710
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray("tags:"))} ${import_picocolors6.default.gray(tagsStr)}`);
|
|
1711
|
+
const by = entry.author?.startsWith("agent:") ? import_picocolors6.default.cyan(entry.author) : entry.author || "human";
|
|
1712
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray("by:"))} ${import_picocolors6.default.gray(by)} ${import_picocolors6.default.dim(import_picocolors6.default.gray("on"))} ${import_picocolors6.default.gray(entry.date)}`);
|
|
1688
1713
|
const rat = (entry.rationale || "").replace(/\s+/g, " ").trim();
|
|
1689
1714
|
if (rat) {
|
|
1690
|
-
const preview = rat.length > 88 ? rat.slice(0, 85) +
|
|
1691
|
-
ui.write(` ${
|
|
1715
|
+
const preview = rat.length > 88 ? rat.slice(0, 85) + import_picocolors6.default.dim(import_picocolors6.default.gray("\u2026")) : rat;
|
|
1716
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray(preview))}`);
|
|
1692
1717
|
}
|
|
1693
1718
|
ui.write("");
|
|
1694
1719
|
}
|
|
1695
1720
|
if (hasStaged) {
|
|
1696
|
-
ui.write(` ${
|
|
1721
|
+
ui.write(` ${import_picocolors6.default.yellow("\u25CF")} ${import_picocolors6.default.bold(import_picocolors6.default.white("Staged / pending"))} (not yet in remote; run ${import_picocolors6.default.dim(import_picocolors6.default.gray("dora journal sync"))} to publish):
|
|
1697
1722
|
`);
|
|
1698
1723
|
for (const entry of staged) {
|
|
1699
1724
|
printEntry(entry);
|
|
@@ -1703,7 +1728,7 @@ var init_list = __esm(() => {
|
|
|
1703
1728
|
}
|
|
1704
1729
|
if (hasCommitted) {
|
|
1705
1730
|
if (hasStaged) {
|
|
1706
|
-
ui.write(` ${
|
|
1731
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray("Committed (from local cache):"))}
|
|
1707
1732
|
`);
|
|
1708
1733
|
}
|
|
1709
1734
|
for (const entry of allEntries) {
|
|
@@ -1711,7 +1736,7 @@ var init_list = __esm(() => {
|
|
|
1711
1736
|
}
|
|
1712
1737
|
}
|
|
1713
1738
|
const totalShown = staged.length + allEntries.length;
|
|
1714
|
-
ui.write(` ${
|
|
1739
|
+
ui.write(` ${import_picocolors6.default.dim(import_picocolors6.default.gray(`${totalShown} entries shown from ${journalRepo}.`))}
|
|
1715
1740
|
`);
|
|
1716
1741
|
process.exit(0);
|
|
1717
1742
|
}
|
|
@@ -1725,13 +1750,13 @@ __export(exports_update, {
|
|
|
1725
1750
|
});
|
|
1726
1751
|
import { existsSync as existsSync5 } from "fs";
|
|
1727
1752
|
import { join as join4 } from "path";
|
|
1728
|
-
var
|
|
1753
|
+
var import_picocolors7, update_default;
|
|
1729
1754
|
var init_update = __esm(() => {
|
|
1730
1755
|
init_dist();
|
|
1731
1756
|
init_out();
|
|
1732
1757
|
init_journal_config();
|
|
1733
1758
|
init_journal_remote();
|
|
1734
|
-
|
|
1759
|
+
import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
1735
1760
|
update_default = defineCommand({
|
|
1736
1761
|
meta: {
|
|
1737
1762
|
name: "update",
|
|
@@ -1750,17 +1775,32 @@ var init_update = __esm(() => {
|
|
|
1750
1775
|
}
|
|
1751
1776
|
},
|
|
1752
1777
|
async run({ args }) {
|
|
1753
|
-
|
|
1778
|
+
const ghCheck = ensureGhCli();
|
|
1779
|
+
if (!ghCheck.ok) {
|
|
1780
|
+
ui.write(` ${import_picocolors7.default.red("\u2717")} ${import_picocolors7.default.white("The GitHub CLI (")}${import_picocolors7.default.bold("gh")}${import_picocolors7.default.white(") is not installed.")}
|
|
1781
|
+
`);
|
|
1782
|
+
ui.write(` doraval uses ${import_picocolors7.default.bold("gh")} to fetch and sync journal files with GitHub.
|
|
1783
|
+
`);
|
|
1784
|
+
ui.write(` Install it:
|
|
1785
|
+
`);
|
|
1786
|
+
ui.write(` macOS: ${import_picocolors7.default.dim("brew install gh")}`);
|
|
1787
|
+
ui.write(` Linux: ${import_picocolors7.default.dim("https://github.com/cli/cli/blob/trunk/docs/install_linux.md")}`);
|
|
1788
|
+
ui.write(` Windows: ${import_picocolors7.default.dim("winget install --id GitHub.cli")}
|
|
1789
|
+
`);
|
|
1790
|
+
ui.write(` Then authenticate: ${import_picocolors7.default.dim("gh auth login")}
|
|
1791
|
+
`);
|
|
1792
|
+
process.exit(1);
|
|
1793
|
+
}
|
|
1754
1794
|
const config = await readConfig();
|
|
1755
1795
|
if (!config?.journal.repo) {
|
|
1756
|
-
ui.write(`${
|
|
1796
|
+
ui.write(`${import_picocolors7.default.red("\u2717")} No journal repo configured. Run ${import_picocolors7.default.dim("dora init")} (or ${import_picocolors7.default.dim("doraval journal init")}) first.`);
|
|
1757
1797
|
process.exit(1);
|
|
1758
1798
|
}
|
|
1759
1799
|
const journalRepo = config.journal.repo;
|
|
1760
1800
|
ensureDoravalDirs();
|
|
1761
1801
|
const journalsDir = getJournalsDir();
|
|
1762
1802
|
ui.write(`
|
|
1763
|
-
${
|
|
1803
|
+
${import_picocolors7.default.bold(import_picocolors7.default.white("dora journal update"))} \u2014 ${import_picocolors7.default.dim(import_picocolors7.default.gray(journalRepo))}
|
|
1764
1804
|
`);
|
|
1765
1805
|
const projectsToUpdate = [];
|
|
1766
1806
|
if (args.all) {
|
|
@@ -1778,27 +1818,39 @@ var init_update = __esm(() => {
|
|
|
1778
1818
|
try {
|
|
1779
1819
|
projectsToUpdate.push(sanitizeProjectName(project));
|
|
1780
1820
|
} catch {
|
|
1781
|
-
ui.write(`${
|
|
1821
|
+
ui.write(`${import_picocolors7.default.red("\u2717")} Invalid project name: ${project}`);
|
|
1782
1822
|
process.exit(1);
|
|
1783
1823
|
}
|
|
1784
1824
|
}
|
|
1785
1825
|
}
|
|
1786
1826
|
const globalLocal = join4(journalsDir, "global.md");
|
|
1787
|
-
const
|
|
1827
|
+
const refreshGlobalRes = await refreshLocalJournalFile(journalRepo, "global.md", globalLocal);
|
|
1828
|
+
let gotGlobal;
|
|
1829
|
+
if (!refreshGlobalRes.ok) {
|
|
1830
|
+
if (refreshGlobalRes.isNotFound) {
|
|
1831
|
+
gotGlobal = false;
|
|
1832
|
+
} else {
|
|
1833
|
+
ui.write(`${import_picocolors7.default.red("\u2717")} Failed to fetch global.md from ${journalRepo}:`);
|
|
1834
|
+
ui.write(refreshGlobalRes.error);
|
|
1835
|
+
process.exit(1);
|
|
1836
|
+
}
|
|
1837
|
+
} else {
|
|
1838
|
+
gotGlobal = refreshGlobalRes.value;
|
|
1839
|
+
}
|
|
1788
1840
|
if (gotGlobal) {
|
|
1789
|
-
ui.write(` ${
|
|
1841
|
+
ui.write(` ${import_picocolors7.default.green("\u2713")} global.md`);
|
|
1790
1842
|
} else {
|
|
1791
|
-
ui.write(` ${
|
|
1843
|
+
ui.write(` ${import_picocolors7.default.dim("\xB7")} global.md ${import_picocolors7.default.dim("(not present on remote)")}`);
|
|
1792
1844
|
}
|
|
1793
1845
|
if (projectsToUpdate.length === 0) {
|
|
1794
1846
|
if (args.all) {
|
|
1795
1847
|
ui.write(`
|
|
1796
|
-
${
|
|
1848
|
+
${import_picocolors7.default.dim(import_picocolors7.default.gray("No projects registered."))}
|
|
1797
1849
|
`);
|
|
1798
1850
|
} else {
|
|
1799
1851
|
ui.write(`
|
|
1800
|
-
${
|
|
1801
|
-
` + ` Run ${
|
|
1852
|
+
${import_picocolors7.default.yellow("\u26A0")} No project mapping found.
|
|
1853
|
+
` + ` Run ${import_picocolors7.default.dim("dora init")} or pass ${import_picocolors7.default.dim("--project <name>")} / ${import_picocolors7.default.dim("--all")}.
|
|
1802
1854
|
`);
|
|
1803
1855
|
}
|
|
1804
1856
|
return;
|
|
@@ -1806,11 +1858,23 @@ var init_update = __esm(() => {
|
|
|
1806
1858
|
for (const project of projectsToUpdate) {
|
|
1807
1859
|
const remotePath = `projects/${project}.md`;
|
|
1808
1860
|
const localPath = join4(journalsDir, `${project}.md`);
|
|
1809
|
-
const
|
|
1861
|
+
const refreshRes = await refreshLocalJournalFile(journalRepo, remotePath, localPath);
|
|
1862
|
+
let got;
|
|
1863
|
+
if (!refreshRes.ok) {
|
|
1864
|
+
if (refreshRes.isNotFound) {
|
|
1865
|
+
got = false;
|
|
1866
|
+
} else {
|
|
1867
|
+
ui.write(`${import_picocolors7.default.red("\u2717")} Failed to fetch ${remotePath} from ${journalRepo}:`);
|
|
1868
|
+
ui.write(refreshRes.error);
|
|
1869
|
+
process.exit(1);
|
|
1870
|
+
}
|
|
1871
|
+
} else {
|
|
1872
|
+
got = refreshRes.value;
|
|
1873
|
+
}
|
|
1810
1874
|
if (got) {
|
|
1811
|
-
ui.write(` ${
|
|
1875
|
+
ui.write(` ${import_picocolors7.default.green("\u2713")} ${remotePath}`);
|
|
1812
1876
|
} else {
|
|
1813
|
-
ui.write(` ${
|
|
1877
|
+
ui.write(` ${import_picocolors7.default.dim("\xB7")} ${remotePath} ${import_picocolors7.default.dim("(not present on remote \u2014 will be created on first sync)")}`);
|
|
1814
1878
|
if (!existsSync5(localPath)) {
|
|
1815
1879
|
await Bun.write(localPath, `# ${project} Journal
|
|
1816
1880
|
|
|
@@ -1821,7 +1885,7 @@ Project-specific decisions.
|
|
|
1821
1885
|
}
|
|
1822
1886
|
const summary = args.all && projectsToUpdate.length > 1 ? `${projectsToUpdate.length} projects + global` : projectsToUpdate.length === 1 ? projectsToUpdate[0] : "journals";
|
|
1823
1887
|
ui.write(`
|
|
1824
|
-
${
|
|
1888
|
+
${import_picocolors7.default.dim(import_picocolors7.default.gray("Local cache refreshed for"))} ${import_picocolors7.default.bold(import_picocolors7.default.white(summary))}.
|
|
1825
1889
|
`);
|
|
1826
1890
|
}
|
|
1827
1891
|
});
|
|
@@ -1929,7 +1993,7 @@ If you cannot produce exactly this, output the JSON with the best you can and se
|
|
|
1929
1993
|
const template = agentCfg.prompt_template || '-p "{{prompt}}" --output-format json';
|
|
1930
1994
|
const extraArgs = buildAgentArgv(template, scaffold);
|
|
1931
1995
|
const shortTemplate = (agentCfg.prompt_template || '-p "{{prompt}}" --output-format json').slice(0, 80);
|
|
1932
|
-
ui.write(` ${
|
|
1996
|
+
ui.write(` ${import_picocolors8.default.dim(`\u2192 ${agentCfg.command} ${shortTemplate}...`)}`);
|
|
1933
1997
|
try {
|
|
1934
1998
|
const result = spawnSync2([agentCfg.command, ...extraArgs], {
|
|
1935
1999
|
stdout: "pipe",
|
|
@@ -1938,12 +2002,12 @@ If you cannot produce exactly this, output the JSON with the best you can and se
|
|
|
1938
2002
|
const stdout = result.stdout.toString().trim();
|
|
1939
2003
|
const stderr = result.stderr.toString().trim();
|
|
1940
2004
|
if (result.exitCode !== 0) {
|
|
1941
|
-
ui.write(` ${
|
|
2005
|
+
ui.write(` ${import_picocolors8.default.yellow("\u26A0")} Configured agent (${agentCfg.command}) exited with code ${result.exitCode}. Falling back to defaults.`);
|
|
1942
2006
|
if (stderr)
|
|
1943
|
-
ui.write(` ${
|
|
2007
|
+
ui.write(` ${import_picocolors8.default.dim("stderr:")}
|
|
1944
2008
|
${stderr.slice(0, 800)}`);
|
|
1945
2009
|
if (stdout)
|
|
1946
|
-
ui.write(` ${
|
|
2010
|
+
ui.write(` ${import_picocolors8.default.dim("stdout:")}
|
|
1947
2011
|
${stdout.slice(0, 400)}`);
|
|
1948
2012
|
return null;
|
|
1949
2013
|
}
|
|
@@ -1988,37 +2052,37 @@ ${stdout.slice(0, 400)}`);
|
|
|
1988
2052
|
parsed = candidates[0] || null;
|
|
1989
2053
|
}
|
|
1990
2054
|
if (!parsed || typeof parsed !== "object") {
|
|
1991
|
-
ui.write(` ${
|
|
1992
|
-
ui.write(` ${
|
|
2055
|
+
ui.write(` ${import_picocolors8.default.yellow("\u26A0")} Agent produced output but no usable JSON was found. Falling back.`);
|
|
2056
|
+
ui.write(` ${import_picocolors8.default.dim("stdout (first 700 chars):")}
|
|
1993
2057
|
${stdout.slice(0, 700)}`);
|
|
1994
2058
|
if (stderr)
|
|
1995
|
-
ui.write(` ${
|
|
2059
|
+
ui.write(` ${import_picocolors8.default.dim("stderr:")}
|
|
1996
2060
|
${stderr.slice(0, 500)}`);
|
|
1997
2061
|
return null;
|
|
1998
2062
|
}
|
|
1999
2063
|
if (!parsed.title && !parsed.rationale) {
|
|
2000
|
-
ui.write(` ${
|
|
2001
|
-
ui.write(` ${
|
|
2002
|
-
ui.write(` ${
|
|
2064
|
+
ui.write(` ${import_picocolors8.default.yellow("\u26A0")} Agent returned JSON without expected fields (title/rationale). Using defaults.`);
|
|
2065
|
+
ui.write(` ${import_picocolors8.default.dim("parsed keys:")} ${Object.keys(parsed).join(", ")}`);
|
|
2066
|
+
ui.write(` ${import_picocolors8.default.dim("stdout (truncated):")}
|
|
2003
2067
|
${stdout.slice(0, 600)}`);
|
|
2004
2068
|
return null;
|
|
2005
2069
|
}
|
|
2006
2070
|
return parsed;
|
|
2007
2071
|
} catch (e) {
|
|
2008
|
-
ui.write(` ${
|
|
2072
|
+
ui.write(` ${import_picocolors8.default.yellow("\u26A0")} Failed to invoke configured agent (${agentCfg.command}): ${e.message}. Using defaults.`);
|
|
2009
2073
|
return null;
|
|
2010
2074
|
}
|
|
2011
2075
|
}
|
|
2012
2076
|
function slugify(title) {
|
|
2013
2077
|
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 60) || "untitled";
|
|
2014
2078
|
}
|
|
2015
|
-
var
|
|
2079
|
+
var import_picocolors8, add_default;
|
|
2016
2080
|
var init_add = __esm(() => {
|
|
2017
2081
|
init_dist();
|
|
2018
2082
|
init_out();
|
|
2019
2083
|
init_journal_config();
|
|
2020
2084
|
init_journal_validate();
|
|
2021
|
-
|
|
2085
|
+
import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
2022
2086
|
add_default = defineCommand({
|
|
2023
2087
|
meta: {
|
|
2024
2088
|
name: "add",
|
|
@@ -2031,7 +2095,7 @@ var init_add = __esm(() => {
|
|
|
2031
2095
|
required: false
|
|
2032
2096
|
},
|
|
2033
2097
|
pushback: {
|
|
2034
|
-
type: "
|
|
2098
|
+
type: "string",
|
|
2035
2099
|
alias: "b",
|
|
2036
2100
|
description: "Pushback intensity (1-10). Optional \u2014 defaults are applied (or supplied by --json / on-the-fly agent).",
|
|
2037
2101
|
required: false
|
|
@@ -2093,15 +2157,15 @@ var init_add = __esm(() => {
|
|
|
2093
2157
|
project = sanitizeProjectName(project);
|
|
2094
2158
|
}
|
|
2095
2159
|
if (!project) {
|
|
2096
|
-
ui.write(`${
|
|
2160
|
+
ui.write(`${import_picocolors8.default.yellow("\u26A0")} No project mapping found.
|
|
2097
2161
|
|
|
2098
|
-
` + `Run ${
|
|
2162
|
+
` + `Run ${import_picocolors8.default.dim("dora init")} (or ${import_picocolors8.default.dim("doraval journal init")}) first, or pass ${import_picocolors8.default.dim("--project <name>")}.`);
|
|
2099
2163
|
process.exit(1);
|
|
2100
2164
|
}
|
|
2101
2165
|
let title;
|
|
2102
2166
|
let pushback;
|
|
2103
2167
|
let tags = [];
|
|
2104
|
-
let author = args.author || "human";
|
|
2168
|
+
let author = String(args.author || "human");
|
|
2105
2169
|
let status = args.status || "active";
|
|
2106
2170
|
let rationale;
|
|
2107
2171
|
let date = new Date().toISOString().split("T")[0];
|
|
@@ -2133,7 +2197,7 @@ var init_add = __esm(() => {
|
|
|
2133
2197
|
if (parsed.date)
|
|
2134
2198
|
date = String(parsed.date);
|
|
2135
2199
|
} catch (e) {
|
|
2136
|
-
ui.write(`${
|
|
2200
|
+
ui.write(`${import_picocolors8.default.red("\u2717")} Failed to parse --json input: ${e.message}`);
|
|
2137
2201
|
process.exit(1);
|
|
2138
2202
|
}
|
|
2139
2203
|
}
|
|
@@ -2154,10 +2218,10 @@ var init_add = __esm(() => {
|
|
|
2154
2218
|
if (!title && rawBody) {
|
|
2155
2219
|
const headingMatch = rawBody.match(/^#+\s+(.+?)(?:\r?\n|$)/m);
|
|
2156
2220
|
if (headingMatch) {
|
|
2157
|
-
title = headingMatch[1].trim();
|
|
2221
|
+
title = (headingMatch[1] ?? "").trim();
|
|
2158
2222
|
rawBody = rawBody.replace(/^#+\s+(.+?)(?:\r?\n|$)/m, "").trimStart();
|
|
2159
2223
|
} else {
|
|
2160
|
-
ui.write(`${
|
|
2224
|
+
ui.write(`${import_picocolors8.default.red("\u2717")} --raw-markdown provided without a TITLE and without a leading '# Heading' in the markdown.`);
|
|
2161
2225
|
process.exit(1);
|
|
2162
2226
|
}
|
|
2163
2227
|
}
|
|
@@ -2197,7 +2261,7 @@ var init_add = __esm(() => {
|
|
|
2197
2261
|
agentCfg = fullConfigForAgent?.agent;
|
|
2198
2262
|
if (agentCfg) {
|
|
2199
2263
|
attemptedAgent = true;
|
|
2200
|
-
ui.write(` ${
|
|
2264
|
+
ui.write(` ${import_picocolors8.default.dim(import_picocolors8.default.gray("(querying your configured coding agent...)"))}`);
|
|
2201
2265
|
const agentResult = await invokeConfiguredAgentForEntry(title, agentCfg);
|
|
2202
2266
|
if (agentResult) {
|
|
2203
2267
|
if (agentResult.title)
|
|
@@ -2230,18 +2294,18 @@ var init_add = __esm(() => {
|
|
|
2230
2294
|
};
|
|
2231
2295
|
const validation = validateEntry(entry);
|
|
2232
2296
|
if (!validation.valid) {
|
|
2233
|
-
ui.write(`${
|
|
2297
|
+
ui.write(`${import_picocolors8.default.red("\u2717")} Invalid entry:
|
|
2234
2298
|
`);
|
|
2235
2299
|
for (const err of validation.errors) {
|
|
2236
|
-
ui.write(` ${
|
|
2300
|
+
ui.write(` ${import_picocolors8.default.red("\u2022")} ${err}`);
|
|
2237
2301
|
}
|
|
2238
2302
|
process.exit(1);
|
|
2239
2303
|
}
|
|
2240
2304
|
for (const warn of validation.warnings) {
|
|
2241
2305
|
if ((warn.includes("not supplied") || warn.includes("empty")) && attemptedAgent) {} else if (warn.includes("not supplied") || warn.includes("empty")) {
|
|
2242
|
-
ui.write(`${
|
|
2306
|
+
ui.write(`${import_picocolors8.default.dim("\xB7")} ${warn}`);
|
|
2243
2307
|
} else {
|
|
2244
|
-
ui.write(`${
|
|
2308
|
+
ui.write(`${import_picocolors8.default.yellow("\u26A0")} ${warn}`);
|
|
2245
2309
|
}
|
|
2246
2310
|
}
|
|
2247
2311
|
if (!rationale) {
|
|
@@ -2269,23 +2333,23 @@ ${rationale}
|
|
|
2269
2333
|
const filePath = join5(pendingDir, filename);
|
|
2270
2334
|
await Bun.write(filePath, content);
|
|
2271
2335
|
ui.write(`
|
|
2272
|
-
${
|
|
2273
|
-
ui.write(` Project: ${
|
|
2336
|
+
${import_picocolors8.default.green("\u2713")} ${import_picocolors8.default.bold(import_picocolors8.default.white(title))}`);
|
|
2337
|
+
ui.write(` Project: ${import_picocolors8.default.white(project)} \xB7 run ${import_picocolors8.default.dim(import_picocolors8.default.gray("dora journal sync"))} to publish
|
|
2274
2338
|
`);
|
|
2275
2339
|
if (args.verbose) {
|
|
2276
|
-
const authorDisplay = author.startsWith("agent:") ?
|
|
2277
|
-
ui.write(` Pushback: ${
|
|
2278
|
-
ui.write(` Tags: ${
|
|
2340
|
+
const authorDisplay = author.startsWith("agent:") ? import_picocolors8.default.cyan(author) : author;
|
|
2341
|
+
ui.write(` Pushback: ${import_picocolors8.default.white(String(pushback))}`);
|
|
2342
|
+
ui.write(` Tags: ${import_picocolors8.default.gray(tags.join(", ") || import_picocolors8.default.dim("(none)"))}`);
|
|
2279
2343
|
ui.write(` Author: ${authorDisplay}`);
|
|
2280
|
-
ui.write(` File: ${
|
|
2344
|
+
ui.write(` File: ${import_picocolors8.default.dim(import_picocolors8.default.gray(filePath))}
|
|
2281
2345
|
`);
|
|
2282
2346
|
}
|
|
2283
2347
|
if (isThinInput && !author.startsWith("agent:")) {
|
|
2284
2348
|
if (attemptedAgent) {
|
|
2285
|
-
ui.write(` ${
|
|
2349
|
+
ui.write(` ${import_picocolors8.default.dim(import_picocolors8.default.gray("Note: agent was called but returned no usable enrichment. Edit the pending file or re-run dora init."))}
|
|
2286
2350
|
`);
|
|
2287
2351
|
} else {
|
|
2288
|
-
ui.write(` ${
|
|
2352
|
+
ui.write(` ${import_picocolors8.default.dim(import_picocolors8.default.gray("Tip: run dora init to configure an agent for auto-enrichment."))}
|
|
2289
2353
|
`);
|
|
2290
2354
|
}
|
|
2291
2355
|
}
|
|
@@ -2329,18 +2393,18 @@ function updateGitHubFile(repo, path, content, message, sha) {
|
|
|
2329
2393
|
stderr: "pipe"
|
|
2330
2394
|
});
|
|
2331
2395
|
if (result.exitCode !== 0) {
|
|
2332
|
-
ui.write(
|
|
2396
|
+
ui.write(import_picocolors9.default.red(`Failed to update ${path} on ${repo}:`));
|
|
2333
2397
|
ui.write(result.stderr.toString());
|
|
2334
2398
|
process.exit(1);
|
|
2335
2399
|
}
|
|
2336
2400
|
}
|
|
2337
|
-
var
|
|
2401
|
+
var import_picocolors9, sync_default;
|
|
2338
2402
|
var init_sync = __esm(() => {
|
|
2339
2403
|
init_dist();
|
|
2340
2404
|
init_out();
|
|
2341
2405
|
init_journal_config();
|
|
2342
2406
|
init_journal_remote();
|
|
2343
|
-
|
|
2407
|
+
import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
2344
2408
|
sync_default = defineCommand({
|
|
2345
2409
|
meta: {
|
|
2346
2410
|
name: "sync",
|
|
@@ -2374,56 +2438,97 @@ var init_sync = __esm(() => {
|
|
|
2374
2438
|
project = sanitizeProjectName(project);
|
|
2375
2439
|
}
|
|
2376
2440
|
if (!project) {
|
|
2377
|
-
ui.write(`${
|
|
2441
|
+
ui.write(`${import_picocolors9.default.yellow("\u26A0")} No project mapping found.
|
|
2378
2442
|
|
|
2379
|
-
` + `Run ${
|
|
2443
|
+
` + `Run ${import_picocolors9.default.dim("dora init")} (or ${import_picocolors9.default.dim("doraval journal init")}) first, or pass ${import_picocolors9.default.dim("--project <name>")}.`);
|
|
2380
2444
|
process.exit(1);
|
|
2381
2445
|
}
|
|
2382
2446
|
if (!config?.journal.repo) {
|
|
2383
|
-
ui.write(`${
|
|
2447
|
+
ui.write(`${import_picocolors9.default.red("\u2717")} No journal repo configured. Run ${import_picocolors9.default.dim("dora init")} (or ${import_picocolors9.default.dim("doraval journal init")}) first.`);
|
|
2448
|
+
process.exit(1);
|
|
2449
|
+
}
|
|
2450
|
+
const ghCheck = ensureGhCli();
|
|
2451
|
+
if (!ghCheck.ok) {
|
|
2452
|
+
ui.write(` ${import_picocolors9.default.red("\u2717")} ${import_picocolors9.default.white("The GitHub CLI (")}${import_picocolors9.default.bold("gh")}${import_picocolors9.default.white(") is not installed.")}
|
|
2453
|
+
`);
|
|
2454
|
+
ui.write(` doraval uses ${import_picocolors9.default.bold("gh")} to fetch and sync journal files with GitHub.
|
|
2455
|
+
`);
|
|
2456
|
+
ui.write(` Install it:
|
|
2457
|
+
`);
|
|
2458
|
+
ui.write(` macOS: ${import_picocolors9.default.dim("brew install gh")}`);
|
|
2459
|
+
ui.write(` Linux: ${import_picocolors9.default.dim("https://github.com/cli/cli/blob/trunk/docs/install_linux.md")}`);
|
|
2460
|
+
ui.write(` Windows: ${import_picocolors9.default.dim("winget install --id GitHub.cli")}
|
|
2461
|
+
`);
|
|
2462
|
+
ui.write(` Then authenticate: ${import_picocolors9.default.dim("gh auth login")}
|
|
2463
|
+
`);
|
|
2384
2464
|
process.exit(1);
|
|
2385
2465
|
}
|
|
2386
|
-
ensureGhCliOrExit();
|
|
2387
2466
|
const journalRepo = config.journal.repo;
|
|
2388
2467
|
const pendingDir = getPendingProjectDir(project);
|
|
2389
2468
|
ui.write(`
|
|
2390
|
-
${
|
|
2469
|
+
${import_picocolors9.default.bold(import_picocolors9.default.white("dora journal sync"))} \u2014 ${import_picocolors9.default.white(project)}
|
|
2391
2470
|
`);
|
|
2392
|
-
ui.write(` Journal repo: ${
|
|
2471
|
+
ui.write(` Journal repo: ${import_picocolors9.default.dim(import_picocolors9.default.gray(journalRepo))}`);
|
|
2393
2472
|
ensureDoravalDirs();
|
|
2394
2473
|
const journalsDir = getJournalsDir();
|
|
2395
2474
|
const remoteProjectPath = `projects/${project}.md`;
|
|
2396
2475
|
const localProjectPath = join6(journalsDir, `${project}.md`);
|
|
2397
|
-
ui.write(` ${
|
|
2398
|
-
const
|
|
2476
|
+
ui.write(` ${import_picocolors9.default.dim(import_picocolors9.default.gray("Refreshing local cache from remote..."))}`);
|
|
2477
|
+
const refreshGlobalRes = await refreshLocalJournalFile(journalRepo, "global.md", join6(journalsDir, "global.md"));
|
|
2478
|
+
if (!refreshGlobalRes.ok) {
|
|
2479
|
+
if (!refreshGlobalRes.isNotFound) {
|
|
2480
|
+
ui.write(import_picocolors9.default.red(`Failed to fetch global.md from ${journalRepo}:`));
|
|
2481
|
+
ui.write(refreshGlobalRes.error);
|
|
2482
|
+
process.exit(1);
|
|
2483
|
+
}
|
|
2484
|
+
}
|
|
2485
|
+
const gotGlobal = refreshGlobalRes.ok && refreshGlobalRes.value;
|
|
2399
2486
|
if (gotGlobal) {
|
|
2400
|
-
ui.write(` ${
|
|
2487
|
+
ui.write(` ${import_picocolors9.default.dim(import_picocolors9.default.gray("\u2713 global.md"))}`);
|
|
2401
2488
|
}
|
|
2402
|
-
const
|
|
2489
|
+
const refreshProjectCacheRes = await refreshLocalJournalFile(journalRepo, remoteProjectPath, localProjectPath);
|
|
2490
|
+
if (!refreshProjectCacheRes.ok) {
|
|
2491
|
+
if (!refreshProjectCacheRes.isNotFound) {
|
|
2492
|
+
ui.write(import_picocolors9.default.red(`Failed to fetch ${remoteProjectPath} from ${journalRepo}:`));
|
|
2493
|
+
ui.write(refreshProjectCacheRes.error);
|
|
2494
|
+
process.exit(1);
|
|
2495
|
+
}
|
|
2496
|
+
}
|
|
2497
|
+
const gotProjectCache = refreshProjectCacheRes.ok && refreshProjectCacheRes.value;
|
|
2403
2498
|
if (gotProjectCache) {
|
|
2404
|
-
ui.write(` ${
|
|
2499
|
+
ui.write(` ${import_picocolors9.default.dim(import_picocolors9.default.gray(`\u2713 ${remoteProjectPath}`))}`);
|
|
2405
2500
|
}
|
|
2406
2501
|
const pendingFiles = existsSync7(pendingDir) ? readdirSync2(pendingDir).filter((f) => f.endsWith(".md") && f !== ".gitkeep").sort() : [];
|
|
2407
2502
|
if (pendingFiles.length === 0) {
|
|
2408
2503
|
ui.write(`
|
|
2409
|
-
${
|
|
2504
|
+
${import_picocolors9.default.yellow("\u26A0")} No pending entries. Local cache is now up to date.
|
|
2410
2505
|
`);
|
|
2411
2506
|
process.exit(0);
|
|
2412
2507
|
}
|
|
2413
2508
|
ui.write(` Found ${pendingFiles.length} pending entr${pendingFiles.length === 1 ? "y" : "ies"}
|
|
2414
2509
|
`);
|
|
2415
2510
|
const remotePath = `projects/${project}.md`;
|
|
2416
|
-
const
|
|
2511
|
+
const metaRes = getRemoteJournalFileMeta(journalRepo, remotePath);
|
|
2417
2512
|
let existingContent = "";
|
|
2418
2513
|
let currentSha;
|
|
2514
|
+
let currentFile = null;
|
|
2515
|
+
if (!metaRes.ok) {
|
|
2516
|
+
if (!metaRes.isNotFound) {
|
|
2517
|
+
ui.write(import_picocolors9.default.red(`Failed to fetch ${remotePath} from ${journalRepo}:`));
|
|
2518
|
+
ui.write(metaRes.error);
|
|
2519
|
+
process.exit(1);
|
|
2520
|
+
}
|
|
2521
|
+
} else {
|
|
2522
|
+
currentFile = metaRes.value;
|
|
2523
|
+
}
|
|
2419
2524
|
if (currentFile) {
|
|
2420
2525
|
existingContent = Buffer.from(currentFile.content, "base64").toString("utf8");
|
|
2421
2526
|
currentSha = currentFile.sha;
|
|
2422
2527
|
if (args.verbose)
|
|
2423
|
-
ui.write(` ${
|
|
2528
|
+
ui.write(` ${import_picocolors9.default.dim(import_picocolors9.default.gray("Found existing remote file (sha: " + (currentSha?.slice(0, 7) ?? "") + "...)"))}`);
|
|
2424
2529
|
} else {
|
|
2425
2530
|
if (args.verbose)
|
|
2426
|
-
ui.write(` ${
|
|
2531
|
+
ui.write(` ${import_picocolors9.default.dim(import_picocolors9.default.gray("No existing file on remote \u2014 will create it"))}`);
|
|
2427
2532
|
}
|
|
2428
2533
|
let newEntries = "";
|
|
2429
2534
|
for (const file of pendingFiles) {
|
|
@@ -2447,12 +2552,12 @@ var init_sync = __esm(() => {
|
|
|
2447
2552
|
const commitMessage = args.message || `journal: add ${pendingFiles.length} entr${pendingFiles.length === 1 ? "y" : "ies"} for ${project}`;
|
|
2448
2553
|
if (args.verbose)
|
|
2449
2554
|
ui.write(`
|
|
2450
|
-
${
|
|
2555
|
+
${import_picocolors9.default.dim(import_picocolors9.default.gray("Pushing to remote..."))}`);
|
|
2451
2556
|
try {
|
|
2452
2557
|
updateGitHubFile(journalRepo, remotePath, newContent, commitMessage, currentSha);
|
|
2453
|
-
ui.write(` ${
|
|
2558
|
+
ui.write(` ${import_picocolors9.default.green("\u2713")} ${import_picocolors9.default.white("Successfully pushed to")} ${import_picocolors9.default.white(remotePath)}`);
|
|
2454
2559
|
} catch (err) {
|
|
2455
|
-
ui.write(`${
|
|
2560
|
+
ui.write(`${import_picocolors9.default.red("\u2717")} ${import_picocolors9.default.white("Failed to push to GitHub.")}`);
|
|
2456
2561
|
process.exit(1);
|
|
2457
2562
|
}
|
|
2458
2563
|
for (const file of pendingFiles) {
|
|
@@ -2461,18 +2566,22 @@ var init_sync = __esm(() => {
|
|
|
2461
2566
|
await Bun.file(fullPath).unlink();
|
|
2462
2567
|
} catch {}
|
|
2463
2568
|
}
|
|
2464
|
-
ui.write(` ${
|
|
2569
|
+
ui.write(` ${import_picocolors9.default.green("\u2713")} ${import_picocolors9.default.white("Cleared local pending entries")}`);
|
|
2465
2570
|
try {
|
|
2466
|
-
const
|
|
2467
|
-
if (
|
|
2571
|
+
const refreshRes = await refreshLocalJournalFile(journalRepo, remotePath, localProjectPath);
|
|
2572
|
+
if (!refreshRes.ok) {
|
|
2573
|
+
if (!refreshRes.isNotFound) {
|
|
2574
|
+
ui.write(` ${import_picocolors9.default.yellow("\u26A0")} Could not re-fetch updated file (you can run sync again later)`);
|
|
2575
|
+
}
|
|
2576
|
+
} else if (refreshRes.value) {
|
|
2468
2577
|
if (args.verbose)
|
|
2469
|
-
ui.write(` ${
|
|
2578
|
+
ui.write(` ${import_picocolors9.default.green("\u2713")} ${import_picocolors9.default.white("Re-fetched")} ${import_picocolors9.default.white(project)}.md ${import_picocolors9.default.white("into local cache")}`);
|
|
2470
2579
|
}
|
|
2471
2580
|
} catch {
|
|
2472
|
-
ui.write(` ${
|
|
2581
|
+
ui.write(` ${import_picocolors9.default.yellow("\u26A0")} Could not re-fetch updated file (you can run sync again later)`);
|
|
2473
2582
|
}
|
|
2474
2583
|
ui.write(`
|
|
2475
|
-
${
|
|
2584
|
+
${import_picocolors9.default.green("Done!")} ${import_picocolors9.default.white(pendingFiles.length + " entr" + (pendingFiles.length === 1 ? "y" : "ies") + " published.")}
|
|
2476
2585
|
`);
|
|
2477
2586
|
process.exit(0);
|
|
2478
2587
|
}
|
|
@@ -3090,13 +3199,13 @@ __export(exports_validate_top, {
|
|
|
3090
3199
|
});
|
|
3091
3200
|
import { existsSync as existsSync17 } from "fs";
|
|
3092
3201
|
import { resolve as resolve11 } from "path";
|
|
3093
|
-
var
|
|
3202
|
+
var import_picocolors10, validate_top_default;
|
|
3094
3203
|
var init_validate_top = __esm(() => {
|
|
3095
3204
|
init_dist();
|
|
3096
3205
|
init_out();
|
|
3097
3206
|
init_validators();
|
|
3098
3207
|
init_remote();
|
|
3099
|
-
|
|
3208
|
+
import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
3100
3209
|
validate_top_default = defineCommand({
|
|
3101
3210
|
meta: {
|
|
3102
3211
|
name: "validate",
|
|
@@ -3136,7 +3245,7 @@ var init_validate_top = __esm(() => {
|
|
|
3136
3245
|
let cleanup;
|
|
3137
3246
|
if (remote) {
|
|
3138
3247
|
ui.info(`
|
|
3139
|
-
Cloning ${
|
|
3248
|
+
Cloning ${import_picocolors10.default.dim(args.path)}...`);
|
|
3140
3249
|
try {
|
|
3141
3250
|
const result = await cloneToTemp(remote);
|
|
3142
3251
|
fullPath = remote.subpath ? resolve11(result.dir, remote.subpath) : result.dir;
|
|
@@ -3184,13 +3293,13 @@ Check that the path is correct and the directory exists.`);
|
|
|
3184
3293
|
` + `Available providers:
|
|
3185
3294
|
` + providers.map((p) => {
|
|
3186
3295
|
const pvs = validators.filter((v) => v.provider === p);
|
|
3187
|
-
return ` ${
|
|
3188
|
-
` + pvs.map((v) => ` \u2022 ${
|
|
3296
|
+
return ` ${import_picocolors10.default.bold(p)}
|
|
3297
|
+
` + pvs.map((v) => ` \u2022 ${import_picocolors10.default.dim(v.id)} \u2014 ${v.description}`).join(`
|
|
3189
3298
|
`);
|
|
3190
3299
|
}).join(`
|
|
3191
3300
|
`) + `
|
|
3192
3301
|
|
|
3193
|
-
Use ${
|
|
3302
|
+
Use ${import_picocolors10.default.dim("--for <provider>")} or ${import_picocolors10.default.dim("--for <provider:type>")} to target explicitly.`);
|
|
3194
3303
|
process.exit(1);
|
|
3195
3304
|
}
|
|
3196
3305
|
const allResults = [];
|
|
@@ -3211,7 +3320,7 @@ Use ${import_picocolors11.default.dim("--for <provider>")} or ${import_picocolor
|
|
|
3211
3320
|
} else {
|
|
3212
3321
|
for (const { id, name, result } of allResults) {
|
|
3213
3322
|
ui.write(`
|
|
3214
|
-
${
|
|
3323
|
+
${import_picocolors10.default.bold("dora validate")} \u2014 ${import_picocolors10.default.white(name)} ${import_picocolors10.default.dim(`(${id})`)}
|
|
3215
3324
|
`);
|
|
3216
3325
|
ui.info(` Path: ${args.path}
|
|
3217
3326
|
`);
|
|
@@ -3226,7 +3335,7 @@ Use ${import_picocolors11.default.dim("--for <provider>")} or ${import_picocolor
|
|
|
3226
3335
|
}
|
|
3227
3336
|
if (result.errors.length === 0 && result.warnings.length === 0) {
|
|
3228
3337
|
ui.write(`
|
|
3229
|
-
${
|
|
3338
|
+
${import_picocolors10.default.green("\u2713")} ${import_picocolors10.default.white("All checks passed.")}
|
|
3230
3339
|
`);
|
|
3231
3340
|
} else {
|
|
3232
3341
|
ui.info(`
|
|
@@ -3250,14 +3359,14 @@ __export(exports_init2, {
|
|
|
3250
3359
|
});
|
|
3251
3360
|
import { basename as basename2, join as join12 } from "path";
|
|
3252
3361
|
var {spawnSync: spawnSync5 } = globalThis.Bun;
|
|
3253
|
-
var
|
|
3362
|
+
var import_picocolors11, init_default2;
|
|
3254
3363
|
var init_init2 = __esm(() => {
|
|
3255
3364
|
init_dist();
|
|
3256
3365
|
init_out();
|
|
3257
3366
|
init_journal_config();
|
|
3258
3367
|
init_journal_remote();
|
|
3259
3368
|
init_prompt();
|
|
3260
|
-
|
|
3369
|
+
import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
3261
3370
|
init_default2 = defineCommand({
|
|
3262
3371
|
meta: {
|
|
3263
3372
|
name: "init",
|
|
@@ -3282,7 +3391,22 @@ var init_init2 = __esm(() => {
|
|
|
3282
3391
|
},
|
|
3283
3392
|
async run({ args }) {
|
|
3284
3393
|
ui.heading("dora init \u2014 Set up doraval, your journal, and the coding agent dora should use on the fly");
|
|
3285
|
-
|
|
3394
|
+
const ghCheck = ensureGhCli();
|
|
3395
|
+
if (!ghCheck.ok) {
|
|
3396
|
+
ui.write(` ${import_picocolors11.default.red("\u2717")} ${import_picocolors11.default.white("The GitHub CLI (")}${import_picocolors11.default.bold("gh")}${import_picocolors11.default.white(") is not installed.")}
|
|
3397
|
+
`);
|
|
3398
|
+
ui.info(` doraval uses ${import_picocolors11.default.bold("gh")} to fetch and sync journal files with GitHub.
|
|
3399
|
+
`);
|
|
3400
|
+
ui.info(` Install it:
|
|
3401
|
+
`);
|
|
3402
|
+
ui.info(` macOS: ${import_picocolors11.default.dim("brew install gh")}`);
|
|
3403
|
+
ui.info(` Linux: ${import_picocolors11.default.dim("https://github.com/cli/cli/blob/trunk/docs/install_linux.md")}`);
|
|
3404
|
+
ui.info(` Windows: ${import_picocolors11.default.dim("winget install --id GitHub.cli")}
|
|
3405
|
+
`);
|
|
3406
|
+
ui.info(` Then authenticate: ${import_picocolors11.default.dim("gh auth login")}
|
|
3407
|
+
`);
|
|
3408
|
+
process.exit(1);
|
|
3409
|
+
}
|
|
3286
3410
|
let repo = args.repo || process.env.DORAVAL_JOURNAL_REPO;
|
|
3287
3411
|
if (!repo) {
|
|
3288
3412
|
const gitOwner = getGitRemoteOwner();
|
|
@@ -3292,28 +3416,28 @@ var init_init2 = __esm(() => {
|
|
|
3292
3416
|
if (gitOwner) {
|
|
3293
3417
|
defaultRepo = `${gitOwner}/${gitOwner}.md`;
|
|
3294
3418
|
if (ghLogin && ghLogin !== gitOwner) {
|
|
3295
|
-
sourceNote = ` ${
|
|
3419
|
+
sourceNote = ` ${import_picocolors11.default.dim("(from git remote; your active gh account is " + ghLogin + ")")}
|
|
3296
3420
|
`;
|
|
3297
3421
|
} else {
|
|
3298
|
-
sourceNote = ` ${
|
|
3422
|
+
sourceNote = ` ${import_picocolors11.default.dim("(from git remote)")}
|
|
3299
3423
|
`;
|
|
3300
3424
|
}
|
|
3301
3425
|
} else if (ghLogin) {
|
|
3302
3426
|
defaultRepo = `${ghLogin}/${ghLogin}.md`;
|
|
3303
|
-
sourceNote = ` ${
|
|
3427
|
+
sourceNote = ` ${import_picocolors11.default.dim("(from your active gh account)")}
|
|
3304
3428
|
`;
|
|
3305
3429
|
} else {
|
|
3306
|
-
ui.warn(`Not logged in to GitHub. Run ${
|
|
3430
|
+
ui.warn(`Not logged in to GitHub. Run ${import_picocolors11.default.dim("gh auth login")} first.
|
|
3307
3431
|
`);
|
|
3308
3432
|
process.exit(1);
|
|
3309
3433
|
}
|
|
3310
3434
|
const existingConfig = await readConfig();
|
|
3311
3435
|
if (existingConfig?.journal.repo) {
|
|
3312
3436
|
defaultRepo = existingConfig.journal.repo;
|
|
3313
|
-
sourceNote = ` ${
|
|
3437
|
+
sourceNote = ` ${import_picocolors11.default.dim("(from your previous journal setup)")}
|
|
3314
3438
|
`;
|
|
3315
3439
|
}
|
|
3316
|
-
ui.info(` Journal repo ${
|
|
3440
|
+
ui.info(` Journal repo ${import_picocolors11.default.dim("(owner/name)")}`);
|
|
3317
3441
|
if (sourceNote)
|
|
3318
3442
|
ui.write(sourceNote);
|
|
3319
3443
|
repo = prompt(" >", defaultRepo);
|
|
@@ -3325,11 +3449,11 @@ var init_init2 = __esm(() => {
|
|
|
3325
3449
|
}
|
|
3326
3450
|
project = sanitizeProjectName(project);
|
|
3327
3451
|
if (!repoExists(repo)) {
|
|
3328
|
-
ui.write(` ${
|
|
3452
|
+
ui.write(` ${import_picocolors11.default.red("\u2717")} ${import_picocolors11.default.white("Repository")} ${import_picocolors11.default.bold(repo)} ${import_picocolors11.default.white("not found on GitHub.")}
|
|
3329
3453
|
`);
|
|
3330
3454
|
ui.info(` Create it first:
|
|
3331
3455
|
`);
|
|
3332
|
-
ui.info(` ${
|
|
3456
|
+
ui.info(` ${import_picocolors11.default.dim(`gh repo create ${repo} --private --description "Personal journal for agent decisions"`)}
|
|
3333
3457
|
`);
|
|
3334
3458
|
process.exit(1);
|
|
3335
3459
|
}
|
|
@@ -3337,11 +3461,11 @@ var init_init2 = __esm(() => {
|
|
|
3337
3461
|
const alreadyRegistered = existing?.journal.projects[project];
|
|
3338
3462
|
const isRefresh = alreadyRegistered && args.refresh;
|
|
3339
3463
|
if (alreadyRegistered && !isRefresh) {
|
|
3340
|
-
ui.write(` ${
|
|
3464
|
+
ui.write(` ${import_picocolors11.default.yellow("\u26A0")} ${import_picocolors11.default.white("Project")} ${import_picocolors11.default.bold(project)} ${import_picocolors11.default.white("is already registered.")}
|
|
3341
3465
|
`);
|
|
3342
3466
|
ui.info(` Repo: ${existing.journal.repo}
|
|
3343
3467
|
`);
|
|
3344
|
-
ui.info(` To refresh journal files, use ${
|
|
3468
|
+
ui.info(` To refresh journal files, use ${import_picocolors11.default.dim("dora journal update")} (or ${import_picocolors11.default.dim("dora init --refresh")}).
|
|
3345
3469
|
`);
|
|
3346
3470
|
}
|
|
3347
3471
|
const journalsDir = getJournalsDir();
|
|
@@ -3357,24 +3481,48 @@ var init_init2 = __esm(() => {
|
|
|
3357
3481
|
local_path: localPath
|
|
3358
3482
|
};
|
|
3359
3483
|
ensureDoravalDirs();
|
|
3360
|
-
ui.write(` ${
|
|
3484
|
+
ui.write(` ${import_picocolors11.default.dim(import_picocolors11.default.gray("Fetching journal files from"))} ${import_picocolors11.default.gray(effectiveRepo)}${import_picocolors11.default.dim(import_picocolors11.default.gray("..."))}
|
|
3361
3485
|
`);
|
|
3362
3486
|
const globalDest = join12(journalsDir, "global.md");
|
|
3363
|
-
const
|
|
3487
|
+
const refreshGlobalRes = await refreshLocalJournalFile(effectiveRepo, "global.md", globalDest);
|
|
3488
|
+
let wroteGlobal;
|
|
3489
|
+
if (!refreshGlobalRes.ok) {
|
|
3490
|
+
if (refreshGlobalRes.isNotFound) {
|
|
3491
|
+
wroteGlobal = false;
|
|
3492
|
+
} else {
|
|
3493
|
+
ui.fail(`Failed to fetch global.md from ${effectiveRepo}:`);
|
|
3494
|
+
ui.info(refreshGlobalRes.error);
|
|
3495
|
+
process.exit(1);
|
|
3496
|
+
}
|
|
3497
|
+
} else {
|
|
3498
|
+
wroteGlobal = refreshGlobalRes.value;
|
|
3499
|
+
}
|
|
3364
3500
|
if (wroteGlobal) {
|
|
3365
3501
|
ui.success("global.md");
|
|
3366
3502
|
} else {
|
|
3367
|
-
ui.write(` ${
|
|
3503
|
+
ui.write(` ${import_picocolors11.default.dim("\xB7")} global.md ${import_picocolors11.default.dim("(not found \u2014 will be created on first sync)")}`);
|
|
3368
3504
|
await Bun.write(globalDest, `# Global Journal
|
|
3369
3505
|
|
|
3370
3506
|
Cross-project principles.
|
|
3371
3507
|
`);
|
|
3372
3508
|
}
|
|
3373
|
-
const
|
|
3509
|
+
const refreshProjectRes = await refreshLocalJournalFile(effectiveRepo, remotePath, localPath);
|
|
3510
|
+
let wroteProject;
|
|
3511
|
+
if (!refreshProjectRes.ok) {
|
|
3512
|
+
if (refreshProjectRes.isNotFound) {
|
|
3513
|
+
wroteProject = false;
|
|
3514
|
+
} else {
|
|
3515
|
+
ui.fail(`Failed to fetch ${remotePath} from ${effectiveRepo}:`);
|
|
3516
|
+
ui.info(refreshProjectRes.error);
|
|
3517
|
+
process.exit(1);
|
|
3518
|
+
}
|
|
3519
|
+
} else {
|
|
3520
|
+
wroteProject = refreshProjectRes.value;
|
|
3521
|
+
}
|
|
3374
3522
|
if (wroteProject) {
|
|
3375
3523
|
ui.success(remotePath);
|
|
3376
3524
|
} else {
|
|
3377
|
-
ui.write(` ${
|
|
3525
|
+
ui.write(` ${import_picocolors11.default.dim("\xB7")} ${remotePath} ${import_picocolors11.default.dim("(not found \u2014 will be created on first sync)")}`);
|
|
3378
3526
|
await Bun.write(localPath, `# ${project} Journal
|
|
3379
3527
|
|
|
3380
3528
|
Project-specific decisions.
|
|
@@ -3382,13 +3530,13 @@ Project-specific decisions.
|
|
|
3382
3530
|
}
|
|
3383
3531
|
await writeConfig(config);
|
|
3384
3532
|
ui.write(`
|
|
3385
|
-
${
|
|
3533
|
+
${import_picocolors11.default.green("\u2713")} ${import_picocolors11.default.white("Journal ready for project")} ${import_picocolors11.default.bold(import_picocolors11.default.white(project))}.
|
|
3386
3534
|
`);
|
|
3387
3535
|
const existingAgent = (await readConfig())?.agent;
|
|
3388
3536
|
if (existingAgent?.command) {
|
|
3389
|
-
ui.write(` ${
|
|
3537
|
+
ui.write(` ${import_picocolors11.default.bold(import_picocolors11.default.white("Coding agent (already configured)"))}
|
|
3390
3538
|
`);
|
|
3391
|
-
ui.write(` Current: ${
|
|
3539
|
+
ui.write(` Current: ${import_picocolors11.default.dim(import_picocolors11.default.gray(existingAgent.command))} template: ${import_picocolors11.default.dim(import_picocolors11.default.gray(existingAgent.prompt_template || "(default)"))}
|
|
3392
3540
|
`);
|
|
3393
3541
|
const change = prompt(" Reconfigure / change the coding agent for on-the-fly enrichment? (y/N)", "n");
|
|
3394
3542
|
if (!/^y/i.test(String(change))) {
|
|
@@ -3398,16 +3546,16 @@ Project-specific decisions.
|
|
|
3398
3546
|
if (existingAgent)
|
|
3399
3547
|
cfg.agent = existingAgent;
|
|
3400
3548
|
await writeConfig(cfg);
|
|
3401
|
-
ui.write(` ${
|
|
3549
|
+
ui.write(` ${import_picocolors11.default.green("\u2713")} ${import_picocolors11.default.white("Try:")} ${import_picocolors11.default.dim(import_picocolors11.default.gray('dora journal add "short decision"'))}
|
|
3402
3550
|
`);
|
|
3403
3551
|
process.exit(0);
|
|
3404
3552
|
return;
|
|
3405
3553
|
}
|
|
3406
3554
|
ui.blank();
|
|
3407
3555
|
} else {
|
|
3408
|
-
ui.write(` ${
|
|
3556
|
+
ui.write(` ${import_picocolors11.default.bold(import_picocolors11.default.white("Coding agent for journal add"))}
|
|
3409
3557
|
`);
|
|
3410
|
-
ui.info(` When configured, ${
|
|
3558
|
+
ui.info(` When configured, ${import_picocolors11.default.dim(import_picocolors11.default.gray('dora journal add ".."'))} will use your agent to enrich entries with tags and rationale automatically.
|
|
3411
3559
|
`);
|
|
3412
3560
|
}
|
|
3413
3561
|
const common = [
|
|
@@ -3426,7 +3574,7 @@ Project-specific decisions.
|
|
|
3426
3574
|
}
|
|
3427
3575
|
}
|
|
3428
3576
|
let agentCmd = detected || "claude";
|
|
3429
|
-
ui.write(` Detected / default agent command: ${
|
|
3577
|
+
ui.write(` Detected / default agent command: ${import_picocolors11.default.dim(import_picocolors11.default.gray(agentCmd))}`);
|
|
3430
3578
|
agentCmd = prompt(" Agent command (the binary you run for prompts)", agentCmd);
|
|
3431
3579
|
let template = detected ? common.find((c) => c.name === detected)?.template || '-p "{{prompt}}" --output-format json' : '-p "{{prompt}}" --output-format json';
|
|
3432
3580
|
ui.info(` Prompt template (use {{prompt}} placeholder):`);
|
|
@@ -3438,11 +3586,11 @@ Project-specific decisions.
|
|
|
3438
3586
|
};
|
|
3439
3587
|
await writeConfig(finalConfig);
|
|
3440
3588
|
ui.write(`
|
|
3441
|
-
${
|
|
3589
|
+
${import_picocolors11.default.green("\u2713")} ${import_picocolors11.default.white("Agent configured.")}
|
|
3442
3590
|
`);
|
|
3443
|
-
ui.info(` Re-run ${
|
|
3591
|
+
ui.info(` Re-run ${import_picocolors11.default.dim(import_picocolors11.default.gray("dora init"))} anytime to change it.
|
|
3444
3592
|
`);
|
|
3445
|
-
ui.info(` Next: ${
|
|
3593
|
+
ui.info(` Next: ${import_picocolors11.default.dim(import_picocolors11.default.gray('dora journal add ".."'))}, ${import_picocolors11.default.dim(import_picocolors11.default.gray("dora journal list"))}, or ${import_picocolors11.default.dim(import_picocolors11.default.gray("dora journal update"))}.
|
|
3446
3594
|
`);
|
|
3447
3595
|
process.exit(0);
|
|
3448
3596
|
}
|
|
@@ -3454,7 +3602,7 @@ init_dist();
|
|
|
3454
3602
|
// package.json
|
|
3455
3603
|
var package_default = {
|
|
3456
3604
|
name: "@hacksmith/doraval",
|
|
3457
|
-
version: "0.2.
|
|
3605
|
+
version: "0.2.19",
|
|
3458
3606
|
author: "Saif",
|
|
3459
3607
|
repository: {
|
|
3460
3608
|
type: "git",
|
|
@@ -3498,6 +3646,7 @@ var package_default = {
|
|
|
3498
3646
|
build: "bun build ./src/cli/index.ts --outfile ./bin/doraval.js --target bun",
|
|
3499
3647
|
dev: "bun run ./src/cli/index.ts",
|
|
3500
3648
|
test: "bun test",
|
|
3649
|
+
typecheck: "bunx tsc --noEmit --skipLibCheck",
|
|
3501
3650
|
prepublishOnly: `bun run build && node -e "const p=require('./package.json'),j=require('./jsr.json');if(p.version!==j.version){console.error('Version mismatch: package.json='+p.version+' jsr.json='+j.version);process.exit(1)}"`,
|
|
3502
3651
|
bump: "bun run scripts/bump.ts",
|
|
3503
3652
|
release: "bun run scripts/release.ts",
|
|
@@ -3514,7 +3663,7 @@ var package_default = {
|
|
|
3514
3663
|
};
|
|
3515
3664
|
|
|
3516
3665
|
// src/cli/index.ts
|
|
3517
|
-
var
|
|
3666
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
3518
3667
|
var skill = defineCommand({
|
|
3519
3668
|
meta: {
|
|
3520
3669
|
name: "skill",
|
|
@@ -3571,7 +3720,7 @@ var main = defineCommand({
|
|
|
3571
3720
|
},
|
|
3572
3721
|
run() {
|
|
3573
3722
|
console.log(`
|
|
3574
|
-
` +
|
|
3723
|
+
` + import_picocolors12.default.blue(doraemonArt) + `
|
|
3575
3724
|
`);
|
|
3576
3725
|
showUsage(main);
|
|
3577
3726
|
}
|