agendex-cli 0.8.2 → 0.8.4
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/cli.js +108 -71
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __getProtoOf = Object.getPrototypeOf;
|
|
5
4
|
var __defProp = Object.defineProperty;
|
|
@@ -45,7 +44,6 @@ var __export = (target, all) => {
|
|
|
45
44
|
});
|
|
46
45
|
};
|
|
47
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
48
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
49
47
|
|
|
50
48
|
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
51
49
|
var require_picocolors = __commonJS((exports, module) => {
|
|
@@ -1478,66 +1476,101 @@ var continueIdeAdapter = {
|
|
|
1478
1476
|
};
|
|
1479
1477
|
|
|
1480
1478
|
// ../shared/src/adapters/cursor.ts
|
|
1481
|
-
import { existsSync } from "node:fs";
|
|
1482
|
-
import { stat as stat4 } from "node:fs/promises";
|
|
1479
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
1480
|
+
import { readFile as readFile4, stat as stat4 } from "node:fs/promises";
|
|
1483
1481
|
import { homedir as homedir4 } from "node:os";
|
|
1484
|
-
import { join as join4 } from "node:path";
|
|
1485
|
-
|
|
1486
|
-
|
|
1482
|
+
import { basename as basename3, join as join4 } from "node:path";
|
|
1483
|
+
var cursorProjectsDir = join4(homedir4(), ".cursor", "projects");
|
|
1484
|
+
function discoverCursorPlanDirs() {
|
|
1485
|
+
if (!existsSync(cursorProjectsDir))
|
|
1486
|
+
return [];
|
|
1487
|
+
const dirs = [];
|
|
1488
|
+
let entries;
|
|
1489
|
+
try {
|
|
1490
|
+
entries = readdirSync(cursorProjectsDir);
|
|
1491
|
+
} catch {
|
|
1492
|
+
return [];
|
|
1493
|
+
}
|
|
1494
|
+
for (const entry of entries) {
|
|
1495
|
+
const trustedFile = join4(cursorProjectsDir, entry, ".workspace-trusted");
|
|
1496
|
+
if (!existsSync(trustedFile))
|
|
1497
|
+
continue;
|
|
1498
|
+
try {
|
|
1499
|
+
const raw = JSON.parse(readFileSync(trustedFile, "utf-8"));
|
|
1500
|
+
if (!raw.workspacePath)
|
|
1501
|
+
continue;
|
|
1502
|
+
const plansDir2 = join4(raw.workspacePath, ".cursor", "plans");
|
|
1503
|
+
if (existsSync(plansDir2)) {
|
|
1504
|
+
dirs.push(plansDir2);
|
|
1505
|
+
}
|
|
1506
|
+
} catch {}
|
|
1507
|
+
}
|
|
1508
|
+
return dirs;
|
|
1509
|
+
}
|
|
1510
|
+
function extractTitle3(content, filename) {
|
|
1511
|
+
const match = content.match(/^#\s+(.+)/m);
|
|
1512
|
+
if (match?.[1])
|
|
1513
|
+
return match[1].replace(/^Plan:\s*/i, "").trim();
|
|
1514
|
+
return basename3(filename, ".plan.md").split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
1515
|
+
}
|
|
1516
|
+
function stripFrontmatter(raw) {
|
|
1517
|
+
const text = raw.replace(/^<!--\s*[\w-]+\s*-->\s*\n?/, "");
|
|
1518
|
+
const fmMatch = text.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
1519
|
+
if (!fmMatch)
|
|
1520
|
+
return { body: text.trim(), metadata: {} };
|
|
1521
|
+
const metadata = {};
|
|
1522
|
+
const fmBody = fmMatch[1] ?? "";
|
|
1523
|
+
const todoIdMatches = fmBody.match(/^\s+-\s+id:\s/gm);
|
|
1524
|
+
if (todoIdMatches) {
|
|
1525
|
+
metadata.todoCount = todoIdMatches.length;
|
|
1526
|
+
}
|
|
1527
|
+
const projectMatch = fmBody.match(/^isProject:\s*(.+)$/m);
|
|
1528
|
+
if (projectMatch?.[1]) {
|
|
1529
|
+
metadata.isProject = projectMatch[1].trim() === "true";
|
|
1530
|
+
}
|
|
1531
|
+
const body = text.slice(fmMatch[0].length).trim();
|
|
1532
|
+
return { body, metadata };
|
|
1533
|
+
}
|
|
1534
|
+
function workspaceFromPlanPath(filePath) {
|
|
1535
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
1536
|
+
const idx = normalized.indexOf("/.cursor/plans/");
|
|
1537
|
+
if (idx === -1)
|
|
1538
|
+
return;
|
|
1539
|
+
return filePath.slice(0, idx);
|
|
1487
1540
|
}
|
|
1488
1541
|
var cursorAdapter = {
|
|
1489
1542
|
agent: "cursor",
|
|
1490
1543
|
writable: false,
|
|
1491
1544
|
getSearchPaths() {
|
|
1492
|
-
return
|
|
1545
|
+
return discoverCursorPlanDirs();
|
|
1493
1546
|
},
|
|
1494
1547
|
getWatchPaths() {
|
|
1495
|
-
return
|
|
1548
|
+
return discoverCursorPlanDirs();
|
|
1496
1549
|
},
|
|
1497
1550
|
matches(filePath) {
|
|
1498
|
-
return filePath.endsWith(".
|
|
1551
|
+
return filePath.endsWith(".plan.md");
|
|
1499
1552
|
},
|
|
1500
1553
|
async parse(filePath) {
|
|
1501
|
-
if (!existsSync(filePath))
|
|
1502
|
-
return [];
|
|
1503
|
-
let db = null;
|
|
1504
1554
|
try {
|
|
1505
|
-
const
|
|
1506
|
-
db = new SqliteDatabase(filePath, { fileMustExist: true, readonly: true });
|
|
1507
|
-
const tables = db.prepare("SELECT name FROM sqlite_master WHERE type = 'table'").all();
|
|
1508
|
-
const plans = [];
|
|
1555
|
+
const raw = await readFile4(filePath, "utf-8");
|
|
1509
1556
|
const stats = await stat4(filePath);
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
agent: "cursor",
|
|
1526
|
-
title: `Cursor: ${table.name}`,
|
|
1527
|
-
content,
|
|
1528
|
-
filePath,
|
|
1529
|
-
format: "sqlite",
|
|
1530
|
-
createdAt: stats.birthtime,
|
|
1531
|
-
updatedAt: stats.mtime,
|
|
1532
|
-
metadata: { table: table.name }
|
|
1533
|
-
});
|
|
1534
|
-
} catch {}
|
|
1535
|
-
}
|
|
1536
|
-
return plans;
|
|
1557
|
+
const { body, metadata } = stripFrontmatter(raw);
|
|
1558
|
+
return [
|
|
1559
|
+
{
|
|
1560
|
+
id: hashPath(filePath),
|
|
1561
|
+
agent: "cursor",
|
|
1562
|
+
title: extractTitle3(body, filePath),
|
|
1563
|
+
content: body,
|
|
1564
|
+
filePath,
|
|
1565
|
+
format: "md",
|
|
1566
|
+
createdAt: stats.birthtime,
|
|
1567
|
+
updatedAt: stats.mtime,
|
|
1568
|
+
workspace: workspaceFromPlanPath(filePath),
|
|
1569
|
+
metadata
|
|
1570
|
+
}
|
|
1571
|
+
];
|
|
1537
1572
|
} catch {
|
|
1538
1573
|
return [];
|
|
1539
|
-
} finally {
|
|
1540
|
-
db?.close();
|
|
1541
1574
|
}
|
|
1542
1575
|
},
|
|
1543
1576
|
async write() {
|
|
@@ -1546,10 +1579,10 @@ var cursorAdapter = {
|
|
|
1546
1579
|
};
|
|
1547
1580
|
|
|
1548
1581
|
// ../shared/src/adapters/oh-my-opencode.ts
|
|
1549
|
-
import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
|
|
1550
|
-
import { readdir, readFile as
|
|
1582
|
+
import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
1583
|
+
import { readdir, readFile as readFile5, stat as stat5, writeFile as writeFile2 } from "node:fs/promises";
|
|
1551
1584
|
import { homedir as homedir5 } from "node:os";
|
|
1552
|
-
import { basename as
|
|
1585
|
+
import { basename as basename4, join as join5 } from "node:path";
|
|
1553
1586
|
var dataHome = process.env.XDG_DATA_HOME || join5(homedir5(), ".local", "share");
|
|
1554
1587
|
var opencodeSessionDir = join5(dataHome, "opencode", "storage", "session");
|
|
1555
1588
|
var cwdPlansDir = join5(process.cwd(), ".sisyphus", "plans");
|
|
@@ -1569,13 +1602,13 @@ function isSessionFile(filePath) {
|
|
|
1569
1602
|
const root = normalizePath(opencodeSessionDir);
|
|
1570
1603
|
return normalized.startsWith(`${root}/`) && normalized.endsWith(".json");
|
|
1571
1604
|
}
|
|
1572
|
-
function
|
|
1605
|
+
function extractTitle4(content, filePath) {
|
|
1573
1606
|
const heading = content.match(/^\s{0,3}#{1,6}\s+(.+?)\s*$/m)?.[1];
|
|
1574
1607
|
if (heading)
|
|
1575
1608
|
return heading.replace(/^Plan:\s*/i, "").trim();
|
|
1576
|
-
return
|
|
1609
|
+
return basename4(filePath, ".md").split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
1577
1610
|
}
|
|
1578
|
-
function
|
|
1611
|
+
function workspaceFromPlanPath2(filePath) {
|
|
1579
1612
|
const normalized = normalizePath(filePath);
|
|
1580
1613
|
const lower = normalized.toLowerCase();
|
|
1581
1614
|
const markerIndex = lower.lastIndexOf(PLAN_PATH_MARKER);
|
|
@@ -1602,14 +1635,14 @@ function discoverPlanDirectories() {
|
|
|
1602
1635
|
if (!existsSync2(opencodeSessionDir))
|
|
1603
1636
|
return Array.from(dirs);
|
|
1604
1637
|
try {
|
|
1605
|
-
const projectDirs =
|
|
1638
|
+
const projectDirs = readdirSync2(opencodeSessionDir, { withFileTypes: true });
|
|
1606
1639
|
for (const projectDir of projectDirs) {
|
|
1607
1640
|
if (!projectDir.isDirectory())
|
|
1608
1641
|
continue;
|
|
1609
1642
|
const projectPath = join5(opencodeSessionDir, projectDir.name);
|
|
1610
1643
|
let sessionFiles = [];
|
|
1611
1644
|
try {
|
|
1612
|
-
sessionFiles =
|
|
1645
|
+
sessionFiles = readdirSync2(projectPath);
|
|
1613
1646
|
} catch {
|
|
1614
1647
|
continue;
|
|
1615
1648
|
}
|
|
@@ -1617,7 +1650,7 @@ function discoverPlanDirectories() {
|
|
|
1617
1650
|
if (!file.endsWith(".json"))
|
|
1618
1651
|
continue;
|
|
1619
1652
|
try {
|
|
1620
|
-
const raw =
|
|
1653
|
+
const raw = readFileSync2(join5(projectPath, file), "utf-8");
|
|
1621
1654
|
const session = parseSessionMeta(raw);
|
|
1622
1655
|
if (!session?.directory)
|
|
1623
1656
|
continue;
|
|
@@ -1632,13 +1665,13 @@ function discoverPlanDirectories() {
|
|
|
1632
1665
|
}
|
|
1633
1666
|
async function parsePlanFile(filePath, workspace, metadata = {}) {
|
|
1634
1667
|
try {
|
|
1635
|
-
const content = await
|
|
1668
|
+
const content = await readFile5(filePath, "utf-8");
|
|
1636
1669
|
const stats = await stat5(filePath);
|
|
1637
1670
|
return [
|
|
1638
1671
|
{
|
|
1639
1672
|
id: hashPath(filePath),
|
|
1640
1673
|
agent: "oh-my-opencode",
|
|
1641
|
-
title:
|
|
1674
|
+
title: extractTitle4(content, filePath),
|
|
1642
1675
|
content,
|
|
1643
1676
|
filePath,
|
|
1644
1677
|
format: "md",
|
|
@@ -1654,7 +1687,7 @@ async function parsePlanFile(filePath, workspace, metadata = {}) {
|
|
|
1654
1687
|
}
|
|
1655
1688
|
async function parseSessionFile(filePath) {
|
|
1656
1689
|
try {
|
|
1657
|
-
const raw = await
|
|
1690
|
+
const raw = await readFile5(filePath, "utf-8");
|
|
1658
1691
|
const session = parseSessionMeta(raw);
|
|
1659
1692
|
if (!session?.directory)
|
|
1660
1693
|
return [];
|
|
@@ -1694,7 +1727,7 @@ var ohMyOpencodeAdapter = {
|
|
|
1694
1727
|
},
|
|
1695
1728
|
async parse(filePath) {
|
|
1696
1729
|
if (isPlanMarkdown(filePath)) {
|
|
1697
|
-
return parsePlanFile(filePath,
|
|
1730
|
+
return parsePlanFile(filePath, workspaceFromPlanPath2(filePath), {
|
|
1698
1731
|
source: "plan-file"
|
|
1699
1732
|
});
|
|
1700
1733
|
}
|
|
@@ -2163,7 +2196,7 @@ function getActiveAdapters() {
|
|
|
2163
2196
|
var activeAdapters = resolveAdapters(getDefaultAdapterIds());
|
|
2164
2197
|
// ../shared/src/config.ts
|
|
2165
2198
|
import { randomBytes } from "node:crypto";
|
|
2166
|
-
import { existsSync as existsSync3, mkdirSync, readFileSync as
|
|
2199
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "node:fs";
|
|
2167
2200
|
import { homedir as homedir7 } from "node:os";
|
|
2168
2201
|
import { join as join7 } from "node:path";
|
|
2169
2202
|
|
|
@@ -2230,7 +2263,7 @@ function readStoredConfig() {
|
|
|
2230
2263
|
if (!existsSync3(configPath))
|
|
2231
2264
|
return null;
|
|
2232
2265
|
try {
|
|
2233
|
-
const raw = JSON.parse(
|
|
2266
|
+
const raw = JSON.parse(readFileSync3(configPath, "utf-8"));
|
|
2234
2267
|
if (!raw || typeof raw !== "object")
|
|
2235
2268
|
return null;
|
|
2236
2269
|
return raw;
|
|
@@ -2352,8 +2385,8 @@ async function loadOrInitConfig(options = {}) {
|
|
|
2352
2385
|
var CLI_DAEMON_HEARTBEAT_INTERVAL_MS = 30000;
|
|
2353
2386
|
var CLI_DAEMON_STALE_AFTER_MS = CLI_DAEMON_HEARTBEAT_INTERVAL_MS * 3;
|
|
2354
2387
|
// ../shared/src/services/plan-service.ts
|
|
2355
|
-
import { existsSync as existsSync4, readdirSync as
|
|
2356
|
-
import { lstat, mkdir, readdir as readdir2, readFile as
|
|
2388
|
+
import { existsSync as existsSync4, readdirSync as readdirSync3, statSync } from "node:fs";
|
|
2389
|
+
import { lstat, mkdir, readdir as readdir2, readFile as readFile6, stat as stat6, writeFile as writeFile3 } from "node:fs/promises";
|
|
2357
2390
|
import { homedir as homedir8 } from "node:os";
|
|
2358
2391
|
import { join as join8, resolve as resolve2, sep as sep2 } from "node:path";
|
|
2359
2392
|
var USER_PLANS_DIR = join8(homedir8(), ".agendex", "plans");
|
|
@@ -2408,7 +2441,7 @@ function discoverProjectPlanDirs() {
|
|
|
2408
2441
|
}
|
|
2409
2442
|
let names;
|
|
2410
2443
|
try {
|
|
2411
|
-
names =
|
|
2444
|
+
names = readdirSync3(dir);
|
|
2412
2445
|
} catch {
|
|
2413
2446
|
return;
|
|
2414
2447
|
}
|
|
@@ -2470,7 +2503,7 @@ async function scanUserPlans() {
|
|
|
2470
2503
|
if (!file.endsWith(".md"))
|
|
2471
2504
|
continue;
|
|
2472
2505
|
try {
|
|
2473
|
-
const content = await
|
|
2506
|
+
const content = await readFile6(file, "utf-8");
|
|
2474
2507
|
const stats = await stat6(file);
|
|
2475
2508
|
let agent = "unknown";
|
|
2476
2509
|
const fmMatch = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n/);
|
|
@@ -2620,7 +2653,7 @@ import { request as httpsRequest } from "node:https";
|
|
|
2620
2653
|
import { hostname as osHostname } from "node:os";
|
|
2621
2654
|
|
|
2622
2655
|
// src/pid.ts
|
|
2623
|
-
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as
|
|
2656
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2624
2657
|
import { homedir as homedir9, hostname } from "node:os";
|
|
2625
2658
|
import { dirname, join as join10 } from "node:path";
|
|
2626
2659
|
var pidPath = join10(homedir9(), ".agendex", "daemon.pid");
|
|
@@ -2636,7 +2669,7 @@ function writePid() {
|
|
|
2636
2669
|
function readPidInfo() {
|
|
2637
2670
|
if (!existsSync6(pidPath))
|
|
2638
2671
|
return null;
|
|
2639
|
-
const raw =
|
|
2672
|
+
const raw = readFileSync4(pidPath, "utf-8").trim();
|
|
2640
2673
|
const asNumber = Number(raw);
|
|
2641
2674
|
if (Number.isFinite(asNumber) && asNumber > 0 && !raw.startsWith("{")) {
|
|
2642
2675
|
return { pid: asNumber };
|
|
@@ -2778,10 +2811,14 @@ async function refreshToken(currentToken, convexUrl) {
|
|
|
2778
2811
|
function requestText(urlString, options) {
|
|
2779
2812
|
const url = new URL(urlString);
|
|
2780
2813
|
const request = url.protocol === "https:" ? httpsRequest : httpRequest;
|
|
2814
|
+
const headers = { ...options.headers };
|
|
2815
|
+
if (options.body) {
|
|
2816
|
+
headers["Content-Length"] = String(Buffer.byteLength(options.body));
|
|
2817
|
+
}
|
|
2781
2818
|
return new Promise((resolve4, reject) => {
|
|
2782
2819
|
const req = request(url, {
|
|
2783
2820
|
agent: false,
|
|
2784
|
-
headers
|
|
2821
|
+
headers,
|
|
2785
2822
|
method: options.method
|
|
2786
2823
|
}, (res) => {
|
|
2787
2824
|
let body = "";
|
|
@@ -3245,13 +3282,13 @@ async function syncAll() {
|
|
|
3245
3282
|
}
|
|
3246
3283
|
|
|
3247
3284
|
// src/version.ts
|
|
3248
|
-
import { existsSync as existsSync7, readFileSync as
|
|
3285
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
3249
3286
|
import { tmpdir } from "node:os";
|
|
3250
3287
|
import { join as join11 } from "node:path";
|
|
3251
3288
|
// package.json
|
|
3252
3289
|
var package_default = {
|
|
3253
3290
|
name: "agendex-cli",
|
|
3254
|
-
version: "0.8.
|
|
3291
|
+
version: "0.8.4",
|
|
3255
3292
|
description: "Agendex CLI for login, sync, and daemon workflows",
|
|
3256
3293
|
homepage: "https://github.com/Tyru5/Agendex#readme",
|
|
3257
3294
|
repository: {
|
|
@@ -3302,7 +3339,7 @@ function readCache(current) {
|
|
|
3302
3339
|
try {
|
|
3303
3340
|
if (!existsSync7(CACHE_FILE))
|
|
3304
3341
|
return null;
|
|
3305
|
-
const { result, ts } = JSON.parse(
|
|
3342
|
+
const { result, ts } = JSON.parse(readFileSync5(CACHE_FILE, "utf8"));
|
|
3306
3343
|
if (Date.now() - ts > CACHE_TTL_MS)
|
|
3307
3344
|
return null;
|
|
3308
3345
|
return normalizeResult(result, current);
|