zdashboard 2.5.1 → 2.6.2

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.
Files changed (38) hide show
  1. package/dist/cli.js +160 -23
  2. package/dist/cli.js.map +1 -1
  3. package/dist/web/assets/FileIcon-Bc03q6Gz.js +279 -0
  4. package/dist/web/assets/FilterPills-CSZQenbh.js +1 -0
  5. package/dist/web/assets/ProgressBar-ycyJBwG-.js +1 -0
  6. package/dist/web/assets/Workspace-jCfxaTOM.js +1 -0
  7. package/dist/web/assets/badge-DUO7nDks.js +1 -0
  8. package/dist/web/assets/index-4aiRmNbP.css +1 -0
  9. package/dist/web/assets/{index-DKB8z9I8.js → index-BrvOKJRF.js} +1 -1
  10. package/dist/web/assets/index-Co_rMXPa.js +7816 -0
  11. package/dist/web/assets/web-BKh2HY35.js +2 -0
  12. package/dist/web/assets/web-BNjs9lCy.js +139 -0
  13. package/dist/web/assets/web-BrsVNrGk.js +1 -0
  14. package/dist/web/assets/web-Bt0s1qFE.js +5 -0
  15. package/dist/web/assets/web-CCoznDNk.js +2 -0
  16. package/dist/web/assets/web-DxK2pSVl.js +1 -0
  17. package/dist/web/assets/web-ShIDOvFD.js +1 -0
  18. package/dist/web/index.html +2 -2
  19. package/package.json +2 -1
  20. package/dist/web/assets/FileIcon-CWL_Aew0.js +0 -110
  21. package/dist/web/assets/FilterPills-DfrtQ2BX.js +0 -1
  22. package/dist/web/assets/MdViewer-DoCxNu7A.js +0 -270
  23. package/dist/web/assets/ProgressBar-CIDdp-03.js +0 -1
  24. package/dist/web/assets/Workspace-CsW6-X9a.js +0 -16
  25. package/dist/web/assets/badge-izTmQYbF.js +0 -1
  26. package/dist/web/assets/book-open-CCPWUzhH.js +0 -6
  27. package/dist/web/assets/file-text-DHJKu2eF.js +0 -6
  28. package/dist/web/assets/index-C39_SyD0.css +0 -1
  29. package/dist/web/assets/index-Cu37wtgU.js +0 -161
  30. package/dist/web/assets/vt323-latin-400-normal-Dqn9ZSPj.woff +0 -0
  31. package/dist/web/assets/web-9Iy8fpbv.js +0 -7
  32. package/dist/web/assets/web-C4KehBpT.js +0 -26
  33. package/dist/web/assets/web-CSsoKnCH.js +0 -2
  34. package/dist/web/assets/web-CnZCJ59N.js +0 -25
  35. package/dist/web/assets/web-DjRxK_Na.js +0 -16
  36. package/dist/web/assets/web-DuuJgOy2.js +0 -21
  37. package/dist/web/assets/web-DxAXHOpi.js +0 -16
  38. /package/dist/web/assets/{MdViewer-BTcE7LSd.css → FileIcon-BTcE7LSd.css} +0 -0
package/dist/cli.js CHANGED
@@ -167,7 +167,7 @@ import { fileURLToPath } from "url";
167
167
  // package.json
168
168
  var package_default = {
169
169
  name: "zdashboard",
170
- version: "2.5.1",
170
+ version: "2.6.2",
171
171
  description: "ZCode skill dashboard platform \u2014 pluggable viewers for zdesign/zview/zreview/zgoal",
172
172
  type: "module",
173
173
  bin: {
@@ -189,6 +189,7 @@ var package_default = {
189
189
  },
190
190
  dependencies: {
191
191
  "@fontsource/vt323": "^5.3.0",
192
+ "@phosphor-icons/react": "^2.1.10",
192
193
  "@radix-ui/react-dropdown-menu": "^2.1.24",
193
194
  "@radix-ui/react-scroll-area": "^1.2.0",
194
195
  "@radix-ui/react-separator": "^1.1.0",
@@ -686,7 +687,8 @@ var ReloadService = class extends Service2 {
686
687
  return () => this.clients.delete(res);
687
688
  });
688
689
  try {
689
- this.watcher = fs5.watch(config.root, { recursive: true }, () => {
690
+ this.watcher = fs5.watch(config.root, { recursive: true }, (eventType, filename) => {
691
+ if (filename && /^(?:\.git|node_modules|dist|\.pnpm)(?:[/\\]|$)/.test(filename)) return;
690
692
  if (this.timer) clearTimeout(this.timer);
691
693
  this.timer = setTimeout(() => {
692
694
  this.ctx.server.refreshGitInfo();
@@ -839,7 +841,7 @@ function scanTree(root, hasOpenspec, hasDocs) {
839
841
  const docs = buildTree(paths).map((n) => ({ ...n, path: n.path ? `docs/${n.path}` : void 0 }));
840
842
  if (docs.length) tree.push({ name: "docs", kind: "dir", children: docs });
841
843
  }
842
- const skip = /* @__PURE__ */ new Set(["openspec", "docs", "node_modules", ".git", "dist", "test-server"]);
844
+ const skip = /* @__PURE__ */ new Set(["openspec", "docs", "node_modules", ".git", "dist", "playground", ".zreview"]);
843
845
  const etc = [];
844
846
  try {
845
847
  for (const ent of fs7.readdirSync(root, { withFileTypes: true })) {
@@ -1245,62 +1247,148 @@ var apply4 = {
1245
1247
  import fs8 from "fs";
1246
1248
  import path7 from "path";
1247
1249
  import YAML2 from "yaml";
1248
- var REVIEW_CANDIDATES = [".zdev/review.yaml", "review.yaml"];
1250
+ var REVIEW_DIR = ".zreview";
1251
+ var REVIEW_FILE = path7.join(REVIEW_DIR, "review.yaml");
1252
+ var DOCS_DIR = path7.join(REVIEW_DIR, "docs");
1253
+ var DIAGRAMS_DIR = path7.join(REVIEW_DIR, "diagrams");
1249
1254
  var ReviewStore = class {
1250
1255
  root;
1251
- file;
1252
1256
  onChange;
1253
1257
  constructor(root, onChange) {
1254
1258
  this.root = root;
1255
1259
  this.onChange = onChange;
1256
- const existing = REVIEW_CANDIDATES.find((rel) => fs8.existsSync(path7.join(root, rel)));
1257
- this.file = path7.join(root, existing ?? REVIEW_CANDIDATES[0]);
1258
1260
  }
1259
1261
  exists() {
1260
- return fs8.existsSync(this.file);
1262
+ return fs8.existsSync(path7.join(this.root, REVIEW_FILE));
1261
1263
  }
1262
1264
  read() {
1265
+ const fullPath = path7.join(this.root, REVIEW_FILE);
1266
+ if (!fs8.existsSync(fullPath)) {
1267
+ return { status: "draft", summary: "", documents: [], codebases: [], diagrams: [], items: [] };
1268
+ }
1263
1269
  try {
1264
- const parsed = YAML2.parse(fs8.readFileSync(this.file, "utf8"));
1265
- if (!parsed || !Array.isArray(parsed.items)) return { status: "draft", items: [] };
1266
- return parsed;
1270
+ const parsed = YAML2.parse(fs8.readFileSync(fullPath, "utf8"));
1271
+ if (!parsed || !Array.isArray(parsed.items)) {
1272
+ return { status: "draft", summary: parsed?.summary ?? "", documents: parsed?.documents ?? [], codebases: parsed?.codebases ?? [], diagrams: parsed?.diagrams ?? [], items: [] };
1273
+ }
1274
+ return {
1275
+ status: parsed.status ?? "draft",
1276
+ summary: parsed.summary ?? "",
1277
+ documents: parsed.documents ?? [],
1278
+ codebases: parsed.codebases ?? [],
1279
+ diagrams: parsed.diagrams ?? [],
1280
+ items: parsed.items
1281
+ };
1267
1282
  } catch {
1268
- return { status: "draft", items: [] };
1283
+ return { status: "draft", summary: "", documents: [], codebases: [], diagrams: [], items: [] };
1269
1284
  }
1270
1285
  }
1271
1286
  write(data) {
1272
- fs8.mkdirSync(path7.dirname(this.file), { recursive: true });
1273
- fs8.writeFileSync(this.file, YAML2.stringify(data), "utf8");
1287
+ fs8.mkdirSync(path7.join(this.root, REVIEW_DIR), { recursive: true });
1288
+ fs8.writeFileSync(path7.join(this.root, REVIEW_FILE), YAML2.stringify(data), "utf8");
1274
1289
  this.onChange?.();
1275
1290
  }
1276
1291
  updateItem(id, patch) {
1277
1292
  const data = this.read();
1278
- const item = data.items.find((i) => i.id === id);
1293
+ const item = this.findItem(data.items, id);
1279
1294
  if (!item) throw new Error(`item ${id} not found`);
1280
1295
  if (patch.answer !== void 0) item.answer = patch.answer;
1281
1296
  if (patch.state !== void 0) item.state = patch.state;
1297
+ if (patch.priority !== void 0) item.priority = patch.priority;
1298
+ if (patch.title !== void 0) item.title = patch.title;
1282
1299
  if (patch.state === "answered" && !patch.answer && !item.answer) item.answer = "";
1283
1300
  this.write(data);
1284
1301
  return data;
1285
1302
  }
1303
+ addChild(parentId, title, priority = "medium") {
1304
+ const data = this.read();
1305
+ const parent = this.findItem(data.items, parentId);
1306
+ if (!parent) throw new Error(`parent ${parentId} not found`);
1307
+ if (!parent.children) parent.children = [];
1308
+ const newId = `${parentId}-${parent.children.length + 1}`;
1309
+ parent.children.push({
1310
+ id: newId,
1311
+ type: "decomposition",
1312
+ state: "open",
1313
+ title,
1314
+ priority
1315
+ });
1316
+ this.write(data);
1317
+ return data;
1318
+ }
1319
+ removeItem(id) {
1320
+ const data = this.read();
1321
+ const removed = this.removeItemFromList(data.items, id);
1322
+ if (!removed) throw new Error(`item ${id} not found`);
1323
+ this.write(data);
1324
+ return data;
1325
+ }
1286
1326
  setStatus(status) {
1287
1327
  const data = this.read();
1288
- if (status === "passed" && data.items.some((i) => i.state === "open")) {
1328
+ if (status === "passed" && this.hasOpenItems(data.items)) {
1289
1329
  throw new Error("\u5B58\u5728\u672A\u5904\u7406\u7684\u8BC4\u5BA1\u9879(open),\u4E0D\u80FD\u901A\u8FC7");
1290
1330
  }
1291
1331
  data.status = status;
1292
1332
  this.write(data);
1293
1333
  return data;
1294
1334
  }
1295
- docs() {
1335
+ listDocs() {
1336
+ const docsDir = path7.join(this.root, DOCS_DIR);
1337
+ if (!fs8.existsSync(docsDir)) return [];
1296
1338
  try {
1297
- const zdevDir = path7.join(this.root, ".zdev");
1298
- if (!fs8.existsSync(zdevDir) || !fs8.statSync(zdevDir).isDirectory()) return [];
1299
- return fs8.readdirSync(zdevDir).filter((f) => /\.(md|markdown)$/i.test(f) && fs8.statSync(path7.join(zdevDir, f)).isFile()).sort();
1339
+ return fs8.readdirSync(docsDir).filter((f) => /\.(md|markdown|txt)$/i.test(f)).sort();
1300
1340
  } catch {
1301
1341
  return [];
1302
1342
  }
1303
1343
  }
1344
+ readDoc(name) {
1345
+ const fullPath = path7.join(this.root, DOCS_DIR, name);
1346
+ if (!fs8.existsSync(fullPath)) throw new Error(`doc ${name} not found`);
1347
+ return fs8.readFileSync(fullPath, "utf8");
1348
+ }
1349
+ listDiagrams() {
1350
+ const dir = path7.join(this.root, DIAGRAMS_DIR);
1351
+ if (!fs8.existsSync(dir)) return [];
1352
+ try {
1353
+ return fs8.readdirSync(dir).filter((f) => /\.html$/i.test(f)).sort();
1354
+ } catch {
1355
+ return [];
1356
+ }
1357
+ }
1358
+ readDiagram(name) {
1359
+ const fullPath = path7.join(this.root, DIAGRAMS_DIR, name);
1360
+ if (!fs8.existsSync(fullPath)) throw new Error(`diagram ${name} not found`);
1361
+ return fs8.readFileSync(fullPath, "utf8");
1362
+ }
1363
+ findItem(items, id) {
1364
+ for (const item of items) {
1365
+ if (item.id === id) return item;
1366
+ if (item.children) {
1367
+ const found = this.findItem(item.children, id);
1368
+ if (found) return found;
1369
+ }
1370
+ }
1371
+ return null;
1372
+ }
1373
+ removeItemFromList(items, id) {
1374
+ for (let i = 0; i < items.length; i++) {
1375
+ if (items[i].id === id) {
1376
+ items.splice(i, 1);
1377
+ return true;
1378
+ }
1379
+ if (items[i].children && this.removeItemFromList(items[i].children, id)) {
1380
+ return true;
1381
+ }
1382
+ }
1383
+ return false;
1384
+ }
1385
+ hasOpenItems(items) {
1386
+ for (const item of items) {
1387
+ if (item.state === "open") return true;
1388
+ if (item.children && this.hasOpenItems(item.children)) return true;
1389
+ }
1390
+ return false;
1391
+ }
1304
1392
  };
1305
1393
 
1306
1394
  // src/plugins/review/index.ts
@@ -1310,7 +1398,7 @@ var apply5 = {
1310
1398
  const root = config.root;
1311
1399
  ctx.inject(["server"], () => {
1312
1400
  if (!ctx.server?.route) return;
1313
- ctx.dashboard.register({ mode: "review", label: "\u6587\u6863\u8BC4\u5BA1", icon: "\u2705", description: "review.yaml \u9010\u9879\u5BF9\u9F50" });
1401
+ ctx.dashboard.register({ mode: "review", label: "\u6587\u6863\u8BC4\u5BA1", icon: "\u2705", description: "\u591A\u6587\u6863\u9700\u6C42\u8BC4\u5BA1\u4E0E\u62C6\u89E3 \xB7 zreview" });
1314
1402
  const reviewStore = new ReviewStore(root, () => {
1315
1403
  ctx.reload.broadcast("files");
1316
1404
  });
@@ -1326,7 +1414,44 @@ var apply5 = {
1326
1414
  }
1327
1415
  try {
1328
1416
  const body = JSON.parse(await readBody(req) || "{}");
1329
- const data = reviewStore.updateItem(body.id, { answer: body.answer, state: body.state });
1417
+ const data = reviewStore.updateItem(body.id, {
1418
+ answer: body.answer,
1419
+ state: body.state,
1420
+ priority: body.priority,
1421
+ title: body.title
1422
+ });
1423
+ res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1424
+ res.end(JSON.stringify(data));
1425
+ } catch (e) {
1426
+ res.writeHead(400, { "Content-Type": "application/json; charset=utf-8" });
1427
+ res.end(JSON.stringify({ error: e instanceof Error ? e.message : "unknown error" }));
1428
+ }
1429
+ });
1430
+ ctx.server.route("/__review/item/add-child", async (req, res) => {
1431
+ if (req.headers["x-stop-token"] !== ctx.server.stopToken) {
1432
+ res.writeHead(403);
1433
+ res.end("forbidden");
1434
+ return;
1435
+ }
1436
+ try {
1437
+ const body = JSON.parse(await readBody(req) || "{}");
1438
+ const data = reviewStore.addChild(body.parentId, body.title, body.priority);
1439
+ res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1440
+ res.end(JSON.stringify(data));
1441
+ } catch (e) {
1442
+ res.writeHead(400, { "Content-Type": "application/json; charset=utf-8" });
1443
+ res.end(JSON.stringify({ error: e instanceof Error ? e.message : "unknown error" }));
1444
+ }
1445
+ });
1446
+ ctx.server.route("/__review/item/remove", async (req, res) => {
1447
+ if (req.headers["x-stop-token"] !== ctx.server.stopToken) {
1448
+ res.writeHead(403);
1449
+ res.end("forbidden");
1450
+ return;
1451
+ }
1452
+ try {
1453
+ const body = JSON.parse(await readBody(req) || "{}");
1454
+ const data = reviewStore.removeItem(body.id);
1330
1455
  res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1331
1456
  res.end(JSON.stringify(data));
1332
1457
  } catch (e) {
@@ -1352,7 +1477,19 @@ var apply5 = {
1352
1477
  });
1353
1478
  ctx.server.route("/__docs", async (_req, res) => {
1354
1479
  res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1355
- res.end(JSON.stringify(reviewStore.docs()));
1480
+ res.end(JSON.stringify(reviewStore.listDocs()));
1481
+ });
1482
+ ctx.server.route("/__docs/:name", async (req, res) => {
1483
+ try {
1484
+ const name = req.params?.name;
1485
+ if (!name) throw new Error("missing doc name");
1486
+ const content = reviewStore.readDoc(name);
1487
+ res.writeHead(200, { "Content-Type": "text/markdown; charset=utf-8", "Cache-Control": "no-cache" });
1488
+ res.end(content);
1489
+ } catch (e) {
1490
+ res.writeHead(404, { "Content-Type": "application/json; charset=utf-8" });
1491
+ res.end(JSON.stringify({ error: e instanceof Error ? e.message : "not found" }));
1492
+ }
1356
1493
  });
1357
1494
  });
1358
1495
  }