@revealui/harnesses 0.1.3 → 0.1.6

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  HarnessCoordinator,
4
4
  checkHarnessesLicense
5
- } from "./chunk-HH2PJYQN.js";
5
+ } from "./chunk-XLIKSLM3.js";
6
6
  import {
7
7
  buildManifest,
8
8
  diffContent,
@@ -10,10 +10,10 @@ import {
10
10
  listContent,
11
11
  listGenerators,
12
12
  validateManifest
13
- } from "./chunk-JDI6B2IB.js";
13
+ } from "./chunk-XXEKWC6F.js";
14
14
  import {
15
15
  WorkboardManager
16
- } from "./chunk-FJGN6DTH.js";
16
+ } from "./chunk-JG6CAG4A.js";
17
17
  import "./chunk-DGUM43GV.js";
18
18
 
19
19
  // src/cli.ts
@@ -459,16 +459,16 @@ async function main() {
459
459
  const workboardPath = join(projectRoot, ".claude", "workboard.md");
460
460
  const manager = new WorkboardManager(workboardPath);
461
461
  const state = manager.read();
462
- process.stdout.write(`Sessions (${state.sessions.length}):
462
+ process.stdout.write(`Agents (${state.agents.length}):
463
463
  `);
464
- for (const s of state.sessions) {
465
- const stale = Date.now() - new Date(s.updated).getTime() > 4 * 60 * 60 * 1e3;
466
- process.stdout.write(` ${s.id} [${s.env}] \u2014 ${s.task}${stale ? " (STALE)" : ""}
464
+ for (const a of state.agents) {
465
+ const stale = Date.now() - new Date(a.updated).getTime() > 4 * 60 * 60 * 1e3;
466
+ process.stdout.write(` ${a.id} [${a.env}] \u2014 ${a.task}${stale ? " (STALE)" : ""}
467
467
  `);
468
- if (s.files) process.stdout.write(` files: ${s.files}
468
+ if (a.files) process.stdout.write(` files: ${a.files}
469
469
  `);
470
470
  }
471
- if (state.sessions.length === 0) process.stdout.write(" (no active sessions)\n");
471
+ if (state.agents.length === 0) process.stdout.write(" (no active agents)\n");
472
472
  }
473
473
  break;
474
474
  }
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * revealui-harnesses — CLI daemon and RPC client for AI harness coordination.\n *\n * Commands:\n * start [--project <path>] Detect harnesses, register in workboard, start RPC server\n * status List available harnesses via RPC\n * list List harnesses in TSV format\n * sync <harnessId> <push|pull> Sync harness config to/from SSD\n * coordinate [--print] Print current workboard state\n * coordinate --init <path> Register this session in the workboard and start daemon\n *\n * License: Pro tier required (isFeatureEnabled(\"harnesses\"))\n */\n\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { createConnection } from 'node:net';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport {\n buildManifest,\n diffContent,\n generateContent,\n listContent,\n listGenerators,\n validateManifest,\n} from './content/index.js';\nimport { HarnessCoordinator } from './coordinator.js';\nimport { checkHarnessesLicense } from './index.js';\nimport { WorkboardManager } from './workboard/workboard-manager.js';\n\nconst DEFAULT_SOCKET = join(homedir(), '.local', 'share', 'revealui', 'harness.sock');\nconst DEFAULT_PROJECT = process.cwd();\n\nconst [, , command, ...args] = process.argv;\n\nasync function rpcCall(method: string, params: unknown = {}): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const socket = createConnection(DEFAULT_SOCKET);\n let buffer = '';\n socket.on('connect', () => {\n const req = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params });\n socket.write(`${req}\\n`);\n });\n socket.on('data', (chunk) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const resp = JSON.parse(line) as { result?: unknown; error?: { message: string } };\n socket.destroy();\n if (resp.error) reject(new Error(resp.error.message));\n else resolve(resp.result);\n } catch {\n reject(new Error(`Invalid JSON: ${line}`));\n }\n }\n });\n socket.on('error', reject);\n setTimeout(() => {\n socket.destroy();\n reject(new Error('RPC timeout'));\n }, 5000);\n });\n}\n\nasync function handleContentCommand(subcommand: string | undefined, args: string[]): Promise<void> {\n const manifest = buildManifest();\n const projectRoot = process.cwd();\n const ctx = { projectRoot };\n\n switch (subcommand) {\n case 'list': {\n const summary = listContent(manifest);\n process.stdout.write(`Canonical content:\\n`);\n process.stdout.write(` Rules: ${summary.rules}\\n`);\n process.stdout.write(` Commands: ${summary.commands}\\n`);\n process.stdout.write(` Agents: ${summary.agents}\\n`);\n process.stdout.write(` Skills: ${summary.skills}\\n`);\n process.stdout.write(` Preambles: ${summary.preambles}\\n`);\n process.stdout.write(` Total: ${summary.total}\\n`);\n process.stdout.write(`\\nRules:\\n`);\n for (const rule of manifest.rules) {\n process.stdout.write(` ${rule.id} (tier ${rule.preambleTier}) — ${rule.description}\\n`);\n }\n process.stdout.write(`\\nCommands:\\n`);\n for (const cmd of manifest.commands) {\n process.stdout.write(\n ` ${cmd.id}${cmd.disableModelInvocation ? ' [manual]' : ''} — ${cmd.description.slice(0, 80)}\\n`,\n );\n }\n process.stdout.write(`\\nAgents:\\n`);\n for (const agent of manifest.agents) {\n process.stdout.write(` ${agent.id} [${agent.isolation}] — ${agent.description}\\n`);\n }\n process.stdout.write(`\\nSkills:\\n`);\n for (const skill of manifest.skills) {\n process.stdout.write(\n ` ${skill.id}${skill.disableModelInvocation ? ' [manual]' : ''} — ${skill.description.slice(0, 80)}\\n`,\n );\n }\n process.stdout.write(`\\nGenerators: ${listGenerators().join(', ')}\\n`);\n break;\n }\n\n case 'validate': {\n const result = validateManifest(manifest);\n if (result.valid) {\n process.stdout.write(`✓ All definitions valid\\n`);\n } else {\n process.stderr.write(`✗ Validation errors:\\n`);\n for (const error of result.errors) {\n process.stderr.write(` - ${error}\\n`);\n }\n process.exit(1);\n }\n break;\n }\n\n case 'diff': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const entries = diffContent(generatorId, manifest, ctx, projectRoot);\n const added = entries.filter((e) => e.status === 'added');\n const modified = entries.filter((e) => e.status === 'modified');\n const unchanged = entries.filter((e) => e.status === 'unchanged');\n\n if (added.length === 0 && modified.length === 0) {\n process.stdout.write(`✓ No changes (${unchanged.length} files up to date)\\n`);\n } else {\n if (added.length > 0) {\n process.stdout.write(`Added (${added.length}):\\n`);\n for (const e of added) process.stdout.write(` + ${e.relativePath}\\n`);\n }\n if (modified.length > 0) {\n process.stdout.write(`Modified (${modified.length}):\\n`);\n for (const e of modified) process.stdout.write(` ~ ${e.relativePath}\\n`);\n }\n process.stdout.write(`Unchanged: ${unchanged.length}\\n`);\n }\n break;\n }\n\n case 'sync': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const dryRun = args.includes('--dry-run');\n const files = generateContent(generatorId, manifest, ctx);\n\n if (dryRun) {\n process.stdout.write(`Dry run — would write ${files.length} files:\\n`);\n for (const file of files) {\n process.stdout.write(` ${file.relativePath}\\n`);\n }\n } else {\n let written = 0;\n for (const file of files) {\n const absolutePath = join(projectRoot, file.relativePath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n writeFileSync(absolutePath, file.content, 'utf-8');\n written++;\n }\n process.stdout.write(`✓ Wrote ${written} files via ${generatorId} generator\\n`);\n }\n break;\n }\n\n case 'export': {\n const outIdx = args.indexOf('--output');\n const rawOutput = outIdx >= 0 ? args[outIdx + 1] : undefined;\n if (!rawOutput) {\n process.stderr.write('Usage: content export --output <path>\\n');\n process.exit(1);\n }\n const outputDir: string = rawOutput;\n\n // 1. Write canonical definitions organized by type/tier\n const definitionTypes = [\n { key: 'rules' as const, items: manifest.rules },\n { key: 'commands' as const, items: manifest.commands },\n { key: 'agents' as const, items: manifest.agents },\n { key: 'skills' as const, items: manifest.skills },\n ];\n\n let canonicalCount = 0;\n for (const { key, items } of definitionTypes) {\n for (const item of items) {\n const tier = item.tier ?? 'oss';\n const filePath = join(outputDir, key, tier, `${item.id}.md`);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, item.content, 'utf-8');\n canonicalCount++;\n }\n }\n\n // 2. Write pre-rendered generator output (compute once, reuse for manifest)\n const generatorIds = listGenerators();\n const generatorOutputs = new Map<string, { relativePath: string; content: string }[]>();\n let generatedCount = 0;\n for (const genId of generatorIds) {\n const files = generateContent(genId, manifest, ctx);\n generatorOutputs.set(genId, files);\n for (const file of files) {\n const filePath = join(outputDir, 'generators', genId, file.relativePath);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, file.content, 'utf-8');\n generatedCount++;\n }\n }\n\n // 3. Write manifest.json with metadata\n interface ManifestEntry {\n id: string;\n type: string;\n name: string;\n description: string;\n tier: string;\n tags?: string[];\n canonicalPath: string;\n generatorPaths: Record<string, string[]>;\n }\n\n const entries: ManifestEntry[] = [];\n for (const { key, items } of definitionTypes) {\n for (const item of items) {\n const tier = item.tier ?? 'oss';\n const type = key.replace(/s$/, ''); // rules → rule\n const entry: ManifestEntry = {\n id: item.id,\n type,\n name: item.name,\n description: item.description,\n tier,\n canonicalPath: `${key}/${tier}/${item.id}.md`,\n generatorPaths: {},\n };\n if ('tags' in item && Array.isArray(item.tags) && item.tags.length > 0) {\n entry.tags = item.tags;\n }\n // Map each generator's output paths for this definition\n for (const genId of generatorIds) {\n const genFiles = generatorOutputs.get(genId) ?? [];\n const matching = genFiles\n .filter((f) => f.relativePath.includes(item.id))\n .map((f) => f.relativePath);\n if (matching.length > 0) {\n entry.generatorPaths[genId] = matching;\n }\n }\n entries.push(entry);\n }\n }\n\n const exportManifest = {\n version: 1,\n generatedAt: new Date().toISOString(),\n generators: generatorIds,\n definitions: entries,\n };\n\n const manifestPath = join(outputDir, 'manifest.json');\n mkdirSync(dirname(manifestPath), { recursive: true });\n writeFileSync(manifestPath, `${JSON.stringify(exportManifest, null, 2)}\\n`, 'utf-8');\n\n process.stdout.write(`✓ Exported to ${outputDir}\\n`);\n process.stdout.write(` Canonical definitions: ${canonicalCount}\\n`);\n process.stdout.write(\n ` Generator output: ${generatedCount} files (${generatorIds.join(', ')})\\n`,\n );\n process.stdout.write(` Manifest: manifest.json\\n`);\n break;\n }\n\n case 'pull': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const tierIdx = args.indexOf('--tier');\n const tierFilter = tierIdx >= 0 ? (args[tierIdx + 1] ?? 'oss') : 'oss';\n\n if (!['oss', 'pro', 'all'].includes(tierFilter)) {\n process.stderr.write(`Invalid tier: ${tierFilter}. Use: oss, pro, all\\n`);\n process.exit(1);\n }\n\n // Pro tier requires a valid license\n const needsLicense = tierFilter === 'pro' || tierFilter === 'all';\n if (needsLicense) {\n const licensed = await checkHarnessesLicense();\n if (!licensed) {\n process.stderr.write(\n 'Pro rules require a valid license key. Visit https://revealui.com/pricing\\n',\n );\n process.exit(1);\n }\n }\n\n const baseUrl =\n args[args.indexOf('--url') + 1] ??\n process.env.REVEALUI_RULES_URL ??\n 'https://raw.githubusercontent.com/RevealUIStudio/editor-configs/main/harnesses';\n\n // Fetch manifest from remote\n process.stdout.write(`Fetching manifest from ${baseUrl}/manifest.json...\\n`);\n const manifestRes = await fetch(`${baseUrl}/manifest.json`);\n if (!manifestRes.ok) {\n process.stderr.write(\n `Failed to fetch manifest: ${manifestRes.status} ${manifestRes.statusText}\\n`,\n );\n process.exit(1);\n }\n\n const remoteManifest = (await manifestRes.json()) as {\n definitions: Array<{\n id: string;\n type: string;\n name: string;\n tier: string;\n generatorPaths: Record<string, string[]>;\n }>;\n };\n\n // Filter definitions by tier\n const filtered = remoteManifest.definitions.filter((def) => {\n if (tierFilter === 'all') return true;\n return def.tier === tierFilter;\n });\n\n process.stdout.write(`Found ${filtered.length} definitions (tier: ${tierFilter})\\n`);\n\n // Download pre-rendered files for the selected generator\n let written = 0;\n let errors = 0;\n for (const def of filtered) {\n const paths = def.generatorPaths[generatorId] ?? [];\n for (const relPath of paths) {\n const fileUrl = `${baseUrl}/generators/${generatorId}/${relPath}`;\n try {\n const fileRes = await fetch(fileUrl);\n if (!fileRes.ok) {\n process.stderr.write(` ✗ ${relPath} (${fileRes.status})\\n`);\n errors++;\n continue;\n }\n const content = await fileRes.text();\n const absolutePath = join(projectRoot, relPath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n writeFileSync(absolutePath, content, 'utf-8');\n written++;\n } catch (err) {\n process.stderr.write(\n ` ✗ ${relPath} (${err instanceof Error ? err.message : 'fetch error'})\\n`,\n );\n errors++;\n }\n }\n }\n\n process.stdout.write(`✓ Pulled ${written} files via ${generatorId} generator\\n`);\n if (errors > 0) {\n process.stderr.write(` ${errors} file(s) failed to download\\n`);\n }\n break;\n }\n\n default:\n process.stderr.write(`Unknown content subcommand: ${subcommand ?? '(none)'}\\n`);\n process.stderr.write(`Available: list, validate, diff, sync, export, pull\\n`);\n process.exit(1);\n }\n}\n\nasync function main() {\n // Content commands are developer tooling — no license required\n if (command === 'content') {\n const [subcommand] = args;\n const contentArgs = args.slice(1);\n await handleContentCommand(subcommand, contentArgs);\n return;\n }\n\n if (!(await checkHarnessesLicense())) {\n process.stderr.write(\n '⚠ @revealui/harnesses requires a Pro license. Visit https://revealui.com/pricing\\n',\n );\n process.exit(2);\n }\n\n switch (command) {\n case 'start': {\n const projectIdx = args.indexOf('--project');\n const projectRoot =\n projectIdx >= 0 ? (args[projectIdx + 1] ?? DEFAULT_PROJECT) : DEFAULT_PROJECT;\n\n const coordinator = new HarnessCoordinator({\n projectRoot,\n task: 'Harness coordination active',\n });\n\n await coordinator.start();\n const ids = await coordinator.getRegistry().listAvailable();\n process.stdout.write(`✓ Detected harnesses: ${ids.length > 0 ? ids.join(', ') : 'none'}\\n`);\n process.stdout.write(`✓ RPC server listening on ${DEFAULT_SOCKET}\\n`);\n process.stdout.write(`✓ Session registered in workboard\\n`);\n\n const shutdown = async () => {\n await coordinator.stop();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n break;\n }\n\n case 'status': {\n try {\n const infos = (await rpcCall('harness.list')) as Array<{\n id: string;\n name: string;\n version?: string;\n }>;\n if (infos.length === 0) {\n process.stdout.write('No harnesses available\\n');\n } else {\n for (const info of infos) {\n process.stdout.write(\n `${info.id}\\t${info.name}${info.version ? `\\t${info.version}` : ''}\\n`,\n );\n }\n }\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'list': {\n try {\n const infos = (await rpcCall('harness.list')) as Array<{ id: string; name: string }>;\n for (const info of infos) {\n process.stdout.write(`${info.id}\\t${info.name}\\n`);\n }\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'sync': {\n const [harnessId, direction] = args;\n if (!(harnessId && direction && ['push', 'pull'].includes(direction))) {\n process.stderr.write('Usage: revealui-harnesses sync <harnessId> <push|pull>\\n');\n process.exit(1);\n }\n try {\n const result = (await rpcCall('harness.syncConfig', { harnessId, direction })) as {\n success: boolean;\n message?: string;\n };\n process.stdout.write(result.success ? `✓ ${result.message}\\n` : `✗ ${result.message}\\n`);\n if (!result.success) process.exit(1);\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'coordinate': {\n if (args.includes('--init')) {\n const pathIdx = args.indexOf('--init');\n const projectRoot = args[pathIdx + 1] ?? DEFAULT_PROJECT;\n const coordinator = new HarnessCoordinator({ projectRoot, task: 'Coordinate harnesses' });\n await coordinator.start();\n const workboard = coordinator.getWorkboard();\n const conflicts = workboard.checkConflicts('', []);\n process.stdout.write(\n `✓ Session registered. Conflicts: ${conflicts.clean ? 'none' : conflicts.conflicts.length}\\n`,\n );\n await coordinator.stop();\n } else {\n // --print: dump current workboard to stdout\n const projectRoot = args[args.indexOf('--project') + 1] ?? DEFAULT_PROJECT;\n const workboardPath = join(projectRoot, '.claude', 'workboard.md');\n const manager = new WorkboardManager(workboardPath);\n const state = manager.read();\n process.stdout.write(`Sessions (${state.sessions.length}):\\n`);\n for (const s of state.sessions) {\n const stale = Date.now() - new Date(s.updated).getTime() > 4 * 60 * 60 * 1000;\n process.stdout.write(` ${s.id} [${s.env}] — ${s.task}${stale ? ' (STALE)' : ''}\\n`);\n if (s.files) process.stdout.write(` files: ${s.files}\\n`);\n }\n if (state.sessions.length === 0) process.stdout.write(' (no active sessions)\\n');\n }\n break;\n }\n\n case 'health': {\n try {\n const result = (await rpcCall('harness.health')) as {\n healthy: boolean;\n registeredHarnesses: Array<{ harnessId: string; available: boolean }>;\n workboard: { readable: boolean; sessionCount: number; staleSessionIds: string[] };\n diagnostics: string[];\n };\n process.stdout.write(`Health: ${result.healthy ? 'HEALTHY' : 'UNHEALTHY'}\\n`);\n process.stdout.write(`Harnesses:\\n`);\n for (const h of result.registeredHarnesses) {\n process.stdout.write(` ${h.harnessId}: ${h.available ? 'available' : 'unavailable'}\\n`);\n }\n process.stdout.write(\n `Workboard: ${result.workboard.readable ? 'readable' : 'unreadable'}, ${result.workboard.sessionCount} session(s)\\n`,\n );\n if (result.workboard.staleSessionIds.length > 0) {\n process.stdout.write(` Stale: ${result.workboard.staleSessionIds.join(', ')}\\n`);\n }\n if (result.diagnostics.length > 0) {\n process.stdout.write(`Diagnostics:\\n`);\n for (const d of result.diagnostics) {\n process.stdout.write(` ${d}\\n`);\n }\n }\n if (!result.healthy) process.exit(1);\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n default:\n process.stdout.write(`revealui-harnesses — AI harness coordination for RevealUI\n\nCommands:\n start [--project <path>] Start daemon (detects harnesses, registers session)\n status List available harnesses (requires daemon)\n list List harnesses in TSV format (requires daemon)\n sync <id> <push|pull> Sync harness config to/from SSD (requires daemon)\n health Run health check (requires daemon)\n coordinate [--project <path>] Print workboard state\n coordinate --init [<path>] Register + start daemon\n content <subcommand> Manage canonical content definitions\n\nContent Subcommands:\n content list List all canonical content with metadata\n content validate Validate all definitions against schemas\n content diff [--generator <id>] Show what would change vs current files\n content sync [--generator <id>] [--dry-run] Generate and write files\n content export --output <path> Export canonical + generated files to directory\n content pull [--generator <id>] [--tier oss|pro|all] Pull rules from rules repo\n`);\n break;\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":["args"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * revealui-harnesses — CLI daemon and RPC client for AI harness coordination.\n *\n * Commands:\n * start [--project <path>] Detect harnesses, register in workboard, start RPC server\n * status List available harnesses via RPC\n * list List harnesses in TSV format\n * sync <harnessId> <push|pull> Sync harness config to/from SSD\n * coordinate [--print] Print current workboard state\n * coordinate --init <path> Register this session in the workboard and start daemon\n *\n * License: Pro tier required (isFeatureEnabled(\"harnesses\"))\n */\n\nimport { mkdirSync, writeFileSync } from 'node:fs';\nimport { createConnection } from 'node:net';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport {\n buildManifest,\n diffContent,\n generateContent,\n listContent,\n listGenerators,\n validateManifest,\n} from './content/index.js';\nimport { HarnessCoordinator } from './coordinator.js';\nimport { checkHarnessesLicense } from './index.js';\nimport { WorkboardManager } from './workboard/workboard-manager.js';\n\nconst DEFAULT_SOCKET = join(homedir(), '.local', 'share', 'revealui', 'harness.sock');\nconst DEFAULT_PROJECT = process.cwd();\n\nconst [, , command, ...args] = process.argv;\n\nasync function rpcCall(method: string, params: unknown = {}): Promise<unknown> {\n return new Promise((resolve, reject) => {\n const socket = createConnection(DEFAULT_SOCKET);\n let buffer = '';\n socket.on('connect', () => {\n const req = JSON.stringify({ jsonrpc: '2.0', id: 1, method, params });\n socket.write(`${req}\\n`);\n });\n socket.on('data', (chunk) => {\n buffer += chunk.toString();\n const lines = buffer.split('\\n');\n buffer = lines.pop() ?? '';\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const resp = JSON.parse(line) as { result?: unknown; error?: { message: string } };\n socket.destroy();\n if (resp.error) reject(new Error(resp.error.message));\n else resolve(resp.result);\n } catch {\n reject(new Error(`Invalid JSON: ${line}`));\n }\n }\n });\n socket.on('error', reject);\n setTimeout(() => {\n socket.destroy();\n reject(new Error('RPC timeout'));\n }, 5000);\n });\n}\n\nasync function handleContentCommand(subcommand: string | undefined, args: string[]): Promise<void> {\n const manifest = buildManifest();\n const projectRoot = process.cwd();\n const ctx = { projectRoot };\n\n switch (subcommand) {\n case 'list': {\n const summary = listContent(manifest);\n process.stdout.write(`Canonical content:\\n`);\n process.stdout.write(` Rules: ${summary.rules}\\n`);\n process.stdout.write(` Commands: ${summary.commands}\\n`);\n process.stdout.write(` Agents: ${summary.agents}\\n`);\n process.stdout.write(` Skills: ${summary.skills}\\n`);\n process.stdout.write(` Preambles: ${summary.preambles}\\n`);\n process.stdout.write(` Total: ${summary.total}\\n`);\n process.stdout.write(`\\nRules:\\n`);\n for (const rule of manifest.rules) {\n process.stdout.write(` ${rule.id} (tier ${rule.preambleTier}) — ${rule.description}\\n`);\n }\n process.stdout.write(`\\nCommands:\\n`);\n for (const cmd of manifest.commands) {\n process.stdout.write(\n ` ${cmd.id}${cmd.disableModelInvocation ? ' [manual]' : ''} — ${cmd.description.slice(0, 80)}\\n`,\n );\n }\n process.stdout.write(`\\nAgents:\\n`);\n for (const agent of manifest.agents) {\n process.stdout.write(` ${agent.id} [${agent.isolation}] — ${agent.description}\\n`);\n }\n process.stdout.write(`\\nSkills:\\n`);\n for (const skill of manifest.skills) {\n process.stdout.write(\n ` ${skill.id}${skill.disableModelInvocation ? ' [manual]' : ''} — ${skill.description.slice(0, 80)}\\n`,\n );\n }\n process.stdout.write(`\\nGenerators: ${listGenerators().join(', ')}\\n`);\n break;\n }\n\n case 'validate': {\n const result = validateManifest(manifest);\n if (result.valid) {\n process.stdout.write(`✓ All definitions valid\\n`);\n } else {\n process.stderr.write(`✗ Validation errors:\\n`);\n for (const error of result.errors) {\n process.stderr.write(` - ${error}\\n`);\n }\n process.exit(1);\n }\n break;\n }\n\n case 'diff': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const entries = diffContent(generatorId, manifest, ctx, projectRoot);\n const added = entries.filter((e) => e.status === 'added');\n const modified = entries.filter((e) => e.status === 'modified');\n const unchanged = entries.filter((e) => e.status === 'unchanged');\n\n if (added.length === 0 && modified.length === 0) {\n process.stdout.write(`✓ No changes (${unchanged.length} files up to date)\\n`);\n } else {\n if (added.length > 0) {\n process.stdout.write(`Added (${added.length}):\\n`);\n for (const e of added) process.stdout.write(` + ${e.relativePath}\\n`);\n }\n if (modified.length > 0) {\n process.stdout.write(`Modified (${modified.length}):\\n`);\n for (const e of modified) process.stdout.write(` ~ ${e.relativePath}\\n`);\n }\n process.stdout.write(`Unchanged: ${unchanged.length}\\n`);\n }\n break;\n }\n\n case 'sync': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const dryRun = args.includes('--dry-run');\n const files = generateContent(generatorId, manifest, ctx);\n\n if (dryRun) {\n process.stdout.write(`Dry run — would write ${files.length} files:\\n`);\n for (const file of files) {\n process.stdout.write(` ${file.relativePath}\\n`);\n }\n } else {\n let written = 0;\n for (const file of files) {\n const absolutePath = join(projectRoot, file.relativePath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n writeFileSync(absolutePath, file.content, 'utf-8');\n written++;\n }\n process.stdout.write(`✓ Wrote ${written} files via ${generatorId} generator\\n`);\n }\n break;\n }\n\n case 'export': {\n const outIdx = args.indexOf('--output');\n const rawOutput = outIdx >= 0 ? args[outIdx + 1] : undefined;\n if (!rawOutput) {\n process.stderr.write('Usage: content export --output <path>\\n');\n process.exit(1);\n }\n const outputDir: string = rawOutput;\n\n // 1. Write canonical definitions organized by type/tier\n const definitionTypes = [\n { key: 'rules' as const, items: manifest.rules },\n { key: 'commands' as const, items: manifest.commands },\n { key: 'agents' as const, items: manifest.agents },\n { key: 'skills' as const, items: manifest.skills },\n ];\n\n let canonicalCount = 0;\n for (const { key, items } of definitionTypes) {\n for (const item of items) {\n const tier = item.tier ?? 'oss';\n const filePath = join(outputDir, key, tier, `${item.id}.md`);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, item.content, 'utf-8');\n canonicalCount++;\n }\n }\n\n // 2. Write pre-rendered generator output (compute once, reuse for manifest)\n const generatorIds = listGenerators();\n const generatorOutputs = new Map<string, { relativePath: string; content: string }[]>();\n let generatedCount = 0;\n for (const genId of generatorIds) {\n const files = generateContent(genId, manifest, ctx);\n generatorOutputs.set(genId, files);\n for (const file of files) {\n const filePath = join(outputDir, 'generators', genId, file.relativePath);\n mkdirSync(dirname(filePath), { recursive: true });\n writeFileSync(filePath, file.content, 'utf-8');\n generatedCount++;\n }\n }\n\n // 3. Write manifest.json with metadata\n interface ManifestEntry {\n id: string;\n type: string;\n name: string;\n description: string;\n tier: string;\n tags?: string[];\n canonicalPath: string;\n generatorPaths: Record<string, string[]>;\n }\n\n const entries: ManifestEntry[] = [];\n for (const { key, items } of definitionTypes) {\n for (const item of items) {\n const tier = item.tier ?? 'oss';\n const type = key.replace(/s$/, ''); // rules → rule\n const entry: ManifestEntry = {\n id: item.id,\n type,\n name: item.name,\n description: item.description,\n tier,\n canonicalPath: `${key}/${tier}/${item.id}.md`,\n generatorPaths: {},\n };\n if ('tags' in item && Array.isArray(item.tags) && item.tags.length > 0) {\n entry.tags = item.tags;\n }\n // Map each generator's output paths for this definition\n for (const genId of generatorIds) {\n const genFiles = generatorOutputs.get(genId) ?? [];\n const matching = genFiles\n .filter((f) => f.relativePath.includes(item.id))\n .map((f) => f.relativePath);\n if (matching.length > 0) {\n entry.generatorPaths[genId] = matching;\n }\n }\n entries.push(entry);\n }\n }\n\n const exportManifest = {\n version: 1,\n generatedAt: new Date().toISOString(),\n generators: generatorIds,\n definitions: entries,\n };\n\n const manifestPath = join(outputDir, 'manifest.json');\n mkdirSync(dirname(manifestPath), { recursive: true });\n writeFileSync(manifestPath, `${JSON.stringify(exportManifest, null, 2)}\\n`, 'utf-8');\n\n process.stdout.write(`✓ Exported to ${outputDir}\\n`);\n process.stdout.write(` Canonical definitions: ${canonicalCount}\\n`);\n process.stdout.write(\n ` Generator output: ${generatedCount} files (${generatorIds.join(', ')})\\n`,\n );\n process.stdout.write(` Manifest: manifest.json\\n`);\n break;\n }\n\n case 'pull': {\n const genIdx = args.indexOf('--generator');\n const generatorId = genIdx >= 0 ? (args[genIdx + 1] ?? 'claude-code') : 'claude-code';\n const tierIdx = args.indexOf('--tier');\n const tierFilter = tierIdx >= 0 ? (args[tierIdx + 1] ?? 'oss') : 'oss';\n\n if (!['oss', 'pro', 'all'].includes(tierFilter)) {\n process.stderr.write(`Invalid tier: ${tierFilter}. Use: oss, pro, all\\n`);\n process.exit(1);\n }\n\n // Pro tier requires a valid license\n const needsLicense = tierFilter === 'pro' || tierFilter === 'all';\n if (needsLicense) {\n const licensed = await checkHarnessesLicense();\n if (!licensed) {\n process.stderr.write(\n 'Pro rules require a valid license key. Visit https://revealui.com/pricing\\n',\n );\n process.exit(1);\n }\n }\n\n const baseUrl =\n args[args.indexOf('--url') + 1] ??\n process.env.REVEALUI_RULES_URL ??\n 'https://raw.githubusercontent.com/RevealUIStudio/editor-configs/main/harnesses';\n\n // Fetch manifest from remote\n process.stdout.write(`Fetching manifest from ${baseUrl}/manifest.json...\\n`);\n const manifestRes = await fetch(`${baseUrl}/manifest.json`);\n if (!manifestRes.ok) {\n process.stderr.write(\n `Failed to fetch manifest: ${manifestRes.status} ${manifestRes.statusText}\\n`,\n );\n process.exit(1);\n }\n\n const remoteManifest = (await manifestRes.json()) as {\n definitions: Array<{\n id: string;\n type: string;\n name: string;\n tier: string;\n generatorPaths: Record<string, string[]>;\n }>;\n };\n\n // Filter definitions by tier\n const filtered = remoteManifest.definitions.filter((def) => {\n if (tierFilter === 'all') return true;\n return def.tier === tierFilter;\n });\n\n process.stdout.write(`Found ${filtered.length} definitions (tier: ${tierFilter})\\n`);\n\n // Download pre-rendered files for the selected generator\n let written = 0;\n let errors = 0;\n for (const def of filtered) {\n const paths = def.generatorPaths[generatorId] ?? [];\n for (const relPath of paths) {\n const fileUrl = `${baseUrl}/generators/${generatorId}/${relPath}`;\n try {\n const fileRes = await fetch(fileUrl);\n if (!fileRes.ok) {\n process.stderr.write(` ✗ ${relPath} (${fileRes.status})\\n`);\n errors++;\n continue;\n }\n const content = await fileRes.text();\n const absolutePath = join(projectRoot, relPath);\n mkdirSync(dirname(absolutePath), { recursive: true });\n writeFileSync(absolutePath, content, 'utf-8');\n written++;\n } catch (err) {\n process.stderr.write(\n ` ✗ ${relPath} (${err instanceof Error ? err.message : 'fetch error'})\\n`,\n );\n errors++;\n }\n }\n }\n\n process.stdout.write(`✓ Pulled ${written} files via ${generatorId} generator\\n`);\n if (errors > 0) {\n process.stderr.write(` ${errors} file(s) failed to download\\n`);\n }\n break;\n }\n\n default:\n process.stderr.write(`Unknown content subcommand: ${subcommand ?? '(none)'}\\n`);\n process.stderr.write(`Available: list, validate, diff, sync, export, pull\\n`);\n process.exit(1);\n }\n}\n\nasync function main() {\n // Content commands are developer tooling — no license required\n if (command === 'content') {\n const [subcommand] = args;\n const contentArgs = args.slice(1);\n await handleContentCommand(subcommand, contentArgs);\n return;\n }\n\n if (!(await checkHarnessesLicense())) {\n process.stderr.write(\n '⚠ @revealui/harnesses requires a Pro license. Visit https://revealui.com/pricing\\n',\n );\n process.exit(2);\n }\n\n switch (command) {\n case 'start': {\n const projectIdx = args.indexOf('--project');\n const projectRoot =\n projectIdx >= 0 ? (args[projectIdx + 1] ?? DEFAULT_PROJECT) : DEFAULT_PROJECT;\n\n const coordinator = new HarnessCoordinator({\n projectRoot,\n task: 'Harness coordination active',\n });\n\n await coordinator.start();\n const ids = await coordinator.getRegistry().listAvailable();\n process.stdout.write(`✓ Detected harnesses: ${ids.length > 0 ? ids.join(', ') : 'none'}\\n`);\n process.stdout.write(`✓ RPC server listening on ${DEFAULT_SOCKET}\\n`);\n process.stdout.write(`✓ Session registered in workboard\\n`);\n\n const shutdown = async () => {\n await coordinator.stop();\n process.exit(0);\n };\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n break;\n }\n\n case 'status': {\n try {\n const infos = (await rpcCall('harness.list')) as Array<{\n id: string;\n name: string;\n version?: string;\n }>;\n if (infos.length === 0) {\n process.stdout.write('No harnesses available\\n');\n } else {\n for (const info of infos) {\n process.stdout.write(\n `${info.id}\\t${info.name}${info.version ? `\\t${info.version}` : ''}\\n`,\n );\n }\n }\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'list': {\n try {\n const infos = (await rpcCall('harness.list')) as Array<{ id: string; name: string }>;\n for (const info of infos) {\n process.stdout.write(`${info.id}\\t${info.name}\\n`);\n }\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'sync': {\n const [harnessId, direction] = args;\n if (!(harnessId && direction && ['push', 'pull'].includes(direction))) {\n process.stderr.write('Usage: revealui-harnesses sync <harnessId> <push|pull>\\n');\n process.exit(1);\n }\n try {\n const result = (await rpcCall('harness.syncConfig', { harnessId, direction })) as {\n success: boolean;\n message?: string;\n };\n process.stdout.write(result.success ? `✓ ${result.message}\\n` : `✗ ${result.message}\\n`);\n if (!result.success) process.exit(1);\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n case 'coordinate': {\n if (args.includes('--init')) {\n const pathIdx = args.indexOf('--init');\n const projectRoot = args[pathIdx + 1] ?? DEFAULT_PROJECT;\n const coordinator = new HarnessCoordinator({ projectRoot, task: 'Coordinate harnesses' });\n await coordinator.start();\n const workboard = coordinator.getWorkboard();\n const conflicts = workboard.checkConflicts('', []);\n process.stdout.write(\n `✓ Session registered. Conflicts: ${conflicts.clean ? 'none' : conflicts.conflicts.length}\\n`,\n );\n await coordinator.stop();\n } else {\n // --print: dump current workboard to stdout\n const projectRoot = args[args.indexOf('--project') + 1] ?? DEFAULT_PROJECT;\n const workboardPath = join(projectRoot, '.claude', 'workboard.md');\n const manager = new WorkboardManager(workboardPath);\n const state = manager.read();\n process.stdout.write(`Agents (${state.agents.length}):\\n`);\n for (const a of state.agents) {\n const stale = Date.now() - new Date(a.updated).getTime() > 4 * 60 * 60 * 1000;\n process.stdout.write(` ${a.id} [${a.env}] — ${a.task}${stale ? ' (STALE)' : ''}\\n`);\n if (a.files) process.stdout.write(` files: ${a.files}\\n`);\n }\n if (state.agents.length === 0) process.stdout.write(' (no active agents)\\n');\n }\n break;\n }\n\n case 'health': {\n try {\n const result = (await rpcCall('harness.health')) as {\n healthy: boolean;\n registeredHarnesses: Array<{ harnessId: string; available: boolean }>;\n workboard: { readable: boolean; sessionCount: number; staleSessionIds: string[] };\n diagnostics: string[];\n };\n process.stdout.write(`Health: ${result.healthy ? 'HEALTHY' : 'UNHEALTHY'}\\n`);\n process.stdout.write(`Harnesses:\\n`);\n for (const h of result.registeredHarnesses) {\n process.stdout.write(` ${h.harnessId}: ${h.available ? 'available' : 'unavailable'}\\n`);\n }\n process.stdout.write(\n `Workboard: ${result.workboard.readable ? 'readable' : 'unreadable'}, ${result.workboard.sessionCount} session(s)\\n`,\n );\n if (result.workboard.staleSessionIds.length > 0) {\n process.stdout.write(` Stale: ${result.workboard.staleSessionIds.join(', ')}\\n`);\n }\n if (result.diagnostics.length > 0) {\n process.stdout.write(`Diagnostics:\\n`);\n for (const d of result.diagnostics) {\n process.stdout.write(` ${d}\\n`);\n }\n }\n if (!result.healthy) process.exit(1);\n } catch (err) {\n process.stderr.write(`RPC error: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n }\n break;\n }\n\n default:\n process.stdout.write(`revealui-harnesses — AI harness coordination for RevealUI\n\nCommands:\n start [--project <path>] Start daemon (detects harnesses, registers session)\n status List available harnesses (requires daemon)\n list List harnesses in TSV format (requires daemon)\n sync <id> <push|pull> Sync harness config to/from SSD (requires daemon)\n health Run health check (requires daemon)\n coordinate [--project <path>] Print workboard state\n coordinate --init [<path>] Register + start daemon\n content <subcommand> Manage canonical content definitions\n\nContent Subcommands:\n content list List all canonical content with metadata\n content validate Validate all definitions against schemas\n content diff [--generator <id>] Show what would change vs current files\n content sync [--generator <id>] [--dry-run] Generate and write files\n content export --output <path> Export canonical + generated files to directory\n content pull [--generator <id>] [--tier oss|pro|all] Pull rules from rules repo\n`);\n break;\n }\n}\n\nmain().catch((err) => {\n process.stderr.write(`${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"],"mappings":"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","names":["args"]}
@@ -14,8 +14,8 @@ declare const AgentSchema: z.ZodObject<{
14
14
  name: z.ZodString;
15
15
  description: z.ZodString;
16
16
  tier: z.ZodDefault<z.ZodEnum<{
17
- oss: "oss";
18
17
  pro: "pro";
18
+ oss: "oss";
19
19
  }>>;
20
20
  isolation: z.ZodDefault<z.ZodEnum<{
21
21
  worktree: "worktree";
@@ -31,8 +31,8 @@ declare const CommandSchema: z.ZodObject<{
31
31
  name: z.ZodString;
32
32
  description: z.ZodString;
33
33
  tier: z.ZodDefault<z.ZodEnum<{
34
- oss: "oss";
35
34
  pro: "pro";
35
+ oss: "oss";
36
36
  }>>;
37
37
  disableModelInvocation: z.ZodDefault<z.ZodBoolean>;
38
38
  argumentHint: z.ZodOptional<z.ZodString>;
@@ -53,8 +53,8 @@ declare const ManifestSchema: z.ZodObject<{
53
53
  }>;
54
54
  preambleTier: z.ZodDefault<z.ZodNumber>;
55
55
  tier: z.ZodDefault<z.ZodEnum<{
56
- oss: "oss";
57
56
  pro: "pro";
57
+ oss: "oss";
58
58
  }>>;
59
59
  tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
60
60
  content: z.ZodString;
@@ -64,8 +64,8 @@ declare const ManifestSchema: z.ZodObject<{
64
64
  name: z.ZodString;
65
65
  description: z.ZodString;
66
66
  tier: z.ZodDefault<z.ZodEnum<{
67
- oss: "oss";
68
67
  pro: "pro";
68
+ oss: "oss";
69
69
  }>>;
70
70
  disableModelInvocation: z.ZodDefault<z.ZodBoolean>;
71
71
  argumentHint: z.ZodOptional<z.ZodString>;
@@ -76,8 +76,8 @@ declare const ManifestSchema: z.ZodObject<{
76
76
  name: z.ZodString;
77
77
  description: z.ZodString;
78
78
  tier: z.ZodDefault<z.ZodEnum<{
79
- oss: "oss";
80
79
  pro: "pro";
80
+ oss: "oss";
81
81
  }>>;
82
82
  isolation: z.ZodDefault<z.ZodEnum<{
83
83
  worktree: "worktree";
@@ -91,8 +91,8 @@ declare const ManifestSchema: z.ZodObject<{
91
91
  name: z.ZodString;
92
92
  description: z.ZodString;
93
93
  tier: z.ZodDefault<z.ZodEnum<{
94
- oss: "oss";
95
94
  pro: "pro";
95
+ oss: "oss";
96
96
  }>>;
97
97
  disableModelInvocation: z.ZodDefault<z.ZodBoolean>;
98
98
  skipFrontmatter: z.ZodDefault<z.ZodBoolean>;
@@ -128,8 +128,8 @@ declare const RuleSchema: z.ZodObject<{
128
128
  }>;
129
129
  preambleTier: z.ZodDefault<z.ZodNumber>;
130
130
  tier: z.ZodDefault<z.ZodEnum<{
131
- oss: "oss";
132
131
  pro: "pro";
132
+ oss: "oss";
133
133
  }>>;
134
134
  tags: z.ZodDefault<z.ZodArray<z.ZodString>>;
135
135
  content: z.ZodString;
@@ -141,8 +141,8 @@ declare const SkillSchema: z.ZodObject<{
141
141
  name: z.ZodString;
142
142
  description: z.ZodString;
143
143
  tier: z.ZodDefault<z.ZodEnum<{
144
- oss: "oss";
145
144
  pro: "pro";
145
+ oss: "oss";
146
146
  }>>;
147
147
  disableModelInvocation: z.ZodDefault<z.ZodBoolean>;
148
148
  skipFrontmatter: z.ZodDefault<z.ZodBoolean>;
@@ -16,7 +16,7 @@ import {
16
16
  registerResolver,
17
17
  resolveTemplate,
18
18
  validateManifest
19
- } from "../chunk-JDI6B2IB.js";
19
+ } from "../chunk-XXEKWC6F.js";
20
20
  import "../chunk-DGUM43GV.js";
21
21
  export {
22
22
  AgentSchema,
package/dist/index.js CHANGED
@@ -18,14 +18,14 @@ import {
18
18
  syncAllConfigs,
19
19
  syncConfig,
20
20
  validateConfigJson
21
- } from "./chunk-HH2PJYQN.js";
21
+ } from "./chunk-XLIKSLM3.js";
22
22
  import {
23
23
  buildManifest,
24
24
  diffContent,
25
25
  generateContent,
26
26
  listContent,
27
27
  validateManifest
28
- } from "./chunk-JDI6B2IB.js";
28
+ } from "./chunk-XXEKWC6F.js";
29
29
  import {
30
30
  WorkboardManager,
31
31
  acquireLock,
@@ -36,7 +36,7 @@ import {
36
36
  releaseLock,
37
37
  withLock,
38
38
  withLockAsync
39
- } from "./chunk-FJGN6DTH.js";
39
+ } from "./chunk-JG6CAG4A.js";
40
40
  import "./chunk-DGUM43GV.js";
41
41
  export {
42
42
  ClaudeCodeAdapter,
@@ -1,47 +1,101 @@
1
1
  /**
2
- * WorkboardProtocol — types for the multi-agent coordination workboard.
2
+ * WorkboardProtocol — types for the multi-agent coordination workboard (v2).
3
3
  *
4
4
  * The workboard (.claude/workboard.md) is the shared coordination primitive
5
- * that lets multiple AI coding agents (Claude Code, Cursor, etc.) work safely
6
- * in parallel on the same codebase without stepping on each other.
5
+ * that lets multiple AI coding agents work safely in parallel.
7
6
  *
8
- * This module defines machine-readable types for parsing and writing the
9
- * workboard's markdown structure programmatically.
7
+ * v2 adds a task board with claiming protocol:
8
+ * Agents — who's running (hook-managed)
9
+ * Tasks — what needs doing (agent-managed, claimable)
10
+ * Blocked — waiting on external action
11
+ * Done — recently completed
12
+ * Log — audit trail
13
+ *
14
+ * Status values: available | claimed | partial | blocked | done
15
+ * Priority values: P0 | P1 | P2 | P3
10
16
  */
11
- /** A row in the ## Sessions table. */
12
- interface WorkboardSession {
13
- /** Unique session identifier, e.g. "zed-1", "terminal-2", "cursor-1" */
17
+ /** Valid task statuses. */
18
+ type TaskStatus = 'available' | 'claimed' | 'partial' | 'blocked' | 'done';
19
+ /** Valid task priorities. */
20
+ type TaskPriority = 'P0' | 'P1' | 'P2' | 'P3';
21
+ /** A row in the ## Agents table (managed by hooks). */
22
+ interface WorkboardAgent {
23
+ /** Unique agent identifier, e.g. "agent-edit", "agent-system", "wsl-root" */
14
24
  id: string;
15
- /** Human-readable environment description, e.g. "Zed/ACP", "WSL/bash" */
25
+ /** Human-readable environment description */
16
26
  env: string;
17
27
  /** ISO timestamp of when the session registered */
18
28
  started: string;
19
29
  /** Current task description */
20
30
  task: string;
21
- /** Comma-separated list of file globs this session is actively modifying */
31
+ /** Comma-separated list of file globs this agent is actively modifying */
22
32
  files: string;
23
33
  /** ISO timestamp of last workboard update */
24
34
  updated: string;
25
35
  }
26
- /** A timestamped entry in the ## Recent section. */
27
- interface WorkboardEntry {
28
- /** ISO-derived display timestamp "[YYYY-MM-DD HH:MM]" */
29
- timestamp: string;
30
- /** Session id that produced this entry */
31
- sessionId: string;
32
- /** Free-form description of what was accomplished */
33
- description: string;
36
+ /** A row in the ## Tasks table (managed by agents). */
37
+ interface WorkboardTask {
38
+ /** Task identifier, e.g. "T-001" */
39
+ id: string;
40
+ /** Short task description */
41
+ task: string;
42
+ /** Priority: P0 (drop everything), P1 (must do), P2 (should do), P3 (nice to have) */
43
+ pri: TaskPriority;
44
+ /** Current status */
45
+ status: TaskStatus;
46
+ /** Agent id that owns this task (empty if available) */
47
+ owner: string;
48
+ /** GitHub issue or PR number, e.g. "#88", "PR #110" */
49
+ gh: string;
50
+ /** ISO date of last update */
51
+ updated: string;
52
+ /** Free-form notes about progress or remaining work */
53
+ notes: string;
54
+ }
55
+ /** A row in the ## Blocked table. */
56
+ interface WorkboardBlockedTask {
57
+ /** Task identifier */
58
+ id: string;
59
+ /** Short task description */
60
+ task: string;
61
+ /** What's blocking this task */
62
+ blocker: string;
63
+ /** GitHub issue or PR number */
64
+ gh: string;
65
+ /** Additional notes */
66
+ notes: string;
34
67
  }
35
- /** Full parsed workboard state. */
68
+ /** A row in the ## Done table. */
69
+ interface WorkboardDoneTask {
70
+ /** Task identifier */
71
+ id: string;
72
+ /** Short task description */
73
+ task: string;
74
+ /** Agent that completed the task */
75
+ owner: string;
76
+ /** ISO date of completion */
77
+ completed: string;
78
+ /** GitHub issue or PR number */
79
+ gh: string;
80
+ /** Additional notes */
81
+ notes: string;
82
+ }
83
+ /** Full parsed workboard state (v2). */
36
84
  interface WorkboardState {
37
- sessions: WorkboardSession[];
38
- recent: WorkboardEntry[];
39
- /** Freeform markdown content of the ## Plans section */
40
- plans: string;
41
- /** Freeform markdown content of the ## Context section */
42
- context: string;
43
- /** Freeform markdown content of the ## Plan Reference section */
44
- planReference: string;
85
+ /** Lines before the first ## section (title, protocol docs) */
86
+ preamble: string[];
87
+ /** Active agent sessions */
88
+ agents: WorkboardAgent[];
89
+ /** Task board claimable work items */
90
+ tasks: WorkboardTask[];
91
+ /** Blocked tasks waiting on external action */
92
+ blocked: WorkboardBlockedTask[];
93
+ /** Recently completed tasks */
94
+ done: WorkboardDoneTask[];
95
+ /** Timestamped log entries (raw markdown list items) */
96
+ log: string[];
97
+ /** Unknown sections preserved as raw markdown, keyed by section title */
98
+ _extra: Record<string, string>;
45
99
  }
46
100
  /** Result of a conflict detection check. */
47
101
  interface ConflictResult {
@@ -54,58 +108,58 @@ interface ConflictResult {
54
108
  overlappingFiles: string[];
55
109
  }>;
56
110
  }
111
+ /** @deprecated Use WorkboardAgent instead */
112
+ type WorkboardSession = WorkboardAgent;
113
+ /** @deprecated Use WorkboardState.log entries instead */
114
+ interface WorkboardEntry {
115
+ timestamp: string;
116
+ sessionId: string;
117
+ description: string;
118
+ }
57
119
 
58
120
  /**
59
- * WorkboardManager — reads, parses, and writes .claude/workboard.md.
60
- *
61
- * The workboard is a markdown file with a specific structure:
62
- * ## Sessions — markdown table
63
- * ## Plans — freeform markdown
64
- * ## Recent — bullet list
65
- * ## Context — freeform markdown
66
- * ## Plan Reference — freeform markdown
121
+ * WorkboardManager — reads, parses, and writes .claude/workboard.md (v2).
67
122
  *
68
- * This class provides programmatic access to the Sessions table and Recent list.
69
- * Plans, Context, and Plan Reference are treated as opaque strings.
123
+ * Supports both v1 (Sessions/Recent) and v2 (Agents/Tasks/Blocked/Done/Log)
124
+ * formats for backward compatibility. Always serializes to v2.
70
125
  *
71
- * All mutating methods use file locking (O_EXCL) to prevent race conditions
72
- * when multiple harness instances write concurrently. Writes are atomic
73
- * (tmp file + rename).
126
+ * All mutating methods use file locking (O_EXCL) to prevent race conditions.
127
+ * Writes are atomic (tmp file + rename).
74
128
  */
75
129
  declare class WorkboardManager {
76
130
  private readonly workboardPath;
77
131
  private readonly lockPath;
78
132
  constructor(workboardPath: string);
79
- /** Read and parse the workboard. */
80
133
  read(): WorkboardState;
81
- /** Write a workboard state back to disk (locked + atomic). */
82
134
  write(state: WorkboardState): void;
83
- /** Read and parse the workboard asynchronously. */
84
135
  readAsync(): Promise<WorkboardState>;
85
- /** Write a workboard state back to disk asynchronously (locked + atomic). */
86
136
  writeAsync(state: WorkboardState): Promise<void>;
87
- /** Register a new session, replacing any existing row with the same id. */
88
- registerSession(session: WorkboardSession): void;
89
- /** Remove a session row by id. */
90
- unregisterSession(id: string): void;
91
- /** Update specific fields of an existing session row. */
92
- updateSession(id: string, updates: Partial<WorkboardSession>): void;
93
- /** Update a session's files list and timestamp. */
137
+ registerAgent(agent: WorkboardAgent): void;
138
+ unregisterAgent(id: string): void;
139
+ updateAgent(id: string, updates: Partial<WorkboardAgent>): void;
140
+ /** Claim an available or partial task. Returns true on success. */
141
+ claimTask(taskId: string, agentId: string): boolean;
142
+ /** Move a task from Tasks to Done. Returns true on success. */
143
+ completeTask(taskId: string, agentId: string): boolean;
144
+ /** Mark a claimed task as partial (agent stopped mid-work). */
145
+ markPartial(taskId: string, notes: string): boolean;
146
+ /** Release a claimed/partial task back to available. */
147
+ releaseTask(taskId: string): boolean;
148
+ /** Move a blocked task to Tasks as available. */
149
+ unblockTask(taskId: string, pri?: string): boolean;
94
150
  claimFiles(id: string, files: string[]): void;
95
- /** Clear a session's file reservations. */
96
151
  releaseFiles(id: string): void;
97
- /** Prepend a timestamped entry to the ## Recent section (keeps last 20). */
98
- addRecentEntry(entry: WorkboardEntry): void;
99
- /** Returns sessions whose `updated` timestamp is older than 4 hours. */
100
- detectStale(): WorkboardSession[];
101
- /**
102
- * Check whether the given files conflict with any other active session's reservations.
103
- * Returns a ConflictResult describing any overlaps found.
104
- */
152
+ addLogEntry(agentId: string, description: string): void;
153
+ detectStale(): WorkboardAgent[];
105
154
  checkConflicts(mySessionId: string, files: string[]): ConflictResult;
155
+ getClaimedTasks(agentId: string): WorkboardTask[];
106
156
  private readUnlocked;
107
157
  private writeUnlocked;
108
158
  }
159
+ /** @deprecated Use registerAgent instead */
160
+ declare const registerSession: (agent: WorkboardAgent) => void;
161
+ /** @deprecated Use unregisterAgent instead */
162
+ declare const unregisterSession: (id: string) => void;
109
163
 
110
164
  /**
111
165
  * Acquire an exclusive file lock using O_EXCL (kernel-level atomic create).
@@ -158,4 +212,4 @@ declare function detectSessionType(): SessionType;
158
212
  */
159
213
  declare function deriveSessionId(type: SessionType, existingIds: string[]): string;
160
214
 
161
- export { type ConflictResult, type SessionType, type WorkboardEntry, WorkboardManager, type WorkboardSession, type WorkboardState, acquireLock, atomicWriteSync, deriveSessionId, detectSessionType, lockPathFor, releaseLock, withLock, withLockAsync };
215
+ export { type ConflictResult, type SessionType, type TaskPriority, type TaskStatus, type WorkboardAgent, type WorkboardBlockedTask, type WorkboardDoneTask, type WorkboardEntry, WorkboardManager, type WorkboardSession, type WorkboardState, type WorkboardTask, acquireLock, atomicWriteSync, deriveSessionId, detectSessionType, lockPathFor, registerSession, releaseLock, unregisterSession, withLock, withLockAsync };
@@ -5,10 +5,12 @@ import {
5
5
  deriveSessionId,
6
6
  detectSessionType,
7
7
  lockPathFor,
8
+ registerSession,
8
9
  releaseLock,
10
+ unregisterSession,
9
11
  withLock,
10
12
  withLockAsync
11
- } from "../chunk-FJGN6DTH.js";
13
+ } from "../chunk-JG6CAG4A.js";
12
14
  import "../chunk-DGUM43GV.js";
13
15
  export {
14
16
  WorkboardManager,
@@ -17,7 +19,9 @@ export {
17
19
  deriveSessionId,
18
20
  detectSessionType,
19
21
  lockPathFor,
22
+ registerSession,
20
23
  releaseLock,
24
+ unregisterSession,
21
25
  withLock,
22
26
  withLockAsync
23
27
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revealui/harnesses",
3
- "version": "0.1.3",
3
+ "version": "0.1.6",
4
4
  "description": "[Pro] AI harness integration system - adapters, daemon, workboard coordination, and JSON-RPC server",
5
5
  "repository": {
6
6
  "type": "git",
@@ -13,7 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "zod": "^4.3.6",
16
- "@revealui/core": "0.5.0"
16
+ "@revealui/core": "0.5.3"
17
17
  },
18
18
  "devDependencies": {
19
19
  "@types/node": "^25.3.0",
@@ -22,6 +22,9 @@
22
22
  "vitest": "^4.0.18",
23
23
  "dev": "0.0.1"
24
24
  },
25
+ "engines": {
26
+ "node": ">=24.13.0"
27
+ },
25
28
  "exports": {
26
29
  ".": {
27
30
  "types": "./dist/index.d.ts",
@@ -49,7 +52,8 @@
49
52
  },
50
53
  "main": "./dist/index.js",
51
54
  "publishConfig": {
52
- "access": "public"
55
+ "access": "public",
56
+ "registry": "https://registry.npmjs.org"
53
57
  },
54
58
  "type": "module",
55
59
  "types": "./dist/index.d.ts",