zdashboard 2.6.1 → 2.7.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/dist/cli.js +861 -282
- package/dist/cli.js.map +1 -1
- package/dist/web/assets/ApprovalPanel-CXQRioSw.js +1 -0
- package/dist/web/assets/BatchDashboard-BigPUG8g.js +2 -0
- package/dist/web/assets/CheckpointViewer-DBmTkC_E.js +1 -0
- package/dist/web/assets/ConfigField-BqjVlteZ.js +1 -0
- package/dist/web/assets/DependencyGraph-DPVneSQh.js +1 -0
- package/dist/web/assets/FileIcon-tDB2mYGC.js +279 -0
- package/dist/web/assets/{FilterPills-B6u1IBeC.js → FilterPills-CvO0pz85.js} +1 -1
- package/dist/web/assets/{ProgressBar-CbyvyLzw.js → ProgressBar-DIoIeYBA.js} +1 -1
- package/dist/web/assets/{Workspace-DQmfVJh6.js → Workspace-B2nKQnQf.js} +1 -1
- package/dist/web/assets/badge-CmIMTBDj.js +1 -0
- package/dist/web/assets/index-BHL7sr_b.css +1 -0
- package/dist/web/assets/{index-BvuOeKbq.js → index-CtlFZEcM.js} +1 -1
- package/dist/web/assets/{index-BfA6l4to.js → index-yx7txO50.js} +1565 -1565
- package/dist/web/assets/web-BBv8hkwo.js +1 -0
- package/dist/web/assets/web-BNjs9lCy.js +139 -0
- package/dist/web/assets/{web-BXCBKn6i.js → web-BX2cajm6.js} +1 -1
- package/dist/web/assets/web-BpBEbcYZ.js +1 -0
- package/dist/web/assets/web-CGbbhItO.js +2 -0
- package/dist/web/assets/web-CcDed_yx.js +1 -0
- package/dist/web/assets/{web-C8I10oqh.js → web-DsIjKVnn.js} +1 -1
- package/dist/web/assets/web-Eo4S0U_k.js +2 -0
- package/dist/web/favicon.svg +13 -5
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/FileIcon-B0-2gV6a.js +0 -10
- package/dist/web/assets/MdViewer-Cvh3TNQI.js +0 -270
- package/dist/web/assets/badge-DTb6qo3S.js +0 -1
- package/dist/web/assets/index-DQkehbup.css +0 -1
- package/dist/web/assets/web-5newSm97.js +0 -1
- package/dist/web/assets/web-BOg9UnpC.js +0 -1
- package/dist/web/assets/web-BcTJQUKr.js +0 -1
- package/dist/web/assets/web-CLCAgjmg.js +0 -1
- package/dist/web/assets/web-CXE89yN1.js +0 -2
- /package/dist/web/assets/{MdViewer-BTcE7LSd.css → FileIcon-BTcE7LSd.css} +0 -0
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/server/detect.ts","../src/server/bugs.ts","../src/server/api/fetch.ts","../src/server/errors.ts","../src/core/server.ts","../package.json","../src/core/instance.ts","../src/core/open-url.ts","../src/core/reload.ts","../src/server/spec-scan.ts","../src/server/walk.ts","../src/core/tree.ts","../src/core/worktrees.ts","../src/core/manifest.ts","../src/server/just-runner.ts","../src/core/read-body.ts","../src/plugins/just/index.ts","../src/plugins/bugs/index.ts","../src/server/review-store.ts","../src/plugins/review/index.ts","../src/plugins/apply/scan.ts","../src/plugins/apply/parse-tasks.ts","../src/plugins/apply/index.ts","../src/server/design-assets.ts","../src/plugins/design/index.ts","../src/plugins/view/index.ts","../src/plugins/stats/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { access, readdir } from 'node:fs/promises';\nimport { exec } from 'node:child_process';\nimport { parseArgs as utilParseArgs } from 'node:util';\nimport { detect } from './server/detect.js';\nimport type { DetectResult } from './server/detect.js';\nimport { Context, Service } from 'cordis';\nimport { ServerService, PLUGIN_STATIC_PREFIX } from './core/server.js';\nimport { ReloadService } from './core/reload.js';\nimport { apply as treeApply } from './core/tree.js';\nimport { apply as worktreesApply } from './core/worktrees.js';\nimport { DashboardService } from './core/manifest.js';\nimport {\n findReusable,\n stopInstance,\n writeRecord,\n clearRecord,\n} from './core/instance.js';\nimport { openUrl } from './core/open-url.js';\nimport { apply as justApply } from './plugins/just/index.js';\nimport { apply as bugsApply } from './plugins/bugs/index.js';\nimport { apply as reviewApply } from './plugins/review/index.js';\nimport { apply as applyApply } from './plugins/apply/index.js';\nimport { apply as designApply } from './plugins/design/index.js';\nimport { apply as viewApply } from './plugins/view/index.js';\nimport { apply as statsApply } from './plugins/stats/index.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst DEFAULT_PORT = 4190;\n\nfunction parseArgs() {\n const args = process.argv.slice(2);\n const { values } = utilParseArgs({\n options: {\n dir: { type: 'string' },\n port: { type: 'string' },\n open: { type: 'boolean', default: false },\n page: { type: 'string' },\n restart: { type: 'boolean', default: false },\n plugins: { type: 'string' },\n },\n args,\n strict: false,\n allowPositionals: false,\n });\n return {\n dir: typeof values.dir === 'string' ? values.dir : process.cwd(),\n port: typeof values.port === 'string' ? Number(values.port) : DEFAULT_PORT,\n portExplicit: args.some(a => a === '--port' || a.startsWith('--port=')),\n open: !!values.open,\n page: typeof values.page === 'string' ? values.page : null,\n restart: !!values.restart,\n plugins: typeof values.plugins === 'string' ? values.plugins : null,\n };\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try { await access(p); return true; } catch { return false; }\n}\n\nasync function loadExternal(ctx: Context, dir: string, root: string) {\n if (!dir) return;\n let tsxLoaded = false;\n try {\n const { register } = await import('tsx/esm/api');\n register();\n tsxLoaded = true;\n } catch {\n // tsx not available\n }\n\n try {\n const entries = await pathExists(dir) ? await readdir(dir, { withFileTypes: true }) : [];\n for (const ent of entries) {\n if (!ent.isDirectory()) continue;\n const candidates = tsxLoaded ? ['index.ts', 'index.js', 'index.mjs'] : ['index.js', 'index.mjs'];\n for (const name of candidates) {\n const p = path.join(dir, ent.name, name);\n if (await pathExists(p)) {\n try {\n const mod = await import(p);\n const plugin = mod.default ?? mod;\n if (plugin?.apply) {\n try {\n await ctx.plugin(plugin, { root });\n } catch (e) {\n console.error(`[zdashboard] failed to apply plugin ${ent.name}:`, e);\n break;\n }\n // 自动接线约定:mode === 目录名时补 external 标记与 viewerUrl\n const m = ctx.dashboard.get(ent.name);\n if (m && m.mode === ent.name) {\n const patch: Record<string, unknown> = { external: true };\n const webDir = path.join(dir, ent.name, 'web');\n if (await pathExists(path.join(webDir, 'index.html'))) {\n ctx.server.static(`${PLUGIN_STATIC_PREFIX}${ent.name}/`, webDir);\n if (!m.viewerUrl) patch.viewerUrl = `${PLUGIN_STATIC_PREFIX}${ent.name}/`;\n }\n ctx.dashboard.register({ ...m, ...patch });\n }\n }\n } catch (e) {\n console.error(`[zdashboard] failed to load plugin ${ent.name}:`, e);\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n}\n\nasync function main() {\n const args = parseArgs();\n const root = path.resolve(args.dir);\n\n // --- instance reuse (before creating Context) ---\n const existing = await findReusable(root);\n if (existing && !args.restart) {\n const u = `http://localhost:${existing.port}` + (args.page ? `#${args.page}` : '');\n if (args.open) openUrl(u);\n console.log(`[zdashboard] 已复用实例 ${u}(--restart 可强制重开)`);\n // 管道场景下 stdout 是异步写,显式等 flush 再 exit,避免日志被截断\n await new Promise<void>((resolve) => process.stdout.write('', () => resolve()));\n process.exit(0);\n }\n // 记录旧端口(--restart 时用于端口继承;stopInstance 会清 record)\n const oldRecord = existing && args.restart ? existing : null;\n if (oldRecord) {\n console.log(`[zdashboard] --restart:停止旧实例 pid=${oldRecord.pid}`);\n await stopInstance(oldRecord);\n }\n\n const appDir = path.resolve(__dirname, 'web');\n\n // P2: restart 且有旧记录时,起始端口用 record.port(用户显式 --port 则尊重)\n const startPort = oldRecord && !args.portExplicit ? oldRecord.port : args.port;\n\n // P0: 数据目录检测(.zdev/ 存在则优先)\n const zdevDir = path.join(root, '.zdev');\n const dataDir = fs.existsSync(zdevDir) ? '.zdev/' : '';\n\n const det = await detect(root);\n\n const ctx = new Context();\n\n // core services\n ctx.plugin(ServerService, {\n root,\n appDir,\n port: startPort,\n open: args.open,\n detect: det,\n page: args.page,\n dataDir: dataDir || undefined,\n onListen: (port: number) => writeRecord(root, port),\n });\n ctx.plugin(ReloadService, { root });\n ctx.plugin(treeApply, { root });\n ctx.plugin(worktreesApply, { root });\n ctx.plugin(DashboardService);\n\n // built-in plugins\n const plugins = [\n { name: 'stats', apply: statsApply },\n { name: 'just', apply: justApply },\n { name: 'bugs', apply: bugsApply },\n { name: 'review', apply: reviewApply },\n { name: 'apply', apply: applyApply },\n { name: 'design', apply: designApply },\n { name: 'view', apply: viewApply },\n ];\n for (const p of plugins) {\n try {\n ctx.plugin(p.apply, { root });\n } catch (e) {\n console.error(`[zdashboard] plugin ${p.name} failed:`, e);\n }\n }\n\n // external plugins\n if (args.plugins) {\n await loadExternal(ctx, path.resolve(args.plugins), root);\n }\n\n // graceful shutdown: clear .zdev record on SIGTERM / SIGINT\n const shutdown = () => {\n try { clearRecord(root); } catch {}\n process.exit(0);\n };\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n return ctx;\n}\n\nawait main().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { execFile } from 'node:child_process';\nimport { BUGS_CONFIG_CANDIDATES } from './bugs.js';\n\nexport interface DetectResult {\n hasOpenspec: boolean;\n hasDocs: boolean;\n hasJust: boolean;\n hasBugs: boolean;\n}\n\nfunction justAvailable(cwd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = execFile('just', ['--list', '--unsorted'], { cwd, timeout: 5000 }, (err) => {\n resolve(!err);\n });\n if (child.killed) resolve(false);\n });\n}\n\nexport async function detect(root: string): Promise<DetectResult> {\n const hasOpenspec = fs.existsSync(path.join(root, 'openspec'));\n const hasDocs = fs.existsSync(path.join(root, 'docs'));\n const hasJust = await justAvailable(root);\n const hasBugs = BUGS_CONFIG_CANDIDATES.some((rel) => fs.existsSync(path.join(root, rel)));\n return { hasOpenspec, hasDocs, hasJust, hasBugs };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\nimport { fetchJson } from './api/fetch.js';\n\n/** .zdev/config.yaml(优先)或 .zgoal/config.yaml(回退):禅道凭据配置,扁平 key: value */\nexport const BUGS_CONFIG_CANDIDATES = ['.zdev/config.yaml', '.zgoal/config.yaml'] as const;\n\nexport interface ZgoalConfig {\n url: string;\n account: string;\n password?: string;\n token?: string;\n product: number;\n}\n\nexport interface ZenBug {\n id: number;\n title: string;\n severity: number | string;\n pri: number | string;\n status: string;\n assignedTo: string;\n openedBy?: string;\n /** 指派给 config.account 的本人 */\n mine: boolean;\n}\n\nexport type BugsResult =\n | { ok: true; url: string; total: number; bugs: ZenBug[] }\n | { ok: false; error: string };\n\nfunction loadConfig(root: string): ZgoalConfig | null {\n for (const rel of BUGS_CONFIG_CANDIDATES) {\n const file = path.join(root, rel);\n if (!fs.existsSync(file)) continue;\n try {\n const kv = YAML.parse(fs.readFileSync(file, 'utf8'));\n if (!kv || typeof kv !== 'object') return null;\n const record = kv as Record<string, unknown>;\n const product = Number(record.product);\n if (!record.url || !product) return null;\n const str = (v: unknown) => (typeof v === 'string' ? v : v == null ? undefined : String(v));\n return {\n url: String(record.url).replace(/\\/+$/, ''),\n account: str(record.account) ?? '',\n password: str(record.password),\n token: str(record.token),\n product,\n };\n } catch {\n return null;\n }\n }\n return null;\n}\n\nlet tokenCache: { key: string; token: string; at: number } | null = null;\n\nasync function getToken(cfg: ZgoalConfig): Promise<string> {\n if (cfg.token) return cfg.token;\n const key = `${cfg.url}|${cfg.account}|${cfg.password ?? ''}`;\n if (tokenCache && tokenCache.key === key && Date.now() - tokenCache.at < 10 * 60_000) return tokenCache.token;\n const json = await fetchJson(`${cfg.url}/api.php/v1/tokens`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ account: cfg.account, password: cfg.password }),\n });\n const token = typeof json.token === 'string' ? json.token : '';\n if (!token) throw new Error('token 获取失败:检查 account / password');\n tokenCache = { key, token, at: Date.now() };\n return token;\n}\n\nfunction normBug(b: Record<string, unknown>, account: string): ZenBug {\n const assigned = b.assignedTo;\n const assignedTo =\n typeof assigned === 'string'\n ? assigned\n : assigned && typeof assigned === 'object' && 'realname' in (assigned as Record<string, unknown>)\n ? String((assigned as Record<string, unknown>).realname ?? '')\n : '';\n const assignedAccount =\n typeof assigned === 'string'\n ? assigned\n : assigned && typeof assigned === 'object'\n ? String((assigned as Record<string, unknown>).account ?? '')\n : '';\n const mine = !!account && (assignedAccount === account || assignedTo === account);\n return {\n id: Number(b.id),\n title: String(b.title ?? ''),\n severity: (b.severity as number | string) ?? 4,\n pri: (b.pri as number | string) ?? 3,\n status: String(b.status ?? ''),\n assignedTo,\n openedBy: typeof b.openedBy === 'string' ? b.openedBy : undefined,\n mine,\n };\n}\n\n/** 只读拉取禅道 bug 列表(GET,绝不写)。失败返回 ok:false,不抛。 */\nexport async function fetchBugs(root: string): Promise<BugsResult> {\n const cfg = loadConfig(root);\n if (!cfg) {\n const anyExists = BUGS_CONFIG_CANDIDATES.some((rel) => fs.existsSync(path.join(root, rel)));\n return {\n ok: false,\n error: anyExists\n ? '配置存在但无效(缺 url 或 product 字段)——检查 .zdev/config.yaml'\n : '.zdev/config.yaml 缺失(由 zgoal skill 创建;存量 .zgoal/config.yaml 亦可)',\n };\n }\n try {\n const token = await getToken(cfg);\n const json = await fetchJson(\n `${cfg.url}/api.php/v1/products/${cfg.product}/bugs?page=1&limit=100`,\n { headers: { Token: token } },\n );\n const raw = Array.isArray(json.bugs) ? (json.bugs as Record<string, unknown>[]) : [];\n return { ok: true, url: cfg.url, total: Number(json.total ?? raw.length), bugs: raw.map((b) => normBug(b, cfg.account)) };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, error: `禅道请求失败(${msg})——检查 url / 凭据 / 是否开启 RESTful API v1` };\n }\n}\n","import ky from 'ky';\nimport { HttpError, NetworkError } from '../errors.js';\n\nexport async function fetchJson(url: string, init?: RequestInit): Promise<Record<string, unknown>> {\n try {\n const res = await ky(url, { ...init, timeout: 8000, retry: 2 });\n return await res.json() as Record<string, unknown>;\n } catch (e) {\n if (e instanceof HttpError) throw e;\n if (e instanceof Error && e.name === 'TimeoutError') {\n throw new NetworkError(`请求超时: ${url}`);\n }\n if (e instanceof Error && e.name === 'HTTPError') {\n throw new HttpError((e as Error & { status?: number }).status ?? 500, e.message);\n }\n throw new NetworkError(`请求失败: ${url}`, e);\n }\n}\n","export class HttpError extends Error {\n constructor(\n public status: number,\n message: string,\n public body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n }\n}\n\nexport class NetworkError extends Error {\n constructor(message: string, public cause?: unknown) {\n super(message);\n this.name = 'NetworkError';\n }\n}\n\nexport function isHttpError(e: unknown): e is HttpError {\n return e instanceof HttpError;\n}\n","import http from 'node:http';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { fileURLToPath } from 'node:url';\nimport pkg from '../../package.json' with { type: 'json' };\nimport type { Context } from 'cordis';\nimport type { DetectResult } from '../server/detect.js';\nimport { Service } from 'cordis';\nimport { clearRecord } from './instance.js';\nimport { openUrl } from './open-url.js';\nimport { execFile } from 'node:child_process';\n\nconst VERSION = pkg.version;\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ServerOptions {\n root: string;\n appDir: string;\n port: number;\n open: boolean;\n page: string | null;\n detect: DetectResult;\n dataDir?: string;\n onListen?: (port: number) => void;\n}\n\ndeclare module 'cordis' {\n interface Context {\n server: ServerService;\n }\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8', '.htm': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8', '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8', '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml', '.png': 'image/png', '.ico': 'image/x-icon',\n '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.md': 'text/markdown; charset=utf-8', '.txt': 'text/plain; charset=utf-8',\n '.sql': 'text/plain; charset=utf-8', '.csv': 'text/plain; charset=utf-8',\n '.tsv': 'text/plain; charset=utf-8', '.yaml': 'text/yaml; charset=utf-8',\n '.yml': 'text/yaml; charset=utf-8', '.xml': 'application/xml; charset=utf-8',\n '.py': 'text/plain; charset=utf-8', '.ts': 'text/plain; charset=utf-8',\n '.java': 'text/plain; charset=utf-8', '.go': 'text/plain; charset=utf-8',\n '.rs': 'text/plain; charset=utf-8', '.rb': 'text/plain; charset=utf-8',\n '.php': 'text/plain; charset=utf-8', '.c': 'text/plain; charset=utf-8',\n '.cpp': 'text/plain; charset=utf-8', '.h': 'text/plain; charset=utf-8',\n '.cs': 'text/plain; charset=utf-8', '.swift': 'text/plain; charset=utf-8',\n '.kt': 'text/plain; charset=utf-8', '.scala': 'text/plain; charset=utf-8',\n '.sh': 'text/plain; charset=utf-8', '.bash': 'text/plain; charset=utf-8',\n '.zsh': 'text/plain; charset=utf-8', '.fish': 'text/plain; charset=utf-8',\n '.env': 'text/plain; charset=utf-8', '.gitignore': 'text/plain; charset=utf-8',\n '.dockerfile': 'text/plain; charset=utf-8',\n '.mp4': 'video/mp4', '.webm': 'video/webm', '.mov': 'video/quicktime',\n '.m4a': 'audio/mp4', '.aac': 'audio/aac',\n '.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/woff',\n '.map': 'application/json; charset=utf-8',\n};\n\nconst INJECT = `<script>(function(){try{var es=new EventSource('/__reload');es.addEventListener('reload',function(){location.reload();});es.onerror=function(){es.close();};}catch(e){}document.addEventListener('click',function(e){var t=e.target;if(t&&t.closest){var a=t.closest('a[target]');if(a&&a.target!=='_self'){a.target='_self';}}},true);})();</script>`;\n\nexport const PLUGIN_STATIC_PREFIX = '/__plugin/';\n\nexport class ServerService extends Service {\n stopToken: string;\n private root: string;\n private appDir: string;\n private open: boolean;\n private page: string | null;\n private det: DetectResult;\n private dataDir?: string;\n private routes = new Map<string, (req: http.IncomingMessage, res: http.ServerResponse) => void>();\n private sses = new Map<string, (res: http.ServerResponse) => (() => void) | void>();\n private prefixStatic = new Map<string, string>();\n private server?: http.Server;\n private onListen?: (port: number) => void;\n\n constructor(ctx: Context, config: ServerOptions) {\n super(ctx, 'server');\n this.stopToken = crypto.randomBytes(12).toString('hex');\n this.root = config.root;\n this.appDir = config.appDir;\n this.open = config.open;\n this.page = config.page;\n this.det = config.detect;\n this.dataDir = config.dataDir;\n this.onListen = config.onListen;\n ctx.effect(() => () => this.dispose());\n\n this.refreshGitInfo();\n this.route('/__config', (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ stopToken: this.stopToken, version: VERSION, root: this.root, ...this.gitInfo }));\n });\n\n this.route('/__stop', async (req, res) => {\n if (req.headers['x-stop-token'] !== this.stopToken) {\n res.writeHead(403);\n res.end('forbidden');\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{\"ok\":true}');\n this.stop();\n });\n\n this.start(config.port);\n }\n\n\n route(path: string, handler: (req: http.IncomingMessage, res: http.ServerResponse) => void) {\n this.routes.set(path, handler);\n this.ctx.effect(() => () => this.routes.delete(path));\n }\n\n sse(path: string, onConnect: (res: http.ServerResponse) => (() => void) | void) {\n this.sses.set(path, onConnect);\n this.ctx.effect(() => () => this.sses.delete(path));\n }\n\n static(prefix: string, dir: string) {\n this.prefixStatic.set(prefix, dir);\n this.ctx.effect(() => () => this.prefixStatic.delete(prefix));\n }\n\n private serveFile(filePath: string, req: http.IncomingMessage, res: http.ServerResponse, injectHtml: boolean) {\n fs.stat(filePath, (err, stat) => {\n if (err) { res.writeHead(404); return res.end('Not found'); }\n const ext = path.extname(filePath).toLowerCase();\n const ct = MIME[ext] ?? 'application/octet-stream';\n\n // ---- HTTP Range support ----\n const rangeHeader = (req.headers['range'] as string | undefined);\n let range: { start: number; end: number } | null = null;\n if (rangeHeader) {\n const m = rangeHeader.match(/^bytes=(\\d+)-(\\d*)$/);\n if (m) {\n const start = Number(m[1]);\n const end = m[2] !== '' ? Number(m[2]) : stat.size - 1;\n if (!Number.isNaN(start) && !Number.isNaN(end) && start <= end && start < stat.size) {\n range = { start, end: Math.min(end, stat.size - 1) };\n }\n // malformed range → fall through to 200 full response\n }\n // unparseable range header → fall through to 200 full response\n }\n\n if (range) {\n const { start, end } = range;\n const chunkSize = end - start + 1;\n res.writeHead(206, {\n 'Content-Type': ct,\n 'Content-Length': String(chunkSize),\n 'Content-Range': `bytes ${start}-${end}/${stat.size}`,\n 'Accept-Ranges': 'bytes',\n 'Cache-Control': 'no-cache',\n });\n // stat 成功后文件仍可能在 open 前被删/换(高频增删的工作区),流错误无人接会崩进程\n const stream = fs.createReadStream(filePath, { start, end });\n stream.on('error', () => { try { res.destroy(); } catch { /* 已断 */ } });\n stream.pipe(res);\n return;\n }\n\n // Full response\n fs.readFile(filePath, (err, data) => {\n if (err) { res.writeHead(404); return res.end('Not found'); }\n let body: string | Buffer = data;\n if (injectHtml && ext === '.html') {\n const s = data.toString('utf8');\n body = Buffer.from(s.indexOf('</body>') >= 0 ? s.replace('</body>', INJECT + '</body>') : s + INJECT);\n }\n res.writeHead(200, { 'Content-Type': ct, 'Accept-Ranges': 'bytes', 'Cache-Control': 'no-cache' });\n res.end(body);\n });\n });\n }\n\n private servePrefix(url: string, req: http.IncomingMessage, res: http.ServerResponse): boolean {\n for (const [prefix, dir] of this.prefixStatic) {\n if (url.indexOf(prefix) === 0) {\n let rel = this.safeDecode(url.slice(prefix.length));\n if (!rel || rel === '/' || !path.extname(rel)) rel = path.join(rel || '', 'index.html');\n const fp = path.join(dir, rel);\n if (fp.indexOf(dir + path.sep) !== 0) { res.writeHead(403); res.end('Forbidden'); return false; }\n this.serveFile(fp, req, res, true);\n return true;\n }\n }\n return false;\n }\n\n private safeDecode(raw: string): string {\n try { return decodeURIComponent(raw); } catch { return raw; }\n }\n\n private handler = (req: http.IncomingMessage, res: http.ServerResponse) => {\n try {\n const rawUrl = req.url || '/';\n const url = rawUrl.split('?')[0];\n\n const rh = this.routes.get(url);\n if (rh) { rh(req, res); return; }\n const sh = this.sses.get(url);\n if (sh) {\n res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' });\n res.write(': connected\\n\\n');\n const cleanup = sh(res);\n req.on('close', () => { cleanup?.(); });\n return;\n }\n\n if (this.servePrefix(url, req, res)) return;\n\n if (url === '/' || url.indexOf('/__app/') === 0 || url.indexOf('/assets/') === 0) {\n let fp = this.appDir;\n if (url !== '/') fp = path.join(this.appDir, this.safeDecode(url));\n if (url.indexOf('/__app/') === 0) fp = path.join(this.appDir, url.slice(7));\n if (fp !== this.appDir && fp.indexOf(this.appDir + path.sep) !== 0) { res.writeHead(403); return res.end('Forbidden'); }\n if (url === '/') fp = path.join(this.appDir, 'index.html');\n return this.serveFile(fp, req, res, false);\n }\n\n const fp = path.join(this.root, this.safeDecode(url));\n if (fp !== this.root && fp.indexOf(this.root + path.sep) !== 0) { res.writeHead(403); return res.end('Forbidden'); }\n return this.serveFile(fp, req, res, true);\n } catch (e) {\n try { res.writeHead(400); res.end('bad request'); } catch {}\n console.error('[zdashboard] handler error', e);\n }\n };\n\n start(port: number) {\n this.server = http.createServer(this.handler);\n // 浏览器复用空闲 keep-alive 连接时若已被服务端关闭,请求会石沉大海(点击无响应)。\n // 拉长 keep-alive 使其远大于浏览器侧空闲窗口\n this.server.keepAliveTimeout = 65_000;\n this.server.headersTimeout = 66_000;\n this.server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(`[zdashboard] port ${port} busy, trying ${port + 1}`);\n this.start(port + 1);\n } else throw err;\n });\n this.server.listen(port, '127.0.0.1', () => {\n const u = `http://localhost:${port}`;\n const target = this.page ? `${u}#${this.page}` : u;\n console.log(`[zdashboard] v${VERSION} dashboard -> ${u}`);\n console.log(`[zdashboard] project -> ${this.root}`);\n console.log(`[zdashboard] detect -> openspec:${this.det.hasOpenspec} docs:${this.det.hasDocs} just:${this.det.hasJust} bugs:${this.det.hasBugs}`);\n if (this.dataDir) console.log(`[zdashboard] data -> ${this.dataDir}`);\n if (this.open) openUrl(target);\n this.onListen?.(port);\n });\n }\n\n /** 项目 git 信息(分支/脏文件数),启动探测一次,文件变更时刷新 */\n private gitInfo: { branch?: string; dirty?: number } = {};\n\n refreshGitInfo() {\n const run = (args: string[]) => new Promise<string>((resolve) => {\n execFile('git', args, { cwd: this.root, timeout: 3000 }, (err, stdout) => resolve(err ? '' : stdout));\n });\n void (async () => {\n const [branch, status] = await Promise.all([\n run(['rev-parse', '--abbrev-ref', 'HEAD']),\n run(['status', '--porcelain']),\n ]);\n const b = branch.trim();\n this.gitInfo = b ? { branch: b, dirty: status ? status.split('\\n').filter(Boolean).length : 0 } : {};\n })();\n }\n\n stop() {\n if (this.server) { try { this.server.close(); } catch {} }\n try { clearRecord(this.root); } catch {}\n setTimeout(() => {\n try { this.ctx.root.fiber.dispose(); } catch {}\n process.exit(0);\n }, 50);\n }\n\n dispose() {\n if (this.server) { try { this.server.close(); } catch {} }\n try { clearRecord(this.root); } catch {}\n }\n}\n","{\n \"name\": \"zdashboard\",\n \"version\": \"2.6.1\",\n \"description\": \"ZCode skill dashboard platform — pluggable viewers for zdesign/zview/zreview/zgoal\",\n \"type\": \"module\",\n \"bin\": {\n \"zdashboard\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"tsup && vite build\",\n \"build:web\": \"vite build\",\n \"build:node\": \"tsup\",\n \"start\": \"node dist/cli.js\",\n \"preview\": \"vite preview\"\n },\n \"dependencies\": {\n \"@fontsource/vt323\": \"^5.3.0\",\n \"@phosphor-icons/react\": \"^2.1.10\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.24\",\n \"@radix-ui/react-scroll-area\": \"^1.2.0\",\n \"@radix-ui/react-separator\": \"^1.1.0\",\n \"@radix-ui/react-slot\": \"^1.1.0\",\n \"@radix-ui/react-tooltip\": \"^1.1.2\",\n \"@uidotdev/usehooks\": \"^2.4.0\",\n \"ansi-to-react\": \"^6.1.6\",\n \"class-variance-authority\": \"^0.7.0\",\n \"clsx\": \"^2.1.1\",\n \"cordis\": \"4.0.0-rc.8\",\n \"cosmokit\": \"^1.8.1\",\n \"date-fns\": \"^3.6.0\",\n \"filesize\": \"^11.0.0\",\n \"highlight.js\": \"^11.11.1\",\n \"katex\": \"^0.16.11\",\n \"ky\": \"^1.7.0\",\n \"lodash-es\": \"^4.17.21\",\n \"lucide-react\": \"^0.460.0\",\n \"pixelarticons\": \"^2.4.1\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-error-boundary\": \"^5.0.0\",\n \"react-markdown\": \"^9.0.1\",\n \"rehype-autolink-headings\": \"^7.1.0\",\n \"rehype-highlight\": \"^7.0.1\",\n \"rehype-katex\": \"^7.0.1\",\n \"rehype-raw\": \"^7.0.0\",\n \"rehype-slug\": \"^6.0.0\",\n \"remark-frontmatter\": \"^5.0.0\",\n \"remark-gfm\": \"^4.0.0\",\n \"remark-math\": \"^6.0.0\",\n \"sonner\": \"^1.5.0\",\n \"tailwind-merge\": \"^2.5.4\",\n \"tsx\": \"^4.7.0\",\n \"use-debounce\": \"^10.0.0\",\n \"yaml\": \"^2.9.0\"\n },\n \"devDependencies\": {\n \"@tailwindcss/typography\": \"^0.5.20\",\n \"@testing-library/jest-dom\": \"^7.0.1\",\n \"@testing-library/react\": \"^16.3.2\",\n \"@types/lodash-es\": \"^4.17.12\",\n \"@types/node\": \"^22.9.0\",\n \"@types/react\": \"^18.3.12\",\n \"@types/react-dom\": \"^18.3.1\",\n \"@vitejs/plugin-react\": \"^4.7.0\",\n \"autoprefixer\": \"^10.4.20\",\n \"jsdom\": \"^30.0.1\",\n \"postcss\": \"^8.4.49\",\n \"tailwindcss\": \"^3.4.14\",\n \"tailwindcss-animate\": \"^1.0.7\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.6.3\",\n \"vite\": \"^5.4.10\",\n \"vitest\": \"^1.6.0\"\n },\n \"pnpm\": {\n \"onlyBuiltDependencies\": [\n \"esbuild\"\n ]\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface InstanceRecord {\n pid: number;\n port: number;\n root: string;\n startedAt: string;\n}\n\nexport const RECORD_FILE = '.zdev/dashboard.json';\nexport const VERIFY_TIMEOUT_MS = 1500;\nexport const STOP_POLL_MS = 2000;\nexport const STOP_POLL_INTERVAL_MS = 100;\nexport const STOP_FINAL_WAIT_MS = 100;\n\nfunction recordPath(root: string): string {\n return path.join(root, RECORD_FILE);\n}\n\nexport function readRecord(root: string): InstanceRecord | null {\n try {\n const fp = recordPath(root);\n const raw = fs.readFileSync(fp, 'utf-8');\n const rec = JSON.parse(raw) as Partial<InstanceRecord>;\n if (\n typeof rec.pid === 'number' &&\n typeof rec.port === 'number' &&\n typeof rec.root === 'string' &&\n typeof rec.startedAt === 'string'\n ) {\n return rec as InstanceRecord;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function writeRecord(root: string, port: number): void {\n fs.mkdirSync(path.dirname(recordPath(root)), { recursive: true });\n const rec: InstanceRecord = {\n pid: process.pid,\n port,\n root,\n startedAt: new Date().toISOString(),\n };\n fs.writeFileSync(recordPath(root), JSON.stringify(rec, null, 2) + '\\n');\n}\n\nexport function clearRecord(root: string): void {\n try {\n // 属主校验:记录若已指向别的实例(并发双启落败者),不得误删胜者记录\n const rec = readRecord(root);\n if (rec && rec.pid !== process.pid) return;\n fs.unlinkSync(recordPath(root));\n } catch {\n // best-effort\n }\n}\n\nexport function isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ESRCH') return false;\n // EPERM or other → process exists, we just can't signal it\n return true;\n }\n}\n\nasync function fetchWithTimeout(url: string): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), VERIFY_TIMEOUT_MS);\n try {\n return await fetch(url, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function verifyRoot(port: number, root: string): Promise<boolean> {\n try {\n const res = await fetchWithTimeout(`http://127.0.0.1:${port}/__config`);\n if (res.status !== 200) return false;\n const body = await res.json();\n if (typeof body.root !== 'string') return false;\n return body.root === root;\n } catch {\n return false;\n }\n}\n\nexport async function findReusable(root: string): Promise<InstanceRecord | null> {\n const rec = readRecord(root);\n if (!rec) return null;\n if (!isAlive(rec.pid)) return null;\n if (!(await verifyRoot(rec.port, root))) return null;\n return rec;\n}\n\nexport async function stopInstance(record: InstanceRecord): Promise<void> {\n try {\n process.kill(record.pid, 'SIGTERM');\n } catch {\n return;\n }\n\n const deadline = Date.now() + STOP_POLL_MS;\n while (Date.now() < deadline) {\n if (!isAlive(record.pid)) return;\n await new Promise((r) => setTimeout(r, STOP_POLL_INTERVAL_MS));\n }\n\n // still alive → SIGKILL\n try {\n process.kill(record.pid, 'SIGKILL');\n } catch {\n // ignore\n }\n await new Promise((r) => setTimeout(r, STOP_FINAL_WAIT_MS));\n}\n","import { exec, execFile } from 'node:child_process';\n\n/** 跨平台打开浏览器(macOS open / Windows start / Linux xdg-open) */\nexport function openUrl(url: string): void {\n const cmd =\n process.platform === 'darwin' ? 'open' :\n process.platform === 'win32' ? 'start' :\n 'xdg-open';\n // win32 `start` 是 shell 内建命令,只能走 shell;其他平台直接用 execFile\n if (process.platform === 'win32') {\n exec(`start \"\" \"${url}\"`);\n } else {\n execFile(cmd, [url]);\n }\n}\n","import fs from 'node:fs';\nimport http from 'node:http';\nimport { Service } from 'cordis';\nimport type { Context } from 'cordis';\n\ndeclare module 'cordis' {\n interface Context {\n reload: ReloadService;\n }\n}\n\nconst WATCH_DEBOUNCE_MS = 150;\n\nexport class ReloadService extends Service {\n static inject = ['server'];\n private clients = new Set<http.ServerResponse>();\n private watcher?: fs.FSWatcher;\n private timer?: NodeJS.Timeout;\n\n constructor(ctx: Context, config: { root: string }) {\n super(ctx, 'reload');\n this.ctx.effect(() => () => this.dispose());\n\n this.ctx.server.sse('/__reload', (res) => {\n this.clients.add(res);\n return () => this.clients.delete(res);\n });\n\n try {\n this.watcher = fs.watch(config.root, { recursive: true }, (eventType, filename) => {\n if (filename && /^(?:\\.git|node_modules|dist|\\.pnpm)(?:[/\\\\]|$)/.test(filename)) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.ctx.server.refreshGitInfo(); // 分支/脏数可能已变,先行刷新再广播\n this.broadcast('reload');\n this.broadcast('files');\n }, WATCH_DEBOUNCE_MS);\n });\n } catch {\n // watch unavailable - static only\n }\n }\n\n broadcast(ev: string, data: unknown = '') {\n const payload = `event: ${ev}\\ndata: ${JSON.stringify(data == null ? '' : data)}\\n\\n`;\n for (const c of this.clients) {\n try { c.write(payload); } catch {}\n }\n }\n\n dispose() {\n if (this.watcher) { try { this.watcher.close(); } catch {} }\n if (this.timer) { clearTimeout(this.timer); }\n for (const c of this.clients) { try { c.end(); } catch {} }\n this.clients.clear();\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from './walk.js';\n\nexport type NodeKind = 'file' | 'dir' | 'log';\nexport interface TreeNode {\n name: string;\n kind: NodeKind;\n path?: string;\n defaultCollapsed?: boolean;\n children?: TreeNode[];\n}\n\nfunction buildTree(paths: string[]): TreeNode[] {\n const root: TreeNode[] = [];\n const map = new Map<string, TreeNode>();\n\n for (const p of paths) {\n const parts = p.split('/');\n let current = '';\n let parent = root;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n current = current ? `${current}/${part}` : part;\n const isLast = i === parts.length - 1;\n\n if (!map.has(current)) {\n const node: TreeNode = {\n name: part,\n kind: isLast ? 'file' : 'dir',\n ...(isLast ? { path: p } : { children: [] }),\n };\n map.set(current, node);\n parent.push(node);\n }\n\n if (!isLast) {\n parent = map.get(current)!.children!;\n }\n }\n }\n\n const sortNodes = (nodes: TreeNode[]) => {\n nodes.sort((a, b) => (a.kind === b.kind ? a.name.localeCompare(b.name) : a.kind === 'dir' ? -1 : 1));\n for (const n of nodes) {\n if (n.children) sortNodes(n.children);\n }\n };\n\n sortNodes(root);\n return root;\n}\n\n/** 方案模式树形扫描:openspec 感知 + docs 聚合 + 其他兜底 */\nexport function scanTree(root: string, hasOpenspec: boolean, hasDocs: boolean): TreeNode[] {\n const tree: TreeNode[] = [];\n if (hasOpenspec && fs.existsSync(path.join(root, 'openspec', 'changes'))) {\n const changesDir = path.join(root, 'openspec', 'changes');\n const active: TreeNode[] = [];\n const archived: TreeNode[] = [];\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.') || ent.name === 'archive') continue;\n const relBase = `openspec/changes/${ent.name}`;\n const paths: string[] = [];\n walkDir(path.join(changesDir, ent.name), { maxDepth: 4, onFile: (_, rel) => paths.push(rel ? `${relBase}/${rel}` : relBase) });\n const children = buildTree(paths).map((n) => ({ ...n, path: n.path ? `${relBase}/${n.path}` : undefined }));\n active.push({ name: ent.name, kind: 'dir', children });\n }\n active.sort((a, b) => a.name.localeCompare(b.name));\n const archiveDir = path.join(changesDir, 'archive');\n if (fs.existsSync(archiveDir)) {\n for (const ent of fs.readdirSync(archiveDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.')) continue;\n const relBase = `openspec/changes/archive/${ent.name}`;\n const paths: string[] = [];\n walkDir(path.join(archiveDir, ent.name), { maxDepth: 4, onFile: (_, rel) => paths.push(rel ? `${relBase}/${rel}` : relBase) });\n const children = buildTree(paths).map((n) => ({ ...n, path: n.path ? `${relBase}/${n.path}` : undefined }));\n archived.push({ name: ent.name, kind: 'dir', children });\n }\n archived.sort((a, b) => b.name.localeCompare(a.name)); // 日期前缀倒序\n }\n if (active.length) tree.push({ name: `changes (${active.length})`, kind: 'dir', children: active });\n if (archived.length) tree.push({ name: `archive (${archived.length})`, kind: 'dir', defaultCollapsed: true, children: archived });\n const specsDir = path.join(root, 'openspec', 'specs');\n if (fs.existsSync(specsDir)) {\n const paths: string[] = [];\n walkDir(specsDir, { maxDepth: 4, onFile: (_, rel) => paths.push(`openspec/specs/${rel}`) });\n const specs = buildTree(paths).map((n) => ({ ...n, path: n.path ? `openspec/specs/${n.path}` : undefined }));\n if (specs.length) tree.push({ name: 'specs', kind: 'dir', children: specs });\n }\n }\n if (hasDocs && fs.existsSync(path.join(root, 'docs'))) {\n const paths: string[] = [];\n walkDir(path.join(root, 'docs'), { maxDepth: 4, onFile: (_, rel) => paths.push(`docs/${rel}`) });\n const docs = buildTree(paths).map((n) => ({ ...n, path: n.path ? `docs/${n.path}` : undefined }));\n if (docs.length) tree.push({ name: 'docs', kind: 'dir', children: docs });\n }\n const skip = new Set(['openspec', 'docs', 'node_modules', '.git', 'dist', 'playground']); // .zworktree 以 . 开头已被点前缀过滤\n // \"其他\"只收根目录的 md 文档(README/CLAUDE 等);构建配置(pom.xml/justfile 等)不收——对\"方案+日志\"定位是噪音\n const etc: TreeNode[] = [];\n try {\n for (const ent of fs.readdirSync(root, { withFileTypes: true })) {\n if (ent.name.startsWith('.') || skip.has(ent.name)) continue;\n const ext = path.extname(ent.name).toLowerCase();\n if (ent.isFile() && (ext === '.md' || ext === '.markdown')) etc.push({ name: ent.name, kind: 'file', path: ent.name });\n }\n } catch (e) { console.error('[zdashboard] scan root etc failed:', e); }\n etc.sort((a, b) => a.name.localeCompare(b.name));\n if (etc.length) tree.push({ name: `other (${etc.length})`, kind: 'dir', children: etc });\n return tree;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface WalkOptions {\n skip?: Set<string>;\n maxDepth?: number;\n onFile?: (abs: string, rel: string) => void;\n onDir?: (abs: string, rel: string) => void;\n}\n\nexport function walkDir(root: string, opts: WalkOptions = {}): void {\n const { skip = new Set(), maxDepth, onFile, onDir } = opts;\n\n function walk(dir: string, rel: string, depth: number) {\n if (typeof maxDepth === 'number' && depth > maxDepth) return;\n let ents: fs.Dirent[];\n try { ents = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }\n for (const ent of ents) {\n if (ent.name.startsWith('.') || skip.has(ent.name)) continue;\n const abs = path.join(dir, ent.name);\n const r = rel ? `${rel}/${ent.name}` : ent.name;\n if (ent.isDirectory()) {\n onDir?.(abs, r);\n walk(abs, r, depth + 1);\n } else if (onFile) {\n onFile(abs, r);\n }\n }\n }\n\n walk(root, '', 0);\n}\n","import type { Context } from 'cordis';\nimport { scanTree } from '../server/spec-scan.js';\nimport { detect } from '../server/detect.js';\nimport type { DetectResult } from '../server/detect.js';\n\nexport const apply = {\n inject: ['server'] as const,\n apply(ctx: Context, config: { root: string }) {\n let cached: { p: Promise<DetectResult>; v?: DetectResult } | null = null;\n const getDet = async (): Promise<DetectResult> => {\n if (cached?.v) return cached.v;\n if (!cached) cached = { p: detect(config.root).catch(() => ({ hasOpenspec: false, hasDocs: false, hasJust: false, hasBugs: false } as DetectResult)) };\n const d = await cached.p;\n cached.v = d;\n return d;\n };\n\n const server = ctx.server;\n if (server?.route) {\n server.route('/__files', async (_req, res) => {\n try {\n const d = await getDet();\n const tree = scanTree(config.root, d.hasOpenspec, d.hasDocs);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ tree, ...d }));\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ tree: [], hasOpenspec: false, hasDocs: false, hasJust: false, hasBugs: false }));\n }\n });\n }\n },\n};\n","import { execFile } from 'node:child_process';\nimport type { Context } from 'cordis';\n\nexport interface WorktreeInfo {\n path: string;\n name: string;\n branch: string;\n head: string;\n dirty: boolean;\n}\n\nconst GIT_TIMEOUT_MS = 5_000;\nconst ZWORKTREE_SEGMENT = '.zworktree/';\n\nfunction runGit(args: string[], cwd: string): Promise<string> {\n return new Promise((resolve) => {\n execFile('git', args, { cwd, timeout: GIT_TIMEOUT_MS }, (err, stdout) => {\n if (err) return resolve('');\n resolve(stdout);\n });\n });\n}\n\nexport async function listWorktrees(root: string): Promise<WorktreeInfo[]> {\n const raw = await runGit(['worktree', 'list', '--porcelain'], root);\n if (!raw) return [];\n\n const entries: WorktreeInfo[] = [];\n const lines = raw.split('\\n');\n let current: Partial<WorktreeInfo> = {};\n\n for (const line of lines) {\n const m = line.match(/^(worktree|HEAD|branch|detached)\\s+(.+)$/);\n if (!m) continue;\n const [, key, val] = m;\n if (key === 'worktree') {\n if (current.path && current.path.includes(ZWORKTREE_SEGMENT)) {\n entries.push({\n path: current.path,\n name: current.path.split(ZWORKTREE_SEGMENT).pop() ?? '',\n branch: current.branch ?? '',\n head: current.head ?? '',\n dirty: false,\n });\n }\n current = { path: val, head: '', branch: '' };\n } else if (key === 'HEAD') {\n current.head = val;\n } else if (key === 'branch') {\n current.branch = val.replace(/^refs\\/heads\\//, '');\n }\n }\n\n // flush last entry\n if (current.path && current.path.includes(ZWORKTREE_SEGMENT)) {\n entries.push({\n path: current.path,\n name: current.path.split(ZWORKTREE_SEGMENT).pop() ?? '',\n branch: current.branch ?? '',\n head: current.head ?? '',\n dirty: false,\n });\n }\n\n // dirty detection: git status --porcelain 非空即 dirty(失败默认 false)\n await Promise.all(\n entries.map(async (entry) => {\n try {\n const statusOut = await runGit(['status', '--porcelain'], entry.path);\n entry.dirty = statusOut.trim().length > 0;\n } catch {\n entry.dirty = false;\n }\n })\n );\n\n return entries;\n}\n\nexport const apply = {\n inject: ['server'] as const,\n apply(ctx: Context, config: { root: string }) {\n const server = ctx.server;\n if (!server?.route) return;\n\n server.route('/__worktrees', async (_req, res) => {\n try {\n const entries = await listWorktrees(config.root);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(entries));\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify([]));\n }\n });\n },\n};\n","import { Service } from 'cordis';\nimport type { Context } from 'cordis';\n\ndeclare module 'cordis' {\n interface Context {\n dashboard: DashboardService;\n }\n}\n\nexport interface PluginManifest {\n mode: string;\n label: string;\n icon: string;\n description?: string;\n viewerUrl?: string; // 同源 URL,前端 iframe 渲染\n external?: boolean;\n}\n\nexport class DashboardService extends Service {\n static inject = ['server'];\n private plugins = new Map<string, PluginManifest>();\n\n constructor(ctx: Context) {\n super(ctx, 'dashboard');\n this.ctx.effect(() => () => this.plugins.clear());\n\n this.ctx.server.route('/__plugins', (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ plugins: Array.from(this.plugins.values()) }));\n });\n }\n\n register(manifest: PluginManifest) {\n this.plugins.set(manifest.mode, manifest);\n this.ctx.effect(() => () => this.plugins.delete(manifest.mode));\n }\n\n list() {\n return Array.from(this.plugins.values());\n }\n\n get(mode: string): PluginManifest | undefined {\n return this.plugins.get(mode);\n }\n}\n","import { spawn, execFile, type ChildProcess } from 'node:child_process';\n\nexport interface Recipe { name: string; description: string; }\nexport type TaskStatus = 'running' | 'exited';\nexport interface TaskInfo { recipe: string; state: TaskStatus; code: number | null; startedAt: number; signal?: string }\n\nexport type JustEvent =\n | { type: 'log'; recipe: string; text: string }\n | { type: 'clear'; recipe: string }\n | { type: 'state'; recipe: string; state: TaskStatus; code: number | null; startedAt?: number; signal?: string };\n\ninterface Task {\n recipe: string;\n child: ChildProcess | null;\n state: TaskStatus;\n code: number | null;\n signal?: string;\n startedAt: number;\n buffer: string[];\n pending: string; // 行缓冲:块缓冲输出会在行中间断开,攒到 \\n 才切行\n}\n\nconst MAX_BUFFER = 1000;\n\n/** 多任务并发 runner:每个 recipe 独立进程/日志/状态,同名 start 即重启,互不影响 */\nexport class JustRunner {\n private cwd: string;\n private tasks = new Map<string, Task>();\n private clients = new Set<(ev: JustEvent) => void>();\n private recipesCache: Recipe[] | null = null;\n\n constructor(cwd: string) { this.cwd = cwd; }\n\n recipes(): Promise<Recipe[]> {\n if (this.recipesCache) return Promise.resolve(this.recipesCache);\n return new Promise((resolve) => {\n execFile('just', ['--list', '--unsorted'], { cwd: this.cwd, maxBuffer: 1 << 20, timeout: 8000 }, (err, stdout) => {\n if (err) { resolve([]); return; }\n const out: Recipe[] = [];\n const seen = new Set<string>();\n for (const line of stdout.split(/\\r?\\n/).slice(1)) { // 跳过 \"Available recipes:\"\n const trimmed = line.trim();\n if (!trimmed) continue;\n const hashIdx = trimmed.indexOf('#');\n const sig = (hashIdx >= 0 ? trimmed.slice(0, hashIdx) : trimmed).trim();\n if (!sig) continue;\n const name = sig.split(/\\s+/)[0]; // \"hello msg=...\" -> \"hello\"\n if (seen.has(name)) continue;\n seen.add(name);\n out.push({ name, description: hashIdx >= 0 ? trimmed.slice(hashIdx + 1).trim() : '' });\n }\n this.recipesCache = out;\n resolve(out);\n });\n });\n }\n\n subscribe(fn: (ev: JustEvent) => void): () => void {\n this.clients.add(fn);\n // 连上即重放:全部任务的日志与状态\n for (const t of this.tasks.values()) {\n for (const text of t.buffer) fn({ type: 'log', recipe: t.recipe, text });\n fn({ type: 'state', recipe: t.recipe, state: t.state, code: t.code, startedAt: t.startedAt });\n }\n return () => this.clients.delete(fn);\n }\n\n private emit(ev: JustEvent) { for (const fn of this.clients) fn(ev); }\n\n list(): TaskInfo[] {\n return Array.from(this.tasks.values(), (t) => ({ recipe: t.recipe, state: t.state, code: t.code, startedAt: t.startedAt }));\n }\n\n /** 启动 recipe:同名先停旧进程(重启语义),不影响其他任务;调用方须先用 recipes() 校验名字 */\n start(recipe: string) {\n this.killOne(recipe);\n const task: Task = { recipe, child: null, state: 'running', code: null, startedAt: Date.now(), buffer: [], pending: '' };\n this.tasks.set(recipe, task);\n this.emit({ type: 'clear', recipe }); // 广播清屏:同步清掉该任务上一轮残留日志\n this.emit({ type: 'state', recipe, state: 'running', code: null, startedAt: task.startedAt });\n const child = spawn('just', [recipe], {\n cwd: this.cwd,\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '1', // node 生态(chalk 等)\n // maven 检测非 tty 会关颜色;经 MAVEN_OPTS 强制开(保留用户已有值)\n MAVEN_OPTS: `${process.env.MAVEN_OPTS ?? ''} -Dstyle.color=always`.trim(),\n CI: '',\n },\n });\n task.child = child;\n // 身份守卫:同名重启后旧进程的迟到输出/退出不得污染新任务(闭包 task 是旧对象时静默丢弃)\n const isStale = () => this.tasks.get(recipe) !== task;\n const push = (d: Buffer) => {\n if (isStale()) return;\n task.pending += d.toString();\n let idx: number;\n while ((idx = task.pending.indexOf('\\n')) >= 0) {\n const line = task.pending.slice(0, idx + 1);\n task.pending = task.pending.slice(idx + 1);\n this.pushLine(task, line);\n }\n // 无 \\n 的尾巴留在 pending,等下个 chunk(块缓冲输出会在行中断开,不能当独立行)\n };\n child.stdout?.on('data', push);\n child.stderr?.on('data', push);\n child.on('error', (err) => { this.pushLine(task, `[zdashboard] spawn error: ${err.message}\\n`); });\n child.on('exit', (code, signal) => {\n if (task.pending && !isStale()) { this.pushLine(task, task.pending + '\\n'); } // flush 末尾无换行的残留\n task.pending = '';\n task.child = null;\n task.state = 'exited';\n task.code = code ?? 0;\n task.signal = signal ?? undefined; // 用户主动 stop 时 code=null+SIGTERM,与成功退出区分\n if (isStale()) return; // 迟到的旧进程退出,不打扰新任务状态\n this.emit({ type: 'state', recipe, state: 'exited', code: task.code, startedAt: task.startedAt, signal: task.signal });\n });\n }\n\n private pushLine(task: Task, line: string) {\n task.buffer.push(line);\n if (task.buffer.length > MAX_BUFFER) task.buffer.shift();\n this.emit({ type: 'log', recipe: task.recipe, text: line });\n }\n\n /** 停单个任务;不传 recipe 停全部 */\n stop(recipe?: string) {\n if (recipe === undefined) { for (const t of this.tasks.values()) this.killOne(t.recipe); }\n else this.killOne(recipe);\n }\n\n restart(recipe: string) {\n if (this.tasks.has(recipe)) this.start(recipe);\n }\n\n /** 清空某任务的日志缓冲并广播(真源清除,重连重放不会复活) */\n clear(recipe: string) {\n const task = this.tasks.get(recipe);\n if (!task) return;\n task.buffer = [];\n task.pending = '';\n this.emit({ type: 'clear', recipe });\n }\n\n private killOne(recipe: string) {\n const task = this.tasks.get(recipe);\n const child = task?.child;\n if (child?.pid) {\n try {\n if (process.platform === 'win32') spawn('taskkill', ['/PID', String(child.pid), '/T', '/F']);\n else child.kill('SIGTERM');\n } catch { /* 已退出 */ }\n }\n if (task) { task.child = null; }\n }\n}\n","import http from 'node:http';\n\n/**\n * Read the full body of an IncomingMessage.\n * Listens for 'error' to prevent a hanging promise when the client aborts mid-stream.\n */\nexport async function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve) => {\n let data = '';\n req.on('data', (chunk: string | Buffer) => { data += chunk; });\n req.on('end', () => resolve(data));\n req.on('error', () => resolve('')); // client abort → settle with empty string\n });\n}\n","import type { Context } from 'cordis';\nimport http from 'node:http';\nimport { JustRunner } from '../../server/just-runner.js';\nimport { readBody } from '../../core/read-body.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n const runner = new JustRunner(root);\n ctx.effect(() => () => runner.stop());\n\n ctx.dashboard.register({ mode: 'just', label: 'Just Runner', icon: '📜', description: 'Just 多任务并发执行与日志' });\n\n ctx.server.route('/__just/recipes', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n try {\n const recipes = await runner.recipes();\n res.end(JSON.stringify(recipes));\n } catch {\n res.end(JSON.stringify([]));\n }\n });\n\n ctx.server.sse('/__just/logs', (res) => {\n const unsub = runner.subscribe((ev) => {\n res.write(`data: ${JSON.stringify(ev)}\\n\\n`);\n });\n return unsub;\n });\n\n /** start/restart 须带合法 recipe(同名 start 即重启,不影响其他任务);stop 可带单个 recipe 或省略(停全部) */\n const handleAction = async (req: http.IncomingMessage, res: http.ServerResponse, act: 'start' | 'stop' | 'restart' | 'clear') => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n const body = await readBody(req);\n let recipe: string | undefined;\n try { recipe = JSON.parse(body || '{}').recipe; } catch { /* ignore */ }\n if (act === 'clear') {\n if (recipe) runner.clear(recipe);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{\"ok\":true}');\n return;\n }\n if (act !== 'stop') {\n if (!recipe) { res.writeHead(400); res.end('{\"error\":\"no recipe\"}'); return; }\n const recipes = await runner.recipes();\n if (!recipes.some((r) => r.name === recipe)) { res.writeHead(403); res.end('{\"error\":\"unknown recipe\"}'); return; }\n runner.start(recipe);\n } else {\n runner.stop(recipe || undefined);\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify(runner.list()));\n };\n\n const routeAction = (name: 'start' | 'stop' | 'restart' | 'clear') => {\n ctx.server.route(`/__just/${name}`, (req, res) => {\n handleAction(req, res, name).catch(() => {\n if (!res.headersSent) { res.writeHead(500); res.end('{\"error\":\"internal\"}'); }\n });\n });\n };\n routeAction('start');\n routeAction('stop');\n routeAction('restart');\n routeAction('clear');\n });\n },\n};\n\n","import type { Context } from 'cordis';\nimport { fetchBugs } from '../../server/bugs.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'bugs', label: '禅道 Bugs', icon: '🎯', description: '只读 bug 列表' });\n\n ctx.server.route('/__bugs', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n try {\n const result = await fetchBugs(root);\n res.end(JSON.stringify(result));\n } catch (e) {\n res.end(JSON.stringify({ ok: false, error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\n\nexport type ItemState = 'open' | 'answered' | 'accepted' | 'dismissed';\nexport type ReviewStatus = 'draft' | 'reviewing' | 'passed' | 'rejected';\n\nexport interface ReviewItem {\n id: string;\n doc?: string;\n category?: string;\n severity?: 'high' | 'medium' | 'low';\n state: ItemState;\n question: string;\n answer?: string;\n}\n\nexport interface ReviewData {\n status: ReviewStatus;\n items: ReviewItem[];\n}\n\nconst REVIEW_CANDIDATES = ['.zdev/review.yaml', 'review.yaml'] as const;\n\nexport class ReviewStore {\n private root: string;\n private file: string;\n private onChange?: () => void;\n\n constructor(root: string, onChange?: () => void) {\n this.root = root;\n this.onChange = onChange;\n // 优先 .zdev/review.yaml,回退根目录 review.yaml;都不存在则用 .zdev 路径(新建跟着新协议走)\n const existing = REVIEW_CANDIDATES.find((rel) => fs.existsSync(path.join(root, rel)));\n this.file = path.join(root, existing ?? REVIEW_CANDIDATES[0]);\n }\n\n exists(): boolean { return fs.existsSync(this.file); }\n\n read(): ReviewData {\n try {\n const parsed = YAML.parse(fs.readFileSync(this.file, 'utf8')) as ReviewData;\n if (!parsed || !Array.isArray(parsed.items)) return { status: 'draft', items: [] };\n return parsed;\n } catch {\n return { status: 'draft', items: [] };\n }\n }\n\n private write(data: ReviewData) {\n fs.mkdirSync(path.dirname(this.file), { recursive: true });\n fs.writeFileSync(this.file, YAML.stringify(data), 'utf8');\n this.onChange?.();\n }\n\n updateItem(id: string, patch: { answer?: string; state?: ItemState }): ReviewData {\n const data = this.read();\n const item = data.items.find((i) => i.id === id);\n if (!item) throw new Error(`item ${id} not found`);\n if (patch.answer !== undefined) item.answer = patch.answer;\n if (patch.state !== undefined) item.state = patch.state;\n if (patch.state === 'answered' && !patch.answer && !item.answer) item.answer = '';\n this.write(data);\n return data;\n }\n\n setStatus(status: ReviewStatus): ReviewData {\n const data = this.read();\n if (status === 'passed' && data.items.some((i) => i.state === 'open')) {\n throw new Error('存在未处理的评审项(open),不能通过');\n }\n data.status = status;\n this.write(data);\n return data;\n }\n\n docs(): string[] {\n try {\n const zdevDir = path.join(this.root, '.zdev');\n if (!fs.existsSync(zdevDir) || !fs.statSync(zdevDir).isDirectory()) return [];\n return fs.readdirSync(zdevDir)\n .filter((f) => /\\.(md|markdown)$/i.test(f) && fs.statSync(path.join(zdevDir, f)).isFile())\n .sort();\n } catch { return []; }\n }\n}\n","import type { Context } from 'cordis';\nimport http from 'node:http';\nimport { ReviewStore, type ItemState, type ReviewStatus } from '../../server/review-store.js';\nimport { readBody } from '../../core/read-body.js';\n\nexport const apply = {\n inject: ['server', 'dashboard', 'reload'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'review', label: '文档评审', icon: '✅', description: 'review.yaml 逐项对齐' });\n\n const reviewStore = new ReviewStore(root, () => {\n ctx.reload.broadcast('files');\n });\n\n ctx.server.route('/__review', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(reviewStore.read()));\n });\n\n ctx.server.route('/__review/item', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.updateItem(body.id, { answer: body.answer, state: body.state as ItemState | undefined });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__review/status', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.setStatus(body.status as ReviewStatus);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__docs', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(reviewStore.docs()));\n });\n });\n },\n};\n\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { countTasks } from './parse-tasks.js';\n\nexport interface ChangeSummary {\n name: string;\n path: string;\n total: number;\n done: number;\n hasProposal: boolean;\n hasDesign: boolean;\n inWorktree: boolean;\n}\n\nexport interface ChangeDetail extends ChangeSummary {\n proposal?: string;\n design?: string;\n tasks: string;\n dependsOn: string[];\n hasTestStrategy: boolean;\n}\n\nfunction readText(p: string): string {\n try { return fs.readFileSync(p, 'utf8'); } catch { return ''; }\n}\n\nfunction worktreeDir(root: string, name: string): string {\n return path.join(root, '.zworktree', name);\n}\n\nfunction changeDir(root: string, name: string): string {\n return path.join(root, 'openspec', 'changes', name);\n}\n\nfunction parseDependsOn(proposal: string): string[] {\n const deps: string[] = [];\n // 提取 \"## 依赖\" 节:紧跟该标题的列表行\n const m = proposal.match(/^##\\s+依赖\\s*\\n([\\s\\S]*?)(?:\\n#{1,6}\\s|\\n---\\s*\\n|$)/i);\n if (!m) return deps;\n for (const line of m[1].split('\\n')) {\n // 仅收集零缩进的一级条目(/^-/),子级列表(缩进 -)不算依赖名\n if (!/^-\\s+/.test(line)) continue;\n const name = line.replace(/^-\\s+/, '').trim();\n if (name) deps.push(name);\n }\n return deps;\n}\n\nexport function scanApplyChanges(root: string): ChangeSummary[] {\n const changesDir = path.join(root, 'openspec', 'changes');\n if (!fs.existsSync(changesDir)) return [];\n const out: ChangeSummary[] = [];\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.') || ent.name === 'archive') continue;\n const wt = worktreeDir(root, ent.name);\n const tasks = readText(path.join(wt, 'openspec', 'changes', ent.name, 'tasks.md'));\n if (!tasks) {\n const fallback = readText(path.join(changesDir, ent.name, 'tasks.md'));\n if (fallback) {\n const { total, done } = countTasks(fallback);\n const wtChange = path.join(wt, 'openspec', 'changes', ent.name);\n const mainChange = path.join(changesDir, ent.name);\n out.push({\n name: ent.name,\n path: `openspec/changes/${ent.name}`,\n total,\n done,\n hasProposal: fs.existsSync(path.join(wtChange, 'proposal.md')) || fs.existsSync(path.join(mainChange, 'proposal.md')),\n hasDesign: fs.existsSync(path.join(wtChange, 'design.md')) || fs.existsSync(path.join(mainChange, 'design.md')),\n // worktree 目录存在即算执行中(tasks.md 可能尚未落盘)\n inWorktree: fs.existsSync(wtChange),\n });\n }\n } else {\n const { total, done } = countTasks(tasks);\n const wtChange = path.join(wt, 'openspec', 'changes', ent.name);\n const mainChange = path.join(changesDir, ent.name);\n out.push({\n name: ent.name,\n path: `openspec/changes/${ent.name}`,\n total,\n done,\n // 任一侧存在即算(详情读取是 worktree 优先、主目录兜底,列表标记保持一致)\n hasProposal: fs.existsSync(path.join(wtChange, 'proposal.md')) || fs.existsSync(path.join(mainChange, 'proposal.md')),\n hasDesign: fs.existsSync(path.join(wtChange, 'design.md')) || fs.existsSync(path.join(mainChange, 'design.md')),\n inWorktree: true,\n });\n }\n }\n out.sort((a, b) => a.name.localeCompare(b.name));\n return out;\n}\n\nexport function readApplyChange(root: string, name: string): ChangeDetail {\n const wt = worktreeDir(root, name);\n const mainChangeDir = changeDir(root, name);\n\n // 优先 worktree 内;回退主目录\n const proposalFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'proposal.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'proposal.md')\n : path.join(mainChangeDir, 'proposal.md');\n const designFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'design.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'design.md')\n : path.join(mainChangeDir, 'design.md');\n const tasksFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'tasks.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'tasks.md')\n : path.join(mainChangeDir, 'tasks.md');\n\n const proposal = readText(proposalFrom);\n const design = readText(designFrom);\n const tasks = readText(tasksFrom);\n const { total, done } = countTasks(tasks);\n const inWorktree = fs.existsSync(path.join(wt, 'openspec', 'changes', name));\n const dependsOn = parseDependsOn(proposal);\n const hasTestStrategy = /^##\\s+测试策略\\s*$/m.test(design);\n\n return {\n name,\n path: `openspec/changes/${name}`,\n total,\n done,\n hasProposal: !!proposal,\n hasDesign: !!design,\n inWorktree,\n proposal,\n design,\n tasks,\n dependsOn,\n hasTestStrategy,\n };\n}\n","const TASK_RE = /^\\s*-\\s*\\[([ xX])\\]\\s*(.*)$/;\n\nexport interface ParsedTask {\n text: string\n checked: boolean\n}\n\nexport function parseTasks(md: string): ParsedTask[] {\n return md\n .split('\\n')\n .filter((l) => TASK_RE.test(l))\n .map((l) => {\n const m = l.match(TASK_RE);\n return { text: (m?.[2] ?? l).trim(), checked: m?.[1] !== ' ' };\n });\n}\n\nexport function countTasks(md: string): { total: number; done: number } {\n const tasks = parseTasks(md);\n return { total: tasks.length, done: tasks.filter((t) => t.checked).length };\n}\n","import type { Context } from 'cordis';\nimport { scanApplyChanges, readApplyChange } from './scan.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'apply', label: '执行进度', icon: '⚙️', description: 'OpenSpec change 任务进度' });\n\n ctx.server.route('/__apply', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(scanApplyChanges(root)));\n });\n\n ctx.server.route('/__apply/change', async (req, res) => {\n const url = new URL(req.url || '', 'http://x');\n const name = url.searchParams.get('name');\n if (!name) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: 'missing name' }));\n return;\n }\n if (name.includes('..') || name.includes('/') || name.includes('\\\\')) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: 'invalid name' }));\n return;\n }\n try {\n const data = readApplyChange(root, name);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from './walk.js';\n\nexport type AssetType = 'page' | 'component' | 'icon' | 'token' | 'md' | 'video' | 'audio' | 'pdf' | 'font';\n\nconst PAGE_EXTS = ['.html', '.htm'];\nconst ICON_EXTS = ['.svg', '.png', '.ico', '.jpg', '.jpeg', '.gif', '.webp'];\nconst VIDEO_EXTS = ['.mp4', '.webm', '.mov', '.ogg', '.ogv'];\nconst AUDIO_EXTS = ['.mp3', '.wav', '.flac', '.aac', '.m4a'];\nconst CODE_EXTS = ['.js', '.mjs', '.cjs', '.mts', '.cts', '.ts', '.tsx', '.jsx', '.css', '.json', '.txt', '.xml', '.yml', '.yaml', '.sh', '.md'];\nconst FONT_EXTS = ['.woff', '.woff2', '.ttf', '.otf'];\nconst TOKEN_RE = /token|theme|design|color|palette|typograph/i;\n\nexport function categorize(rel: string, ext: string): AssetType | null {\n if (rel.indexOf('components/') === 0) return 'component';\n if (VIDEO_EXTS.includes(ext)) return 'video';\n if (AUDIO_EXTS.includes(ext)) return 'audio';\n if (ext === '.pdf') return 'pdf';\n if (ext === '.md') return 'md';\n if (FONT_EXTS.includes(ext)) return 'font';\n if (ICON_EXTS.includes(ext)) return 'icon';\n if (PAGE_EXTS.includes(ext)) return 'page';\n if (CODE_EXTS.includes(ext)) {\n if (TOKEN_RE.test(rel) && (ext === '.css' || ext === '.json')) return 'token';\n return null;\n }\n return null;\n}\n\nexport interface AssetFile { path: string; name: string; ext: string; type: AssetType; }\nexport type ScanResult = Record<AssetType, AssetFile[]>;\n\nexport function scanAssets(root: string): ScanResult {\n const out: ScanResult = {} as ScanResult;\n const keys: AssetType[] = ['page','component','icon','token','md','video','audio','pdf','font'];\n for (const k of keys) out[k] = [];\n const SKIP = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.next', '.cache']);\n walkDir(root, { skip: SKIP, onFile: (abs, rel) => {\n const ext = path.extname(abs).toLowerCase();\n const t = categorize(rel, ext);\n if (t) out[t].push({ path: rel, name: path.basename(abs), ext, type: t });\n }});\n return out;\n}\n","import type { Context } from 'cordis';\nimport { scanAssets } from '../../server/design-assets.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'design', label: '设计资产', icon: '🎨', description: '页面/组件/图标/Token 分类预览' });\n\n ctx.server.route('/__design/assets', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(scanAssets(root)));\n });\n });\n },\n};\n","import type { Context } from 'cordis';\n\nexport const apply = {\n inject: ['dashboard'] as const,\n apply(ctx: Context) {\n ctx.dashboard.register({ mode: 'view', label: '项目浏览', icon: '👁️', description: 'openspec / docs / 文档预览' });\n },\n};\n","import type { Context } from 'cordis';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from '../../server/walk.js';\n\ninterface Stats {\n root: string;\n files: number;\n dirs: number;\n totalSize: number;\n byExt: { ext: string; count: number }[];\n markdown: number;\n openspec: { active: number; archived: number };\n hasJust: boolean;\n}\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.cache']);\n\nfunction scan(root: string): Stats {\n const stats: Stats = {\n root: path.basename(root),\n files: 0,\n dirs: 0,\n totalSize: 0,\n byExt: [],\n markdown: 0,\n openspec: { active: 0, archived: 0 },\n hasJust: fs.existsSync(path.join(root, 'justfile')),\n };\n const extMap = new Map<string, number>();\n\n const walk = (dir: string) => {\n walkDir(dir, { skip: SKIP_DIRS, onDir: () => { stats.dirs++; }, onFile: (abs) => {\n stats.files++;\n try { stats.totalSize += fs.statSync(abs).size; } catch {}\n const ext = path.extname(abs).toLowerCase() || '(无扩展名)';\n extMap.set(ext, (extMap.get(ext) ?? 0) + 1);\n if (ext === '.md' || ext === '.markdown') stats.markdown++;\n }});\n };\n walk(root);\n\n const changesDir = path.join(root, 'openspec', 'changes');\n if (fs.existsSync(changesDir)) {\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.')) continue;\n if (ent.name === 'archive') {\n try {\n stats.openspec.archived = fs.readdirSync(path.join(changesDir, 'archive'), { withFileTypes: true })\n .filter(e => e.isDirectory() && !e.name.startsWith('.')).length;\n } catch { /* ignore */ }\n } else stats.openspec.active++;\n }\n }\n\n stats.byExt = Array.from(extMap.entries())\n .map(([ext, count]) => ({ ext, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n return stats;\n}\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n ctx.inject(['server', 'dashboard'], () => {\n const server = (ctx as any).server;\n const dashboard = (ctx as any).dashboard;\n if (!server?.route || !dashboard?.register) return;\n\n dashboard.register({\n mode: 'stats',\n label: '项目统计',\n icon: '📊',\n description: '项目文件统计 · 扫描生成',\n });\n\n server.route('/__stats/data', (_req: unknown, res: import('node:http').ServerResponse) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(scan(config.root)));\n });\n });\n },\n};\n"],"mappings":"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","names":["path","fs","fileURLToPath","fs","path","fs","path","fs","path","fs","path","execFile","execFile","path","fs","err","fp","fs","Service","fs","path","fs","path","fs","path","execFile","apply","Service","execFile","apply","apply","fs","path","YAML","apply","fs","path","fs","path","apply","path","path","apply","apply","fs","path","path","fs","apply","__dirname","path","fileURLToPath","fs","apply"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/server/detect.ts","../src/core/server.ts","../package.json","../src/core/instance.ts","../src/core/open-url.ts","../src/core/reload.ts","../src/server/spec-scan.ts","../src/server/walk.ts","../src/core/tree.ts","../src/core/worktrees.ts","../src/core/manifest.ts","../src/core/read-body.ts","../src/server/just-runner.ts","../src/plugins/just/index.ts","../src/server/api/fetch.ts","../src/server/errors.ts","../src/server/bugs.ts","../src/plugins/bugs/index.ts","../src/server/review-store.ts","../src/plugins/review/index.ts","../src/plugins/apply/scan.ts","../src/plugins/apply/parse-tasks.ts","../src/plugins/apply/index.ts","../src/plugins/design/index.ts","../src/server/design-assets.ts","../src/plugins/view/index.ts","../src/plugins/stats/index.ts","../src/server/apply-batch-store.ts","../src/plugins/apply-batch/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { access, readdir } from 'node:fs/promises';\nimport { exec } from 'node:child_process';\nimport { parseArgs as utilParseArgs } from 'node:util';\nimport { detect } from './server/detect.js';\nimport type { DetectResult } from './server/detect.js';\nimport { Context, Service } from 'cordis';\nimport { ServerService, PLUGIN_STATIC_PREFIX } from './core/server.js';\nimport { ReloadService } from './core/reload.js';\nimport { apply as treeApply } from './core/tree.js';\nimport { apply as worktreesApply } from './core/worktrees.js';\nimport { DashboardService } from './core/manifest.js';\nimport {\n findReusable,\n stopInstance,\n writeRecord,\n clearRecord,\n readPluginsConfig,\n writePluginsConfig,\n} from './core/instance.js';\nimport { openUrl } from './core/open-url.js';\nimport { apply as justApply } from './plugins/just/index.js';\nimport { apply as bugsApply } from './plugins/bugs/index.js';\nimport { apply as reviewApply } from './plugins/review/index.js';\nimport { apply as applyApply } from './plugins/apply/index.js';\nimport { apply as designApply } from './plugins/design/index.js';\nimport { apply as viewApply } from './plugins/view/index.js';\nimport { apply as statsApply } from './plugins/stats/index.js';\nimport { apply as applyBatchApply } from './plugins/apply-batch/index.js';\nimport YAML from 'yaml';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nconst DEFAULT_PORT = 4190;\n\nfunction parseArgs() {\n const args = process.argv.slice(2);\n const { values } = utilParseArgs({\n options: {\n dir: { type: 'string' },\n port: { type: 'string' },\n open: { type: 'boolean', default: false },\n page: { type: 'string' },\n restart: { type: 'boolean', default: false },\n plugins: { type: 'string' },\n },\n args,\n strict: false,\n allowPositionals: false,\n });\n return {\n dir: typeof values.dir === 'string' ? values.dir : process.cwd(),\n port: typeof values.port === 'string' ? Number(values.port) : DEFAULT_PORT,\n portExplicit: args.some(a => a === '--port' || a.startsWith('--port=')),\n open: !!values.open,\n page: typeof values.page === 'string' ? values.page : null,\n restart: !!values.restart,\n plugins: typeof values.plugins === 'string' ? values.plugins : null,\n };\n}\n\nasync function pathExists(p: string): Promise<boolean> {\n try { await access(p); return true; } catch { return false; }\n}\n\nfunction migrateLegacyBugsConfig(root: string): void {\n const zgoalConfigYaml = path.join(root, '.zgoal', 'config.yaml');\n const zdevConfigYaml = path.join(root, '.zdev', 'config.yaml');\n\n if (fs.existsSync(zgoalConfigYaml)) {\n try { fs.unlinkSync(zgoalConfigYaml); } catch { /* ignore */ }\n }\n\n if (!fs.existsSync(zdevConfigYaml)) return;\n\n const pluginsConfig = readPluginsConfig(root);\n if ('bugs' in pluginsConfig) {\n try { fs.unlinkSync(zdevConfigYaml); } catch { /* ignore */ }\n return;\n }\n\n let yamlContent: string;\n try {\n yamlContent = fs.readFileSync(zdevConfigYaml, 'utf8');\n } catch {\n return;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = YAML.parse(yamlContent) as Record<string, unknown>;\n } catch {\n console.warn('[zdashboard] 无效的 .zdev/config.yaml,已忽略并删除');\n try { fs.unlinkSync(zdevConfigYaml); } catch { /* ignore */ }\n return;\n }\n\n if (!parsed || typeof parsed !== 'object' || !parsed.url || !parsed.product) {\n console.warn('[zdashboard] .zdev/config.yaml 缺少必要字段,已忽略并删除');\n try { fs.unlinkSync(zdevConfigYaml); } catch { /* ignore */ }\n return;\n }\n\n const bugsConfig: Record<string, unknown> = {\n url: String(parsed.url).replace(/\\/+$/, ''),\n account: typeof parsed.account === 'string' ? parsed.account : '',\n token: typeof parsed.token === 'string' ? parsed.token : (typeof parsed.password === 'string' ? parsed.password : ''),\n product: Number(parsed.product),\n };\n\n pluginsConfig.bugs = bugsConfig;\n writePluginsConfig(root, pluginsConfig);\n\n try { fs.unlinkSync(zdevConfigYaml); } catch { /* ignore */ }\n}\n\nasync function loadExternal(ctx: Context, dir: string, root: string) {\n if (!dir) return;\n let tsxLoaded = false;\n try {\n const { register } = await import('tsx/esm/api');\n register();\n tsxLoaded = true;\n } catch {\n // tsx not available\n }\n\n try {\n const entries = await pathExists(dir) ? await readdir(dir, { withFileTypes: true }) : [];\n for (const ent of entries) {\n if (!ent.isDirectory()) continue;\n const candidates = tsxLoaded ? ['index.ts', 'index.js', 'index.mjs'] : ['index.js', 'index.mjs'];\n for (const name of candidates) {\n const p = path.join(dir, ent.name, name);\n if (await pathExists(p)) {\n try {\n const mod = await import(p);\n const plugin = mod.default ?? mod;\n if (plugin?.apply) {\n try {\n await ctx.plugin(plugin, { root });\n } catch (e) {\n console.error(`[zdashboard] failed to apply plugin ${ent.name}:`, e);\n break;\n }\n // 自动接线约定:mode === 目录名时补 external 标记与 viewerUrl\n const m = ctx.dashboard.get(ent.name);\n if (m && m.mode === ent.name) {\n const patch: Record<string, unknown> = { external: true };\n const webDir = path.join(dir, ent.name, 'web');\n if (await pathExists(path.join(webDir, 'index.html'))) {\n ctx.server.static(`${PLUGIN_STATIC_PREFIX}${ent.name}/`, webDir);\n if (!m.viewerUrl) patch.viewerUrl = `${PLUGIN_STATIC_PREFIX}${ent.name}/`;\n }\n ctx.dashboard.register({ ...m, ...patch });\n }\n }\n } catch (e) {\n console.error(`[zdashboard] failed to load plugin ${ent.name}:`, e);\n }\n break;\n }\n }\n }\n } catch {\n // ignore\n }\n}\n\nasync function main() {\n const args = parseArgs();\n const root = path.resolve(args.dir);\n\n // --- instance reuse (before creating Context) ---\n const existing = await findReusable(root);\n if (existing && !args.restart) {\n const u = `http://localhost:${existing.port}` + (args.page ? `#${args.page}` : '');\n if (args.open) openUrl(u);\n console.log(`[zdashboard] 已复用实例 ${u}(--restart 可强制重开)`);\n // 管道场景下 stdout 是异步写,显式等 flush 再 exit,避免日志被截断\n await new Promise<void>((resolve) => process.stdout.write('', () => resolve()));\n process.exit(0);\n }\n // 记录旧端口(--restart 时用于端口继承;stopInstance 会清 record)\n const oldRecord = existing && args.restart ? existing : null;\n if (oldRecord) {\n console.log(`[zdashboard] --restart:停止旧实例 pid=${oldRecord.pid}`);\n await stopInstance(oldRecord);\n }\n\n const appDir = path.resolve(__dirname, 'web');\n\n // P2: restart 且有旧记录时,起始端口用 record.port(用户显式 --port 则尊重)\n const startPort = oldRecord && !args.portExplicit ? oldRecord.port : args.port;\n\n // P0: 数据目录检测(.zdev/ 存在则优先)\n const zdevDir = path.join(root, '.zdev');\n const dataDir = fs.existsSync(zdevDir) ? '.zdev/' : '';\n\n const det = await detect(root);\n\n migrateLegacyBugsConfig(root);\n\n const ctx = new Context();\n\n // core services\n ctx.plugin(ServerService, {\n root,\n appDir,\n port: startPort,\n open: args.open,\n detect: det,\n page: args.page,\n dataDir: dataDir || undefined,\n onListen: (port: number) => writeRecord(root, port),\n });\n ctx.plugin(ReloadService, { root });\n ctx.plugin(treeApply, { root });\n ctx.plugin(worktreesApply, { root });\n ctx.plugin(DashboardService);\n\n // built-in plugins\n const plugins = [\n { name: 'stats', apply: statsApply },\n { name: 'just', apply: justApply },\n { name: 'bugs', apply: bugsApply },\n { name: 'review', apply: reviewApply },\n { name: 'apply', apply: applyApply },\n { name: 'apply-batch', apply: applyBatchApply },\n { name: 'design', apply: designApply },\n { name: 'view', apply: viewApply },\n ];\n for (const p of plugins) {\n try {\n ctx.plugin(p.apply, { root });\n } catch (e) {\n console.error(`[zdashboard] plugin ${p.name} failed:`, e);\n }\n }\n\n // external plugins\n if (args.plugins) {\n await loadExternal(ctx, path.resolve(args.plugins), root);\n }\n\n // graceful shutdown: clear .zdev record on SIGTERM / SIGINT\n const shutdown = () => {\n try { clearRecord(root); } catch {}\n process.exit(0);\n };\n process.on('SIGTERM', shutdown);\n process.on('SIGINT', shutdown);\n\n return ctx;\n}\n\nawait main().catch((e) => {\n console.error(e);\n process.exit(1);\n});\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { execFile } from 'node:child_process';\n\nexport interface DetectResult {\n hasOpenspec: boolean;\n hasDocs: boolean;\n hasJust: boolean;\n hasBugs: boolean;\n}\n\nfunction justAvailable(cwd: string): Promise<boolean> {\n return new Promise((resolve) => {\n const child = execFile('just', ['--list', '--unsupported'], { cwd, timeout: 5000 }, (err) => {\n resolve(!err);\n });\n if (child.killed) resolve(false);\n });\n}\n\nfunction hasBugsConfig(root: string): boolean {\n const dashboardPath = path.join(root, '.zdev', 'dashboard.json');\n if (!fs.existsSync(dashboardPath)) return false;\n try {\n const raw = fs.readFileSync(dashboardPath, 'utf-8');\n const rec = JSON.parse(raw) as { plugins?: { bugs?: Record<string, unknown> } };\n const bugs = rec.plugins?.bugs;\n if (bugs && typeof bugs === 'object' && bugs.url && bugs.product) return true;\n } catch { /* ignore */ }\n return false;\n}\n\nexport async function detect(root: string): Promise<DetectResult> {\n const hasOpenspec = fs.existsSync(path.join(root, 'openspec'));\n const hasDocs = fs.existsSync(path.join(root, 'docs'));\n const hasJust = await justAvailable(root);\n const hasBugs = hasBugsConfig(root);\n return { hasOpenspec, hasDocs, hasJust, hasBugs };\n}\n","import http from 'node:http';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport crypto from 'node:crypto';\nimport { fileURLToPath } from 'node:url';\nimport pkg from '../../package.json' with { type: 'json' };\nimport type { Context } from 'cordis';\nimport type { DetectResult } from '../server/detect.js';\nimport type { PluginManifest, ConfigField } from '../core/manifest.js';\nimport { Service } from 'cordis';\nimport { clearRecord, readPluginsConfig, writePluginsConfig } from './instance.js';\nimport { openUrl } from './open-url.js';\nimport { readBody } from './read-body.js';\nimport { execFile } from 'node:child_process';\n\nconst VERSION = pkg.version;\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport interface ServerOptions {\n root: string;\n appDir: string;\n port: number;\n open: boolean;\n page: string | null;\n detect: DetectResult;\n dataDir?: string;\n onListen?: (port: number) => void;\n}\n\ndeclare module 'cordis' {\n interface Context {\n server: ServerService;\n }\n}\n\nconst MIME: Record<string, string> = {\n '.html': 'text/html; charset=utf-8', '.htm': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8', '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8', '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml', '.png': 'image/png', '.ico': 'image/x-icon',\n '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.gif': 'image/gif', '.webp': 'image/webp',\n '.avif': 'image/avif',\n '.md': 'text/markdown; charset=utf-8', '.txt': 'text/plain; charset=utf-8',\n '.sql': 'text/plain; charset=utf-8', '.csv': 'text/plain; charset=utf-8',\n '.tsv': 'text/plain; charset=utf-8', '.yaml': 'text/yaml; charset=utf-8',\n '.yml': 'text/yaml; charset=utf-8', '.xml': 'application/xml; charset=utf-8',\n '.py': 'text/plain; charset=utf-8', '.ts': 'text/plain; charset=utf-8',\n '.java': 'text/plain; charset=utf-8', '.go': 'text/plain; charset=utf-8',\n '.rs': 'text/plain; charset=utf-8', '.rb': 'text/plain; charset=utf-8',\n '.php': 'text/plain; charset=utf-8', '.c': 'text/plain; charset=utf-8',\n '.cpp': 'text/plain; charset=utf-8', '.h': 'text/plain; charset=utf-8',\n '.cs': 'text/plain; charset=utf-8', '.swift': 'text/plain; charset=utf-8',\n '.kt': 'text/plain; charset=utf-8', '.scala': 'text/plain; charset=utf-8',\n '.sh': 'text/plain; charset=utf-8', '.bash': 'text/plain; charset=utf-8',\n '.zsh': 'text/plain; charset=utf-8', '.fish': 'text/plain; charset=utf-8',\n '.env': 'text/plain; charset=utf-8', '.gitignore': 'text/plain; charset=utf-8',\n '.dockerfile': 'text/plain; charset=utf-8',\n '.mp4': 'video/mp4', '.webm': 'video/webm', '.mov': 'video/quicktime',\n '.m4a': 'audio/mp4', '.aac': 'audio/aac',\n '.woff': 'font/woff', '.woff2': 'font/woff2', '.ttf': 'font/woff',\n '.map': 'application/json; charset=utf-8',\n};\n\nconst INJECT = `<script>(function(){try{var es=new EventSource('/__reload');es.addEventListener('files',function(){/* plugin 局部刷新由 useSSE 消费,此处不再整页 reload */});es.onerror=function(){/* EventSource 原生重连,静默处理 */};}catch(e){}document.addEventListener('click',function(e){var t=e.target;if(t&&t.closest){var a=t.closest('a[target]');if(a&&a.target!=='_self'){a.target='_self';}}},true);})();</script>`;\n\nexport const PLUGIN_STATIC_PREFIX = '/__plugin/';\n\nexport class ServerService extends Service {\n stopToken: string;\n private root: string;\n private appDir: string;\n private open: boolean;\n private page: string | null;\n private det: DetectResult;\n private dataDir?: string;\n private routes = new Map<string, (req: http.IncomingMessage, res: http.ServerResponse) => void>();\n private sses = new Map<string, (res: http.ServerResponse) => (() => void) | void>();\n private prefixStatic = new Map<string, string>();\n private server?: http.Server;\n private onListen?: (port: number) => void;\n\n constructor(ctx: Context, config: ServerOptions) {\n super(ctx, 'server');\n this.stopToken = crypto.randomBytes(12).toString('hex');\n this.root = config.root;\n this.appDir = config.appDir;\n this.open = config.open;\n this.page = config.page;\n this.det = config.detect;\n this.dataDir = config.dataDir;\n this.onListen = config.onListen;\n ctx.effect(() => () => this.dispose());\n\n this.refreshGitInfo();\n this.route('/__config', (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ stopToken: this.stopToken, version: VERSION, root: this.root, ...this.gitInfo }));\n });\n\n this.route('/__stop', async (req, res) => {\n if (req.headers['x-stop-token'] !== this.stopToken) {\n res.writeHead(403);\n res.end('forbidden');\n return;\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{\"ok\":true}');\n this.stop();\n });\n\n this.start(config.port);\n }\n\n route(path: string, handler: (req: http.IncomingMessage, res: http.ServerResponse) => void) {\n this.routes.set(path, handler);\n this.ctx.effect(() => () => this.routes.delete(path));\n }\n\n sse(path: string, onConnect: (res: http.ServerResponse) => (() => void) | void) {\n this.sses.set(path, onConnect);\n this.ctx.effect(() => () => this.sses.delete(path));\n }\n\n static(prefix: string, dir: string) {\n this.prefixStatic.set(prefix, dir);\n this.ctx.effect(() => () => this.prefixStatic.delete(prefix));\n }\n\n private pluginsConfig: Record<string, Record<string, unknown>> = {};\n\n getPluginConfig(mode: string): Record<string, unknown> {\n return this.pluginsConfig[mode] ?? {};\n }\n\n refreshPluginsConfig() {\n this.pluginsConfig = readPluginsConfig(this.root);\n }\n\n savePluginConfig(merged: Record<string, Record<string, unknown>>) {\n this.pluginsConfig = merged;\n writePluginsConfig(this.root, merged);\n }\n\n private serveFile(filePath: string, req: http.IncomingMessage, res: http.ServerResponse, injectHtml: boolean) {\n fs.stat(filePath, (err, stat) => {\n if (err) { res.writeHead(404); return res.end('Not found'); }\n const ext = path.extname(filePath).toLowerCase();\n const ct = MIME[ext] ?? 'application/octet-stream';\n\n // ---- HTTP Range support ----\n const rangeHeader = (req.headers['range'] as string | undefined);\n let range: { start: number; end: number } | null = null;\n if (rangeHeader) {\n const m = rangeHeader.match(/^bytes=(\\d+)-(\\d*)$/);\n if (m) {\n const start = Number(m[1]);\n const end = m[2] !== '' ? Number(m[2]) : stat.size - 1;\n if (!Number.isNaN(start) && !Number.isNaN(end) && start <= end && start < stat.size) {\n range = { start, end: Math.min(end, stat.size - 1) };\n }\n // malformed range → fall through to 200 full response\n }\n // unparseable range header → fall through to 200 full response\n }\n\n if (range) {\n const { start, end } = range;\n const chunkSize = end - start + 1;\n res.writeHead(206, {\n 'Content-Type': ct,\n 'Content-Length': String(chunkSize),\n 'Content-Range': `bytes ${start}-${end}/${stat.size}`,\n 'Accept-Ranges': 'bytes',\n 'Cache-Control': 'no-cache',\n });\n // stat 成功后文件仍可能在 open 前被删/换(高频增删的工作区),流错误无人接会崩进程\n const stream = fs.createReadStream(filePath, { start, end });\n stream.on('error', () => { try { res.destroy(); } catch { /* 已断 */ } });\n stream.pipe(res);\n return;\n }\n\n // Full response\n fs.readFile(filePath, (err, data) => {\n if (err) { res.writeHead(404); return res.end('Not found'); }\n let body: string | Buffer = data;\n if (injectHtml && ext === '.html') {\n const s = data.toString('utf8');\n body = Buffer.from(s.indexOf('</body>') >= 0 ? s.replace('</body>', INJECT + '</body>') : s + INJECT);\n }\n res.writeHead(200, { 'Content-Type': ct, 'Accept-Ranges': 'bytes', 'Cache-Control': 'no-cache' });\n res.end(body);\n });\n });\n }\n\n private servePrefix(url: string, req: http.IncomingMessage, res: http.ServerResponse): boolean {\n for (const [prefix, dir] of this.prefixStatic) {\n if (url.indexOf(prefix) === 0) {\n let rel = this.safeDecode(url.slice(prefix.length));\n if (!rel || rel === '/' || !path.extname(rel)) rel = path.join(rel || '', 'index.html');\n const fp = path.join(dir, rel);\n if (fp.indexOf(dir + path.sep) !== 0) { res.writeHead(403); res.end('Forbidden'); return false; }\n this.serveFile(fp, req, res, true);\n return true;\n }\n }\n return false;\n }\n\n private safeDecode(raw: string): string {\n try { return decodeURIComponent(raw); } catch { return raw; }\n }\n\n private handler = (req: http.IncomingMessage, res: http.ServerResponse) => {\n try {\n const rawUrl = req.url || '/';\n const url = rawUrl.split('?')[0];\n\n const rh = this.routes.get(url);\n if (rh) { rh(req, res); return; }\n const sh = this.sses.get(url);\n if (sh) {\n res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive' });\n res.write(': connected\\n\\n');\n const cleanup = sh(res);\n req.on('close', () => { cleanup?.(); });\n return;\n }\n\n if (this.servePrefix(url, req, res)) return;\n\n if (url === '/' || url.indexOf('/__app/') === 0 || url.indexOf('/assets/') === 0) {\n let fp = this.appDir;\n if (url !== '/') fp = path.join(this.appDir, this.safeDecode(url));\n if (url.indexOf('/__app/') === 0) fp = path.join(this.appDir, url.slice(7));\n if (fp !== this.appDir && fp.indexOf(this.appDir + path.sep) !== 0) { res.writeHead(403); return res.end('Forbidden'); }\n if (url === '/') fp = path.join(this.appDir, 'index.html');\n return this.serveFile(fp, req, res, false);\n }\n\n const fp = path.join(this.root, this.safeDecode(url));\n if (fp !== this.root && fp.indexOf(this.root + path.sep) !== 0) { res.writeHead(403); return res.end('Forbidden'); }\n return this.serveFile(fp, req, res, true);\n } catch (e) {\n try { res.writeHead(400); res.end('bad request'); } catch {}\n console.error('[zdashboard] handler error', e);\n }\n };\n\n start(port: number) {\n this.server = http.createServer(this.handler);\n // 浏览器复用空闲 keep-alive 连接时若已被服务端关闭,请求会石沉大海(点击无响应)。\n // 拉长 keep-alive 使其远大于浏览器侧空闲窗口\n this.server.keepAliveTimeout = 65_000;\n this.server.headersTimeout = 66_000;\n this.server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(`[zdashboard] port ${port} busy, trying ${port + 1}`);\n this.start(port + 1);\n } else throw err;\n });\n this.server.listen(port, '127.0.0.1', () => {\n const u = `http://localhost:${port}`;\n const target = this.page ? `${u}#${this.page}` : u;\n console.log(`[zdashboard] v${VERSION} dashboard -> ${u}`);\n console.log(`[zdashboard] project -> ${this.root}`);\n console.log(`[zdashboard] detect -> openspec:${this.det.hasOpenspec} docs:${this.det.hasDocs} just:${this.det.hasJust} bugs:${this.det.hasBugs}`);\n if (this.dataDir) console.log(`[zdashboard] data -> ${this.dataDir}`);\n if (this.open) openUrl(target);\n this.onListen?.(port);\n });\n }\n\n /** 项目 git 信息(分支/脏文件数),启动探测一次,文件变更时刷新 */\n private gitInfo: { branch?: string; dirty?: number } = {};\n\n refreshGitInfo() {\n const run = (args: string[]) => new Promise<string>((resolve) => {\n execFile('git', args, { cwd: this.root, timeout: 3000 }, (err, stdout) => resolve(err ? '' : stdout));\n });\n void (async () => {\n const [branch, status] = await Promise.all([\n run(['rev-parse', '--abbrev-ref', 'HEAD']),\n run(['status', '--porcelain']),\n ]);\n const b = branch.trim();\n this.gitInfo = b ? { branch: b, dirty: status ? status.split('\\n').filter(Boolean).length : 0 } : {};\n })();\n }\n\n stop() {\n if (this.server) { try { this.server.close(); } catch {} }\n try { clearRecord(this.root); } catch {}\n setTimeout(() => {\n try { this.ctx.root.fiber.dispose(); } catch {}\n process.exit(0);\n }, 50);\n }\n\n dispose() {\n if (this.server) { try { this.server.close(); } catch {} }\n try { clearRecord(this.root); } catch {}\n }\n}\n","{\n \"name\": \"zdashboard\",\n \"version\": \"2.7.0\",\n \"description\": \"ZCode skill dashboard platform — pluggable viewers for zdesign/zview/zreview/zgoal\",\n \"type\": \"module\",\n \"bin\": {\n \"zdashboard\": \"./dist/cli.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"dev\": \"vite\",\n \"build\": \"tsup && vite build\",\n \"build:web\": \"vite build\",\n \"build:node\": \"tsup\",\n \"start\": \"node dist/cli.js\",\n \"preview\": \"vite preview\"\n },\n \"dependencies\": {\n \"@fontsource/vt323\": \"^5.3.0\",\n \"@phosphor-icons/react\": \"^2.1.10\",\n \"@radix-ui/react-dropdown-menu\": \"^2.1.24\",\n \"@radix-ui/react-scroll-area\": \"^1.2.0\",\n \"@radix-ui/react-separator\": \"^1.1.0\",\n \"@radix-ui/react-slot\": \"^1.1.0\",\n \"@radix-ui/react-tooltip\": \"^1.1.2\",\n \"@uidotdev/usehooks\": \"^2.4.0\",\n \"ansi-to-react\": \"^6.1.6\",\n \"class-variance-authority\": \"^0.7.0\",\n \"clsx\": \"^2.1.1\",\n \"cordis\": \"4.0.0-rc.8\",\n \"cosmokit\": \"^1.8.1\",\n \"date-fns\": \"^3.6.0\",\n \"filesize\": \"^11.0.0\",\n \"highlight.js\": \"^11.11.1\",\n \"katex\": \"^0.16.11\",\n \"ky\": \"^1.7.0\",\n \"lodash-es\": \"^4.17.21\",\n \"lucide-react\": \"^0.460.0\",\n \"pixelarticons\": \"^2.4.1\",\n \"react\": \"^18.3.1\",\n \"react-dom\": \"^18.3.1\",\n \"react-error-boundary\": \"^5.0.0\",\n \"react-markdown\": \"^9.0.1\",\n \"rehype-autolink-headings\": \"^7.1.0\",\n \"rehype-highlight\": \"^7.0.1\",\n \"rehype-katex\": \"^7.0.1\",\n \"rehype-raw\": \"^7.0.0\",\n \"rehype-slug\": \"^6.0.0\",\n \"remark-frontmatter\": \"^5.0.0\",\n \"remark-gfm\": \"^4.0.0\",\n \"remark-math\": \"^6.0.0\",\n \"sonner\": \"^1.5.0\",\n \"tailwind-merge\": \"^2.5.4\",\n \"tsx\": \"^4.7.0\",\n \"use-debounce\": \"^10.0.0\",\n \"yaml\": \"^2.9.0\"\n },\n \"devDependencies\": {\n \"@tailwindcss/typography\": \"^0.5.20\",\n \"@testing-library/jest-dom\": \"^7.0.1\",\n \"@testing-library/react\": \"^16.3.2\",\n \"@types/lodash-es\": \"^4.17.12\",\n \"@types/node\": \"^22.9.0\",\n \"@types/react\": \"^18.3.12\",\n \"@types/react-dom\": \"^18.3.1\",\n \"@vitejs/plugin-react\": \"^4.7.0\",\n \"autoprefixer\": \"^10.4.20\",\n \"jsdom\": \"^30.0.1\",\n \"postcss\": \"^8.4.49\",\n \"tailwindcss\": \"^3.4.14\",\n \"tailwindcss-animate\": \"^1.0.7\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^5.6.3\",\n \"vite\": \"^5.4.10\",\n \"vitest\": \"^1.6.0\"\n },\n \"pnpm\": {\n \"onlyBuiltDependencies\": [\n \"esbuild\"\n ]\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface InstanceRecord {\n pid: number;\n port: number;\n root: string;\n startedAt: string;\n plugins?: Record<string, Record<string, unknown>>;\n}\n\nexport const RECORD_FILE = '.zdev/dashboard.json';\nexport const VERIFY_TIMEOUT_MS = 1500;\nexport const STOP_POLL_MS = 2000;\nexport const STOP_POLL_INTERVAL_MS = 100;\nexport const STOP_FINAL_WAIT_MS = 100;\n\nfunction recordPath(root: string): string {\n return path.join(root, RECORD_FILE);\n}\n\nexport function readRecord(root: string): InstanceRecord | null {\n try {\n const fp = recordPath(root);\n const raw = fs.readFileSync(fp, 'utf-8');\n const rec = JSON.parse(raw) as Partial<InstanceRecord>;\n if (\n typeof rec.pid === 'number' &&\n typeof rec.port === 'number' &&\n typeof rec.root === 'string' &&\n typeof rec.startedAt === 'string'\n ) {\n return rec as InstanceRecord;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport function writeRecord(root: string, port: number): void {\n fs.mkdirSync(path.dirname(recordPath(root)), { recursive: true });\n const rec: InstanceRecord = {\n pid: process.pid,\n port,\n root,\n startedAt: new Date().toISOString(),\n };\n fs.writeFileSync(recordPath(root), JSON.stringify(rec, null, 2) + '\\n');\n}\n\nexport function readPluginsConfig(root: string): Record<string, Record<string, unknown>> {\n try {\n const rec = readRecord(root);\n if (rec?.plugins && typeof rec.plugins === 'object') {\n return rec.plugins as Record<string, Record<string, unknown>>;\n }\n } catch { /* ignore */ }\n return {};\n}\n\nexport function writePluginsConfig(root: string, plugins: Record<string, Record<string, unknown>>): void {\n const fp = recordPath(root);\n let rec: InstanceRecord;\n try {\n const raw = fs.readFileSync(fp, 'utf-8');\n rec = JSON.parse(raw) as InstanceRecord;\n } catch {\n rec = { pid: process.pid, port: 0, root, startedAt: new Date().toISOString() };\n }\n rec.plugins = plugins;\n const tmp = fp + '.tmp';\n fs.writeFileSync(tmp, JSON.stringify(rec, null, 2) + '\\n');\n fs.renameSync(tmp, fp);\n}\n\nexport function clearRecord(root: string): void {\n try {\n // 属主校验:记录若已指向别的实例(并发双启落败者),不得误删胜者记录\n const rec = readRecord(root);\n if (rec && rec.pid !== process.pid) return;\n fs.unlinkSync(recordPath(root));\n } catch {\n // best-effort\n }\n}\n\nexport function isAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (e) {\n if ((e as NodeJS.ErrnoException).code === 'ESRCH') return false;\n // EPERM or other → process exists, we just can't signal it\n return true;\n }\n}\n\nasync function fetchWithTimeout(url: string): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), VERIFY_TIMEOUT_MS);\n try {\n return await fetch(url, { signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function verifyRoot(port: number, root: string): Promise<boolean> {\n try {\n const res = await fetchWithTimeout(`http://127.0.0.1:${port}/__config`);\n if (res.status !== 200) return false;\n const body = await res.json();\n if (typeof body.root !== 'string') return false;\n return body.root === root;\n } catch {\n return false;\n }\n}\n\nexport async function findReusable(root: string): Promise<InstanceRecord | null> {\n const rec = readRecord(root);\n if (!rec) return null;\n if (!isAlive(rec.pid)) return null;\n if (!(await verifyRoot(rec.port, root))) return null;\n return rec;\n}\n\nexport async function stopInstance(record: InstanceRecord): Promise<void> {\n try {\n process.kill(record.pid, 'SIGTERM');\n } catch {\n return;\n }\n\n const deadline = Date.now() + STOP_POLL_MS;\n while (Date.now() < deadline) {\n if (!isAlive(record.pid)) return;\n await new Promise((r) => setTimeout(r, STOP_POLL_INTERVAL_MS));\n }\n\n // still alive → SIGKILL\n try {\n process.kill(record.pid, 'SIGKILL');\n } catch {\n // ignore\n }\n await new Promise((r) => setTimeout(r, STOP_FINAL_WAIT_MS));\n}\n","import { exec, execFile } from 'node:child_process';\n\n/** 跨平台打开浏览器(macOS open / Windows start / Linux xdg-open) */\nexport function openUrl(url: string): void {\n const cmd =\n process.platform === 'darwin' ? 'open' :\n process.platform === 'win32' ? 'start' :\n 'xdg-open';\n // win32 `start` 是 shell 内建命令,只能走 shell;其他平台直接用 execFile\n if (process.platform === 'win32') {\n exec(`start \"\" \"${url}\"`);\n } else {\n execFile(cmd, [url]);\n }\n}\n","import fs from 'node:fs';\nimport http from 'node:http';\nimport { Service } from 'cordis';\nimport type { Context } from 'cordis';\n\ndeclare module 'cordis' {\n interface Context {\n reload: ReloadService;\n }\n}\n\nconst WATCH_DEBOUNCE_MS = 300;\n\nexport class ReloadService extends Service {\n static inject = ['server'];\n private clients = new Set<http.ServerResponse>();\n private watcher?: fs.FSWatcher;\n private timer?: NodeJS.Timeout;\n\n constructor(ctx: Context, config: { root: string }) {\n super(ctx, 'reload');\n this.ctx.effect(() => () => this.dispose());\n\n this.ctx.server.sse('/__reload', (res) => {\n this.clients.add(res);\n return () => this.clients.delete(res);\n });\n\n try {\n this.watcher = fs.watch(config.root, { recursive: true }, (eventType, filename) => {\n if (filename && /^(?:\\.git|node_modules|dist|\\.pnpm)(?:[/\\\\]|$)/.test(filename)) return;\n if (filename && /\\.(?:swp|tmp)$|~$|^\\.DS_Store$|^Thumbs\\.db$/i.test(filename)) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.ctx.server.refreshGitInfo();\n this.broadcast('reload');\n this.broadcast('files');\n this.timer = undefined;\n }, WATCH_DEBOUNCE_MS);\n });\n } catch {\n // watch unavailable - static only\n }\n }\n\n broadcast(ev: string, data: unknown = '') {\n const payload = `event: ${ev}\\ndata: ${JSON.stringify(data == null ? '' : data)}\\n\\n`;\n for (const c of this.clients) {\n try { c.write(payload); } catch {}\n }\n }\n\n dispose() {\n if (this.watcher) { try { this.watcher.close(); } catch {} }\n if (this.timer) { clearTimeout(this.timer); }\n for (const c of this.clients) { try { c.end(); } catch {} }\n this.clients.clear();\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from './walk.js';\n\nexport type NodeKind = 'file' | 'dir' | 'log';\nexport interface TreeNode {\n name: string;\n kind: NodeKind;\n path?: string;\n defaultCollapsed?: boolean;\n children?: TreeNode[];\n}\n\nfunction buildTree(paths: string[], defaultExpandDepth = 2): TreeNode[] {\n const root: TreeNode[] = [];\n const map = new Map<string, TreeNode>();\n\n for (const p of paths) {\n const parts = p.split('/');\n let current = '';\n let parent = root;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n current = current ? `${current}/${part}` : part;\n const isLast = i === parts.length - 1;\n const depth = i;\n\n if (!map.has(current)) {\n const isDir = !isLast;\n const collapsed = isDir && typeof defaultExpandDepth === 'number' && depth > defaultExpandDepth;\n const node: TreeNode = {\n name: part,\n kind: isLast ? 'file' : 'dir',\n ...(collapsed ? { defaultCollapsed: true } : {}),\n ...(isLast ? { path: p } : { children: [] }),\n };\n map.set(current, node);\n parent.push(node);\n }\n\n if (!isLast) {\n parent = map.get(current)!.children!;\n }\n }\n }\n\n const sortNodes = (nodes: TreeNode[]) => {\n nodes.sort((a, b) => (a.kind === b.kind ? a.name.localeCompare(b.name) : a.kind === 'dir' ? -1 : 1));\n for (const n of nodes) {\n if (n.children) sortNodes(n.children);\n }\n };\n\n sortNodes(root);\n return root;\n}\n\nexport interface ScanTreeOptions {\n hiddenDirs?: string[];\n showHidden?: boolean;\n defaultExpandDepth?: number;\n}\n\n/** 方案模式树形扫描:openspec 感知 + docs 聚合 + 其他兜底 */\nexport function scanTree(root: string, hasOpenspec: boolean, hasDocs: boolean, opts?: ScanTreeOptions): TreeNode[] {\n const tree: TreeNode[] = [];\n const defaultExpandDepth = typeof opts?.defaultExpandDepth === 'number' ? opts.defaultExpandDepth : 2;\n if (hasOpenspec && fs.existsSync(path.join(root, 'openspec', 'changes'))) {\n const changesDir = path.join(root, 'openspec', 'changes');\n const active: TreeNode[] = [];\n const archived: TreeNode[] = [];\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.') || ent.name === 'archive') continue;\n const relBase = `openspec/changes/${ent.name}`;\n const paths: string[] = [];\n walkDir(path.join(changesDir, ent.name), { maxDepth: 4, showHidden: opts?.showHidden, onFile: (_, rel) => paths.push(rel ? `${relBase}/${rel}` : relBase) });\n const children = buildTree(paths, defaultExpandDepth).map((n) => ({ ...n, path: n.path ? `${relBase}/${n.path}` : undefined }));\n active.push({ name: ent.name, kind: 'dir', children });\n }\n active.sort((a, b) => a.name.localeCompare(b.name));\n const archiveDir = path.join(changesDir, 'archive');\n if (fs.existsSync(archiveDir)) {\n for (const ent of fs.readdirSync(archiveDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.')) continue;\n const relBase = `openspec/changes/archive/${ent.name}`;\n const paths: string[] = [];\n walkDir(path.join(archiveDir, ent.name), { maxDepth: 4, showHidden: opts?.showHidden, onFile: (_, rel) => paths.push(rel ? `${relBase}/${rel}` : relBase) });\n const children = buildTree(paths, defaultExpandDepth).map((n) => ({ ...n, path: n.path ? `${relBase}/${n.path}` : undefined }));\n archived.push({ name: ent.name, kind: 'dir', children });\n }\n archived.sort((a, b) => b.name.localeCompare(a.name)); // 日期前缀倒序\n }\n if (active.length) tree.push({ name: `changes (${active.length})`, kind: 'dir', children: active });\n if (archived.length) tree.push({ name: `archive (${archived.length})`, kind: 'dir', defaultCollapsed: true, children: archived });\n const specsDir = path.join(root, 'openspec', 'specs');\n if (fs.existsSync(specsDir)) {\n const paths: string[] = [];\n walkDir(specsDir, { maxDepth: 4, showHidden: opts?.showHidden, onFile: (_, rel) => paths.push(`openspec/specs/${rel}`) });\n const specs = buildTree(paths, defaultExpandDepth).map((n) => ({ ...n, path: n.path ? `openspec/specs/${n.path}` : undefined }));\n if (specs.length) tree.push({ name: 'specs', kind: 'dir', children: specs });\n }\n }\n if (hasDocs && fs.existsSync(path.join(root, 'docs'))) {\n const paths: string[] = [];\n walkDir(path.join(root, 'docs'), { maxDepth: 4, showHidden: opts?.showHidden, onFile: (_, rel) => paths.push(`docs/${rel}`) });\n const docs = buildTree(paths, defaultExpandDepth).map((n) => ({ ...n, path: n.path ? `docs/${n.path}` : undefined }));\n if (docs.length) tree.push({ name: 'docs', kind: 'dir', children: docs });\n }\n const skip = new Set(['openspec', 'docs', 'node_modules', '.git', 'dist', 'playground', '.zreview']);\n if (Array.isArray(opts?.hiddenDirs)) {\n for (const d of opts.hiddenDirs) skip.add(d);\n }\n // \"其他\"只收根目录的 md 文档(README/CLAUDE 等);构建配置(pom.xml/justfile 等)不收——对\"方案+日志\"定位是噪音\n const etc: TreeNode[] = [];\n try {\n for (const ent of fs.readdirSync(root, { withFileTypes: true })) {\n if (!opts?.showHidden && ent.name.startsWith('.')) continue;\n if (skip.has(ent.name)) continue;\n const ext = path.extname(ent.name).toLowerCase();\n if (ent.isFile() && (ext === '.md' || ext === '.markdown')) etc.push({ name: ent.name, kind: 'file', path: ent.name });\n }\n } catch (e) { console.error('[zdashboard] scan root etc failed:', e); }\n etc.sort((a, b) => a.name.localeCompare(b.name));\n if (etc.length) tree.push({ name: `other (${etc.length})`, kind: 'dir', children: etc });\n return tree;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface WalkOptions {\n skip?: Set<string>;\n maxDepth?: number;\n showHidden?: boolean;\n onFile?: (abs: string, rel: string) => void;\n onDir?: (abs: string, rel: string) => void;\n}\n\nexport function walkDir(root: string, opts: WalkOptions = {}): void {\n const { skip = new Set(), maxDepth, showHidden, onFile, onDir } = opts;\n\n function walk(dir: string, rel: string, depth: number) {\n if (typeof maxDepth === 'number' && depth > maxDepth) return;\n let ents: fs.Dirent[];\n try { ents = fs.readdirSync(dir, { withFileTypes: true }); } catch { return; }\n for (const ent of ents) {\n if (!showHidden && ent.name.startsWith('.')) continue;\n if (skip.has(ent.name)) continue;\n const abs = path.join(dir, ent.name);\n const r = rel ? `${rel}/${ent.name}` : ent.name;\n if (ent.isDirectory()) {\n onDir?.(abs, r);\n walk(abs, r, depth + 1);\n } else if (onFile) {\n onFile(abs, r);\n }\n }\n }\n\n walk(root, '', 0);\n}\n","import type { Context } from 'cordis';\nimport { scanTree } from '../server/spec-scan.js';\nimport { detect } from '../server/detect.js';\nimport type { DetectResult } from '../server/detect.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n let cached: { p: Promise<DetectResult>; v?: DetectResult } | null = null;\n const getDet = async (): Promise<DetectResult> => {\n if (cached?.v) return cached.v;\n if (!cached) cached = { p: detect(config.root).catch(() => ({ hasOpenspec: false, hasDocs: false, hasJust: false, hasBugs: false } as DetectResult)) };\n const d = await cached.p;\n cached.v = d;\n return d;\n };\n\n const server = ctx.server;\n if (server?.route) {\n server.route('/__files', async (_req, res) => {\n try {\n const d = await getDet();\n const viewCfg = ctx.dashboard.getConfig('view') as { hiddenDirs?: string[]; defaultExpandDepth?: number; showHidden?: boolean } | undefined;\n const tree = scanTree(config.root, d.hasOpenspec, d.hasDocs, {\n hiddenDirs: Array.isArray(viewCfg?.hiddenDirs) ? viewCfg.hiddenDirs : undefined,\n defaultExpandDepth: typeof viewCfg?.defaultExpandDepth === 'number' ? viewCfg.defaultExpandDepth : undefined,\n showHidden: typeof viewCfg?.showHidden === 'boolean' ? viewCfg.showHidden : undefined,\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ tree, ...d }));\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ tree: [], hasOpenspec: false, hasDocs: false, hasJust: false, hasBugs: false }));\n }\n });\n }\n },\n};\n","import { execFile } from 'node:child_process';\nimport type { Context } from 'cordis';\n\nexport interface WorktreeInfo {\n path: string;\n name: string;\n branch: string;\n head: string;\n dirty: boolean;\n}\n\nconst GIT_TIMEOUT_MS = 5_000;\nconst ZWORKTREE_SEGMENT = '.zworktree/';\n\nfunction runGit(args: string[], cwd: string): Promise<string> {\n return new Promise((resolve) => {\n execFile('git', args, { cwd, timeout: GIT_TIMEOUT_MS }, (err, stdout) => {\n if (err) return resolve('');\n resolve(stdout);\n });\n });\n}\n\nexport async function listWorktrees(root: string): Promise<WorktreeInfo[]> {\n const raw = await runGit(['worktree', 'list', '--porcelain'], root);\n if (!raw) return [];\n\n const entries: WorktreeInfo[] = [];\n const lines = raw.split('\\n');\n let current: Partial<WorktreeInfo> = {};\n\n for (const line of lines) {\n const m = line.match(/^(worktree|HEAD|branch|detached)\\s+(.+)$/);\n if (!m) continue;\n const [, key, val] = m;\n if (key === 'worktree') {\n if (current.path && current.path.includes(ZWORKTREE_SEGMENT)) {\n entries.push({\n path: current.path,\n name: current.path.split(ZWORKTREE_SEGMENT).pop() ?? '',\n branch: current.branch ?? '',\n head: current.head ?? '',\n dirty: false,\n });\n }\n current = { path: val, head: '', branch: '' };\n } else if (key === 'HEAD') {\n current.head = val;\n } else if (key === 'branch') {\n current.branch = val.replace(/^refs\\/heads\\//, '');\n }\n }\n\n // flush last entry\n if (current.path && current.path.includes(ZWORKTREE_SEGMENT)) {\n entries.push({\n path: current.path,\n name: current.path.split(ZWORKTREE_SEGMENT).pop() ?? '',\n branch: current.branch ?? '',\n head: current.head ?? '',\n dirty: false,\n });\n }\n\n // dirty detection: git status --porcelain 非空即 dirty(失败默认 false)\n await Promise.all(\n entries.map(async (entry) => {\n try {\n const statusOut = await runGit(['status', '--porcelain'], entry.path);\n entry.dirty = statusOut.trim().length > 0;\n } catch {\n entry.dirty = false;\n }\n })\n );\n\n return entries;\n}\n\nexport const apply = {\n inject: ['server'] as const,\n apply(ctx: Context, config: { root: string }) {\n const server = ctx.server;\n if (!server?.route) return;\n\n server.route('/__worktrees', async (_req, res) => {\n try {\n const entries = await listWorktrees(config.root);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(entries));\n } catch {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify([]));\n }\n });\n },\n};\n","import { Service } from 'cordis';\nimport type { Context } from 'cordis';\nimport { readBody } from './read-body.js';\n\ndeclare module 'cordis' {\n interface Context {\n dashboard: DashboardService;\n }\n}\n\nexport interface PluginManifest {\n mode: string;\n label: string;\n icon: string;\n description?: string;\n viewerUrl?: string; // 同源 URL,前端 iframe 渲染\n external?: boolean;\n config?: Record<string, ConfigField>;\n}\n\nexport interface ConfigField {\n type: 'string' | 'text' | 'number' | 'boolean' | 'string[]' | 'select' | 'multiselect';\n label: string;\n default?: unknown;\n placeholder?: string;\n options?: { value: string; label: string }[];\n min?: number;\n max?: number;\n}\n\nexport class DashboardService extends Service {\n static inject = ['server', 'reload'];\n private plugins = new Map<string, PluginManifest>();\n private reloadRef: any;\n\n constructor(ctx: Context) {\n super(ctx, 'dashboard');\n this.ctx.effect(() => () => this.plugins.clear());\n this.reloadRef = ctx.reload;\n\n this.ctx.server.route('/__plugins', (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify({ plugins: Array.from(this.plugins.values()) }));\n });\n\n this.ctx.server.route('/__plugins/config', async (req, res) => {\n const out: Record<string, Record<string, unknown>> = {};\n if (req.method === 'GET') {\n for (const m of this.plugins.values()) {\n const stored = this.ctx.server.getPluginConfig(m.mode);\n const schema = m.config ?? {};\n const merged: Record<string, unknown> = {};\n for (const [key, field] of Object.entries(schema)) {\n merged[key] = key in stored ? stored[key] : (field as ConfigField).default ?? '';\n }\n if (Object.keys(merged).length) out[m.mode] = merged;\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(out));\n return;\n }\n if (req.method === 'POST') {\n if (req.headers['x-stop-token'] !== this.ctx.server.stopToken) {\n res.writeHead(403);\n res.end('forbidden');\n return;\n }\n try {\n const body = JSON.parse(await readBody(req));\n const merged = {};\n for (const mode of Object.keys(body)) {\n merged[mode] = body[mode] ?? {};\n }\n this.ctx.server.savePluginConfig(merged);\n for (const mode of Object.keys(body)) {\n try { this.reloadRef.broadcast('config', { plugin: mode }); } catch { /* ignore */ }\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{\"ok\":true}');\n } catch (e) {\n console.error('[config] POST error', e);\n res.writeHead(400);\n res.end('{\"error\":\"bad request\"}');\n }\n return;\n }\n res.writeHead(405);\n res.end('{\"error\":\"method not allowed\"}');\n });\n }\n\n register(manifest: PluginManifest) {\n this.plugins.set(manifest.mode, manifest);\n this.ctx.effect(() => () => this.plugins.delete(manifest.mode));\n }\n\n list() {\n return Array.from(this.plugins.values());\n }\n\n get(mode: string): PluginManifest | undefined {\n return this.plugins.get(mode);\n }\n\n getConfig(mode: string): Record<string, unknown> {\n return this.ctx.server.getPluginConfig(mode);\n }\n}\n","import http from 'node:http';\n\n/**\n * Read the full body of an IncomingMessage.\n * Listens for 'error' to prevent a hanging promise when the client aborts mid-stream.\n */\nexport async function readBody(req: http.IncomingMessage): Promise<string> {\n return new Promise((resolve) => {\n let data = '';\n req.on('data', (chunk: string | Buffer) => { data += chunk; });\n req.on('end', () => resolve(data));\n req.on('error', () => resolve('')); // client abort → settle with empty string\n });\n}\n","import { spawn, execFile, type ChildProcess } from 'node:child_process';\n\nexport interface Recipe { name: string; description: string; }\nexport type TaskStatus = 'running' | 'exited';\nexport interface TaskInfo { recipe: string; state: TaskStatus; code: number | null; startedAt: number; signal?: string }\n\nexport type JustEvent =\n | { type: 'log'; recipe: string; text: string }\n | { type: 'clear'; recipe: string }\n | { type: 'state'; recipe: string; state: TaskStatus; code: number | null; startedAt?: number; signal?: string };\n\ninterface Task {\n recipe: string;\n child: ChildProcess | null;\n state: TaskStatus;\n code: number | null;\n signal?: string;\n startedAt: number;\n buffer: string[];\n pending: string; // 行缓冲:块缓冲输出会在行中间断开,攒到 \\n 才切行\n}\n\nconst MAX_BUFFER = 1000;\n\n/** 多任务并发 runner:每个 recipe 独立进程/日志/状态,同名 start 即重启,互不影响 */\nexport class JustRunner {\n private cwd: string;\n private tasks = new Map<string, Task>();\n private clients = new Set<(ev: JustEvent) => void>();\n private recipesCache: Recipe[] | null = null;\n\n constructor(cwd: string) { this.cwd = cwd; }\n\n recipes(): Promise<Recipe[]> {\n if (this.recipesCache) return Promise.resolve(this.recipesCache);\n return new Promise((resolve) => {\n execFile('just', ['--list', '--unsorted'], { cwd: this.cwd, maxBuffer: 1 << 20, timeout: 8000 }, (err, stdout) => {\n if (err) { resolve([]); return; }\n const out: Recipe[] = [];\n const seen = new Set<string>();\n for (const line of stdout.split(/\\r?\\n/).slice(1)) { // 跳过 \"Available recipes:\"\n const trimmed = line.trim();\n if (!trimmed) continue;\n const hashIdx = trimmed.indexOf('#');\n const sig = (hashIdx >= 0 ? trimmed.slice(0, hashIdx) : trimmed).trim();\n if (!sig) continue;\n const name = sig.split(/\\s+/)[0]; // \"hello msg=...\" -> \"hello\"\n if (seen.has(name)) continue;\n seen.add(name);\n out.push({ name, description: hashIdx >= 0 ? trimmed.slice(hashIdx + 1).trim() : '' });\n }\n this.recipesCache = out;\n resolve(out);\n });\n });\n }\n\n subscribe(fn: (ev: JustEvent) => void): () => void {\n this.clients.add(fn);\n // 连上即重放:全部任务的日志与状态\n for (const t of this.tasks.values()) {\n for (const text of t.buffer) fn({ type: 'log', recipe: t.recipe, text });\n fn({ type: 'state', recipe: t.recipe, state: t.state, code: t.code, startedAt: t.startedAt });\n }\n return () => this.clients.delete(fn);\n }\n\n private emit(ev: JustEvent) { for (const fn of this.clients) fn(ev); }\n\n list(): TaskInfo[] {\n return Array.from(this.tasks.values(), (t) => ({ recipe: t.recipe, state: t.state, code: t.code, startedAt: t.startedAt }));\n }\n\n /** 启动 recipe:同名先停旧进程(重启语义),不影响其他任务;调用方须先用 recipes() 校验名字 */\n start(recipe: string) {\n this.killOne(recipe);\n const task: Task = { recipe, child: null, state: 'running', code: null, startedAt: Date.now(), buffer: [], pending: '' };\n this.tasks.set(recipe, task);\n this.emit({ type: 'clear', recipe }); // 广播清屏:同步清掉该任务上一轮残留日志\n this.emit({ type: 'state', recipe, state: 'running', code: null, startedAt: task.startedAt });\n const child = spawn('just', [recipe], {\n cwd: this.cwd,\n shell: true,\n env: {\n ...process.env,\n FORCE_COLOR: '1', // node 生态(chalk 等)\n // maven 检测非 tty 会关颜色;经 MAVEN_OPTS 强制开(保留用户已有值)\n MAVEN_OPTS: `${process.env.MAVEN_OPTS ?? ''} -Dstyle.color=always`.trim(),\n CI: '',\n },\n });\n task.child = child;\n // 身份守卫:同名重启后旧进程的迟到输出/退出不得污染新任务(闭包 task 是旧对象时静默丢弃)\n const isStale = () => this.tasks.get(recipe) !== task;\n const push = (d: Buffer) => {\n if (isStale()) return;\n task.pending += d.toString();\n let idx: number;\n while ((idx = task.pending.indexOf('\\n')) >= 0) {\n const line = task.pending.slice(0, idx + 1);\n task.pending = task.pending.slice(idx + 1);\n this.pushLine(task, line);\n }\n // 无 \\n 的尾巴留在 pending,等下个 chunk(块缓冲输出会在行中断开,不能当独立行)\n };\n child.stdout?.on('data', push);\n child.stderr?.on('data', push);\n child.on('error', (err) => { this.pushLine(task, `[zdashboard] spawn error: ${err.message}\\n`); });\n child.on('exit', (code, signal) => {\n if (task.pending && !isStale()) { this.pushLine(task, task.pending + '\\n'); } // flush 末尾无换行的残留\n task.pending = '';\n task.child = null;\n task.state = 'exited';\n task.code = code ?? 0;\n task.signal = signal ?? undefined; // 用户主动 stop 时 code=null+SIGTERM,与成功退出区分\n if (isStale()) return; // 迟到的旧进程退出,不打扰新任务状态\n this.emit({ type: 'state', recipe, state: 'exited', code: task.code, startedAt: task.startedAt, signal: task.signal });\n });\n }\n\n private pushLine(task: Task, line: string) {\n task.buffer.push(line);\n if (task.buffer.length > MAX_BUFFER) task.buffer.shift();\n this.emit({ type: 'log', recipe: task.recipe, text: line });\n }\n\n /** 停单个任务;不传 recipe 停全部 */\n stop(recipe?: string) {\n if (recipe === undefined) { for (const t of this.tasks.values()) this.killOne(t.recipe); }\n else this.killOne(recipe);\n }\n\n restart(recipe: string) {\n if (this.tasks.has(recipe)) this.start(recipe);\n }\n\n /** 清空某任务的日志缓冲并广播(真源清除,重连重放不会复活) */\n clear(recipe: string) {\n const task = this.tasks.get(recipe);\n if (!task) return;\n task.buffer = [];\n task.pending = '';\n this.emit({ type: 'clear', recipe });\n }\n\n private killOne(recipe: string) {\n const task = this.tasks.get(recipe);\n const child = task?.child;\n if (child?.pid) {\n try {\n if (process.platform === 'win32') spawn('taskkill', ['/PID', String(child.pid), '/T', '/F']);\n else child.kill('SIGTERM');\n } catch { /* 已退出 */ }\n }\n if (task) { task.child = null; }\n }\n}\n","import type { Context } from 'cordis';\nimport http from 'node:http';\nimport { JustRunner } from '../../server/just-runner.js';\nimport { readBody } from '../../core/read-body.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n const runner = new JustRunner(root);\n ctx.effect(() => () => runner.stop());\n\n ctx.dashboard.register({ mode: 'just', label: 'Just Runner', icon: '📜', description: 'Just 多任务并发执行与日志' });\n\n ctx.server.route('/__just/recipes', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n try {\n const recipes = await runner.recipes();\n res.end(JSON.stringify(recipes));\n } catch {\n res.end(JSON.stringify([]));\n }\n });\n\n ctx.server.sse('/__just/logs', (res) => {\n const unsub = runner.subscribe((ev) => {\n res.write(`data: ${JSON.stringify(ev)}\\n\\n`);\n });\n return unsub;\n });\n\n /** start/restart 须带合法 recipe(同名 start 即重启,不影响其他任务);stop 可带单个 recipe 或省略(停全部) */\n const handleAction = async (req: http.IncomingMessage, res: http.ServerResponse, act: 'start' | 'stop' | 'restart' | 'clear') => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n const body = await readBody(req);\n let recipe: string | undefined;\n try { recipe = JSON.parse(body || '{}').recipe; } catch { /* ignore */ }\n if (act === 'clear') {\n if (recipe) runner.clear(recipe);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end('{\"ok\":true}');\n return;\n }\n if (act !== 'stop') {\n if (!recipe) { res.writeHead(400); res.end('{\"error\":\"no recipe\"}'); return; }\n const recipes = await runner.recipes();\n if (!recipes.some((r) => r.name === recipe)) { res.writeHead(403); res.end('{\"error\":\"unknown recipe\"}'); return; }\n runner.start(recipe);\n } else {\n runner.stop(recipe || undefined);\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify(runner.list()));\n };\n\n const routeAction = (name: 'start' | 'stop' | 'restart' | 'clear') => {\n ctx.server.route(`/__just/${name}`, (req, res) => {\n handleAction(req, res, name).catch(() => {\n if (!res.headersSent) { res.writeHead(500); res.end('{\"error\":\"internal\"}'); }\n });\n });\n };\n routeAction('start');\n routeAction('stop');\n routeAction('restart');\n routeAction('clear');\n });\n },\n};\n\n","import ky from 'ky';\nimport { HttpError, NetworkError } from '../errors.js';\n\nexport async function fetchJson(url: string, init?: RequestInit): Promise<Record<string, unknown>> {\n try {\n const res = await ky(url, { ...init, timeout: 8000, retry: 2 });\n return await res.json() as Record<string, unknown>;\n } catch (e) {\n if (e instanceof HttpError) throw e;\n if (e instanceof Error && e.name === 'TimeoutError') {\n throw new NetworkError(`请求超时: ${url}`);\n }\n if (e instanceof Error && e.name === 'HTTPError') {\n throw new HttpError((e as Error & { status?: number }).status ?? 500, e.message);\n }\n throw new NetworkError(`请求失败: ${url}`, e);\n }\n}\n","export class HttpError extends Error {\n constructor(\n public status: number,\n message: string,\n public body?: unknown,\n ) {\n super(message);\n this.name = 'HttpError';\n }\n}\n\nexport class NetworkError extends Error {\n constructor(message: string, public cause?: unknown) {\n super(message);\n this.name = 'NetworkError';\n }\n}\n\nexport function isHttpError(e: unknown): e is HttpError {\n return e instanceof HttpError;\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fetchJson } from './api/fetch.js';\n\nexport interface ZenBug {\n id: number;\n title: string;\n severity: number | string;\n pri: number | string;\n status: string;\n assignedTo: string;\n openedBy?: string;\n /** 指派给 config.account 的本人 */\n mine: boolean;\n}\n\nexport type BugsResult =\n | { ok: true; url: string; total: number; bugs: ZenBug[] }\n | { ok: false; error: string };\n\nlet tokenCache: { key: string; token: string; at: number } | null = null;\n\nasync function getToken(cfg: { url: string; account: string; token?: string }): Promise<string> {\n if (cfg.token) return cfg.token;\n const key = `${cfg.url}|${cfg.account}`;\n if (tokenCache && tokenCache.key === key && Date.now() - tokenCache.at < 10 * 60_000) return tokenCache.token;\n const json = await fetchJson(`${cfg.url}/api.php/v1/tokens`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ account: cfg.account, password: '' }),\n });\n const token = typeof json.token === 'string' ? json.token : '';\n if (!token) throw new Error('token 获取失败:检查 account / password');\n tokenCache = { key, token, at: Date.now() };\n return token;\n}\n\nfunction normBug(b: Record<string, unknown>, account: string): ZenBug {\n const assigned = b.assignedTo;\n const assignedTo =\n typeof assigned === 'string'\n ? assigned\n : assigned && typeof assigned === 'object' && 'realname' in (assigned as Record<string, unknown>)\n ? String((assigned as Record<string, unknown>).realname ?? '')\n : '';\n const assignedAccount =\n typeof assigned === 'string'\n ? assigned\n : assigned && typeof assigned === 'object'\n ? String((assigned as Record<string, unknown>).account ?? '')\n : '';\n const mine = !!account && (assignedAccount === account || assignedTo === account);\n return {\n id: Number(b.id),\n title: String(b.title ?? ''),\n severity: (b.severity as number | string) ?? 4,\n pri: (b.pri as number | string) ?? 3,\n status: String(b.status ?? ''),\n assignedTo,\n openedBy: typeof b.openedBy === 'string' ? b.openedBy : undefined,\n mine,\n };\n}\n\nexport async function fetchBugs(config: { url: string; account: string; token: string; product: number }): Promise<BugsResult> {\n if (!config.url || !config.product) {\n return { ok: false, error: '配置无效:请设置服务器 URL 和产品 ID' };\n }\n try {\n const token = await getToken(config);\n const json = await fetchJson(\n `${config.url}/api.php/v1/products/${config.product}/bugs?page=1&limit=100`,\n { headers: { Token: token } },\n );\n const raw = Array.isArray(json.bugs) ? (json.bugs as Record<string, unknown>[]) : [];\n return { ok: true, url: config.url, total: Number(json.total ?? raw.length), bugs: raw.map((b) => normBug(b, config.account)) };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return { ok: false, error: `禅道请求失败(${msg})——检查 url / 凭据 / 是否开启 RESTful API v1` };\n }\n}\n","import type { Context } from 'cordis';\nimport { fetchBugs } from '../../server/bugs.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({\n mode: 'bugs',\n label: '禅道 Bugs',\n icon: '🎯',\n description: '只读 bug 列表',\n config: {\n url: { type: 'string', label: '服务器 URL', default: '' },\n account: { type: 'string', label: '账号', default: '' },\n token: { type: 'string', label: 'Token', default: '' },\n product: { type: 'number', label: '产品 ID', default: 0 },\n },\n });\n\n ctx.server.route('/__bugs', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n try {\n const bugConfig = ctx.dashboard.getConfig('bugs') as { url?: string; account?: string; token?: string; product?: number } | undefined;\n const result = await fetchBugs({\n url: String(bugConfig?.url ?? ''),\n account: String(bugConfig?.account ?? ''),\n token: String(bugConfig?.token ?? ''),\n product: Number(bugConfig?.product ?? 0),\n });\n res.end(JSON.stringify(result));\n } catch (e) {\n res.end(JSON.stringify({ ok: false, error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport YAML from 'yaml';\n\nexport type ItemState = 'open' | 'answered' | 'accepted' | 'dismissed';\nexport type ReviewStatus = 'draft' | 'reviewing' | 'passed' | 'rejected';\nexport type ItemType = 'question' | 'conflict' | 'gap' | 'ambiguity' | 'decomposition';\nexport type Priority = 'high' | 'medium' | 'low';\nexport type Severity = 'high' | 'medium' | 'low';\n\nexport interface ReviewItem {\n id: string;\n type: ItemType;\n severity?: Severity;\n state: ItemState;\n title: string;\n question?: string;\n answer?: string;\n doc?: string;\n context?: string;\n sources?: Array<{ doc: string; quote: string }>;\n priority?: Priority;\n children?: ReviewItem[];\n}\n\nexport interface ReviewDocument {\n id: string;\n path: string;\n title: string;\n type: string;\n parsedAt: string;\n}\n\nexport interface ReviewCodebase {\n id: string;\n path: string;\n title: string;\n type: string;\n summary: string;\n}\n\nexport interface ReviewDiagram {\n path: string;\n title: string;\n type: string;\n}\n\nexport interface ReviewData {\n status: ReviewStatus;\n summary: string;\n documents: ReviewDocument[];\n codebases: ReviewCodebase[];\n diagrams: ReviewDiagram[];\n items: ReviewItem[];\n}\n\nconst REVIEW_DIR = '.zreview';\nconst REVIEW_FILE = path.join(REVIEW_DIR, 'review.yaml');\nconst DOCS_DIR = path.join(REVIEW_DIR, 'docs');\nconst DIAGRAMS_DIR = path.join(REVIEW_DIR, 'diagrams');\n\nexport class ReviewStore {\n private root: string;\n private onChange?: () => void;\n\n constructor(root: string, onChange?: () => void) {\n this.root = root;\n this.onChange = onChange;\n }\n\n exists(): boolean { return fs.existsSync(path.join(this.root, REVIEW_FILE)); }\n\n read(): ReviewData {\n const fullPath = path.join(this.root, REVIEW_FILE);\n if (!fs.existsSync(fullPath)) {\n return { status: 'draft', summary: '', documents: [], codebases: [], diagrams: [], items: [] };\n }\n try {\n const parsed = YAML.parse(fs.readFileSync(fullPath, 'utf8')) as ReviewData;\n if (!parsed || !Array.isArray(parsed.items)) {\n return { status: 'draft', summary: parsed?.summary ?? '', documents: parsed?.documents ?? [], codebases: parsed?.codebases ?? [], diagrams: parsed?.diagrams ?? [], items: [] };\n }\n return {\n status: parsed.status ?? 'draft',\n summary: parsed.summary ?? '',\n documents: parsed.documents ?? [],\n codebases: parsed.codebases ?? [],\n diagrams: parsed.diagrams ?? [],\n items: parsed.items,\n };\n } catch {\n return { status: 'draft', summary: '', documents: [], codebases: [], diagrams: [], items: [] };\n }\n }\n\n private write(data: ReviewData) {\n fs.mkdirSync(path.join(this.root, REVIEW_DIR), { recursive: true });\n fs.writeFileSync(path.join(this.root, REVIEW_FILE), YAML.stringify(data), 'utf8');\n this.onChange?.();\n }\n\n updateItem(id: string, patch: { answer?: string; state?: ItemState; priority?: Priority; title?: string }): ReviewData {\n const data = this.read();\n const item = this.findItem(data.items, id);\n if (!item) throw new Error(`item ${id} not found`);\n if (patch.answer !== undefined) item.answer = patch.answer;\n if (patch.state !== undefined) item.state = patch.state;\n if (patch.priority !== undefined) item.priority = patch.priority;\n if (patch.title !== undefined) item.title = patch.title;\n if (patch.state === 'answered' && !patch.answer && !item.answer) item.answer = '';\n this.write(data);\n return data;\n }\n\n addChild(parentId: string, title: string, priority: Priority = 'medium'): ReviewData {\n const data = this.read();\n const parent = this.findItem(data.items, parentId);\n if (!parent) throw new Error(`parent ${parentId} not found`);\n if (!parent.children) parent.children = [];\n const newId = `${parentId}-${parent.children.length + 1}`;\n parent.children.push({\n id: newId,\n type: 'decomposition',\n state: 'open',\n title,\n priority,\n });\n this.write(data);\n return data;\n }\n\n removeItem(id: string): ReviewData {\n const data = this.read();\n const removed = this.removeItemFromList(data.items, id);\n if (!removed) throw new Error(`item ${id} not found`);\n this.write(data);\n return data;\n }\n\n setStatus(status: ReviewStatus): ReviewData {\n const data = this.read();\n if (status === 'passed' && this.hasOpenItems(data.items)) {\n throw new Error('存在未处理的评审项(open),不能通过');\n }\n data.status = status;\n this.write(data);\n return data;\n }\n\n listDocs(): string[] {\n const docsDir = path.join(this.root, DOCS_DIR);\n if (!fs.existsSync(docsDir)) return [];\n try {\n return fs.readdirSync(docsDir)\n .filter((f) => /\\.(md|markdown|txt)$/i.test(f))\n .sort();\n } catch { return []; }\n }\n\n readDoc(name: string): string {\n const fullPath = path.join(this.root, DOCS_DIR, name);\n if (!fs.existsSync(fullPath)) throw new Error(`doc ${name} not found`);\n return fs.readFileSync(fullPath, 'utf8');\n }\n\n listDiagrams(): string[] {\n const dir = path.join(this.root, DIAGRAMS_DIR);\n if (!fs.existsSync(dir)) return [];\n try {\n return fs.readdirSync(dir)\n .filter((f) => /\\.html$/i.test(f))\n .sort();\n } catch { return []; }\n }\n\n readDiagram(name: string): string {\n const fullPath = path.join(this.root, DIAGRAMS_DIR, name);\n if (!fs.existsSync(fullPath)) throw new Error(`diagram ${name} not found`);\n return fs.readFileSync(fullPath, 'utf8');\n }\n\n private findItem(items: ReviewItem[], id: string): ReviewItem | null {\n for (const item of items) {\n if (item.id === id) return item;\n if (item.children) {\n const found = this.findItem(item.children, id);\n if (found) return found;\n }\n }\n return null;\n }\n\n private removeItemFromList(items: ReviewItem[], id: string): boolean {\n for (let i = 0; i < items.length; i++) {\n if (items[i].id === id) {\n items.splice(i, 1);\n return true;\n }\n if (items[i].children && this.removeItemFromList(items[i].children!, id)) {\n return true;\n }\n }\n return false;\n }\n\n private hasOpenItems(items: ReviewItem[]): boolean {\n for (const item of items) {\n if (item.state === 'open') return true;\n if (item.children && this.hasOpenItems(item.children)) return true;\n }\n return false;\n }\n}\n","import type { Context } from 'cordis';\nimport { ReviewStore, type ItemState, type ReviewStatus, type Priority } from '../../server/review-store.js';\nimport { readBody } from '../../core/read-body.js';\n\nexport const apply = {\n inject: ['server', 'dashboard', 'reload'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'review', label: '文档评审', icon: '✅', description: '多文档需求评审与拆解 · zreview' });\n\n const reviewStore = new ReviewStore(root, () => {\n ctx.reload.broadcast('files');\n });\n\n ctx.server.route('/__review', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(reviewStore.read()));\n });\n\n ctx.server.route('/__review/item', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.updateItem(body.id, {\n answer: body.answer,\n state: body.state as ItemState | undefined,\n priority: body.priority as Priority | undefined,\n title: body.title,\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__review/item/add-child', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.addChild(body.parentId, body.title, body.priority);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__review/item/remove', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.removeItem(body.id);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__review/status', async (req, res) => {\n if (req.headers['x-stop-token'] !== ctx.server.stopToken) { res.writeHead(403); res.end('forbidden'); return; }\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const data = reviewStore.setStatus(body.status as ReviewStatus);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__docs', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(reviewStore.listDocs()));\n });\n\n ctx.server.route('/__docs/:name', async (req, res) => {\n try {\n const name = (req as any).params?.name;\n if (!name) throw new Error('missing doc name');\n const content = reviewStore.readDoc(name);\n res.writeHead(200, { 'Content-Type': 'text/markdown; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(content);\n } catch (e) {\n res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'not found' }));\n }\n });\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { countTasks } from './parse-tasks.js';\n\nexport interface ChangeSummary {\n name: string;\n path: string;\n total: number;\n done: number;\n hasProposal: boolean;\n hasDesign: boolean;\n inWorktree: boolean;\n}\n\nexport interface ChangeDetail extends ChangeSummary {\n proposal?: string;\n design?: string;\n tasks: string;\n dependsOn: string[];\n hasTestStrategy: boolean;\n}\n\nfunction readText(p: string): string {\n try { return fs.readFileSync(p, 'utf8'); } catch { return ''; }\n}\n\nfunction worktreeDir(root: string, name: string): string {\n return path.join(root, '.zworktree', name);\n}\n\nfunction changeDir(root: string, name: string): string {\n return path.join(root, 'openspec', 'changes', name);\n}\n\nfunction parseDependsOn(proposal: string): string[] {\n const deps: string[] = [];\n // 提取 \"## 依赖\" 节:紧跟该标题的列表行\n const m = proposal.match(/^##\\s+依赖\\s*\\n([\\s\\S]*?)(?:\\n#{1,6}\\s|\\n---\\s*\\n|$)/i);\n if (!m) return deps;\n for (const line of m[1].split('\\n')) {\n // 仅收集零缩进的一级条目(/^-/),子级列表(缩进 -)不算依赖名\n if (!/^-\\s+/.test(line)) continue;\n const name = line.replace(/^-\\s+/, '').trim();\n if (name) deps.push(name);\n }\n return deps;\n}\n\nexport function scanApplyChanges(root: string): ChangeSummary[] {\n const changesDir = path.join(root, 'openspec', 'changes');\n if (!fs.existsSync(changesDir)) return [];\n const out: ChangeSummary[] = [];\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.') || ent.name === 'archive') continue;\n const wt = worktreeDir(root, ent.name);\n const tasks = readText(path.join(wt, 'openspec', 'changes', ent.name, 'tasks.md'));\n if (!tasks) {\n const fallback = readText(path.join(changesDir, ent.name, 'tasks.md'));\n if (fallback) {\n const { total, done } = countTasks(fallback);\n const wtChange = path.join(wt, 'openspec', 'changes', ent.name);\n const mainChange = path.join(changesDir, ent.name);\n out.push({\n name: ent.name,\n path: `openspec/changes/${ent.name}`,\n total,\n done,\n hasProposal: fs.existsSync(path.join(wtChange, 'proposal.md')) || fs.existsSync(path.join(mainChange, 'proposal.md')),\n hasDesign: fs.existsSync(path.join(wtChange, 'design.md')) || fs.existsSync(path.join(mainChange, 'design.md')),\n // worktree 目录存在即算执行中(tasks.md 可能尚未落盘)\n inWorktree: fs.existsSync(wtChange),\n });\n }\n } else {\n const { total, done } = countTasks(tasks);\n const wtChange = path.join(wt, 'openspec', 'changes', ent.name);\n const mainChange = path.join(changesDir, ent.name);\n out.push({\n name: ent.name,\n path: `openspec/changes/${ent.name}`,\n total,\n done,\n // 任一侧存在即算(详情读取是 worktree 优先、主目录兜底,列表标记保持一致)\n hasProposal: fs.existsSync(path.join(wtChange, 'proposal.md')) || fs.existsSync(path.join(mainChange, 'proposal.md')),\n hasDesign: fs.existsSync(path.join(wtChange, 'design.md')) || fs.existsSync(path.join(mainChange, 'design.md')),\n inWorktree: true,\n });\n }\n }\n out.sort((a, b) => a.name.localeCompare(b.name));\n return out;\n}\n\nexport function readApplyChange(root: string, name: string): ChangeDetail {\n const wt = worktreeDir(root, name);\n const mainChangeDir = changeDir(root, name);\n\n // 优先 worktree 内;回退主目录\n const proposalFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'proposal.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'proposal.md')\n : path.join(mainChangeDir, 'proposal.md');\n const designFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'design.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'design.md')\n : path.join(mainChangeDir, 'design.md');\n const tasksFrom = fs.existsSync(path.join(wt, 'openspec', 'changes', name, 'tasks.md'))\n ? path.join(wt, 'openspec', 'changes', name, 'tasks.md')\n : path.join(mainChangeDir, 'tasks.md');\n\n const proposal = readText(proposalFrom);\n const design = readText(designFrom);\n const tasks = readText(tasksFrom);\n const { total, done } = countTasks(tasks);\n const inWorktree = fs.existsSync(path.join(wt, 'openspec', 'changes', name));\n const dependsOn = parseDependsOn(proposal);\n const hasTestStrategy = /^##\\s+测试策略\\s*$/m.test(design);\n\n return {\n name,\n path: `openspec/changes/${name}`,\n total,\n done,\n hasProposal: !!proposal,\n hasDesign: !!design,\n inWorktree,\n proposal,\n design,\n tasks,\n dependsOn,\n hasTestStrategy,\n };\n}\n","const TASK_RE = /^\\s*-\\s*\\[([ xX])\\]\\s*(.*)$/;\n\nexport interface ParsedTask {\n text: string\n checked: boolean\n}\n\nexport function parseTasks(md: string): ParsedTask[] {\n return md\n .split('\\n')\n .filter((l) => TASK_RE.test(l))\n .map((l) => {\n const m = l.match(TASK_RE);\n return { text: (m?.[2] ?? l).trim(), checked: m?.[1] !== ' ' };\n });\n}\n\nexport function countTasks(md: string): { total: number; done: number } {\n const tasks = parseTasks(md);\n return { total: tasks.length, done: tasks.filter((t) => t.checked).length };\n}\n","import type { Context } from 'cordis';\nimport { scanApplyChanges, readApplyChange } from './scan.js';\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({ mode: 'apply', label: '执行进度', icon: '⚙️', description: 'OpenSpec change 任务进度' });\n\n ctx.server.route('/__apply', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(scanApplyChanges(root)));\n });\n\n ctx.server.route('/__apply/change', async (req, res) => {\n const url = new URL(req.url || '', 'http://x');\n const name = url.searchParams.get('name');\n if (!name) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: 'missing name' }));\n return;\n }\n if (name.includes('..') || name.includes('/') || name.includes('\\\\')) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: 'invalid name' }));\n return;\n }\n try {\n const data = readApplyChange(root, name);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(data));\n } catch (e) {\n res.writeHead(400);\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n });\n },\n};\n","import type { Context } from 'cordis';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { scanAssets, type ScanResult, type AssetType } from '../../server/design-assets.js';\n\nconst ASSET_KEYS: AssetType[] = ['page','component','icon','token','md','video','audio','pdf','font'];\n\nfunction mergeScanResults(a: ScanResult, b: ScanResult): ScanResult {\n const out: ScanResult = {} as ScanResult;\n for (const k of ASSET_KEYS) {\n out[k] = [...a[k], ...b[k]];\n }\n return out;\n}\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({\n mode: 'design',\n label: '设计资产',\n icon: '🎨',\n description: '页面/组件/图标/Token 分类预览',\n config: {\n folders: { type: 'string[]', label: '扫描文件夹', default: [] },\n },\n });\n\n ctx.server.route('/__design/assets', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n const designConfig = ctx.dashboard.getConfig('design') as { folders?: string[] } | undefined;\n const folders = Array.isArray(designConfig?.folders) ? designConfig.folders : [];\n\n if (folders.length === 0) {\n res.end(JSON.stringify(scanAssets(root)));\n return;\n }\n\n let merged: ScanResult = {} as ScanResult;\n for (const k of ASSET_KEYS) merged[k] = [];\n\n for (const folder of folders) {\n const folderPath = path.resolve(root, folder);\n if (fs.existsSync(folderPath) && fs.statSync(folderPath).isDirectory()) {\n const result = scanAssets(folderPath);\n merged = mergeScanResults(merged, result);\n }\n }\n\n res.end(JSON.stringify(merged));\n });\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from './walk.js';\n\nexport type AssetType = 'page' | 'component' | 'icon' | 'token' | 'md' | 'video' | 'audio' | 'pdf' | 'font';\n\nconst PAGE_EXTS = ['.html', '.htm'];\nconst ICON_EXTS = ['.svg', '.png', '.ico', '.jpg', '.jpeg', '.gif', '.webp'];\nconst VIDEO_EXTS = ['.mp4', '.webm', '.mov', '.ogg', '.ogv'];\nconst AUDIO_EXTS = ['.mp3', '.wav', '.flac', '.aac', '.m4a'];\nconst CODE_EXTS = ['.js', '.mjs', '.cjs', '.mts', '.cts', '.ts', '.tsx', '.jsx', '.css', '.json', '.txt', '.xml', '.yml', '.yaml', '.sh', '.md'];\nconst FONT_EXTS = ['.woff', '.woff2', '.ttf', '.otf'];\nconst TOKEN_RE = /token|theme|design|color|palette|typograph/i;\n\nexport function categorize(rel: string, ext: string): AssetType | null {\n if (rel.indexOf('components/') === 0) return 'component';\n if (VIDEO_EXTS.includes(ext)) return 'video';\n if (AUDIO_EXTS.includes(ext)) return 'audio';\n if (ext === '.pdf') return 'pdf';\n if (ext === '.md') return 'md';\n if (FONT_EXTS.includes(ext)) return 'font';\n if (ICON_EXTS.includes(ext)) return 'icon';\n if (PAGE_EXTS.includes(ext)) return 'page';\n if (CODE_EXTS.includes(ext)) {\n if (TOKEN_RE.test(rel) && (ext === '.css' || ext === '.json')) return 'token';\n return null;\n }\n return null;\n}\n\nexport interface AssetFile { path: string; name: string; ext: string; type: AssetType; }\nexport type ScanResult = Record<AssetType, AssetFile[]>;\n\nexport function scanAssets(root: string, subDir = ''): ScanResult {\n const out: ScanResult = {} as ScanResult;\n const keys: AssetType[] = ['page','component','icon','token','md','video','audio','pdf','font'];\n for (const k of keys) out[k] = [];\n const SKIP = new Set(['node_modules', '.git', 'dist', 'build', 'coverage', '.next', '.cache']);\n const scanRoot = subDir ? path.join(root, subDir) : root;\n walkDir(scanRoot, { skip: SKIP, onFile: (abs, rel) => {\n const ext = path.extname(abs).toLowerCase();\n const t = categorize(rel, ext);\n if (t) out[t].push({ path: rel, name: path.basename(abs), ext, type: t });\n }});\n return out;\n}\n","import type { Context } from 'cordis';\n\nexport const apply = {\n inject: ['dashboard'] as const,\n apply(ctx: Context) {\n ctx.dashboard.register({\n mode: 'view',\n label: '项目浏览',\n icon: '👁️',\n description: 'openspec / docs / 文档预览',\n config: {\n hiddenDirs: { type: 'string[]', label: '隐藏目录', default: ['.git', 'node_modules', 'dist', 'build'] },\n defaultExpandDepth: { type: 'number', label: '默认展开深度', default: 2 },\n showHidden: { type: 'boolean', label: '显示隐藏文件', default: false },\n },\n });\n },\n};\n","import type { Context } from 'cordis';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { walkDir } from '../../server/walk.js';\n\ninterface Stats {\n root: string;\n files: number;\n dirs: number;\n totalSize: number;\n byExt: { ext: string; count: number }[];\n markdown: number;\n openspec: { active: number; archived: number };\n hasJust: boolean;\n}\n\nconst SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', '.cache']);\n\nfunction scan(root: string): Stats {\n const stats: Stats = {\n root: path.basename(root),\n files: 0,\n dirs: 0,\n totalSize: 0,\n byExt: [],\n markdown: 0,\n openspec: { active: 0, archived: 0 },\n hasJust: fs.existsSync(path.join(root, 'justfile')),\n };\n const extMap = new Map<string, number>();\n\n const walk = (dir: string) => {\n walkDir(dir, { skip: SKIP_DIRS, onDir: () => { stats.dirs++; }, onFile: (abs) => {\n stats.files++;\n try { stats.totalSize += fs.statSync(abs).size; } catch {}\n const ext = path.extname(abs).toLowerCase() || '(无扩展名)';\n extMap.set(ext, (extMap.get(ext) ?? 0) + 1);\n if (ext === '.md' || ext === '.markdown') stats.markdown++;\n }});\n };\n walk(root);\n\n const changesDir = path.join(root, 'openspec', 'changes');\n if (fs.existsSync(changesDir)) {\n for (const ent of fs.readdirSync(changesDir, { withFileTypes: true })) {\n if (!ent.isDirectory() || ent.name.startsWith('.')) continue;\n if (ent.name === 'archive') {\n try {\n stats.openspec.archived = fs.readdirSync(path.join(changesDir, 'archive'), { withFileTypes: true })\n .filter(e => e.isDirectory() && !e.name.startsWith('.')).length;\n } catch { /* ignore */ }\n } else stats.openspec.active++;\n }\n }\n\n stats.byExt = Array.from(extMap.entries())\n .map(([ext, count]) => ({ ext, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n return stats;\n}\n\nexport const apply = {\n inject: ['server', 'dashboard'] as const,\n apply(ctx: Context, config: { root: string }) {\n ctx.inject(['server', 'dashboard'], () => {\n const server = (ctx as any).server;\n const dashboard = (ctx as any).dashboard;\n if (!server?.route || !dashboard?.register) return;\n\n dashboard.register({\n mode: 'stats',\n label: '项目统计',\n icon: '📊',\n description: '项目文件统计 · 扫描生成',\n });\n\n server.route('/__stats/data', (_req: unknown, res: import('node:http').ServerResponse) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(scan(config.root)));\n });\n });\n },\n};\n","import fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface BatchChange {\n name: string;\n path: string;\n status: 'pending' | 'running' | 'completed' | 'failed' | 'parked' | 'skipped';\n priority: number;\n risk: 'low' | 'medium' | 'high' | 'unknown';\n dependencies: string[];\n estimatedDuration: number;\n batchIndex: number;\n checkpoint?: {\n currentTaskIndex: number;\n totalTasks: number;\n completedTasks: number;\n currentTask: string;\n };\n error?: string;\n retryCount: number;\n startedAt?: string;\n completedAt?: string;\n}\n\nexport interface BatchLog {\n timestamp: string;\n level: 'info' | 'warn' | 'error' | 'success';\n message: string;\n changeName?: string;\n}\n\nexport interface BatchConflict {\n changeA: string;\n changeB: string;\n files: string[];\n resolution: 'serialize' | 'merge' | 'ignore';\n}\n\nexport interface BatchState {\n version: string;\n status: 'idle' | 'analyzing' | 'pending-approval' | 'running' | 'paused' | 'completed' | 'failed';\n changes: BatchChange[];\n batches: {\n index: number;\n changeNames: string[];\n status: 'pending' | 'running' | 'completed' | 'failed';\n startedAt?: string;\n completedAt?: string;\n }[];\n currentBatchIndex: number;\n parallelism: number;\n logs: BatchLog[];\n conflicts: BatchConflict[];\n createdAt: string;\n updatedAt: string;\n}\n\nconst DEFAULT_STATE: Omit<BatchState, 'createdAt' | 'updatedAt'> = {\n version: '1',\n status: 'idle',\n changes: [],\n batches: [],\n currentBatchIndex: -1,\n parallelism: 2,\n logs: [],\n conflicts: [],\n};\n\nexport class ApplyBatchStore {\n private root: string;\n private statePath: string;\n private state: BatchState;\n private listeners: Set<() => void> = new Set();\n\n constructor(root: string, onBroadcast?: () => void) {\n this.root = root;\n this.statePath = path.join(root, '.zapply', 'batch-state.json');\n this.state = this.load();\n }\n\n private load(): BatchState {\n try {\n if (fs.existsSync(this.statePath)) {\n return JSON.parse(fs.readFileSync(this.statePath, 'utf8'));\n }\n } catch { /* ignore */ }\n return { ...DEFAULT_STATE, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };\n }\n\n private save(): void {\n this.state.updatedAt = new Date().toISOString();\n fs.mkdirSync(path.dirname(this.statePath), { recursive: true });\n fs.writeFileSync(this.statePath, JSON.stringify(this.state, null, 2));\n this.listeners.forEach(fn => fn());\n }\n\n subscribe(fn: () => void) {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n read(): BatchState {\n return this.state;\n }\n\n updateStatus(status: BatchState['status']) {\n this.state.status = status;\n this.save();\n }\n\n updateChanges(changes: BatchChange[]) {\n this.state.changes = changes;\n this.save();\n }\n\n updateBatches(batches: BatchState['batches']) {\n this.state.batches = batches;\n this.save();\n }\n\n updateParallelism(parallelism: number) {\n this.state.parallelism = Math.max(1, Math.min(8, parallelism));\n this.save();\n }\n\n addLog(log: BatchLog) {\n this.state.logs.push(log);\n // Keep only last 1000 logs\n if (this.state.logs.length > 1000) {\n this.state.logs = this.state.logs.slice(-1000);\n }\n this.save();\n }\n\n updateConflicts(conflicts: BatchConflict[]) {\n this.state.conflicts = conflicts;\n this.save();\n }\n\n updateChange(name: string, patch: Partial<BatchChange>) {\n const idx = this.state.changes.findIndex(c => c.name === name);\n if (idx !== -1) {\n this.state.changes[idx] = { ...this.state.changes[idx], ...patch };\n this.save();\n }\n }\n\n updateCheckpoint(name: string, checkpoint: BatchChange['checkpoint']) {\n const idx = this.state.changes.findIndex(c => c.name === name);\n if (idx !== -1) {\n this.state.changes[idx].checkpoint = checkpoint;\n this.save();\n }\n }\n\n reset() {\n this.state = { ...DEFAULT_STATE, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() };\n this.save();\n }\n}\n","import type { Context } from 'cordis';\nimport { ApplyBatchStore } from '../../server/apply-batch-store.js';\n\nexport const apply = {\n inject: ['server', 'dashboard', 'reload'] as const,\n apply(ctx: Context, config: { root: string }) {\n const root = config.root;\n\n ctx.inject(['server'], () => {\n if (!ctx.server?.route) return;\n\n ctx.dashboard.register({\n mode: 'apply-batch',\n label: '批量执行',\n icon: '⚡',\n description: 'zapply 批量并行执行驾驶舱',\n });\n\n const store = new ApplyBatchStore(root, () => {\n try { ctx.reload.broadcast('files'); } catch { /* ignore */ }\n });\n\n ctx.server.route('/__apply-batch', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n });\n\n ctx.server.route('/__apply-batch/status', async (req, res) => {\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n store.updateStatus(body.status);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__apply-batch/changes', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read().changes));\n });\n\n ctx.server.route('/__apply-batch/graph', async (_req, res) => {\n const state = store.read();\n const graph = {\n changes: state.changes.map(c => ({\n name: c.name,\n status: c.status,\n dependencies: c.dependencies,\n batchIndex: c.batchIndex,\n })),\n batches: state.batches,\n conflicts: state.conflicts,\n };\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(graph));\n });\n\n ctx.server.route('/__apply-batch/logs', async (_req, res) => {\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read().logs.slice(-100)));\n });\n\n ctx.server.route('/__apply-batch/approve', async (req, res) => {\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n store.updateStatus('running');\n store.updateParallelism(body.parallelism ?? 2);\n if (body.skipChanges?.length) {\n for (const name of body.skipChanges) {\n store.updateChange(name, { status: 'skipped' });\n }\n }\n store.addLog({\n timestamp: new Date().toISOString(),\n level: 'info',\n message: `用户确认执行计划,并行度=${body.parallelism ?? 2}`,\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__apply-batch/adjust', async (req, res) => {\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n if (body.parallelism) store.updateParallelism(body.parallelism);\n if (body.skipChanges?.length) {\n for (const name of body.skipChanges) {\n store.updateChange(name, { status: 'skipped' });\n }\n }\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__apply-batch/retry', async (req, res) => {\n try {\n const body = JSON.parse(await readBody(req) || '{}');\n const name = body.name;\n if (!name) throw new Error('missing name');\n const change = store.read().changes.find(c => c.name === name);\n if (!change) throw new Error('change not found');\n store.updateChange(name, {\n status: 'pending',\n error: undefined,\n retryCount: (change.retryCount ?? 0) + 1,\n });\n store.addLog({\n timestamp: new Date().toISOString(),\n level: 'info',\n message: `重试 change: ${name}`,\n changeName: name,\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n } catch (e) {\n res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(JSON.stringify({ error: e instanceof Error ? e.message : 'unknown error' }));\n }\n });\n\n ctx.server.route('/__apply-batch/pause', async (req, res) => {\n store.updateStatus('paused');\n store.addLog({\n timestamp: new Date().toISOString(),\n level: 'warn',\n message: '用户暂停批量执行',\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n });\n\n ctx.server.route('/__apply-batch/resume', async (req, res) => {\n store.updateStatus('running');\n store.addLog({\n timestamp: new Date().toISOString(),\n level: 'info',\n message: '用户恢复批量执行',\n });\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n });\n\n ctx.server.route('/__apply-batch/reset', async (req, res) => {\n store.reset();\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-cache' });\n res.end(JSON.stringify(store.read()));\n });\n });\n },\n};\n"],"mappings":"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","names":["path","fs","fileURLToPath","fs","path","fs","path","execFile","execFile","path","fs","err","fp","fs","Service","fs","path","fs","path","fs","path","execFile","apply","Service","readBody","Service","readBody","execFile","apply","readBody","apply","fs","path","apply","readBody","fs","path","fs","path","apply","path","fs","path","path","apply","path","fs","apply","fs","path","path","fs","apply","fs","path","apply","YAML","__dirname","path","fileURLToPath","fs","apply"]}
|