zdashboard 2.6.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 (28) hide show
  1. package/dist/cli.js +157 -22
  2. package/dist/cli.js.map +1 -1
  3. package/dist/web/assets/FileIcon-Bc03q6Gz.js +279 -0
  4. package/dist/web/assets/{FilterPills-B6u1IBeC.js → FilterPills-CSZQenbh.js} +1 -1
  5. package/dist/web/assets/{ProgressBar-CbyvyLzw.js → ProgressBar-ycyJBwG-.js} +1 -1
  6. package/dist/web/assets/{Workspace-DQmfVJh6.js → Workspace-jCfxaTOM.js} +1 -1
  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-BvuOeKbq.js → index-BrvOKJRF.js} +1 -1
  10. package/dist/web/assets/{index-BfA6l4to.js → index-Co_rMXPa.js} +2 -2
  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-BcTJQUKr.js → web-BrsVNrGk.js} +1 -1
  14. package/dist/web/assets/{web-BXCBKn6i.js → web-Bt0s1qFE.js} +1 -1
  15. package/dist/web/assets/{web-C8I10oqh.js → web-CCoznDNk.js} +1 -1
  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 +1 -1
  20. package/dist/web/assets/FileIcon-B0-2gV6a.js +0 -10
  21. package/dist/web/assets/MdViewer-Cvh3TNQI.js +0 -270
  22. package/dist/web/assets/badge-DTb6qo3S.js +0 -1
  23. package/dist/web/assets/index-DQkehbup.css +0 -1
  24. package/dist/web/assets/web-5newSm97.js +0 -1
  25. package/dist/web/assets/web-BOg9UnpC.js +0 -1
  26. package/dist/web/assets/web-CLCAgjmg.js +0 -1
  27. package/dist/web/assets/web-CXE89yN1.js +0 -2
  28. /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.6.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: {
@@ -841,7 +841,7 @@ function scanTree(root, hasOpenspec, hasDocs) {
841
841
  const docs = buildTree(paths).map((n) => ({ ...n, path: n.path ? `docs/${n.path}` : void 0 }));
842
842
  if (docs.length) tree.push({ name: "docs", kind: "dir", children: docs });
843
843
  }
844
- const skip = /* @__PURE__ */ new Set(["openspec", "docs", "node_modules", ".git", "dist", "playground"]);
844
+ const skip = /* @__PURE__ */ new Set(["openspec", "docs", "node_modules", ".git", "dist", "playground", ".zreview"]);
845
845
  const etc = [];
846
846
  try {
847
847
  for (const ent of fs7.readdirSync(root, { withFileTypes: true })) {
@@ -1247,62 +1247,148 @@ var apply4 = {
1247
1247
  import fs8 from "fs";
1248
1248
  import path7 from "path";
1249
1249
  import YAML2 from "yaml";
1250
- 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");
1251
1254
  var ReviewStore = class {
1252
1255
  root;
1253
- file;
1254
1256
  onChange;
1255
1257
  constructor(root, onChange) {
1256
1258
  this.root = root;
1257
1259
  this.onChange = onChange;
1258
- const existing = REVIEW_CANDIDATES.find((rel) => fs8.existsSync(path7.join(root, rel)));
1259
- this.file = path7.join(root, existing ?? REVIEW_CANDIDATES[0]);
1260
1260
  }
1261
1261
  exists() {
1262
- return fs8.existsSync(this.file);
1262
+ return fs8.existsSync(path7.join(this.root, REVIEW_FILE));
1263
1263
  }
1264
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
+ }
1265
1269
  try {
1266
- const parsed = YAML2.parse(fs8.readFileSync(this.file, "utf8"));
1267
- if (!parsed || !Array.isArray(parsed.items)) return { status: "draft", items: [] };
1268
- 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
+ };
1269
1282
  } catch {
1270
- return { status: "draft", items: [] };
1283
+ return { status: "draft", summary: "", documents: [], codebases: [], diagrams: [], items: [] };
1271
1284
  }
1272
1285
  }
1273
1286
  write(data) {
1274
- fs8.mkdirSync(path7.dirname(this.file), { recursive: true });
1275
- 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");
1276
1289
  this.onChange?.();
1277
1290
  }
1278
1291
  updateItem(id, patch) {
1279
1292
  const data = this.read();
1280
- const item = data.items.find((i) => i.id === id);
1293
+ const item = this.findItem(data.items, id);
1281
1294
  if (!item) throw new Error(`item ${id} not found`);
1282
1295
  if (patch.answer !== void 0) item.answer = patch.answer;
1283
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;
1284
1299
  if (patch.state === "answered" && !patch.answer && !item.answer) item.answer = "";
1285
1300
  this.write(data);
1286
1301
  return data;
1287
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
+ }
1288
1326
  setStatus(status) {
1289
1327
  const data = this.read();
1290
- if (status === "passed" && data.items.some((i) => i.state === "open")) {
1328
+ if (status === "passed" && this.hasOpenItems(data.items)) {
1291
1329
  throw new Error("\u5B58\u5728\u672A\u5904\u7406\u7684\u8BC4\u5BA1\u9879(open),\u4E0D\u80FD\u901A\u8FC7");
1292
1330
  }
1293
1331
  data.status = status;
1294
1332
  this.write(data);
1295
1333
  return data;
1296
1334
  }
1297
- docs() {
1335
+ listDocs() {
1336
+ const docsDir = path7.join(this.root, DOCS_DIR);
1337
+ if (!fs8.existsSync(docsDir)) return [];
1298
1338
  try {
1299
- const zdevDir = path7.join(this.root, ".zdev");
1300
- if (!fs8.existsSync(zdevDir) || !fs8.statSync(zdevDir).isDirectory()) return [];
1301
- 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();
1302
1340
  } catch {
1303
1341
  return [];
1304
1342
  }
1305
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
+ }
1306
1392
  };
1307
1393
 
1308
1394
  // src/plugins/review/index.ts
@@ -1312,7 +1398,7 @@ var apply5 = {
1312
1398
  const root = config.root;
1313
1399
  ctx.inject(["server"], () => {
1314
1400
  if (!ctx.server?.route) return;
1315
- 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" });
1316
1402
  const reviewStore = new ReviewStore(root, () => {
1317
1403
  ctx.reload.broadcast("files");
1318
1404
  });
@@ -1328,7 +1414,44 @@ var apply5 = {
1328
1414
  }
1329
1415
  try {
1330
1416
  const body = JSON.parse(await readBody(req) || "{}");
1331
- 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);
1332
1455
  res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1333
1456
  res.end(JSON.stringify(data));
1334
1457
  } catch (e) {
@@ -1354,7 +1477,19 @@ var apply5 = {
1354
1477
  });
1355
1478
  ctx.server.route("/__docs", async (_req, res) => {
1356
1479
  res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "no-cache" });
1357
- 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
+ }
1358
1493
  });
1359
1494
  });
1360
1495
  }