hypercore-cli 1.1.2 → 1.4.0
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/LICENSE +92 -21
- package/README.md +8 -1
- package/dist/App-YMX7FSXR.js +1 -0
- package/dist/api-ELP6F4NC.js +1 -0
- package/dist/auth-SICBMA3P.js +1 -0
- package/dist/auth-X6CUT3DW.js +1 -0
- package/dist/background-ACODXSUG.js +1 -0
- package/dist/backlog-JD2IM336.js +1 -0
- package/dist/chunk-2QI2IU2V.js +1 -0
- package/dist/chunk-3KFRDIPQ.js +1 -0
- package/dist/chunk-42C5J7PN.js +1 -0
- package/dist/chunk-4D7XVJ7Q.js +1 -0
- package/dist/chunk-5KUSGQP2.js +1 -0
- package/dist/chunk-5OEFAGD5.js +1 -0
- package/dist/chunk-AUQ64BK2.js +1 -0
- package/dist/chunk-AV244H5C.js +1 -0
- package/dist/chunk-BQVBEFS4.js +1 -0
- package/dist/chunk-BYWQLFP2.js +1 -0
- package/dist/chunk-C6YL7UHE.js +1 -0
- package/dist/chunk-COITWWZJ.js +1 -0
- package/dist/chunk-CR7UUJVX.js +1 -0
- package/dist/chunk-E3MULLBX.js +1 -0
- package/dist/chunk-EZHYVJGQ.js +1 -0
- package/dist/chunk-FAMURNNH.js +1 -0
- package/dist/chunk-FGP56E4W.js +1 -0
- package/dist/chunk-FHGATV5B.js +1 -0
- package/dist/chunk-I2G27Y5P.js +1 -0
- package/dist/chunk-IKF43TX2.js +1 -0
- package/dist/chunk-INSPHCBN.js +1 -0
- package/dist/chunk-JHMV366T.js +1 -0
- package/dist/chunk-L52HX5SX.js +1 -0
- package/dist/chunk-LQMDUKIE.js +1 -0
- package/dist/chunk-M3MTKGA5.js +1 -0
- package/dist/chunk-MPO54FU3.js +1 -0
- package/dist/chunk-PVKCZI6A.js +1 -0
- package/dist/chunk-Q7KEPCYL.js +1 -0
- package/dist/chunk-ROBZ6PAL.js +1 -0
- package/dist/chunk-RXB5BS2N.js +1 -0
- package/dist/chunk-RZ3HNYMT.js +1 -0
- package/dist/chunk-UCGLRMTG.js +1 -0
- package/dist/chunk-UEHJVRKB.js +1 -0
- package/dist/chunk-UZYX5GGF.js +1 -0
- package/dist/chunk-XQJBB725.js +1 -0
- package/dist/chunk-YXCRL6K3.js +1 -0
- package/dist/claude-US2QPRBA.js +1 -0
- package/dist/commands-EKPWCB3T.js +1 -0
- package/dist/commands-GYNKP5WV.js +1 -0
- package/dist/commands-QHJLREPM.js +1 -0
- package/dist/config-2OUL5FLS.js +1 -0
- package/dist/config-loader-N7IBWN2P.js +1 -0
- package/dist/diagnose-NLHN4SAJ.js +1 -0
- package/dist/display-RYAW2GFB.js +1 -0
- package/dist/extractor-3KTM2IUL.js +1 -0
- package/dist/feature-flag-VVIF5FJG.js +1 -0
- package/dist/history-3R2UHRDQ.js +1 -0
- package/dist/index.js +1 -402
- package/dist/instance-registry-I5AIVJE2.js +1 -0
- package/dist/keybindings-RN3A7CRW.js +1 -0
- package/dist/loader-3IKPXP4R.js +1 -0
- package/dist/network-K5HRJE44.js +1 -0
- package/dist/notify-O6FNVHC4.js +1 -0
- package/dist/openai-compat-IPCMINVF.js +1 -0
- package/dist/panels-2R5YEFXH.js +1 -0
- package/dist/permissions-5O7KVAXU.js +1 -0
- package/dist/prompt-VWFPFM4N.js +1 -0
- package/dist/quality-GPQD25UL.js +1 -0
- package/dist/repl-CL4SYHU4.js +1 -0
- package/dist/roadmap-QRZODSNJ.js +1 -0
- package/dist/server-PKOHK5M2.js +1 -0
- package/dist/session-5HDDQQP6.js +1 -0
- package/dist/skills-DXWSVJSU.js +1 -0
- package/dist/store-WXXTKTTL.js +1 -0
- package/dist/team-N2GF4YYS.js +1 -0
- package/dist/telemetry-NT4UZLBS.js +1 -0
- package/dist/test-runner-F6B6RH3S.js +1 -0
- package/dist/theme-JJJ6ABR2.js +1 -0
- package/dist/upgrade-RUG3R7R5.js +1 -0
- package/dist/verify-6OGRY2PR.js +1 -0
- package/dist/version-4RHTDUNQ.js +1 -0
- package/dist/web/static/app.js +1 -562
- package/dist/web/static/index.html +114 -126
- package/dist/web/static/mirror.css +1 -1001
- package/dist/web/static/mirror.html +155 -178
- package/dist/web/static/mirror.js +1 -1125
- package/dist/web/static/onboard.css +1 -302
- package/dist/web/static/onboard.html +121 -145
- package/dist/web/static/onboard.js +1 -300
- package/dist/web/static/style.css +1 -602
- package/dist/web/static/utils.js +1 -0
- package/dist/web/static/workspace.css +1 -1568
- package/dist/web/static/workspace.html +369 -402
- package/dist/web/static/workspace.js +1 -1683
- package/dist/web-CIC7ZKBM.js +1 -0
- package/package.json +26 -4
- package/dist/api-JHHOZTL6.js +0 -162
- package/dist/auth-5QFJLW7J.js +0 -21
- package/dist/background-2EGCAAQH.js +0 -14
- package/dist/backlog-Q2NZCLNY.js +0 -24
- package/dist/chunk-2CMSCWQW.js +0 -162
- package/dist/chunk-4DVYJAJL.js +0 -57
- package/dist/chunk-5GDYH676.js +0 -271
- package/dist/chunk-5NLVGLD7.js +0 -66
- package/dist/chunk-6XTEAFZQ.js +0 -575
- package/dist/chunk-AQBSMYLT.js +0 -2025
- package/dist/chunk-BE46C7JW.js +0 -46
- package/dist/chunk-CLKIMCXZ.js +0 -139
- package/dist/chunk-DN4ASQ26.js +0 -167
- package/dist/chunk-DUWREZXK.js +0 -173
- package/dist/chunk-FCW3K6F2.js +0 -263
- package/dist/chunk-GFORWAMW.js +0 -251
- package/dist/chunk-GH7E2OJE.js +0 -223
- package/dist/chunk-GU2FZQ6A.js +0 -69
- package/dist/chunk-I7WI3BMB.js +0 -161
- package/dist/chunk-IOPKN5GD.js +0 -190
- package/dist/chunk-LBVHDGZE.js +0 -133
- package/dist/chunk-MGLJ53QN.js +0 -219
- package/dist/chunk-NETIY5UB.js +0 -134
- package/dist/chunk-NP47L7LG.js +0 -288
- package/dist/chunk-O6MG7TOH.js +0 -58
- package/dist/chunk-OPZYEVYR.js +0 -150
- package/dist/chunk-R3GPQC7I.js +0 -393
- package/dist/chunk-R5T3A2NQ.js +0 -166
- package/dist/chunk-RKB2JOV2.js +0 -43
- package/dist/chunk-RNG3K465.js +0 -80
- package/dist/chunk-TGTYKBGC.js +0 -86
- package/dist/chunk-UCX4VZCT.js +0 -681
- package/dist/chunk-WHLVZCQY.js +0 -245
- package/dist/chunk-Y6HMJZDJ.js +0 -1505
- package/dist/chunk-ZSBHUGWR.js +0 -262
- package/dist/claude-4BX3MJSK.js +0 -12
- package/dist/commands-2X4OB5RF.js +0 -128
- package/dist/commands-GLBCEVQK.js +0 -1044
- package/dist/commands-IINRNBYX.js +0 -232
- package/dist/config-RSNQJQPS.js +0 -8
- package/dist/config-loader-SXO674TF.js +0 -24
- package/dist/diagnose-7UPLS7I4.js +0 -12
- package/dist/display-IIUBEYWN.js +0 -58
- package/dist/extractor-D3XWOAXI.js +0 -129
- package/dist/history-6I6FADAU.js +0 -180
- package/dist/index.d.ts +0 -1
- package/dist/instance-registry-J7UJ7U4Z.js +0 -15
- package/dist/keybindings-PDXIOV3O.js +0 -15
- package/dist/loader-GKEYT6Y7.js +0 -58
- package/dist/network-JYGHQXAR.js +0 -279
- package/dist/notify-HPTALZDC.js +0 -14
- package/dist/openai-compat-R7EKWG6Z.js +0 -12
- package/dist/permissions-JUKXMNDH.js +0 -10
- package/dist/prompt-UWHSZU4P.js +0 -166
- package/dist/quality-ST7PPNFR.js +0 -16
- package/dist/repl-QHIZ2JGF.js +0 -3374
- package/dist/roadmap-5OBEKROY.js +0 -17
- package/dist/server-HCNIP7ZQ.js +0 -57
- package/dist/session-5EBECDUP.js +0 -21
- package/dist/skills-HBQQTYO4.js +0 -175
- package/dist/store-FKUTR7GW.js +0 -25
- package/dist/team-7BBBP5YQ.js +0 -385
- package/dist/telemetry-6R4EIE6O.js +0 -30
- package/dist/test-runner-AUAGIBNM.js +0 -619
- package/dist/theme-3SYJ3UQA.js +0 -14
- package/dist/upgrade-MZFH7OCN.js +0 -83
- package/dist/verify-JUDKTPKZ.js +0 -14
- package/dist/web-KS3FUGJA.js +0 -39
package/dist/chunk-LBVHDGZE.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HYPERCORE_DIR
|
|
3
|
-
} from "./chunk-I7WI3BMB.js";
|
|
4
|
-
|
|
5
|
-
// src/core/instance-registry.ts
|
|
6
|
-
import { readFile, writeFile, unlink } from "fs/promises";
|
|
7
|
-
import { existsSync } from "fs";
|
|
8
|
-
import { join } from "path";
|
|
9
|
-
var REGISTRY_PATH = join(HYPERCORE_DIR, "instances.json");
|
|
10
|
-
var LOCK_PATH = join(HYPERCORE_DIR, "instances.lock");
|
|
11
|
-
function isPidAlive(pid) {
|
|
12
|
-
try {
|
|
13
|
-
process.kill(pid, 0);
|
|
14
|
-
return true;
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
async function withLock(fn) {
|
|
20
|
-
const maxRetries = 5;
|
|
21
|
-
const baseDelay = 50;
|
|
22
|
-
for (let i = 0; i < maxRetries; i++) {
|
|
23
|
-
try {
|
|
24
|
-
await writeFile(LOCK_PATH, String(process.pid), { flag: "wx" });
|
|
25
|
-
try {
|
|
26
|
-
return await fn();
|
|
27
|
-
} finally {
|
|
28
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
} catch (err) {
|
|
32
|
-
const code = err.code;
|
|
33
|
-
if (code === "EEXIST") {
|
|
34
|
-
try {
|
|
35
|
-
const lockPid = parseInt(await readFile(LOCK_PATH, "utf-8"), 10);
|
|
36
|
-
if (!isPidAlive(lockPid)) {
|
|
37
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
38
|
-
});
|
|
39
|
-
} else {
|
|
40
|
-
await new Promise((r) => setTimeout(r, baseDelay * (i + 1)));
|
|
41
|
-
}
|
|
42
|
-
} catch {
|
|
43
|
-
await unlink(LOCK_PATH).catch(() => {
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
throw err;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
throw new Error("Failed to acquire instance registry lock after " + maxRetries + " retries");
|
|
52
|
-
}
|
|
53
|
-
async function readRegistry() {
|
|
54
|
-
try {
|
|
55
|
-
if (!existsSync(REGISTRY_PATH)) {
|
|
56
|
-
return { instances: [], lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
57
|
-
}
|
|
58
|
-
const data = JSON.parse(await readFile(REGISTRY_PATH, "utf-8"));
|
|
59
|
-
return data;
|
|
60
|
-
} catch {
|
|
61
|
-
return { instances: [], lastUpdated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
async function writeRegistry(registry) {
|
|
65
|
-
registry.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
66
|
-
await writeFile(REGISTRY_PATH, JSON.stringify(registry, null, 2), "utf-8");
|
|
67
|
-
}
|
|
68
|
-
async function registerInstance(instance) {
|
|
69
|
-
await withLock(async () => {
|
|
70
|
-
const registry = await readRegistry();
|
|
71
|
-
registry.instances = registry.instances.filter(
|
|
72
|
-
(inst) => inst.pid !== instance.pid && isPidAlive(inst.pid)
|
|
73
|
-
);
|
|
74
|
-
registry.instances.push(instance);
|
|
75
|
-
await writeRegistry(registry);
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
async function updateInstanceRuntime(pid, patch) {
|
|
79
|
-
if (Object.keys(patch).length === 0) return;
|
|
80
|
-
await withLock(async () => {
|
|
81
|
-
const registry = await readRegistry();
|
|
82
|
-
let changed = false;
|
|
83
|
-
const aliveInstances = registry.instances.filter((inst) => isPidAlive(inst.pid));
|
|
84
|
-
if (aliveInstances.length !== registry.instances.length) {
|
|
85
|
-
changed = true;
|
|
86
|
-
}
|
|
87
|
-
registry.instances = aliveInstances.map((inst) => {
|
|
88
|
-
if (inst.pid !== pid) return inst;
|
|
89
|
-
changed = true;
|
|
90
|
-
return { ...inst, ...patch };
|
|
91
|
-
});
|
|
92
|
-
if (changed) {
|
|
93
|
-
await writeRegistry(registry);
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
async function unregisterInstance(pid) {
|
|
98
|
-
await withLock(async () => {
|
|
99
|
-
const registry = await readRegistry();
|
|
100
|
-
registry.instances = registry.instances.filter((inst) => inst.pid !== pid);
|
|
101
|
-
await writeRegistry(registry);
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
async function listInstances() {
|
|
105
|
-
const registry = await readRegistry();
|
|
106
|
-
const alive = registry.instances.filter((inst) => isPidAlive(inst.pid));
|
|
107
|
-
if (alive.length !== registry.instances.length) {
|
|
108
|
-
withLock(async () => {
|
|
109
|
-
const fresh = await readRegistry();
|
|
110
|
-
fresh.instances = fresh.instances.filter((inst) => isPidAlive(inst.pid));
|
|
111
|
-
await writeRegistry(fresh);
|
|
112
|
-
}).catch(() => {
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return alive;
|
|
116
|
-
}
|
|
117
|
-
async function getCanonicalDashboardPort(fallbackPort = 3210) {
|
|
118
|
-
try {
|
|
119
|
-
const instances = await listInstances();
|
|
120
|
-
if (instances.length === 0) return fallbackPort;
|
|
121
|
-
return Math.min(...instances.map((i) => i.port));
|
|
122
|
-
} catch {
|
|
123
|
-
return fallbackPort;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export {
|
|
128
|
-
registerInstance,
|
|
129
|
-
updateInstanceRuntime,
|
|
130
|
-
unregisterInstance,
|
|
131
|
-
listInstances,
|
|
132
|
-
getCanonicalDashboardPort
|
|
133
|
-
};
|
package/dist/chunk-MGLJ53QN.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
// src/admin/backlog.ts
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
4
|
-
import { existsSync } from "fs";
|
|
5
|
-
var HYPERCORE_DIR = join(process.env.HOME || "~", ".hypercore");
|
|
6
|
-
var ADMIN_DIR = join(HYPERCORE_DIR, "admin");
|
|
7
|
-
var BACKLOG_FILE = join(ADMIN_DIR, "backlog.json");
|
|
8
|
-
var DEFAULT_METRICS = {
|
|
9
|
-
baselineKey: null,
|
|
10
|
-
baselineValue: null,
|
|
11
|
-
baselineDate: null,
|
|
12
|
-
afterValue: null,
|
|
13
|
-
afterDate: null,
|
|
14
|
-
verified: false
|
|
15
|
-
};
|
|
16
|
-
function normalizeMetrics(metrics) {
|
|
17
|
-
return {
|
|
18
|
-
baselineKey: typeof metrics?.baselineKey === "string" ? metrics.baselineKey : null,
|
|
19
|
-
baselineValue: typeof metrics?.baselineValue === "number" && Number.isFinite(metrics.baselineValue) ? metrics.baselineValue : null,
|
|
20
|
-
baselineDate: typeof metrics?.baselineDate === "string" ? metrics.baselineDate : null,
|
|
21
|
-
afterValue: typeof metrics?.afterValue === "number" && Number.isFinite(metrics.afterValue) ? metrics.afterValue : null,
|
|
22
|
-
afterDate: typeof metrics?.afterDate === "string" ? metrics.afterDate : null,
|
|
23
|
-
verified: typeof metrics?.verified === "boolean" ? metrics.verified : false
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function normalizeItem(raw, fallbackId) {
|
|
27
|
-
if (!raw || typeof raw !== "object") return null;
|
|
28
|
-
const item = raw;
|
|
29
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
30
|
-
const type = item.type === "feature" || item.type === "improvement" || item.type === "idea" || item.type === "bugfix" ? item.type : "feature";
|
|
31
|
-
const wuxing = item.wuxing === "\u6728" || item.wuxing === "\u706B" || item.wuxing === "\u6C34" || item.wuxing === "\u91D1" || item.wuxing === "\u571F" ? item.wuxing : "\u6728";
|
|
32
|
-
const priority = item.priority === "S" || item.priority === "A" || item.priority === "B" || item.priority === "C" ? item.priority : "B";
|
|
33
|
-
const status = item.status === "idea" || item.status === "planned" || item.status === "developing" || item.status === "done" || item.status === "archived" ? item.status : "idea";
|
|
34
|
-
const source = item.source === "auto-diagnose" ? "auto-diagnose" : "manual";
|
|
35
|
-
const createdAt = typeof item.createdAt === "string" ? item.createdAt : now;
|
|
36
|
-
const id = typeof item.id === "number" && Number.isFinite(item.id) ? Math.floor(item.id) : fallbackId;
|
|
37
|
-
return {
|
|
38
|
-
id: id > 0 ? id : fallbackId,
|
|
39
|
-
title: typeof item.title === "string" ? item.title : `Untitled #${fallbackId}`,
|
|
40
|
-
description: typeof item.description === "string" ? item.description : "",
|
|
41
|
-
type,
|
|
42
|
-
wuxing,
|
|
43
|
-
priority,
|
|
44
|
-
status,
|
|
45
|
-
source,
|
|
46
|
-
sourceDetail: typeof item.sourceDetail === "string" ? item.sourceDetail : "",
|
|
47
|
-
evidence: typeof item.evidence === "string" ? item.evidence : "",
|
|
48
|
-
targetVersion: typeof item.targetVersion === "string" ? item.targetVersion : "",
|
|
49
|
-
tags: Array.isArray(item.tags) ? item.tags.filter((t) => typeof t === "string") : [],
|
|
50
|
-
createdAt,
|
|
51
|
-
updatedAt: typeof item.updatedAt === "string" ? item.updatedAt : createdAt,
|
|
52
|
-
startedAt: typeof item.startedAt === "string" ? item.startedAt : null,
|
|
53
|
-
resolvedAt: typeof item.resolvedAt === "string" ? item.resolvedAt : null,
|
|
54
|
-
metrics: normalizeMetrics(item.metrics)
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
async function ensureDir() {
|
|
58
|
-
if (!existsSync(ADMIN_DIR)) {
|
|
59
|
-
await mkdir(ADMIN_DIR, { recursive: true });
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
async function loadStore() {
|
|
63
|
-
await ensureDir();
|
|
64
|
-
if (!existsSync(BACKLOG_FILE)) {
|
|
65
|
-
return { nextId: 1, items: [] };
|
|
66
|
-
}
|
|
67
|
-
try {
|
|
68
|
-
const raw = await readFile(BACKLOG_FILE, "utf-8");
|
|
69
|
-
const parsed = JSON.parse(raw);
|
|
70
|
-
const rawItems = Array.isArray(parsed.items) ? parsed.items : [];
|
|
71
|
-
const items = [];
|
|
72
|
-
for (let i = 0; i < rawItems.length; i++) {
|
|
73
|
-
const normalized = normalizeItem(rawItems[i], i + 1);
|
|
74
|
-
if (normalized) items.push(normalized);
|
|
75
|
-
}
|
|
76
|
-
const maxId = items.reduce((max, item) => item.id > max ? item.id : max, 0);
|
|
77
|
-
const nextIdFromFile = typeof parsed.nextId === "number" && Number.isFinite(parsed.nextId) ? Math.floor(parsed.nextId) : maxId + 1;
|
|
78
|
-
return {
|
|
79
|
-
nextId: Math.max(nextIdFromFile, maxId + 1, 1),
|
|
80
|
-
items
|
|
81
|
-
};
|
|
82
|
-
} catch {
|
|
83
|
-
return { nextId: 1, items: [] };
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
async function saveStore(store) {
|
|
87
|
-
await ensureDir();
|
|
88
|
-
await writeFile(BACKLOG_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
89
|
-
}
|
|
90
|
-
async function addItem(opts) {
|
|
91
|
-
const store = await loadStore();
|
|
92
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
93
|
-
const item = {
|
|
94
|
-
id: store.nextId++,
|
|
95
|
-
title: opts.title,
|
|
96
|
-
description: opts.description || "",
|
|
97
|
-
type: opts.type || "feature",
|
|
98
|
-
wuxing: opts.wuxing || "\u6728",
|
|
99
|
-
priority: opts.priority || "B",
|
|
100
|
-
status: "idea",
|
|
101
|
-
source: opts.source || "manual",
|
|
102
|
-
sourceDetail: "",
|
|
103
|
-
evidence: opts.evidence || "",
|
|
104
|
-
targetVersion: opts.targetVersion || "",
|
|
105
|
-
tags: opts.tags || [],
|
|
106
|
-
createdAt: now,
|
|
107
|
-
updatedAt: now,
|
|
108
|
-
startedAt: null,
|
|
109
|
-
resolvedAt: null,
|
|
110
|
-
metrics: { ...DEFAULT_METRICS }
|
|
111
|
-
};
|
|
112
|
-
store.items.push(item);
|
|
113
|
-
await saveStore(store);
|
|
114
|
-
return item;
|
|
115
|
-
}
|
|
116
|
-
async function listItems(filters) {
|
|
117
|
-
const store = await loadStore();
|
|
118
|
-
let items = store.items.filter((i) => i.status !== "archived");
|
|
119
|
-
if (filters) {
|
|
120
|
-
if (filters.status) items = items.filter((i) => i.status === filters.status);
|
|
121
|
-
if (filters.wuxing) items = items.filter((i) => i.wuxing === filters.wuxing);
|
|
122
|
-
if (filters.priority) items = items.filter((i) => i.priority === filters.priority);
|
|
123
|
-
if (filters.version) items = items.filter((i) => i.targetVersion === filters.version);
|
|
124
|
-
if (filters.type) items = items.filter((i) => i.type === filters.type);
|
|
125
|
-
}
|
|
126
|
-
const priorityOrder = { S: 0, A: 1, B: 2, C: 3 };
|
|
127
|
-
return items.sort((a, b) => {
|
|
128
|
-
const pd = priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
129
|
-
if (pd !== 0) return pd;
|
|
130
|
-
return a.id - b.id;
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
async function getItem(id) {
|
|
134
|
-
const store = await loadStore();
|
|
135
|
-
return store.items.find((i) => i.id === id) || null;
|
|
136
|
-
}
|
|
137
|
-
async function updateItem(id, updates) {
|
|
138
|
-
const store = await loadStore();
|
|
139
|
-
const item = store.items.find((i) => i.id === id);
|
|
140
|
-
if (!item) return null;
|
|
141
|
-
Object.assign(item, updates);
|
|
142
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
143
|
-
await saveStore(store);
|
|
144
|
-
return item;
|
|
145
|
-
}
|
|
146
|
-
async function updateItemMetrics(id, metrics) {
|
|
147
|
-
const store = await loadStore();
|
|
148
|
-
const item = store.items.find((i) => i.id === id);
|
|
149
|
-
if (!item) return null;
|
|
150
|
-
item.metrics = normalizeMetrics(metrics);
|
|
151
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
152
|
-
await saveStore(store);
|
|
153
|
-
return item;
|
|
154
|
-
}
|
|
155
|
-
async function pickItem(id) {
|
|
156
|
-
const store = await loadStore();
|
|
157
|
-
const item = store.items.find((i) => i.id === id);
|
|
158
|
-
if (!item) return null;
|
|
159
|
-
item.status = "developing";
|
|
160
|
-
item.startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
161
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
162
|
-
await saveStore(store);
|
|
163
|
-
return item;
|
|
164
|
-
}
|
|
165
|
-
async function doneItem(id) {
|
|
166
|
-
const store = await loadStore();
|
|
167
|
-
const item = store.items.find((i) => i.id === id);
|
|
168
|
-
if (!item) return null;
|
|
169
|
-
item.status = "done";
|
|
170
|
-
item.resolvedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
171
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
172
|
-
await saveStore(store);
|
|
173
|
-
return item;
|
|
174
|
-
}
|
|
175
|
-
async function archiveItem(id) {
|
|
176
|
-
const store = await loadStore();
|
|
177
|
-
const item = store.items.find((i) => i.id === id);
|
|
178
|
-
if (!item) return null;
|
|
179
|
-
item.status = "archived";
|
|
180
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
181
|
-
await saveStore(store);
|
|
182
|
-
return item;
|
|
183
|
-
}
|
|
184
|
-
async function reopenItem(id) {
|
|
185
|
-
const store = await loadStore();
|
|
186
|
-
const item = store.items.find((i) => i.id === id);
|
|
187
|
-
if (!item) return null;
|
|
188
|
-
item.status = "planned";
|
|
189
|
-
item.resolvedAt = null;
|
|
190
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
191
|
-
await saveStore(store);
|
|
192
|
-
return item;
|
|
193
|
-
}
|
|
194
|
-
async function getStats() {
|
|
195
|
-
const store = await loadStore();
|
|
196
|
-
const active = store.items.filter((i) => i.status !== "archived");
|
|
197
|
-
const byStatus = {};
|
|
198
|
-
const byPriority = {};
|
|
199
|
-
const byWuxing = {};
|
|
200
|
-
for (const item of active) {
|
|
201
|
-
byStatus[item.status] = (byStatus[item.status] || 0) + 1;
|
|
202
|
-
byPriority[item.priority] = (byPriority[item.priority] || 0) + 1;
|
|
203
|
-
byWuxing[item.wuxing] = (byWuxing[item.wuxing] || 0) + 1;
|
|
204
|
-
}
|
|
205
|
-
return { total: active.length, byStatus, byPriority, byWuxing };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export {
|
|
209
|
-
addItem,
|
|
210
|
-
listItems,
|
|
211
|
-
getItem,
|
|
212
|
-
updateItem,
|
|
213
|
-
updateItemMetrics,
|
|
214
|
-
pickItem,
|
|
215
|
-
doneItem,
|
|
216
|
-
archiveItem,
|
|
217
|
-
reopenItem,
|
|
218
|
-
getStats
|
|
219
|
-
};
|
package/dist/chunk-NETIY5UB.js
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HYPERCORE_DIR
|
|
3
|
-
} from "./chunk-I7WI3BMB.js";
|
|
4
|
-
|
|
5
|
-
// src/repl/session.ts
|
|
6
|
-
import { mkdir, writeFile, readFile, readdir, rename } from "fs/promises";
|
|
7
|
-
import { join } from "path";
|
|
8
|
-
import { existsSync } from "fs";
|
|
9
|
-
var SESSIONS_DIR = join(HYPERCORE_DIR, "sessions");
|
|
10
|
-
function generateSessionId() {
|
|
11
|
-
const now = /* @__PURE__ */ new Date();
|
|
12
|
-
const date = now.toISOString().split("T")[0];
|
|
13
|
-
const time = now.toTimeString().split(" ")[0].replace(/:/g, "");
|
|
14
|
-
return `${date}-${time}`;
|
|
15
|
-
}
|
|
16
|
-
async function saveSession(sessionId, messages, name) {
|
|
17
|
-
await mkdir(SESSIONS_DIR, { recursive: true });
|
|
18
|
-
const data = {
|
|
19
|
-
id: sessionId,
|
|
20
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22
|
-
messages
|
|
23
|
-
};
|
|
24
|
-
const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
|
|
25
|
-
if (existsSync(filePath)) {
|
|
26
|
-
try {
|
|
27
|
-
const existing = JSON.parse(await readFile(filePath, "utf-8"));
|
|
28
|
-
data.createdAt = existing.createdAt;
|
|
29
|
-
if (!name && existing.name) data.name = existing.name;
|
|
30
|
-
} catch {
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (name) data.name = name;
|
|
34
|
-
await writeFile(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
35
|
-
}
|
|
36
|
-
async function loadSession(sessionId) {
|
|
37
|
-
const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
|
|
38
|
-
if (!existsSync(filePath)) {
|
|
39
|
-
throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
|
|
40
|
-
}
|
|
41
|
-
const data = JSON.parse(await readFile(filePath, "utf-8"));
|
|
42
|
-
return data.messages;
|
|
43
|
-
}
|
|
44
|
-
async function listSessions(limit = 10) {
|
|
45
|
-
if (!existsSync(SESSIONS_DIR)) return [];
|
|
46
|
-
const files = await readdir(SESSIONS_DIR);
|
|
47
|
-
const sessions = [];
|
|
48
|
-
for (const file of files) {
|
|
49
|
-
if (!file.endsWith(".json")) continue;
|
|
50
|
-
try {
|
|
51
|
-
const data = JSON.parse(await readFile(join(SESSIONS_DIR, file), "utf-8"));
|
|
52
|
-
sessions.push({
|
|
53
|
-
id: data.id,
|
|
54
|
-
name: data.name,
|
|
55
|
-
updatedAt: data.updatedAt,
|
|
56
|
-
messageCount: data.messages.length
|
|
57
|
-
});
|
|
58
|
-
} catch {
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
sessions.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
62
|
-
return sessions.slice(0, limit);
|
|
63
|
-
}
|
|
64
|
-
async function renameSession(oldId, newId) {
|
|
65
|
-
const oldPath = join(SESSIONS_DIR, `${oldId}.json`);
|
|
66
|
-
const newPath = join(SESSIONS_DIR, `${newId}.json`);
|
|
67
|
-
if (!existsSync(oldPath)) throw new Error(`\u4F1A\u8BDD ${oldId} \u4E0D\u5B58\u5728`);
|
|
68
|
-
if (existsSync(newPath)) throw new Error(`\u4F1A\u8BDD ${newId} \u5DF2\u5B58\u5728`);
|
|
69
|
-
const data = JSON.parse(await readFile(oldPath, "utf-8"));
|
|
70
|
-
data.id = newId;
|
|
71
|
-
data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
72
|
-
await writeFile(newPath, JSON.stringify(data, null, 2), "utf-8");
|
|
73
|
-
await rename(oldPath, join(SESSIONS_DIR, `${oldId}.json.bak`)).catch(() => {
|
|
74
|
-
});
|
|
75
|
-
const { unlink } = await import("fs/promises");
|
|
76
|
-
await unlink(join(SESSIONS_DIR, `${oldId}.json.bak`)).catch(() => {
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
async function forkSession(sourceId) {
|
|
80
|
-
const sourcePath = join(SESSIONS_DIR, `${sourceId}.json`);
|
|
81
|
-
if (!existsSync(sourcePath)) throw new Error(`\u4F1A\u8BDD ${sourceId} \u4E0D\u5B58\u5728`);
|
|
82
|
-
const newId = generateSessionId() + "-fork";
|
|
83
|
-
const newPath = join(SESSIONS_DIR, `${newId}.json`);
|
|
84
|
-
const data = JSON.parse(await readFile(sourcePath, "utf-8"));
|
|
85
|
-
data.id = newId;
|
|
86
|
-
data.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
87
|
-
await writeFile(newPath, JSON.stringify(data, null, 2), "utf-8");
|
|
88
|
-
return newId;
|
|
89
|
-
}
|
|
90
|
-
async function exportSession(sessionId, outputPath) {
|
|
91
|
-
const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
|
|
92
|
-
if (!existsSync(filePath)) throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
|
|
93
|
-
const data = JSON.parse(await readFile(filePath, "utf-8"));
|
|
94
|
-
const lines = [
|
|
95
|
-
`# \u4F1A\u8BDD: ${data.id}`,
|
|
96
|
-
``,
|
|
97
|
-
`- \u521B\u5EFA: ${data.createdAt}`,
|
|
98
|
-
`- \u66F4\u65B0: ${data.updatedAt}`,
|
|
99
|
-
`- \u6D88\u606F\u6570: ${data.messages.length}`,
|
|
100
|
-
``,
|
|
101
|
-
`---`,
|
|
102
|
-
``
|
|
103
|
-
];
|
|
104
|
-
for (const msg of data.messages) {
|
|
105
|
-
const role = msg.role === "user" ? "\u{1F464} \u7528\u6237" : "\u{1F916} AI";
|
|
106
|
-
lines.push(`## ${role}
|
|
107
|
-
`);
|
|
108
|
-
lines.push(msg.content);
|
|
109
|
-
lines.push("");
|
|
110
|
-
lines.push("---");
|
|
111
|
-
lines.push("");
|
|
112
|
-
}
|
|
113
|
-
const mdContent = lines.join("\n");
|
|
114
|
-
const dest = outputPath || join(process.cwd(), `session-${sessionId}.md`);
|
|
115
|
-
await writeFile(dest, mdContent, "utf-8");
|
|
116
|
-
return dest;
|
|
117
|
-
}
|
|
118
|
-
async function deleteSession(sessionId) {
|
|
119
|
-
const filePath = join(SESSIONS_DIR, `${sessionId}.json`);
|
|
120
|
-
if (!existsSync(filePath)) throw new Error(`\u4F1A\u8BDD ${sessionId} \u4E0D\u5B58\u5728`);
|
|
121
|
-
const { unlink } = await import("fs/promises");
|
|
122
|
-
await unlink(filePath);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
export {
|
|
126
|
-
generateSessionId,
|
|
127
|
-
saveSession,
|
|
128
|
-
loadSession,
|
|
129
|
-
listSessions,
|
|
130
|
-
renameSession,
|
|
131
|
-
forkSession,
|
|
132
|
-
exportSession,
|
|
133
|
-
deleteSession
|
|
134
|
-
};
|