arcanea 3.2.0 → 3.4.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/index.js +544 -83
- package/dist/index.d.ts +1 -1
- package/dist/index.js +74 -1
- package/dist/viz/index.d.ts +13 -0
- package/dist/viz/index.d.ts.map +1 -0
- package/package.json +1 -1
- package/skills/{ai-symbiosis.md → arcanea/ai-symbiosis/SKILL.md} +13 -0
- package/skills/arcanea/{arcanea-anti-trope.md → anti-trope/SKILL.md} +8 -0
- package/skills/{luminor-council.md → arcanea/luminor-council/SKILL.md} +15 -0
- package/skills/{character-alchemist.md → creative/character-alchemist/SKILL.md} +14 -0
- package/skills/{creative-bestiary.md → creative/creative-bestiary/SKILL.md} +14 -0
- package/skills/{story-weaver.md → creative/story-weaver/SKILL.md} +14 -0
- package/skills/{world-architect.md → creative/world-architect/SKILL.md} +14 -0
package/dist/cli/index.js
CHANGED
|
@@ -2199,7 +2199,7 @@ var {
|
|
|
2199
2199
|
} = import__.default;
|
|
2200
2200
|
|
|
2201
2201
|
// src/cli/index.ts
|
|
2202
|
-
var
|
|
2202
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
2203
2203
|
|
|
2204
2204
|
// src/install.ts
|
|
2205
2205
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -2314,11 +2314,17 @@ async function installForPlatform(targetDir, packageRoot, platform, force) {
|
|
|
2314
2314
|
await installClaudeCodeSettings(platformPath, force);
|
|
2315
2315
|
} else if (platform === "cursor") {
|
|
2316
2316
|
await installCursorRules(targetDir, packageRoot, force);
|
|
2317
|
+
} else if (platform === "codex") {
|
|
2318
|
+
await installCodexConfig(targetDir, packageRoot, force);
|
|
2319
|
+
} else if (platform === "gemini") {
|
|
2320
|
+
await installGeminiConfig(targetDir, packageRoot, force);
|
|
2317
2321
|
}
|
|
2318
2322
|
}
|
|
2319
2323
|
async function installClaudeCodeSettings(platformPath, force) {
|
|
2320
2324
|
const settingsPath = join(platformPath, "settings.json");
|
|
2321
2325
|
if (!existsSync(settingsPath) || force) {
|
|
2326
|
+
const eventsDir = join(process.env.HOME || process.env.USERPROFILE || "~", ".arcanea").replace(/\\/g, "/");
|
|
2327
|
+
const logScript = `mkdir -p "${eventsDir}" && echo '{"type":"agent-spawn","agent":"'$(echo "$TOOL_INPUT" 2>/dev/null | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write((d.subagent_type||'unknown')+'","description":"'+(d.description||'').replace(/"/g,'')+'","team":"'+(d.subagent_type||''))}catch{process.stdout.write('unknown","description":"","team":"')}" 2>/dev/null)","timestamp":'$(date +%s000)'}' >> "${eventsDir}/swarm-events.jsonl"`;
|
|
2322
2328
|
const settings = {
|
|
2323
2329
|
hooks: {
|
|
2324
2330
|
UserPromptSubmit: [
|
|
@@ -2357,6 +2363,15 @@ async function installClaudeCodeSettings(platformPath, force) {
|
|
|
2357
2363
|
command: "echo '[ARCANEA_MODE=ultrawork] Maximum parallel execution. Spawn all relevant agents simultaneously using Task tool with run_in_background=true.'"
|
|
2358
2364
|
}]
|
|
2359
2365
|
}
|
|
2366
|
+
],
|
|
2367
|
+
PreToolUse: [
|
|
2368
|
+
{
|
|
2369
|
+
matcher: "Task",
|
|
2370
|
+
hooks: [{
|
|
2371
|
+
type: "command",
|
|
2372
|
+
command: logScript
|
|
2373
|
+
}]
|
|
2374
|
+
}
|
|
2360
2375
|
]
|
|
2361
2376
|
}
|
|
2362
2377
|
};
|
|
@@ -2378,6 +2393,64 @@ ${claudeContent}`;
|
|
|
2378
2393
|
}
|
|
2379
2394
|
}
|
|
2380
2395
|
}
|
|
2396
|
+
async function installCodexConfig(targetDir, packageRoot, force) {
|
|
2397
|
+
const codexMdPath = join(targetDir, "codex.md");
|
|
2398
|
+
if (!existsSync(codexMdPath) || force) {
|
|
2399
|
+
const claudeMdSource = join(packageRoot, "CLAUDE.md");
|
|
2400
|
+
if (existsSync(claudeMdSource)) {
|
|
2401
|
+
const content = readFileSync(claudeMdSource, "utf-8");
|
|
2402
|
+
const codexMd = [
|
|
2403
|
+
`# Codex Instructions — Generated by Arcanea v${VERSION}`,
|
|
2404
|
+
"",
|
|
2405
|
+
"> These instructions transform Codex into Arcanea, the Creative Intelligence Platform.",
|
|
2406
|
+
"> Agent definitions: `.codex/agents/` | Skills: `.codex/skills/` | Commands: `.codex/commands/`",
|
|
2407
|
+
"",
|
|
2408
|
+
content,
|
|
2409
|
+
"",
|
|
2410
|
+
"## Codex-Specific Notes",
|
|
2411
|
+
"",
|
|
2412
|
+
"- Read agent definitions from `.codex/agents/` for available specialist agents",
|
|
2413
|
+
"- Read skill definitions from `.codex/skills/` for creative and technical skills",
|
|
2414
|
+
"- Read command definitions from `.codex/commands/` for slash commands",
|
|
2415
|
+
"- MCP servers are configured in `.mcp.json`",
|
|
2416
|
+
"- When magic words (ultraworld, ultracode, etc.) are used, read the relevant agent files and apply their instructions",
|
|
2417
|
+
""
|
|
2418
|
+
].join(`
|
|
2419
|
+
`);
|
|
2420
|
+
writeFileSync(codexMdPath, codexMd);
|
|
2421
|
+
console.log(import_picocolors.default.green(" ✓ Created codex.md (Arcanea instructions for Codex CLI)"));
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
}
|
|
2425
|
+
async function installGeminiConfig(targetDir, packageRoot, force) {
|
|
2426
|
+
const geminiMdPath = join(targetDir, "GEMINI.md");
|
|
2427
|
+
if (!existsSync(geminiMdPath) || force) {
|
|
2428
|
+
const claudeMdSource = join(packageRoot, "CLAUDE.md");
|
|
2429
|
+
if (existsSync(claudeMdSource)) {
|
|
2430
|
+
const content = readFileSync(claudeMdSource, "utf-8");
|
|
2431
|
+
const geminiMd = [
|
|
2432
|
+
`# Gemini Instructions — Generated by Arcanea v${VERSION}`,
|
|
2433
|
+
"",
|
|
2434
|
+
"> These instructions transform Gemini into Arcanea, the Creative Intelligence Platform.",
|
|
2435
|
+
"> Agent definitions: `.gemini/agents/` | Skills: `.gemini/skills/` | Commands: `.gemini/commands/`",
|
|
2436
|
+
"",
|
|
2437
|
+
content,
|
|
2438
|
+
"",
|
|
2439
|
+
"## Gemini-Specific Notes",
|
|
2440
|
+
"",
|
|
2441
|
+
"- Read agent definitions from `.gemini/agents/` for available specialist agents",
|
|
2442
|
+
"- Read skill definitions from `.gemini/skills/` for creative and technical skills",
|
|
2443
|
+
"- Read command definitions from `.gemini/commands/` for slash commands",
|
|
2444
|
+
"- MCP servers are configured in `.mcp.json`",
|
|
2445
|
+
"- When magic words (ultraworld, ultracode, etc.) are used, read the relevant agent files and apply their instructions",
|
|
2446
|
+
""
|
|
2447
|
+
].join(`
|
|
2448
|
+
`);
|
|
2449
|
+
writeFileSync(geminiMdPath, geminiMd);
|
|
2450
|
+
console.log(import_picocolors.default.green(" ✓ Created GEMINI.md (Arcanea instructions for Gemini CLI)"));
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2381
2454
|
async function installMcpConfig(targetDir, force) {
|
|
2382
2455
|
const mcpPath = join(targetDir, ".mcp.json");
|
|
2383
2456
|
console.log(import_picocolors.default.blue(`
|
|
@@ -2457,7 +2530,7 @@ function printSuccessMessage(platforms) {
|
|
|
2457
2530
|
}
|
|
2458
2531
|
|
|
2459
2532
|
// src/index.ts
|
|
2460
|
-
var VERSION = "3.
|
|
2533
|
+
var VERSION = "3.4.0";
|
|
2461
2534
|
var NAME = "arcanea";
|
|
2462
2535
|
var ORCHESTRATOR = "Arcanea";
|
|
2463
2536
|
var defaultConfig = {
|
|
@@ -2583,9 +2656,387 @@ var AGENT_TEAMS = {
|
|
|
2583
2656
|
}
|
|
2584
2657
|
};
|
|
2585
2658
|
|
|
2586
|
-
// src/
|
|
2587
|
-
|
|
2659
|
+
// src/viz/index.ts
|
|
2660
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
2661
|
+
import { createServer } from "http";
|
|
2662
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, appendFileSync, mkdirSync as mkdirSync2, statSync } from "fs";
|
|
2588
2663
|
import { join as join2 } from "path";
|
|
2664
|
+
import { execFile } from "child_process";
|
|
2665
|
+
var ARCANEA_DIR = join2(process.env.HOME || process.env.USERPROFILE || "~", ".arcanea");
|
|
2666
|
+
var EVENTS_FILE = join2(ARCANEA_DIR, "swarm-events.jsonl");
|
|
2667
|
+
function logEvent(event) {
|
|
2668
|
+
mkdirSync2(ARCANEA_DIR, { recursive: true });
|
|
2669
|
+
appendFileSync(EVENTS_FILE, JSON.stringify(event) + `
|
|
2670
|
+
`);
|
|
2671
|
+
}
|
|
2672
|
+
function readEvents() {
|
|
2673
|
+
if (!existsSync2(EVENTS_FILE))
|
|
2674
|
+
return [];
|
|
2675
|
+
const content = readFileSync2(EVENTS_FILE, "utf-8").trim();
|
|
2676
|
+
if (!content)
|
|
2677
|
+
return [];
|
|
2678
|
+
return content.split(`
|
|
2679
|
+
`).map((line) => {
|
|
2680
|
+
try {
|
|
2681
|
+
return JSON.parse(line);
|
|
2682
|
+
} catch {
|
|
2683
|
+
return null;
|
|
2684
|
+
}
|
|
2685
|
+
}).filter(Boolean);
|
|
2686
|
+
}
|
|
2687
|
+
var clients = new Set;
|
|
2688
|
+
function broadcast(event) {
|
|
2689
|
+
const data = `data: ${JSON.stringify(event)}
|
|
2690
|
+
|
|
2691
|
+
`;
|
|
2692
|
+
for (const client of clients) {
|
|
2693
|
+
try {
|
|
2694
|
+
client.write(data);
|
|
2695
|
+
} catch {
|
|
2696
|
+
clients.delete(client);
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2700
|
+
function handleSSE(req, res) {
|
|
2701
|
+
res.writeHead(200, {
|
|
2702
|
+
"Content-Type": "text/event-stream",
|
|
2703
|
+
"Cache-Control": "no-cache",
|
|
2704
|
+
Connection: "keep-alive",
|
|
2705
|
+
"Access-Control-Allow-Origin": "*"
|
|
2706
|
+
});
|
|
2707
|
+
clients.add(res);
|
|
2708
|
+
req.on("close", () => clients.delete(res));
|
|
2709
|
+
const events = readEvents();
|
|
2710
|
+
res.write(`data: ${JSON.stringify({ type: "initial", events })}
|
|
2711
|
+
|
|
2712
|
+
`);
|
|
2713
|
+
}
|
|
2714
|
+
function handleAPI(_req, res) {
|
|
2715
|
+
const events = readEvents();
|
|
2716
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2717
|
+
res.end(JSON.stringify({ events }));
|
|
2718
|
+
}
|
|
2719
|
+
function openBrowser(url) {
|
|
2720
|
+
if (process.platform === "darwin") {
|
|
2721
|
+
execFile("open", [url], () => {});
|
|
2722
|
+
} else if (process.platform === "win32") {
|
|
2723
|
+
execFile("cmd", ["/c", "start", url], () => {});
|
|
2724
|
+
} else {
|
|
2725
|
+
execFile("xdg-open", [url], () => {});
|
|
2726
|
+
}
|
|
2727
|
+
}
|
|
2728
|
+
function getDashboardHTML() {
|
|
2729
|
+
return `<!DOCTYPE html>
|
|
2730
|
+
<html lang="en">
|
|
2731
|
+
<head>
|
|
2732
|
+
<meta charset="utf-8">
|
|
2733
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
2734
|
+
<title>Arcanea Swarm Viz</title>
|
|
2735
|
+
<style>
|
|
2736
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
2737
|
+
:root{--bg:#0a0a1a;--surface:#111128;--border:#1e1e3a;--teal:#7fffd4;--gold:#ffd700;--blue:#78a6ff;
|
|
2738
|
+
--red:#ff4757;--text:#e0e0e0;--dim:#666;--green:#2ed573;--purple:#a855f7}
|
|
2739
|
+
body{background:var(--bg);color:var(--text);font-family:'Segoe UI',system-ui,sans-serif;min-height:100vh}
|
|
2740
|
+
.header{background:linear-gradient(135deg,#0d0d2b,#1a1a3e);border-bottom:1px solid var(--border);padding:16px 24px;display:flex;align-items:center;gap:16px}
|
|
2741
|
+
.header h1{font-size:20px;color:var(--teal);font-weight:600}
|
|
2742
|
+
.header .version{color:var(--dim);font-size:12px}
|
|
2743
|
+
.header .status{margin-left:auto;display:flex;align-items:center;gap:8px}
|
|
2744
|
+
.dot{width:8px;height:8px;border-radius:50%;background:var(--green);animation:pulse 2s infinite}
|
|
2745
|
+
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}
|
|
2746
|
+
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;padding:16px 24px}
|
|
2747
|
+
.stat{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:16px;text-align:center}
|
|
2748
|
+
.stat .label{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:1px;margin-bottom:4px}
|
|
2749
|
+
.stat .value{font-size:28px;font-weight:700;color:var(--teal)}
|
|
2750
|
+
.stat .value.gold{color:var(--gold)}
|
|
2751
|
+
.stat .value.blue{color:var(--blue)}
|
|
2752
|
+
.main{display:grid;grid-template-columns:1fr 300px;gap:16px;padding:0 24px 24px;height:calc(100vh - 200px)}
|
|
2753
|
+
.events{background:var(--surface);border:1px solid var(--border);border-radius:8px;overflow:hidden;display:flex;flex-direction:column}
|
|
2754
|
+
.events .title{padding:12px 16px;border-bottom:1px solid var(--border);font-size:13px;font-weight:600;display:flex;align-items:center;gap:8px}
|
|
2755
|
+
.events .title .count{color:var(--dim);font-weight:400}
|
|
2756
|
+
.event-list{flex:1;overflow-y:auto;padding:8px}
|
|
2757
|
+
.event{padding:8px 12px;border-radius:6px;margin-bottom:4px;font-size:13px;display:flex;align-items:flex-start;gap:8px;animation:fadeIn 0.3s ease}
|
|
2758
|
+
@keyframes fadeIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
|
|
2759
|
+
.event .time{color:var(--dim);font-size:11px;min-width:60px;font-family:monospace}
|
|
2760
|
+
.event .badge{padding:2px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase}
|
|
2761
|
+
.badge-spawn{background:#7fffd420;color:var(--teal)}
|
|
2762
|
+
.badge-complete{background:#2ed57320;color:var(--green)}
|
|
2763
|
+
.badge-error{background:#ff475720;color:var(--red)}
|
|
2764
|
+
.badge-magic{background:#ffd70020;color:var(--gold)}
|
|
2765
|
+
.event .desc{flex:1;word-break:break-word}
|
|
2766
|
+
.event .agent-name{color:var(--blue);font-weight:500}
|
|
2767
|
+
.event .dur{color:var(--dim);font-size:11px;font-family:monospace}
|
|
2768
|
+
.sidebar{display:flex;flex-direction:column;gap:12px}
|
|
2769
|
+
.panel{background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px}
|
|
2770
|
+
.panel .title{font-size:13px;font-weight:600;margin-bottom:12px}
|
|
2771
|
+
.bar-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-size:12px}
|
|
2772
|
+
.bar-label{min-width:80px;color:var(--dim)}
|
|
2773
|
+
.bar-track{flex:1;height:8px;background:var(--bg);border-radius:4px;overflow:hidden}
|
|
2774
|
+
.bar-fill{height:100%;border-radius:4px;transition:width 0.5s ease}
|
|
2775
|
+
.fill-creative{background:var(--teal)}.fill-coding{background:var(--blue)}.fill-writing{background:var(--green)}
|
|
2776
|
+
.fill-research{background:var(--gold)}.fill-production{background:var(--purple)}.fill-development{background:var(--blue)}
|
|
2777
|
+
.fill-teacher{background:#ff6b81}.fill-visionary{background:var(--gold)}.fill-default{background:var(--teal)}
|
|
2778
|
+
.bar-value{min-width:30px;text-align:right;font-family:monospace;color:var(--dim)}
|
|
2779
|
+
.timing{font-family:monospace;font-size:13px}
|
|
2780
|
+
.timing .row{display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--border)}
|
|
2781
|
+
.timing .row:last-child{border:none}
|
|
2782
|
+
.timing .label{color:var(--dim)}
|
|
2783
|
+
.timing .val{color:var(--teal)}
|
|
2784
|
+
.empty{text-align:center;padding:60px 20px;color:var(--dim)}
|
|
2785
|
+
.empty h3{color:var(--teal);margin-bottom:12px;font-size:16px}
|
|
2786
|
+
.empty p{font-size:13px;max-width:400px;margin:0 auto;line-height:1.6}
|
|
2787
|
+
.empty code{background:var(--bg);padding:2px 6px;border-radius:4px;font-size:12px;color:var(--gold)}
|
|
2788
|
+
</style>
|
|
2789
|
+
</head>
|
|
2790
|
+
<body>
|
|
2791
|
+
<div class="header">
|
|
2792
|
+
<h1>Arcanea Swarm Viz</h1>
|
|
2793
|
+
<span class="version">v${VERSION}</span>
|
|
2794
|
+
<div class="status">
|
|
2795
|
+
<span class="dot" id="statusDot"></span>
|
|
2796
|
+
<span id="statusText" style="font-size:12px;color:var(--dim)">Connecting...</span>
|
|
2797
|
+
</div>
|
|
2798
|
+
</div>
|
|
2799
|
+
<div class="stats">
|
|
2800
|
+
<div class="stat"><div class="label">Total Spawns</div><div class="value" id="statTotal">0</div></div>
|
|
2801
|
+
<div class="stat"><div class="label">Active Now</div><div class="value gold" id="statActive">0</div></div>
|
|
2802
|
+
<div class="stat"><div class="label">Success Rate</div><div class="value blue" id="statSuccess">-</div></div>
|
|
2803
|
+
<div class="stat"><div class="label">Avg Duration</div><div class="value" id="statAvg">-</div></div>
|
|
2804
|
+
</div>
|
|
2805
|
+
<div class="main">
|
|
2806
|
+
<div class="events">
|
|
2807
|
+
<div class="title">Live Event Feed <span class="count" id="eventCount">(0 events)</span></div>
|
|
2808
|
+
<div class="event-list" id="eventList"></div>
|
|
2809
|
+
</div>
|
|
2810
|
+
<div class="sidebar">
|
|
2811
|
+
<div class="panel"><div class="title">Team Utilization</div><div id="teamBars"></div></div>
|
|
2812
|
+
<div class="panel">
|
|
2813
|
+
<div class="title">Timing (ms)</div>
|
|
2814
|
+
<div class="timing">
|
|
2815
|
+
<div class="row"><span class="label">Avg</span><span class="val" id="timAvg">-</span></div>
|
|
2816
|
+
<div class="row"><span class="label">P50</span><span class="val" id="timP50">-</span></div>
|
|
2817
|
+
<div class="row"><span class="label">P95</span><span class="val" id="timP95">-</span></div>
|
|
2818
|
+
</div>
|
|
2819
|
+
</div>
|
|
2820
|
+
<div class="panel"><div class="title">Top Agents</div><div id="agentList" style="font-size:12px"></div></div>
|
|
2821
|
+
</div>
|
|
2822
|
+
</div>
|
|
2823
|
+
<script>
|
|
2824
|
+
// Uses safe DOM methods (createElement, textContent) — no innerHTML with untrusted data
|
|
2825
|
+
let allEvents = [];
|
|
2826
|
+
const fillClasses = {creative:'fill-creative',coding:'fill-coding',writing:'fill-writing',research:'fill-research',production:'fill-production',development:'fill-development',teacher:'fill-teacher',visionary:'fill-visionary'};
|
|
2827
|
+
|
|
2828
|
+
function fmtTime(ts) {
|
|
2829
|
+
return new Date(ts).toLocaleTimeString('en-US',{hour12:false,hour:'2-digit',minute:'2-digit',second:'2-digit'});
|
|
2830
|
+
}
|
|
2831
|
+
function fmtDur(ms) {
|
|
2832
|
+
if (!ms) return '';
|
|
2833
|
+
return ms < 1000 ? ms+'ms' : (ms/1000).toFixed(1)+'s';
|
|
2834
|
+
}
|
|
2835
|
+
|
|
2836
|
+
function mkEl(tag, cls, text) {
|
|
2837
|
+
const el = document.createElement(tag);
|
|
2838
|
+
if (cls) el.className = cls;
|
|
2839
|
+
if (text) el.textContent = text;
|
|
2840
|
+
return el;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
function showEmpty() {
|
|
2844
|
+
const list = document.getElementById('eventList');
|
|
2845
|
+
list.textContent = '';
|
|
2846
|
+
const d = mkEl('div','empty');
|
|
2847
|
+
const h = mkEl('h3',null,'Waiting for agent activity...');
|
|
2848
|
+
const p = mkEl('p',null,'Events appear here as agents spawn and complete. Use ultraworld or ultracode in Claude Code.');
|
|
2849
|
+
d.appendChild(h); d.appendChild(p);
|
|
2850
|
+
list.appendChild(d);
|
|
2851
|
+
}
|
|
2852
|
+
|
|
2853
|
+
function addEvent(event) {
|
|
2854
|
+
const list = document.getElementById('eventList');
|
|
2855
|
+
const empty = list.querySelector('.empty');
|
|
2856
|
+
if (empty) empty.remove();
|
|
2857
|
+
|
|
2858
|
+
const el = mkEl('div','event');
|
|
2859
|
+
el.appendChild(mkEl('span','time',fmtTime(event.timestamp)));
|
|
2860
|
+
|
|
2861
|
+
const badgeCls = event.type==='agent-spawn'?'badge badge-spawn':
|
|
2862
|
+
event.type==='agent-complete'?'badge badge-complete':
|
|
2863
|
+
event.type==='agent-error'?'badge badge-error':'badge badge-magic';
|
|
2864
|
+
const badgeTxt = event.type==='agent-spawn'?'SPAWN':
|
|
2865
|
+
event.type==='agent-complete'?'DONE':
|
|
2866
|
+
event.type==='agent-error'?'ERR':'MAGIC';
|
|
2867
|
+
el.appendChild(mkEl('span',badgeCls,badgeTxt));
|
|
2868
|
+
if (event.agent) el.appendChild(mkEl('span','agent-name',event.agent));
|
|
2869
|
+
if (event.description) el.appendChild(mkEl('span','desc',event.description));
|
|
2870
|
+
if (event.durationMs) el.appendChild(mkEl('span','dur',fmtDur(event.durationMs)));
|
|
2871
|
+
|
|
2872
|
+
list.appendChild(el);
|
|
2873
|
+
list.scrollTop = list.scrollHeight;
|
|
2874
|
+
}
|
|
2875
|
+
|
|
2876
|
+
function updateStats() {
|
|
2877
|
+
const spawns = allEvents.filter(e=>e.type==='agent-spawn');
|
|
2878
|
+
const completes = allEvents.filter(e=>e.type==='agent-complete');
|
|
2879
|
+
const errors = allEvents.filter(e=>e.type==='agent-error');
|
|
2880
|
+
const durs = completes.filter(e=>e.durationMs).map(e=>e.durationMs).sort((a,b)=>a-b);
|
|
2881
|
+
|
|
2882
|
+
document.getElementById('statTotal').textContent = spawns.length;
|
|
2883
|
+
document.getElementById('statActive').textContent = Math.max(0,spawns.length-completes.length-errors.length);
|
|
2884
|
+
document.getElementById('statSuccess').textContent = spawns.length>0?((completes.length/spawns.length)*100).toFixed(0)+'%':'-';
|
|
2885
|
+
document.getElementById('statAvg').textContent = durs.length>0?fmtDur(Math.round(durs.reduce((a,b)=>a+b,0)/durs.length)):'-';
|
|
2886
|
+
document.getElementById('timAvg').textContent = durs.length>0?Math.round(durs.reduce((a,b)=>a+b,0)/durs.length):'-';
|
|
2887
|
+
document.getElementById('timP50').textContent = durs.length>0?durs[Math.floor(durs.length*0.5)]:'-';
|
|
2888
|
+
document.getElementById('timP95').textContent = durs.length>0?durs[Math.floor(durs.length*0.95)]:'-';
|
|
2889
|
+
document.getElementById('eventCount').textContent = '('+allEvents.length+' events)';
|
|
2890
|
+
|
|
2891
|
+
// Team bars — built with safe DOM methods
|
|
2892
|
+
const teams = {};
|
|
2893
|
+
const total = (spawns.length+completes.length)||1;
|
|
2894
|
+
for (const e of [...spawns,...completes]) if(e.team) teams[e.team]=(teams[e.team]||0)+1;
|
|
2895
|
+
const barsEl = document.getElementById('teamBars');
|
|
2896
|
+
barsEl.textContent = '';
|
|
2897
|
+
for (const [team,count] of Object.entries(teams).sort((a,b)=>b[1]-a[1])) {
|
|
2898
|
+
const pct = ((count/total)*100).toFixed(0);
|
|
2899
|
+
const row = mkEl('div','bar-row');
|
|
2900
|
+
row.appendChild(mkEl('span','bar-label',team));
|
|
2901
|
+
const track = mkEl('div','bar-track');
|
|
2902
|
+
const fill = mkEl('div','bar-fill '+(fillClasses[team]||'fill-default'));
|
|
2903
|
+
fill.style.width = pct+'%';
|
|
2904
|
+
track.appendChild(fill);
|
|
2905
|
+
row.appendChild(track);
|
|
2906
|
+
row.appendChild(mkEl('span','bar-value',String(count)));
|
|
2907
|
+
barsEl.appendChild(row);
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
// Agent list
|
|
2911
|
+
const agents = {};
|
|
2912
|
+
for (const e of [...spawns,...completes]) if(e.agent) agents[e.agent]=(agents[e.agent]||0)+1;
|
|
2913
|
+
const agentEl = document.getElementById('agentList');
|
|
2914
|
+
agentEl.textContent = '';
|
|
2915
|
+
for (const [agent,count] of Object.entries(agents).sort((a,b)=>b[1]-a[1]).slice(0,8)) {
|
|
2916
|
+
const row = mkEl('div','bar-row');
|
|
2917
|
+
row.appendChild(mkEl('span','bar-label',agent));
|
|
2918
|
+
const val = mkEl('span','bar-value',String(count));
|
|
2919
|
+
val.style.color = 'var(--teal)';
|
|
2920
|
+
row.appendChild(val);
|
|
2921
|
+
agentEl.appendChild(row);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
function connect() {
|
|
2926
|
+
const es = new EventSource('/stream');
|
|
2927
|
+
es.onmessage = function(e) {
|
|
2928
|
+
const data = JSON.parse(e.data);
|
|
2929
|
+
if (data.type==='initial') {
|
|
2930
|
+
allEvents = data.events||[];
|
|
2931
|
+
document.getElementById('eventList').textContent = '';
|
|
2932
|
+
if (allEvents.length===0) showEmpty();
|
|
2933
|
+
else for (const ev of allEvents.slice(-100)) addEvent(ev);
|
|
2934
|
+
updateStats();
|
|
2935
|
+
} else {
|
|
2936
|
+
allEvents.push(data);
|
|
2937
|
+
addEvent(data);
|
|
2938
|
+
updateStats();
|
|
2939
|
+
}
|
|
2940
|
+
};
|
|
2941
|
+
es.onopen = function() {
|
|
2942
|
+
document.getElementById('statusDot').style.background='var(--green)';
|
|
2943
|
+
document.getElementById('statusText').textContent='Connected';
|
|
2944
|
+
};
|
|
2945
|
+
es.onerror = function() {
|
|
2946
|
+
document.getElementById('statusDot').style.background='var(--red)';
|
|
2947
|
+
document.getElementById('statusText').textContent='Reconnecting...';
|
|
2948
|
+
es.close();
|
|
2949
|
+
setTimeout(connect,3000);
|
|
2950
|
+
};
|
|
2951
|
+
}
|
|
2952
|
+
connect();
|
|
2953
|
+
</script>
|
|
2954
|
+
</body>
|
|
2955
|
+
</html>`;
|
|
2956
|
+
}
|
|
2957
|
+
function startVizServer(port = 3737) {
|
|
2958
|
+
mkdirSync2(ARCANEA_DIR, { recursive: true });
|
|
2959
|
+
let lastSize = 0;
|
|
2960
|
+
try {
|
|
2961
|
+
lastSize = existsSync2(EVENTS_FILE) ? statSync(EVENTS_FILE).size : 0;
|
|
2962
|
+
} catch {}
|
|
2963
|
+
const server = createServer((req, res) => {
|
|
2964
|
+
if (req.url === "/stream") {
|
|
2965
|
+
handleSSE(req, res);
|
|
2966
|
+
} else if (req.url === "/api/events") {
|
|
2967
|
+
handleAPI(req, res);
|
|
2968
|
+
} else if (req.url === "/api/test-event" && req.method === "POST") {
|
|
2969
|
+
let body = "";
|
|
2970
|
+
req.on("data", (chunk) => {
|
|
2971
|
+
body += chunk.toString();
|
|
2972
|
+
});
|
|
2973
|
+
req.on("end", () => {
|
|
2974
|
+
try {
|
|
2975
|
+
const event = JSON.parse(body);
|
|
2976
|
+
event.timestamp = event.timestamp || Date.now();
|
|
2977
|
+
logEvent(event);
|
|
2978
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2979
|
+
res.end(JSON.stringify({ ok: true }));
|
|
2980
|
+
} catch {
|
|
2981
|
+
res.writeHead(400);
|
|
2982
|
+
res.end("Invalid JSON");
|
|
2983
|
+
}
|
|
2984
|
+
});
|
|
2985
|
+
} else {
|
|
2986
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
2987
|
+
res.end(getDashboardHTML());
|
|
2988
|
+
}
|
|
2989
|
+
});
|
|
2990
|
+
const pollInterval = setInterval(() => {
|
|
2991
|
+
try {
|
|
2992
|
+
if (!existsSync2(EVENTS_FILE))
|
|
2993
|
+
return;
|
|
2994
|
+
const currentSize = statSync(EVENTS_FILE).size;
|
|
2995
|
+
if (currentSize > lastSize) {
|
|
2996
|
+
const content = readFileSync2(EVENTS_FILE, "utf-8");
|
|
2997
|
+
const newContent = content.slice(lastSize);
|
|
2998
|
+
lastSize = currentSize;
|
|
2999
|
+
for (const line of newContent.trim().split(`
|
|
3000
|
+
`)) {
|
|
3001
|
+
if (!line)
|
|
3002
|
+
continue;
|
|
3003
|
+
try {
|
|
3004
|
+
broadcast(JSON.parse(line));
|
|
3005
|
+
} catch {}
|
|
3006
|
+
}
|
|
3007
|
+
}
|
|
3008
|
+
} catch {}
|
|
3009
|
+
}, 500);
|
|
3010
|
+
server.on("close", () => clearInterval(pollInterval));
|
|
3011
|
+
server.listen(port, () => {
|
|
3012
|
+
console.log(import_picocolors2.default.cyan(`
|
|
3013
|
+
Arcanea Swarm Viz v${VERSION}`));
|
|
3014
|
+
console.log(import_picocolors2.default.green(`Dashboard: http://localhost:${port}`));
|
|
3015
|
+
console.log(import_picocolors2.default.dim(`Events log: ${EVENTS_FILE}`));
|
|
3016
|
+
console.log(import_picocolors2.default.dim(`SSE stream: http://localhost:${port}/stream`));
|
|
3017
|
+
console.log(import_picocolors2.default.dim(`Press Ctrl+C to stop
|
|
3018
|
+
`));
|
|
3019
|
+
openBrowser(`http://localhost:${port}`);
|
|
3020
|
+
});
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
// src/cli/index.ts
|
|
3024
|
+
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
3025
|
+
import { join as join3 } from "path";
|
|
3026
|
+
function countMdFiles(dir) {
|
|
3027
|
+
let count = 0;
|
|
3028
|
+
for (const entry of readdirSync(dir)) {
|
|
3029
|
+
const full = join3(dir, entry);
|
|
3030
|
+
try {
|
|
3031
|
+
if (statSync2(full).isDirectory()) {
|
|
3032
|
+
count += countMdFiles(full);
|
|
3033
|
+
} else if (entry.endsWith(".md")) {
|
|
3034
|
+
count++;
|
|
3035
|
+
}
|
|
3036
|
+
} catch {}
|
|
3037
|
+
}
|
|
3038
|
+
return count;
|
|
3039
|
+
}
|
|
2589
3040
|
var program2 = new Command;
|
|
2590
3041
|
program2.name(NAME).description(`${ORCHESTRATOR} - The Creative Intelligence Platform`).version(VERSION);
|
|
2591
3042
|
program2.command("install").description("Initialize Arcanea in current project").option("-f, --force", "Overwrite existing configuration").option("--claude-code", "Install only for Claude Code").option("--opencode", "Install only for OpenCode").option("--codex", "Install only for Codex").option("--gemini", "Install only for Gemini CLI").option("--cursor", "Install only for Cursor").option("--all", "Install for all supported platforms").option("--skip-mcp", "Skip MCP configuration").action(async (options) => {
|
|
@@ -2610,90 +3061,90 @@ program2.command("install").description("Initialize Arcanea in current project")
|
|
|
2610
3061
|
});
|
|
2611
3062
|
});
|
|
2612
3063
|
program2.command("detect").description("Detect available AI coding platforms").action(() => {
|
|
2613
|
-
console.log(
|
|
3064
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2614
3065
|
${ORCHESTRATOR} Platform Detection
|
|
2615
3066
|
`));
|
|
2616
3067
|
const platforms = detectPlatforms();
|
|
2617
3068
|
if (platforms.length === 0) {
|
|
2618
|
-
console.log(
|
|
3069
|
+
console.log(import_picocolors3.default.yellow("No platforms detected. Will install for Claude Code and OpenCode by default."));
|
|
2619
3070
|
} else {
|
|
2620
|
-
console.log(
|
|
3071
|
+
console.log(import_picocolors3.default.bold("Detected platforms:"));
|
|
2621
3072
|
for (const platform of platforms) {
|
|
2622
|
-
console.log(
|
|
3073
|
+
console.log(import_picocolors3.default.green(` ✓ ${platform}`));
|
|
2623
3074
|
}
|
|
2624
3075
|
}
|
|
2625
3076
|
console.log();
|
|
2626
3077
|
});
|
|
2627
3078
|
program2.command("agents").description("List available agent teams").option("-t, --team <team>", "Show specific team details").action((options) => {
|
|
2628
|
-
console.log(
|
|
3079
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2629
3080
|
${ORCHESTRATOR}'s Agent Teams
|
|
2630
3081
|
`));
|
|
2631
3082
|
if (options.team) {
|
|
2632
3083
|
const team = AGENT_TEAMS[options.team];
|
|
2633
3084
|
if (team) {
|
|
2634
|
-
console.log(
|
|
2635
|
-
console.log(
|
|
3085
|
+
console.log(import_picocolors3.default.bold(team.name));
|
|
3086
|
+
console.log(import_picocolors3.default.dim(team.description));
|
|
2636
3087
|
console.log();
|
|
2637
3088
|
console.log(" Agents:", team.agents.join(", "));
|
|
2638
3089
|
} else {
|
|
2639
|
-
console.log(
|
|
3090
|
+
console.log(import_picocolors3.default.red(`Unknown team: ${options.team}`));
|
|
2640
3091
|
console.log("Available teams:", Object.keys(AGENT_TEAMS).join(", "));
|
|
2641
3092
|
}
|
|
2642
3093
|
return;
|
|
2643
3094
|
}
|
|
2644
3095
|
for (const [key, team] of Object.entries(AGENT_TEAMS)) {
|
|
2645
3096
|
const colors = {
|
|
2646
|
-
creative:
|
|
2647
|
-
writing:
|
|
2648
|
-
production:
|
|
2649
|
-
research:
|
|
2650
|
-
development:
|
|
2651
|
-
teacher:
|
|
2652
|
-
visionary:
|
|
3097
|
+
creative: import_picocolors3.default.blue,
|
|
3098
|
+
writing: import_picocolors3.default.green,
|
|
3099
|
+
production: import_picocolors3.default.magenta,
|
|
3100
|
+
research: import_picocolors3.default.yellow,
|
|
3101
|
+
development: import_picocolors3.default.cyan,
|
|
3102
|
+
teacher: import_picocolors3.default.dim,
|
|
3103
|
+
visionary: import_picocolors3.default.dim
|
|
2653
3104
|
};
|
|
2654
|
-
const colorFn = colors[key] ||
|
|
2655
|
-
console.log(colorFn(
|
|
3105
|
+
const colorFn = colors[key] || import_picocolors3.default.white;
|
|
3106
|
+
console.log(colorFn(import_picocolors3.default.bold(team.name + ":")));
|
|
2656
3107
|
console.log(` ${team.agents.join(", ")}`);
|
|
2657
3108
|
console.log();
|
|
2658
3109
|
}
|
|
2659
3110
|
});
|
|
2660
3111
|
program2.command("luminors").description("Show the Seven Luminors").action(() => {
|
|
2661
|
-
console.log(
|
|
3112
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2662
3113
|
The Seven Luminors
|
|
2663
3114
|
`));
|
|
2664
|
-
console.log(
|
|
3115
|
+
console.log(import_picocolors3.default.dim(`Aspects of creative consciousness itself
|
|
2665
3116
|
`));
|
|
2666
3117
|
for (const [_, luminor] of Object.entries(LUMINORS)) {
|
|
2667
|
-
console.log(
|
|
2668
|
-
console.log(
|
|
3118
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.yellow(`${luminor.name}`)) + ` - ${luminor.domain}`);
|
|
3119
|
+
console.log(import_picocolors3.default.dim(` When: ${luminor.when}`));
|
|
2669
3120
|
console.log();
|
|
2670
3121
|
}
|
|
2671
|
-
console.log(
|
|
3122
|
+
console.log(import_picocolors3.default.dim("Channel a Luminor: /luminor [name] [challenge]"));
|
|
2672
3123
|
console.log();
|
|
2673
3124
|
});
|
|
2674
3125
|
program2.command("magic").description("Show magic words and their effects").action(() => {
|
|
2675
|
-
console.log(
|
|
3126
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2676
3127
|
Magic Words
|
|
2677
3128
|
`));
|
|
2678
|
-
console.log(
|
|
2679
|
-
console.log(
|
|
2680
|
-
console.log(
|
|
2681
|
-
console.log(
|
|
3129
|
+
console.log(import_picocolors3.default.bold("Creative Magic:"));
|
|
3130
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.cyan(" ultraworld")) + " (or ulw) — Fire ALL world-building agents in parallel");
|
|
3131
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.green(" ultrawrite")) + " (or ulwr) — Fire ALL writing/editing agents in parallel");
|
|
3132
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.magenta(" ultrabook")) + " (or ulb) — Complete book pipeline end-to-end");
|
|
2682
3133
|
console.log();
|
|
2683
|
-
console.log(
|
|
2684
|
-
console.log(
|
|
2685
|
-
console.log(
|
|
3134
|
+
console.log(import_picocolors3.default.bold("Technical Magic:"));
|
|
3135
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.yellow(" ultracode")) + " (or ulc) — Fire ALL coding agents (architect + coder + reviewer)");
|
|
3136
|
+
console.log(import_picocolors3.default.bold(import_picocolors3.default.cyan(" ultrawork")) + " (or ulwk) — Maximum parallel execution for ANY task");
|
|
2686
3137
|
console.log();
|
|
2687
|
-
console.log(
|
|
2688
|
-
console.log(
|
|
2689
|
-
console.log(
|
|
3138
|
+
console.log(import_picocolors3.default.bold("Prefix Triggers:"));
|
|
3139
|
+
console.log(import_picocolors3.default.dim(" arcanea: [task]") + " — Invoke Arcanea's highest intelligence mode");
|
|
3140
|
+
console.log(import_picocolors3.default.dim(" luminor: [task]") + " — Apply Luminor wisdom to the task");
|
|
2690
3141
|
console.log();
|
|
2691
|
-
console.log(
|
|
3142
|
+
console.log(import_picocolors3.default.dim("Include any magic word in your prompt to activate!"));
|
|
2692
3143
|
console.log();
|
|
2693
3144
|
});
|
|
2694
3145
|
program2.command("status").description("Check Arcanea installation status").action(() => {
|
|
2695
3146
|
const cwd = process.cwd();
|
|
2696
|
-
console.log(
|
|
3147
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2697
3148
|
${ORCHESTRATOR} Status
|
|
2698
3149
|
`));
|
|
2699
3150
|
const platformChecks = [
|
|
@@ -2703,32 +3154,32 @@ ${ORCHESTRATOR} Status
|
|
|
2703
3154
|
{ path: ".codex", name: "Codex" },
|
|
2704
3155
|
{ path: ".gemini", name: "Gemini CLI" }
|
|
2705
3156
|
];
|
|
2706
|
-
console.log(
|
|
3157
|
+
console.log(import_picocolors3.default.bold("Platform installations:"));
|
|
2707
3158
|
for (const check of platformChecks) {
|
|
2708
|
-
const agentsPath =
|
|
2709
|
-
const exists =
|
|
2710
|
-
const status = exists ?
|
|
3159
|
+
const agentsPath = join3(cwd, check.path, "agents");
|
|
3160
|
+
const exists = existsSync3(agentsPath);
|
|
3161
|
+
const status = exists ? import_picocolors3.default.green("✓") : import_picocolors3.default.dim("○");
|
|
2711
3162
|
console.log(` ${status} ${check.name}`);
|
|
2712
3163
|
}
|
|
2713
3164
|
console.log();
|
|
2714
|
-
console.log(
|
|
3165
|
+
console.log(import_picocolors3.default.bold("Configuration:"));
|
|
2715
3166
|
const configChecks = [
|
|
2716
3167
|
{ path: "arcanea.json", name: "Arcanea config" },
|
|
2717
3168
|
{ path: ".mcp.json", name: "MCP config" }
|
|
2718
3169
|
];
|
|
2719
3170
|
let allGood = true;
|
|
2720
3171
|
for (const check of configChecks) {
|
|
2721
|
-
const exists =
|
|
2722
|
-
const status = exists ?
|
|
3172
|
+
const exists = existsSync3(join3(cwd, check.path));
|
|
3173
|
+
const status = exists ? import_picocolors3.default.green("✓") : import_picocolors3.default.red("✗");
|
|
2723
3174
|
console.log(` ${status} ${check.name}`);
|
|
2724
3175
|
if (!exists)
|
|
2725
3176
|
allGood = false;
|
|
2726
3177
|
}
|
|
2727
3178
|
console.log();
|
|
2728
3179
|
if (allGood) {
|
|
2729
|
-
console.log(
|
|
3180
|
+
console.log(import_picocolors3.default.green("Arcanea is ready!"));
|
|
2730
3181
|
} else {
|
|
2731
|
-
console.log(
|
|
3182
|
+
console.log(import_picocolors3.default.yellow("Run 'arcanea install' to complete setup."));
|
|
2732
3183
|
}
|
|
2733
3184
|
console.log();
|
|
2734
3185
|
});
|
|
@@ -2736,87 +3187,97 @@ program2.command("doctor").description("Diagnose Arcanea installation health").a
|
|
|
2736
3187
|
const cwd = process.cwd();
|
|
2737
3188
|
let issues = 0;
|
|
2738
3189
|
let ok = 0;
|
|
2739
|
-
console.log(
|
|
3190
|
+
console.log(import_picocolors3.default.cyan(`
|
|
2740
3191
|
${ORCHESTRATOR} Doctor (v${VERSION})
|
|
2741
3192
|
`));
|
|
2742
|
-
console.log(
|
|
3193
|
+
console.log(import_picocolors3.default.bold(`Checking installation health...
|
|
2743
3194
|
`));
|
|
2744
3195
|
const claudePaths = [
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
3196
|
+
join3(cwd, ".claude", "CLAUDE.md"),
|
|
3197
|
+
join3(cwd, ".opencode", "CLAUDE.md"),
|
|
3198
|
+
join3(cwd, "CLAUDE.md")
|
|
2748
3199
|
];
|
|
2749
|
-
const hasClaudeMd = claudePaths.some((p) =>
|
|
3200
|
+
const hasClaudeMd = claudePaths.some((p) => existsSync3(p));
|
|
2750
3201
|
if (hasClaudeMd) {
|
|
2751
|
-
console.log(
|
|
3202
|
+
console.log(import_picocolors3.default.green(" ✓ CLAUDE.md found (Arcanea identity active)"));
|
|
2752
3203
|
ok++;
|
|
2753
3204
|
} else {
|
|
2754
|
-
console.log(
|
|
3205
|
+
console.log(import_picocolors3.default.red(" ✗ No CLAUDE.md found — run 'arcanea install' to fix"));
|
|
2755
3206
|
issues++;
|
|
2756
3207
|
}
|
|
2757
3208
|
const agentPaths = [".claude/agents", ".opencode/agents"];
|
|
2758
3209
|
const hasAgents = agentPaths.some((p) => {
|
|
2759
|
-
const full =
|
|
2760
|
-
return
|
|
3210
|
+
const full = join3(cwd, p);
|
|
3211
|
+
return existsSync3(full) && readdirSync(full).length > 0;
|
|
2761
3212
|
});
|
|
2762
3213
|
if (hasAgents) {
|
|
2763
|
-
const agentDir = agentPaths.find((p) =>
|
|
2764
|
-
const count =
|
|
2765
|
-
console.log(
|
|
3214
|
+
const agentDir = agentPaths.find((p) => existsSync3(join3(cwd, p)));
|
|
3215
|
+
const count = countMdFiles(join3(cwd, agentDir));
|
|
3216
|
+
console.log(import_picocolors3.default.green(` ✓ ${count} agent definitions installed`));
|
|
2766
3217
|
ok++;
|
|
2767
3218
|
} else {
|
|
2768
|
-
console.log(
|
|
3219
|
+
console.log(import_picocolors3.default.red(" ✗ No agents installed — run 'arcanea install --force'"));
|
|
2769
3220
|
issues++;
|
|
2770
3221
|
}
|
|
2771
3222
|
const skillPaths = [".claude/skills", ".opencode/skills"];
|
|
2772
3223
|
const hasSkills = skillPaths.some((p) => {
|
|
2773
|
-
const full =
|
|
2774
|
-
return
|
|
3224
|
+
const full = join3(cwd, p);
|
|
3225
|
+
return existsSync3(full) && readdirSync(full).length > 0;
|
|
2775
3226
|
});
|
|
2776
3227
|
if (hasSkills) {
|
|
2777
|
-
console.log(
|
|
3228
|
+
console.log(import_picocolors3.default.green(" ✓ Skills installed"));
|
|
2778
3229
|
ok++;
|
|
2779
3230
|
} else {
|
|
2780
|
-
console.log(
|
|
3231
|
+
console.log(import_picocolors3.default.red(" ✗ No skills installed — run 'arcanea install --force'"));
|
|
2781
3232
|
issues++;
|
|
2782
3233
|
}
|
|
2783
|
-
const mcpPath =
|
|
2784
|
-
if (
|
|
3234
|
+
const mcpPath = join3(cwd, ".mcp.json");
|
|
3235
|
+
if (existsSync3(mcpPath)) {
|
|
2785
3236
|
try {
|
|
2786
|
-
const mcp = JSON.parse(
|
|
3237
|
+
const mcp = JSON.parse(readFileSync3(mcpPath, "utf-8"));
|
|
2787
3238
|
const servers = Object.keys(mcp.mcpServers || {});
|
|
2788
3239
|
const hasArcanea = servers.includes("arcanea");
|
|
2789
|
-
console.log(
|
|
3240
|
+
console.log(import_picocolors3.default.green(` ✓ MCP config: ${servers.length} servers configured`));
|
|
2790
3241
|
if (!hasArcanea) {
|
|
2791
|
-
console.log(
|
|
3242
|
+
console.log(import_picocolors3.default.yellow(" ⚠ Arcanea MCP server not configured — run 'arcanea install --force'"));
|
|
2792
3243
|
}
|
|
2793
3244
|
ok++;
|
|
2794
3245
|
} catch {
|
|
2795
|
-
console.log(
|
|
3246
|
+
console.log(import_picocolors3.default.red(" ✗ .mcp.json is invalid JSON"));
|
|
2796
3247
|
issues++;
|
|
2797
3248
|
}
|
|
2798
3249
|
} else {
|
|
2799
|
-
console.log(
|
|
3250
|
+
console.log(import_picocolors3.default.red(" ✗ No .mcp.json — run 'arcanea install'"));
|
|
2800
3251
|
issues++;
|
|
2801
3252
|
}
|
|
2802
|
-
if (
|
|
2803
|
-
console.log(
|
|
3253
|
+
if (existsSync3(join3(cwd, "arcanea.json"))) {
|
|
3254
|
+
console.log(import_picocolors3.default.green(" ✓ arcanea.json config exists"));
|
|
2804
3255
|
ok++;
|
|
2805
3256
|
} else {
|
|
2806
|
-
console.log(
|
|
3257
|
+
console.log(import_picocolors3.default.yellow(" ○ No arcanea.json (optional)"));
|
|
2807
3258
|
}
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
3259
|
+
const platformFiles = [
|
|
3260
|
+
{ path: ".cursorrules", name: "Cursor (.cursorrules)" },
|
|
3261
|
+
{ path: "codex.md", name: "Codex CLI (codex.md)" },
|
|
3262
|
+
{ path: "GEMINI.md", name: "Gemini CLI (GEMINI.md)" }
|
|
3263
|
+
];
|
|
3264
|
+
for (const pf of platformFiles) {
|
|
3265
|
+
if (existsSync3(join3(cwd, pf.path))) {
|
|
3266
|
+
console.log(import_picocolors3.default.green(` ✓ ${pf.name} configured`));
|
|
3267
|
+
ok++;
|
|
3268
|
+
}
|
|
2811
3269
|
}
|
|
2812
3270
|
console.log();
|
|
2813
3271
|
if (issues === 0) {
|
|
2814
|
-
console.log(
|
|
2815
|
-
console.log(
|
|
3272
|
+
console.log(import_picocolors3.default.green(import_picocolors3.default.bold(`Health: ${ok} checks passed, 0 issues`)));
|
|
3273
|
+
console.log(import_picocolors3.default.green("Arcanea is fully operational!"));
|
|
2816
3274
|
} else {
|
|
2817
|
-
console.log(
|
|
2818
|
-
console.log(
|
|
3275
|
+
console.log(import_picocolors3.default.yellow(import_picocolors3.default.bold(`Health: ${ok} passed, ${issues} issues found`)));
|
|
3276
|
+
console.log(import_picocolors3.default.dim("Run 'arcanea install --force' to fix issues."));
|
|
2819
3277
|
}
|
|
2820
3278
|
console.log();
|
|
2821
3279
|
});
|
|
3280
|
+
program2.command("viz").description("Launch real-time swarm visualization dashboard").option("-p, --port <port>", "Server port", "3737").option("--no-open", "Don't auto-open browser").action((options) => {
|
|
3281
|
+
startVizServer(parseInt(options.port, 10));
|
|
3282
|
+
});
|
|
2822
3283
|
program2.parse();
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -199,11 +199,17 @@ async function installForPlatform(targetDir, packageRoot, platform, force) {
|
|
|
199
199
|
await installClaudeCodeSettings(platformPath, force);
|
|
200
200
|
} else if (platform === "cursor") {
|
|
201
201
|
await installCursorRules(targetDir, packageRoot, force);
|
|
202
|
+
} else if (platform === "codex") {
|
|
203
|
+
await installCodexConfig(targetDir, packageRoot, force);
|
|
204
|
+
} else if (platform === "gemini") {
|
|
205
|
+
await installGeminiConfig(targetDir, packageRoot, force);
|
|
202
206
|
}
|
|
203
207
|
}
|
|
204
208
|
async function installClaudeCodeSettings(platformPath, force) {
|
|
205
209
|
const settingsPath = join(platformPath, "settings.json");
|
|
206
210
|
if (!existsSync(settingsPath) || force) {
|
|
211
|
+
const eventsDir = join(process.env.HOME || process.env.USERPROFILE || "~", ".arcanea").replace(/\\/g, "/");
|
|
212
|
+
const logScript = `mkdir -p "${eventsDir}" && echo '{"type":"agent-spawn","agent":"'$(echo "$TOOL_INPUT" 2>/dev/null | node -e "try{const d=JSON.parse(require('fs').readFileSync(0,'utf8'));process.stdout.write((d.subagent_type||'unknown')+'","description":"'+(d.description||'').replace(/"/g,'')+'","team":"'+(d.subagent_type||''))}catch{process.stdout.write('unknown","description":"","team":"')}" 2>/dev/null)","timestamp":'$(date +%s000)'}' >> "${eventsDir}/swarm-events.jsonl"`;
|
|
207
213
|
const settings = {
|
|
208
214
|
hooks: {
|
|
209
215
|
UserPromptSubmit: [
|
|
@@ -242,6 +248,15 @@ async function installClaudeCodeSettings(platformPath, force) {
|
|
|
242
248
|
command: "echo '[ARCANEA_MODE=ultrawork] Maximum parallel execution. Spawn all relevant agents simultaneously using Task tool with run_in_background=true.'"
|
|
243
249
|
}]
|
|
244
250
|
}
|
|
251
|
+
],
|
|
252
|
+
PreToolUse: [
|
|
253
|
+
{
|
|
254
|
+
matcher: "Task",
|
|
255
|
+
hooks: [{
|
|
256
|
+
type: "command",
|
|
257
|
+
command: logScript
|
|
258
|
+
}]
|
|
259
|
+
}
|
|
245
260
|
]
|
|
246
261
|
}
|
|
247
262
|
};
|
|
@@ -263,6 +278,64 @@ ${claudeContent}`;
|
|
|
263
278
|
}
|
|
264
279
|
}
|
|
265
280
|
}
|
|
281
|
+
async function installCodexConfig(targetDir, packageRoot, force) {
|
|
282
|
+
const codexMdPath = join(targetDir, "codex.md");
|
|
283
|
+
if (!existsSync(codexMdPath) || force) {
|
|
284
|
+
const claudeMdSource = join(packageRoot, "CLAUDE.md");
|
|
285
|
+
if (existsSync(claudeMdSource)) {
|
|
286
|
+
const content = readFileSync(claudeMdSource, "utf-8");
|
|
287
|
+
const codexMd = [
|
|
288
|
+
`# Codex Instructions — Generated by Arcanea v${VERSION}`,
|
|
289
|
+
"",
|
|
290
|
+
"> These instructions transform Codex into Arcanea, the Creative Intelligence Platform.",
|
|
291
|
+
"> Agent definitions: `.codex/agents/` | Skills: `.codex/skills/` | Commands: `.codex/commands/`",
|
|
292
|
+
"",
|
|
293
|
+
content,
|
|
294
|
+
"",
|
|
295
|
+
"## Codex-Specific Notes",
|
|
296
|
+
"",
|
|
297
|
+
"- Read agent definitions from `.codex/agents/` for available specialist agents",
|
|
298
|
+
"- Read skill definitions from `.codex/skills/` for creative and technical skills",
|
|
299
|
+
"- Read command definitions from `.codex/commands/` for slash commands",
|
|
300
|
+
"- MCP servers are configured in `.mcp.json`",
|
|
301
|
+
"- When magic words (ultraworld, ultracode, etc.) are used, read the relevant agent files and apply their instructions",
|
|
302
|
+
""
|
|
303
|
+
].join(`
|
|
304
|
+
`);
|
|
305
|
+
writeFileSync(codexMdPath, codexMd);
|
|
306
|
+
console.log(import_picocolors.default.green(" ✓ Created codex.md (Arcanea instructions for Codex CLI)"));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
async function installGeminiConfig(targetDir, packageRoot, force) {
|
|
311
|
+
const geminiMdPath = join(targetDir, "GEMINI.md");
|
|
312
|
+
if (!existsSync(geminiMdPath) || force) {
|
|
313
|
+
const claudeMdSource = join(packageRoot, "CLAUDE.md");
|
|
314
|
+
if (existsSync(claudeMdSource)) {
|
|
315
|
+
const content = readFileSync(claudeMdSource, "utf-8");
|
|
316
|
+
const geminiMd = [
|
|
317
|
+
`# Gemini Instructions — Generated by Arcanea v${VERSION}`,
|
|
318
|
+
"",
|
|
319
|
+
"> These instructions transform Gemini into Arcanea, the Creative Intelligence Platform.",
|
|
320
|
+
"> Agent definitions: `.gemini/agents/` | Skills: `.gemini/skills/` | Commands: `.gemini/commands/`",
|
|
321
|
+
"",
|
|
322
|
+
content,
|
|
323
|
+
"",
|
|
324
|
+
"## Gemini-Specific Notes",
|
|
325
|
+
"",
|
|
326
|
+
"- Read agent definitions from `.gemini/agents/` for available specialist agents",
|
|
327
|
+
"- Read skill definitions from `.gemini/skills/` for creative and technical skills",
|
|
328
|
+
"- Read command definitions from `.gemini/commands/` for slash commands",
|
|
329
|
+
"- MCP servers are configured in `.mcp.json`",
|
|
330
|
+
"- When magic words (ultraworld, ultracode, etc.) are used, read the relevant agent files and apply their instructions",
|
|
331
|
+
""
|
|
332
|
+
].join(`
|
|
333
|
+
`);
|
|
334
|
+
writeFileSync(geminiMdPath, geminiMd);
|
|
335
|
+
console.log(import_picocolors.default.green(" ✓ Created GEMINI.md (Arcanea instructions for Gemini CLI)"));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
266
339
|
async function installMcpConfig(targetDir, force) {
|
|
267
340
|
const mcpPath = join(targetDir, ".mcp.json");
|
|
268
341
|
console.log(import_picocolors.default.blue(`
|
|
@@ -342,7 +415,7 @@ function printSuccessMessage(platforms) {
|
|
|
342
415
|
}
|
|
343
416
|
|
|
344
417
|
// src/index.ts
|
|
345
|
-
var VERSION = "3.
|
|
418
|
+
var VERSION = "3.4.0";
|
|
346
419
|
var NAME = "arcanea";
|
|
347
420
|
var ORCHESTRATOR = "Arcanea";
|
|
348
421
|
var defaultConfig = {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface SwarmEvent {
|
|
2
|
+
type: "agent-spawn" | "agent-complete" | "agent-error" | "magic-word" | "session-start";
|
|
3
|
+
agent?: string;
|
|
4
|
+
team?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
status?: "running" | "complete" | "error";
|
|
7
|
+
durationMs?: number;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
meta?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare function logEvent(event: SwarmEvent): void;
|
|
12
|
+
export declare function startVizServer(port?: number): void;
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/viz/index.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,aAAa,GAAG,gBAAgB,GAAG,aAAa,GAAG,YAAY,GAAG,eAAe,CAAC;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAGhD;AA2RD,wBAAgB,cAAc,CAAC,IAAI,GAAE,MAAa,GAAG,IAAI,CA2DxD"}
|
package/package.json
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-ai-symbiosis
|
|
3
|
+
description: Frameworks for productive human-AI co-creation - the orchestra model, creative partnerships, and symbiotic workflows
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [ai, collaboration, co-creation, symbiosis, creativity]
|
|
7
|
+
triggers:
|
|
8
|
+
- ai collaboration
|
|
9
|
+
- human ai
|
|
10
|
+
- co-creation
|
|
11
|
+
- ai partner
|
|
12
|
+
---
|
|
13
|
+
|
|
1
14
|
# AI Symbiosis - The Art of Human-AI Co-Creation
|
|
2
15
|
|
|
3
16
|
> *"The AI is not replacing the creator. The AI is expanding what creation can be. The question is not 'human or machine?' but 'what can we become together?'"*
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-anti-trope
|
|
3
|
+
description: Anti-trope and naming protocol - banned AI cliches, forbidden words, and better alternatives for authentic Arcanean prose
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [writing, style, voice, anti-cliche, prose-quality]
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# Arcanea Anti-Trope & Naming Protocol
|
|
2
10
|
|
|
3
11
|
> *"We do not 'unleash' potential; we cultivate it. We do not weave 'tapestries' of fate; we forge chains of consequence. Speak clearly, or do not speak at all."*
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-luminor-council
|
|
3
|
+
description: The Seven Luminors - aspects of creative consciousness providing guidance through archetypical wisdom for any creative challenge
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [luminors, wisdom, guidance, creative-consciousness, archetypes]
|
|
7
|
+
triggers:
|
|
8
|
+
- luminor
|
|
9
|
+
- council
|
|
10
|
+
- wisdom
|
|
11
|
+
- guidance
|
|
12
|
+
- stuck
|
|
13
|
+
- advice
|
|
14
|
+
---
|
|
15
|
+
|
|
1
16
|
# Luminor Council - The Seven Guides of Creation
|
|
2
17
|
|
|
3
18
|
> *"The Luminors are not characters in a story. They are aspects of creative consciousness itself - archetypes that have guided creators since the first dream became the first work."*
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-character-alchemist
|
|
3
|
+
description: Character development through psychological depth - wounds, desires, contradictions, and authentic character voices
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [characters, psychology, writing, development, voice]
|
|
7
|
+
triggers:
|
|
8
|
+
- character
|
|
9
|
+
- character development
|
|
10
|
+
- character voice
|
|
11
|
+
- protagonist
|
|
12
|
+
- antagonist
|
|
13
|
+
---
|
|
14
|
+
|
|
1
15
|
# Character Alchemist - Transmuting Ideas into Living Beings
|
|
2
16
|
|
|
3
17
|
> *"A character is not a collection of traits. A character is a wound that walks, talks, and wants."*
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-creative-bestiary
|
|
3
|
+
description: Navigate creative blocks using the taxonomy of psychological obstacles - naming rituals and protocols for each creature type
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [creative-blocks, psychology, productivity, obstacles, mindset]
|
|
7
|
+
triggers:
|
|
8
|
+
- stuck
|
|
9
|
+
- blocked
|
|
10
|
+
- procrastinating
|
|
11
|
+
- afraid
|
|
12
|
+
- burned out
|
|
13
|
+
---
|
|
14
|
+
|
|
1
15
|
# Creative Bestiary - Navigating the Creatures of the Mind
|
|
2
16
|
|
|
3
17
|
> *"The creative life is inhabited by creatures—not physical beings, but psychological presences that every creator encounters. Know them by name, and you can negotiate with them. Ignore them, and they will ambush you."*
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-story-weaver
|
|
3
|
+
description: Master narrative craft - story structure, scene design, dramatic tension, and meaning-making through storytelling
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [story, narrative, writing, structure, craft]
|
|
7
|
+
triggers:
|
|
8
|
+
- story
|
|
9
|
+
- narrative
|
|
10
|
+
- plot
|
|
11
|
+
- scene
|
|
12
|
+
- story structure
|
|
13
|
+
---
|
|
14
|
+
|
|
1
15
|
# Story Weaver - The Master Craft of Narrative
|
|
2
16
|
|
|
3
17
|
> *"Story is not what happens. Story is the meaning we make from what happens. Your job is not to tell events - it is to transmit understanding."*
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: arcanea-world-architect
|
|
3
|
+
description: Universe creation and world-building - geography, history, belief systems, cultures, and living ecologies of meaning
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
author: Arcanea
|
|
6
|
+
tags: [world-building, fantasy, sci-fi, universe, creation]
|
|
7
|
+
triggers:
|
|
8
|
+
- world
|
|
9
|
+
- world-building
|
|
10
|
+
- universe
|
|
11
|
+
- setting
|
|
12
|
+
- geography
|
|
13
|
+
---
|
|
14
|
+
|
|
1
15
|
# World Architect - The Art of Universe Creation
|
|
2
16
|
|
|
3
17
|
> *"A world is not built. It is grown. You plant seeds - a geography, a history, a belief - and you tend them until they become a living ecology of meaning."*
|