hypercore-cli 1.1.1 → 1.3.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-Q2TX5JJL.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-545IGTXV.js +1 -0
- package/dist/chunk-5KUSGQP2.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-COITWWZJ.js +1 -0
- package/dist/chunk-CR7UUJVX.js +1 -0
- package/dist/chunk-E3MULLBX.js +1 -0
- package/dist/chunk-EWBV7YPP.js +1 -0
- package/dist/chunk-EZHYVJGQ.js +1 -0
- package/dist/chunk-FAKXBY7Q.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-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-R5XD3NT2.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-ZB5ZQSXH.js +1 -0
- package/dist/claude-US2QPRBA.js +1 -0
- package/dist/commands-5TFN74MD.js +1 -0
- package/dist/commands-EKPWCB3T.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-TB5YACJV.js +1 -0
- package/dist/extractor-3KTM2IUL.js +1 -0
- package/dist/feature-flag-VVIF5FJG.js +1 -0
- package/dist/history-GVNDPXXQ.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-GI2F3IDE.js +1 -0
- package/dist/notify-O6FNVHC4.js +1 -0
- package/dist/openai-compat-IPCMINVF.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-YNXCDVU4.js +1 -0
- package/dist/roadmap-QRZODSNJ.js +1 -0
- package/dist/server-USQP4GC4.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-VTPJ3WRT.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-DLROA5JN.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-P5YUKEAU.js +1 -0
- package/package.json +25 -4
- package/dist/api-D4PUN5BN.js +0 -162
- package/dist/auth-UTR4I6QY.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-77FRUHTU.js +0 -271
- package/dist/chunk-7ZYMJFCA.js +0 -251
- package/dist/chunk-BE46C7JW.js +0 -46
- package/dist/chunk-CM423E2U.js +0 -133
- package/dist/chunk-E4NKO2KI.js +0 -263
- package/dist/chunk-GH7E2OJE.js +0 -223
- package/dist/chunk-GMLQ7GZ5.js +0 -134
- package/dist/chunk-GU2FZQ6A.js +0 -69
- package/dist/chunk-IOPKN5GD.js +0 -190
- package/dist/chunk-LWDNLX6B.js +0 -2025
- package/dist/chunk-MGLJ53QN.js +0 -219
- package/dist/chunk-NHPDLYEW.js +0 -139
- package/dist/chunk-OGQGKMDX.js +0 -173
- package/dist/chunk-OPZYEVYR.js +0 -150
- package/dist/chunk-OWAOKDIN.js +0 -1505
- package/dist/chunk-R3GPQC7I.js +0 -393
- package/dist/chunk-RKB2JOV2.js +0 -43
- package/dist/chunk-RNG3K465.js +0 -80
- package/dist/chunk-SHJQMIJL.js +0 -288
- package/dist/chunk-SVF2VWOZ.js +0 -145
- package/dist/chunk-TGTYKBGC.js +0 -86
- package/dist/chunk-V2EBSFPU.js +0 -575
- package/dist/chunk-VJDQNNSO.js +0 -681
- package/dist/chunk-VQ35XX7B.js +0 -167
- package/dist/chunk-WHLVZCQY.js +0 -245
- package/dist/chunk-XMGHVNH2.js +0 -66
- package/dist/chunk-YWOSOTUO.js +0 -58
- package/dist/chunk-ZQRNV2US.js +0 -166
- package/dist/chunk-ZSBHUGWR.js +0 -262
- package/dist/claude-O5FSOXZC.js +0 -12
- package/dist/commands-43PLOWRU.js +0 -128
- package/dist/commands-5YVUSUMP.js +0 -232
- package/dist/commands-VZMZJFZF.js +0 -1044
- package/dist/config-WXXEEEVW.js +0 -8
- package/dist/config-loader-SXO674TF.js +0 -24
- package/dist/diagnose-BX45APUZ.js +0 -12
- package/dist/display-IIUBEYWN.js +0 -58
- package/dist/extractor-R5ABXNTJ.js +0 -129
- package/dist/history-JPXZEOT3.js +0 -180
- package/dist/index.d.ts +0 -1
- package/dist/instance-registry-6NJTCAE4.js +0 -15
- package/dist/keybindings-ADWNOX5M.js +0 -15
- package/dist/loader-AXDDCB2G.js +0 -58
- package/dist/network-V3O4UZYZ.js +0 -279
- package/dist/notify-HPTALZDC.js +0 -14
- package/dist/openai-compat-UFDV2SCK.js +0 -12
- package/dist/permissions-JUKXMNDH.js +0 -10
- package/dist/prompt-5CZ34WGA.js +0 -166
- package/dist/quality-ST7PPNFR.js +0 -16
- package/dist/repl-EOWP6AAB.js +0 -3374
- package/dist/roadmap-5OBEKROY.js +0 -17
- package/dist/server-BB5AENWU.js +0 -57
- package/dist/session-5NDKKFLN.js +0 -21
- package/dist/skills-JVLIQVJN.js +0 -175
- package/dist/store-G7KRD4PN.js +0 -25
- package/dist/team-FVNNVDBY.js +0 -385
- package/dist/telemetry-6R4EIE6O.js +0 -30
- package/dist/test-runner-REKSVPPY.js +0 -619
- package/dist/theme-3SYJ3UQA.js +0 -14
- package/dist/upgrade-YSXCO63I.js +0 -83
- package/dist/verify-JUDKTPKZ.js +0 -14
- package/dist/web-H2BJXUBZ.js +0 -39
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-NHPDLYEW.js
DELETED
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
HYPERCORE_DIR
|
|
3
|
-
} from "./chunk-SVF2VWOZ.js";
|
|
4
|
-
|
|
5
|
-
// src/core/hooks.ts
|
|
6
|
-
import { existsSync } from "fs";
|
|
7
|
-
import { readFile } from "fs/promises";
|
|
8
|
-
import { join } from "path";
|
|
9
|
-
import { spawn } from "child_process";
|
|
10
|
-
var HookManager = class {
|
|
11
|
-
hooks = [];
|
|
12
|
-
loaded = false;
|
|
13
|
-
/** 从配置文件加载钩子 */
|
|
14
|
-
async load() {
|
|
15
|
-
this.hooks = [];
|
|
16
|
-
const systemPath = join(HYPERCORE_DIR, "hooks.json");
|
|
17
|
-
await this.loadFromFile(systemPath);
|
|
18
|
-
const projectPath = join(process.cwd(), ".hypercore", "hooks.json");
|
|
19
|
-
if (projectPath !== systemPath) {
|
|
20
|
-
await this.loadFromFile(projectPath);
|
|
21
|
-
}
|
|
22
|
-
this.loaded = true;
|
|
23
|
-
}
|
|
24
|
-
async loadFromFile(filePath) {
|
|
25
|
-
if (!existsSync(filePath)) return;
|
|
26
|
-
try {
|
|
27
|
-
const content = await readFile(filePath, "utf-8");
|
|
28
|
-
const config = JSON.parse(content);
|
|
29
|
-
if (Array.isArray(config.hooks)) {
|
|
30
|
-
for (const hook of config.hooks) {
|
|
31
|
-
if (hook.event && hook.command) {
|
|
32
|
-
this.hooks.push(hook);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
/** 触发钩子,返回拦截结果 */
|
|
40
|
-
async trigger(event, context = {}) {
|
|
41
|
-
if (!this.loaded) await this.load();
|
|
42
|
-
const matching = this.hooks.filter((h) => {
|
|
43
|
-
if (h.event !== event) return false;
|
|
44
|
-
if (h.match?.toolName && context.toolName !== h.match.toolName) return false;
|
|
45
|
-
if (h.match?.model && context.model !== h.match.model) return false;
|
|
46
|
-
return true;
|
|
47
|
-
});
|
|
48
|
-
if (matching.length === 0) return { intercepted: false };
|
|
49
|
-
const fullContext = {
|
|
50
|
-
event,
|
|
51
|
-
...context
|
|
52
|
-
};
|
|
53
|
-
const blocking = matching.filter((h) => h.blocking);
|
|
54
|
-
const nonBlocking = matching.filter((h) => !h.blocking);
|
|
55
|
-
for (const hook of nonBlocking) {
|
|
56
|
-
this.executeHook(hook, fullContext).catch(() => {
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
for (const hook of blocking) {
|
|
60
|
-
const result = await this.executeHook(hook, fullContext);
|
|
61
|
-
if (hook.intercept && event === "onToolCall" && result.exitCode !== 0) {
|
|
62
|
-
return {
|
|
63
|
-
intercepted: true,
|
|
64
|
-
reason: result.stdout || `Hook "${hook.name || hook.command}" \u62E6\u622A\u4E86\u64CD\u4F5C (exit code: ${result.exitCode})`
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return { intercepted: false };
|
|
69
|
-
}
|
|
70
|
-
async executeHook(hook, context) {
|
|
71
|
-
const timeout = hook.timeout || 1e4;
|
|
72
|
-
const env = {
|
|
73
|
-
...process.env,
|
|
74
|
-
HYPERCORE_EVENT: context.event,
|
|
75
|
-
HYPERCORE_SESSION_ID: context.sessionId || "",
|
|
76
|
-
HYPERCORE_MODEL: context.model || "",
|
|
77
|
-
HYPERCORE_CWD: process.cwd()
|
|
78
|
-
};
|
|
79
|
-
if (context.toolName) env.HYPERCORE_TOOL_NAME = context.toolName;
|
|
80
|
-
if (context.toolInput) env.HYPERCORE_TOOL_INPUT = context.toolInput.slice(0, 1e3);
|
|
81
|
-
if (context.toolResult) env.HYPERCORE_TOOL_RESULT = context.toolResult.slice(0, 1e3);
|
|
82
|
-
if (context.userPrompt) env.HYPERCORE_USER_PROMPT = context.userPrompt.slice(0, 500);
|
|
83
|
-
if (context.error) env.HYPERCORE_ERROR = context.error.slice(0, 500);
|
|
84
|
-
return await new Promise((resolve) => {
|
|
85
|
-
const child = spawn("sh", ["-c", hook.command], {
|
|
86
|
-
cwd: process.cwd(),
|
|
87
|
-
env,
|
|
88
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
89
|
-
});
|
|
90
|
-
let stdout = "";
|
|
91
|
-
let stderr = "";
|
|
92
|
-
let settled = false;
|
|
93
|
-
const finish = (exitCode, output) => {
|
|
94
|
-
if (settled) return;
|
|
95
|
-
settled = true;
|
|
96
|
-
resolve({ exitCode, stdout: output.trim() });
|
|
97
|
-
};
|
|
98
|
-
const timer = setTimeout(() => {
|
|
99
|
-
child.kill("SIGTERM");
|
|
100
|
-
setTimeout(() => child.kill("SIGKILL"), 1e3);
|
|
101
|
-
const output = stdout || stderr || `Hook timeout after ${timeout}ms`;
|
|
102
|
-
finish(124, output);
|
|
103
|
-
}, timeout);
|
|
104
|
-
child.stdout?.on("data", (chunk) => {
|
|
105
|
-
stdout += chunk.toString("utf-8");
|
|
106
|
-
});
|
|
107
|
-
child.stderr?.on("data", (chunk) => {
|
|
108
|
-
stderr += chunk.toString("utf-8");
|
|
109
|
-
});
|
|
110
|
-
child.on("error", (err) => {
|
|
111
|
-
clearTimeout(timer);
|
|
112
|
-
finish(1, stderr || stdout || err.message);
|
|
113
|
-
});
|
|
114
|
-
child.on("close", (code) => {
|
|
115
|
-
clearTimeout(timer);
|
|
116
|
-
const output = stdout || stderr;
|
|
117
|
-
finish(code ?? 1, output);
|
|
118
|
-
});
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
/** 获取已加载的钩子数量 */
|
|
122
|
-
get count() {
|
|
123
|
-
return this.hooks.length;
|
|
124
|
-
}
|
|
125
|
-
/** 获取按事件分组的钩子列表 */
|
|
126
|
-
listByEvent() {
|
|
127
|
-
const grouped = {};
|
|
128
|
-
for (const hook of this.hooks) {
|
|
129
|
-
if (!grouped[hook.event]) grouped[hook.event] = [];
|
|
130
|
-
grouped[hook.event].push(hook);
|
|
131
|
-
}
|
|
132
|
-
return grouped;
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
var hookManager = new HookManager();
|
|
136
|
-
|
|
137
|
-
export {
|
|
138
|
-
hookManager
|
|
139
|
-
};
|
package/dist/chunk-OGQGKMDX.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
generateId,
|
|
3
|
-
generateJoinCode,
|
|
4
|
-
generateToken
|
|
5
|
-
} from "./chunk-XMGHVNH2.js";
|
|
6
|
-
import {
|
|
7
|
-
HYPERCORE_DIR
|
|
8
|
-
} from "./chunk-SVF2VWOZ.js";
|
|
9
|
-
|
|
10
|
-
// src/team/store.ts
|
|
11
|
-
import { readFile, writeFile, mkdir, readdir } from "fs/promises";
|
|
12
|
-
import { existsSync } from "fs";
|
|
13
|
-
import { join } from "path";
|
|
14
|
-
var TEAMS_DIR = join(HYPERCORE_DIR, "teams");
|
|
15
|
-
function teamDir(teamId) {
|
|
16
|
-
return join(TEAMS_DIR, teamId);
|
|
17
|
-
}
|
|
18
|
-
function configPath(teamId) {
|
|
19
|
-
return join(teamDir(teamId), "config.json");
|
|
20
|
-
}
|
|
21
|
-
function tasksPath(teamId) {
|
|
22
|
-
return join(teamDir(teamId), "tasks.json");
|
|
23
|
-
}
|
|
24
|
-
function runsDir(teamId) {
|
|
25
|
-
return join(teamDir(teamId), "runs");
|
|
26
|
-
}
|
|
27
|
-
function runPath(teamId, runId) {
|
|
28
|
-
return join(runsDir(teamId), `${runId}.json`);
|
|
29
|
-
}
|
|
30
|
-
async function readJSON(path) {
|
|
31
|
-
if (!existsSync(path)) return null;
|
|
32
|
-
try {
|
|
33
|
-
const data = await readFile(path, "utf-8");
|
|
34
|
-
return JSON.parse(data);
|
|
35
|
-
} catch {
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
async function writeJSON(path, data) {
|
|
40
|
-
const dir = join(path, "..");
|
|
41
|
-
await mkdir(dir, { recursive: true });
|
|
42
|
-
await writeFile(path, JSON.stringify(data, null, 2), "utf-8");
|
|
43
|
-
}
|
|
44
|
-
async function createTeam(teamName, ownerName) {
|
|
45
|
-
const teamId = generateId();
|
|
46
|
-
const memberId = generateId();
|
|
47
|
-
const token = generateToken();
|
|
48
|
-
const owner = {
|
|
49
|
-
id: memberId,
|
|
50
|
-
name: ownerName,
|
|
51
|
-
role: "owner",
|
|
52
|
-
token,
|
|
53
|
-
joinedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
54
|
-
status: "online",
|
|
55
|
-
lastSeen: (/* @__PURE__ */ new Date()).toISOString()
|
|
56
|
-
};
|
|
57
|
-
const team = {
|
|
58
|
-
id: teamId,
|
|
59
|
-
name: teamName,
|
|
60
|
-
joinCode: generateJoinCode(),
|
|
61
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
62
|
-
owner: memberId,
|
|
63
|
-
members: [owner]
|
|
64
|
-
};
|
|
65
|
-
await writeJSON(configPath(teamId), team);
|
|
66
|
-
await writeJSON(tasksPath(teamId), []);
|
|
67
|
-
return { team, ownerToken: token };
|
|
68
|
-
}
|
|
69
|
-
async function loadTeam(teamId) {
|
|
70
|
-
return readJSON(configPath(teamId));
|
|
71
|
-
}
|
|
72
|
-
async function findTeamByJoinCode(code) {
|
|
73
|
-
if (!existsSync(TEAMS_DIR)) return null;
|
|
74
|
-
const dirs = await readdir(TEAMS_DIR);
|
|
75
|
-
for (const dir of dirs) {
|
|
76
|
-
const team = await readJSON(configPath(dir));
|
|
77
|
-
if (team && team.joinCode === code.toUpperCase()) return team;
|
|
78
|
-
}
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
async function saveTeam(team) {
|
|
82
|
-
await writeJSON(configPath(team.id), team);
|
|
83
|
-
}
|
|
84
|
-
async function addMember(teamId, memberName) {
|
|
85
|
-
const team = await loadTeam(teamId);
|
|
86
|
-
if (!team) return null;
|
|
87
|
-
if (team.members.some((m) => m.name === memberName)) {
|
|
88
|
-
memberName = `${memberName}_${team.members.length}`;
|
|
89
|
-
}
|
|
90
|
-
const member = {
|
|
91
|
-
id: generateId(),
|
|
92
|
-
name: memberName,
|
|
93
|
-
role: "member",
|
|
94
|
-
token: generateToken(),
|
|
95
|
-
joinedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
96
|
-
status: "online",
|
|
97
|
-
lastSeen: (/* @__PURE__ */ new Date()).toISOString()
|
|
98
|
-
};
|
|
99
|
-
team.members.push(member);
|
|
100
|
-
await saveTeam(team);
|
|
101
|
-
return { member, team };
|
|
102
|
-
}
|
|
103
|
-
async function updateMemberStatus(teamId, memberId, status) {
|
|
104
|
-
const team = await loadTeam(teamId);
|
|
105
|
-
if (!team) return;
|
|
106
|
-
const member = team.members.find((m) => m.id === memberId);
|
|
107
|
-
if (member) {
|
|
108
|
-
member.status = status;
|
|
109
|
-
member.lastSeen = (/* @__PURE__ */ new Date()).toISOString();
|
|
110
|
-
await saveTeam(team);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
async function listTasks(teamId) {
|
|
114
|
-
return await readJSON(tasksPath(teamId)) || [];
|
|
115
|
-
}
|
|
116
|
-
async function addTask(teamId, task) {
|
|
117
|
-
const tasks = await listTasks(teamId);
|
|
118
|
-
const maxId = tasks.reduce((max, t) => Math.max(max, parseInt(t.id) || 0), 0);
|
|
119
|
-
const newTask = {
|
|
120
|
-
...task,
|
|
121
|
-
id: String(maxId + 1),
|
|
122
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
123
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
124
|
-
};
|
|
125
|
-
tasks.push(newTask);
|
|
126
|
-
await writeJSON(tasksPath(teamId), tasks);
|
|
127
|
-
return newTask;
|
|
128
|
-
}
|
|
129
|
-
async function updateTask(teamId, taskId, updates) {
|
|
130
|
-
const tasks = await listTasks(teamId);
|
|
131
|
-
const idx = tasks.findIndex((t) => t.id === taskId);
|
|
132
|
-
if (idx === -1) return null;
|
|
133
|
-
tasks[idx] = { ...tasks[idx], ...updates, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
134
|
-
await writeJSON(tasksPath(teamId), tasks);
|
|
135
|
-
return tasks[idx];
|
|
136
|
-
}
|
|
137
|
-
async function deleteTask(teamId, taskId) {
|
|
138
|
-
const tasks = await listTasks(teamId);
|
|
139
|
-
const filtered = tasks.filter((t) => t.id !== taskId);
|
|
140
|
-
if (filtered.length === tasks.length) return false;
|
|
141
|
-
await writeJSON(tasksPath(teamId), filtered);
|
|
142
|
-
return true;
|
|
143
|
-
}
|
|
144
|
-
async function loadRun(teamId, runId) {
|
|
145
|
-
return readJSON(runPath(teamId, runId));
|
|
146
|
-
}
|
|
147
|
-
async function listRuns(teamId) {
|
|
148
|
-
const dir = runsDir(teamId);
|
|
149
|
-
if (!existsSync(dir)) return [];
|
|
150
|
-
const files = await readdir(dir);
|
|
151
|
-
const runs = [];
|
|
152
|
-
for (const file of files) {
|
|
153
|
-
if (file.endsWith(".json")) {
|
|
154
|
-
const run = await readJSON(join(dir, file));
|
|
155
|
-
if (run) runs.push(run);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return runs.sort((a, b) => b.startedAt.localeCompare(a.startedAt));
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export {
|
|
162
|
-
createTeam,
|
|
163
|
-
loadTeam,
|
|
164
|
-
findTeamByJoinCode,
|
|
165
|
-
addMember,
|
|
166
|
-
updateMemberStatus,
|
|
167
|
-
listTasks,
|
|
168
|
-
addTask,
|
|
169
|
-
updateTask,
|
|
170
|
-
deleteTask,
|
|
171
|
-
loadRun,
|
|
172
|
-
listRuns
|
|
173
|
-
};
|
package/dist/chunk-OPZYEVYR.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
listItems
|
|
3
|
-
} from "./chunk-MGLJ53QN.js";
|
|
4
|
-
|
|
5
|
-
// src/admin/roadmap.ts
|
|
6
|
-
import { join } from "path";
|
|
7
|
-
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
8
|
-
import { existsSync } from "fs";
|
|
9
|
-
var HYPERCORE_DIR = join(process.env.HOME || "~", ".hypercore");
|
|
10
|
-
var ADMIN_DIR = join(HYPERCORE_DIR, "admin");
|
|
11
|
-
var MILESTONES_FILE = join(ADMIN_DIR, "milestones.json");
|
|
12
|
-
async function ensureDir() {
|
|
13
|
-
if (!existsSync(ADMIN_DIR)) {
|
|
14
|
-
await mkdir(ADMIN_DIR, { recursive: true });
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
async function loadStore() {
|
|
18
|
-
await ensureDir();
|
|
19
|
-
if (!existsSync(MILESTONES_FILE)) {
|
|
20
|
-
return { milestones: [] };
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
const raw = await readFile(MILESTONES_FILE, "utf-8");
|
|
24
|
-
return JSON.parse(raw);
|
|
25
|
-
} catch {
|
|
26
|
-
return { milestones: [] };
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
async function saveStore(store) {
|
|
30
|
-
await ensureDir();
|
|
31
|
-
await writeFile(MILESTONES_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
32
|
-
}
|
|
33
|
-
async function addMilestone(version, name, description) {
|
|
34
|
-
const store = await loadStore();
|
|
35
|
-
if (store.milestones.find((m) => m.version === version)) {
|
|
36
|
-
throw new Error(`\u91CC\u7A0B\u7891 ${version} \u5DF2\u5B58\u5728`);
|
|
37
|
-
}
|
|
38
|
-
const milestone = {
|
|
39
|
-
version,
|
|
40
|
-
name,
|
|
41
|
-
description: description || "",
|
|
42
|
-
status: "planning",
|
|
43
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
44
|
-
doneAt: null
|
|
45
|
-
};
|
|
46
|
-
store.milestones.push(milestone);
|
|
47
|
-
await saveStore(store);
|
|
48
|
-
return milestone;
|
|
49
|
-
}
|
|
50
|
-
async function doneMilestone(version) {
|
|
51
|
-
const store = await loadStore();
|
|
52
|
-
const ms = store.milestones.find((m) => m.version === version);
|
|
53
|
-
if (!ms) return null;
|
|
54
|
-
ms.status = "done";
|
|
55
|
-
ms.doneAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
56
|
-
await saveStore(store);
|
|
57
|
-
return ms;
|
|
58
|
-
}
|
|
59
|
-
async function activateMilestone(version) {
|
|
60
|
-
const store = await loadStore();
|
|
61
|
-
const ms = store.milestones.find((m) => m.version === version);
|
|
62
|
-
if (!ms) return null;
|
|
63
|
-
ms.status = "active";
|
|
64
|
-
await saveStore(store);
|
|
65
|
-
return ms;
|
|
66
|
-
}
|
|
67
|
-
async function listMilestones() {
|
|
68
|
-
const store = await loadStore();
|
|
69
|
-
return store.milestones;
|
|
70
|
-
}
|
|
71
|
-
async function getMilestone(version) {
|
|
72
|
-
const store = await loadStore();
|
|
73
|
-
return store.milestones.find((m) => m.version === version) || null;
|
|
74
|
-
}
|
|
75
|
-
async function getRoadmap() {
|
|
76
|
-
const allItems = await listItems();
|
|
77
|
-
const milestones = await listMilestones();
|
|
78
|
-
const grouped = {};
|
|
79
|
-
const unversioned = [];
|
|
80
|
-
for (const item of allItems) {
|
|
81
|
-
if (item.targetVersion) {
|
|
82
|
-
if (!grouped[item.targetVersion]) grouped[item.targetVersion] = [];
|
|
83
|
-
grouped[item.targetVersion].push(item);
|
|
84
|
-
} else {
|
|
85
|
-
unversioned.push(item);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
for (const ms of milestones) {
|
|
89
|
-
if (!grouped[ms.version]) grouped[ms.version] = [];
|
|
90
|
-
}
|
|
91
|
-
const versions = Object.keys(grouped).sort(compareVersions);
|
|
92
|
-
const roadmap = versions.map((ver) => {
|
|
93
|
-
const items = grouped[ver];
|
|
94
|
-
const milestone = milestones.find((m) => m.version === ver) || null;
|
|
95
|
-
const done = items.filter((i) => i.status === "done").length;
|
|
96
|
-
const developing = items.filter((i) => i.status === "developing").length;
|
|
97
|
-
const planned = items.filter((i) => i.status === "planned").length;
|
|
98
|
-
const idea = items.filter((i) => i.status === "idea").length;
|
|
99
|
-
const total = items.length;
|
|
100
|
-
return {
|
|
101
|
-
version: ver,
|
|
102
|
-
milestone,
|
|
103
|
-
items,
|
|
104
|
-
stats: {
|
|
105
|
-
total,
|
|
106
|
-
done,
|
|
107
|
-
developing,
|
|
108
|
-
planned,
|
|
109
|
-
idea,
|
|
110
|
-
progress: total > 0 ? Math.round(done / total * 100) : 0
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
});
|
|
114
|
-
if (unversioned.length > 0) {
|
|
115
|
-
const done = unversioned.filter((i) => i.status === "done").length;
|
|
116
|
-
roadmap.push({
|
|
117
|
-
version: "(\u672A\u5206\u914D)",
|
|
118
|
-
milestone: null,
|
|
119
|
-
items: unversioned,
|
|
120
|
-
stats: {
|
|
121
|
-
total: unversioned.length,
|
|
122
|
-
done,
|
|
123
|
-
developing: unversioned.filter((i) => i.status === "developing").length,
|
|
124
|
-
planned: unversioned.filter((i) => i.status === "planned").length,
|
|
125
|
-
idea: unversioned.filter((i) => i.status === "idea").length,
|
|
126
|
-
progress: unversioned.length > 0 ? Math.round(done / unversioned.length * 100) : 0
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
return roadmap;
|
|
131
|
-
}
|
|
132
|
-
function compareVersions(a, b) {
|
|
133
|
-
const normalize = (v) => v.replace(/^v/, "").split(".").map((n) => parseInt(n) || 0);
|
|
134
|
-
const aParts = normalize(a);
|
|
135
|
-
const bParts = normalize(b);
|
|
136
|
-
for (let i = 0; i < Math.max(aParts.length, bParts.length); i++) {
|
|
137
|
-
const diff = (aParts[i] || 0) - (bParts[i] || 0);
|
|
138
|
-
if (diff !== 0) return diff;
|
|
139
|
-
}
|
|
140
|
-
return 0;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export {
|
|
144
|
-
addMilestone,
|
|
145
|
-
doneMilestone,
|
|
146
|
-
activateMilestone,
|
|
147
|
-
listMilestones,
|
|
148
|
-
getMilestone,
|
|
149
|
-
getRoadmap
|
|
150
|
-
};
|