一键导入
server-setup
Noctrace server architecture and API specification. Use when building the Express server, WebSocket handler, file watcher, or REST API endpoints.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Noctrace server architecture and API specification. Use when building the Express server, WebSocket handler, file watcher, or REST API endpoints.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Scan Claude Code, GitHub Copilot, and Codex CLI releases plus competitor tools for new observability features worth implementing in noctrace. Produces a prioritized feature list with effort estimates. Use when the user says "scan", "auto-scan", "what's new", "feature scan", "release scan", "competitor scan", "what should we build next", or wants to check for new opportunities. Also trigger proactively at the start of a new development session if the last scan is more than 7 days old (check docs/research/ for the most recent scan file).
Context Health scoring algorithm for detecting session quality degradation. Use when implementing or modifying the health grade computation, health bar visualization, compaction boundary rendering, or the breakdown panel.
Claude Code JSONL session log parsing specification. Use when implementing or modifying the JSONL parser, building test fixtures, or debugging parsing issues.
Waterfall timeline UI specification for noctrace. Use when building or modifying the waterfall component, detail panel, session picker, or any visual element.
基于 SOC 职业分类
| name | server-setup |
| description | Noctrace server architecture and API specification. Use when building the Express server, WebSocket handler, file watcher, or REST API endpoints. |
Single Express app serving three concerns:
dist/client//api//ws// src/server/index.ts
import express from "express";
import { createServer } from "http";
import { setupWebSocket } from "./ws";
import { setupRoutes } from "./routes";
import { getClaudeHome } from "./config";
const app = express();
const server = createServer(app);
setupRoutes(app, getClaudeHome());
setupWebSocket(server, getClaudeHome());
// Serve SPA in production
app.use(express.static("dist/client"));
app.get("*", (req, res) => res.sendFile("index.html", { root: "dist/client" }));
const PORT = process.env.PORT || 4117;
server.listen(PORT, () => console.log(`Noctrace running at http://localhost:${PORT}`));
Returns list of Claude Code projects.
// Response
interface ProjectListResponse {
projects: {
slug: string; // encoded path (e.g., "-Users-jane-myapp")
path: string; // decoded path (e.g., "/Users/jane/myapp")
sessionCount: number;
lastModified: string; // ISO-8601
}[];
}
Implementation: read directory listing of ~/.claude/projects/, decode slugs by replacing - with /, count JSONL files per project, get latest mtime.
Returns sessions for a project, sorted by most recent.
interface SessionListResponse {
sessions: {
id: string; // session UUID (filename without .jsonl)
summary: string; // first user message or auto-summary
messageCount: number;
startTime: string;
endTime: string;
hasErrors: boolean;
}[];
}
Implementation: read sessions-index.json if it exists, otherwise parse first/last lines of each JSONL file for timestamps and first user message.
Returns parsed waterfall data for a session.
interface SessionDataResponse {
sessionId: string;
projectSlug: string;
startTime: number; // Unix ms
endTime: number; // Unix ms
rows: WaterfallRow[]; // full parsed waterfall hierarchy
}
Implementation: find the JSONL file across all project directories, parse with the JSONL parser, return the WaterfallRow tree.
Client connects to ws://localhost:4117/ws?session={sessionId}.
// New waterfall row (tool_use detected)
{ type: "row:start", row: WaterfallRow }
// Row completed (tool_result received)
{ type: "row:end", id: string, endTime: number, status: "success" | "error", output: string }
// Session ended
{ type: "session:end" }
// Error
{ type: "error", message: string }
// Subscribe to a session
{ type: "subscribe", sessionId: string }
// Unsubscribe
{ type: "unsubscribe" }
Watch the active session's JSONL file for changes:
import chokidar from "chokidar";
// Watch specific file, not entire directory
const watcher = chokidar.watch(sessionFilePath, {
persistent: true,
ignoreInitial: true,
awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },
});
watcher.on("change", () => {
// Read new lines since last known position (byte offset)
// Parse new lines
// Push new events via WebSocket
});
Key implementation detail: track the byte offset of the last read position. On file change, read only the new bytes appended since that offset. Parse each new line and emit WebSocket events.
// bin/noctrace.js
#!/usr/bin/env node
import { startServer } from "../dist/server/index.js";
import open from "open";
const port = await startServer();
console.log(`\n Noctrace running at http://localhost:${port}\n`);
await open(`http://localhost:${port}`);
~/.claude/ doesn't exist: serve the SPA with an empty state and a helpful messagesession:end