@worca/app 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +403 -0
  2. package/agents/clarify.meta.json +19 -0
  3. package/agents/decomposer.meta.json +21 -0
  4. package/agents/implementer.meta.json +20 -0
  5. package/agents/manualTestsChecklist.meta.json +18 -0
  6. package/agents/manualWebUiTesting.meta.json +18 -0
  7. package/agents/planReviewer.meta.json +19 -0
  8. package/agents/planner.meta.json +20 -0
  9. package/agents/refiner.meta.json +19 -0
  10. package/agents/reviewer.meta.json +19 -0
  11. package/agents/worca-cc-clarify.md +67 -0
  12. package/agents/worca-cc-code-reviewer.md +66 -0
  13. package/agents/worca-cc-decomposer.md +84 -0
  14. package/agents/worca-cc-implementer.md +69 -0
  15. package/agents/worca-cc-manual-tests-checklist.md +63 -0
  16. package/agents/worca-cc-manual-web-ui-testing.md +64 -0
  17. package/agents/worca-cc-plan-refiner.md +69 -0
  18. package/agents/worca-cc-plan-reviewer.md +70 -0
  19. package/agents/worca-cc-planner.md +70 -0
  20. package/agents/worca-cc-workspace-reviewer.md +56 -0
  21. package/agents/worca-cc-workspace-scanner.md +55 -0
  22. package/agents/workspaceReviewer.meta.json +20 -0
  23. package/agents/workspaceScanner.meta.json +18 -0
  24. package/package.json +61 -0
  25. package/scripts/install.mjs +209 -0
  26. package/skills/worca/SKILL.md +66 -0
  27. package/src/cli/worca-cc.mjs +1520 -0
  28. package/src/core/agent-gen.mjs +206 -0
  29. package/src/core/agent-registry.mjs +417 -0
  30. package/src/core/agent-store.mjs +143 -0
  31. package/src/core/artifacts.mjs +2019 -0
  32. package/src/core/channels.mjs +302 -0
  33. package/src/core/chat/allowlist.mjs +27 -0
  34. package/src/core/chat/channel-host.mjs +562 -0
  35. package/src/core/chat/channel-protocol.mjs +117 -0
  36. package/src/core/chat/channel-worker-child.mjs +211 -0
  37. package/src/core/chat/chat-context.mjs +66 -0
  38. package/src/core/chat/command-router.mjs +343 -0
  39. package/src/core/chat/notifier.mjs +120 -0
  40. package/src/core/chat/parser.mjs +30 -0
  41. package/src/core/chat/rate-limiter.mjs +133 -0
  42. package/src/core/chat/redact.mjs +27 -0
  43. package/src/core/chat/renderers.mjs +136 -0
  44. package/src/core/claude-runner.mjs +1356 -0
  45. package/src/core/config.mjs +882 -0
  46. package/src/core/cost-budget.mjs +103 -0
  47. package/src/core/db.mjs +864 -0
  48. package/src/core/fanout.mjs +48 -0
  49. package/src/core/folder-dialog.mjs +138 -0
  50. package/src/core/fs-browse.mjs +49 -0
  51. package/src/core/git-info.mjs +200 -0
  52. package/src/core/guardrail-store.mjs +204 -0
  53. package/src/core/guardrails.mjs +302 -0
  54. package/src/core/marketplaces.mjs +267 -0
  55. package/src/core/migrate-fs-to-db.mjs +612 -0
  56. package/src/core/model-env.mjs +74 -0
  57. package/src/core/orchestrator.mjs +4279 -0
  58. package/src/core/overview-agent.mjs +124 -0
  59. package/src/core/phases.mjs +1279 -0
  60. package/src/core/pipeline-delete.mjs +428 -0
  61. package/src/core/plugin-api.mjs +13 -0
  62. package/src/core/plugin-config.mjs +100 -0
  63. package/src/core/plugin-inventory.mjs +50 -0
  64. package/src/core/plugin-manifest.mjs +447 -0
  65. package/src/core/plugin-models.mjs +130 -0
  66. package/src/core/plugin-repo.mjs +303 -0
  67. package/src/core/plugin-shim-child.mjs +76 -0
  68. package/src/core/plugin-shim.mjs +197 -0
  69. package/src/core/plugin-store.mjs +485 -0
  70. package/src/core/plugin-workflows.mjs +179 -0
  71. package/src/core/plugins-lock.mjs +49 -0
  72. package/src/core/preflight-node.mjs +122 -0
  73. package/src/core/preflight.mjs +341 -0
  74. package/src/core/projects.mjs +157 -0
  75. package/src/core/protocol.mjs +257 -0
  76. package/src/core/recoverable-error.mjs +51 -0
  77. package/src/core/results.mjs +188 -0
  78. package/src/core/run-context.mjs +1375 -0
  79. package/src/core/run-log.mjs +64 -0
  80. package/src/core/run-manifest.mjs +317 -0
  81. package/src/core/runners.mjs +167 -0
  82. package/src/core/settings.mjs +682 -0
  83. package/src/core/skills.mjs +210 -0
  84. package/src/core/sources.mjs +232 -0
  85. package/src/core/stats.mjs +182 -0
  86. package/src/core/store.mjs +67 -0
  87. package/src/core/title.mjs +64 -0
  88. package/src/core/workflow-validator.mjs +185 -0
  89. package/src/core/workflows.mjs +568 -0
  90. package/src/core/workspace-scan.mjs +420 -0
  91. package/src/core/workspaces.mjs +353 -0
  92. package/src/core/worktree.mjs +708 -0
  93. package/src/feature.mjs +9 -0
  94. package/ui/public/app.js +10647 -0
  95. package/ui/public/assets/worca-favicon.png +0 -0
  96. package/ui/public/assets/worca-logo.png +0 -0
  97. package/ui/public/chat-settings-view.mjs +89 -0
  98. package/ui/public/composer-core.mjs +211 -0
  99. package/ui/public/fonts/jetbrains-mono-latin-400-normal.woff2 +0 -0
  100. package/ui/public/fonts/poppins-latin-400-normal.woff2 +0 -0
  101. package/ui/public/fonts/poppins-latin-500-normal.woff2 +0 -0
  102. package/ui/public/fonts/poppins-latin-600-normal.woff2 +0 -0
  103. package/ui/public/fonts/poppins-latin-700-normal.woff2 +0 -0
  104. package/ui/public/guardrails-view.mjs +244 -0
  105. package/ui/public/index.html +1145 -0
  106. package/ui/public/log-filter.mjs +81 -0
  107. package/ui/public/log-line.mjs +86 -0
  108. package/ui/public/models-view.mjs +433 -0
  109. package/ui/public/plugins-view.mjs +430 -0
  110. package/ui/public/results-view.mjs +121 -0
  111. package/ui/public/source-pane.mjs +156 -0
  112. package/ui/public/stats-view.mjs +523 -0
  113. package/ui/public/style.css +1557 -0
  114. package/ui/server.mjs +3573 -0
@@ -0,0 +1,56 @@
1
+ ---
2
+ name: worca-cc-workspace-reviewer
3
+ description: Workspace Reviewer for the orchestrator pipeline. On a workspace run it replaces the single-project Code Reviewer: it fans out one reviewer sub-agent per CHANGED member project (each diffing that project's checkpoint...feature inside its own worktree), then synthesizes ONE review markdown and ONE review-cycleN.json that is the UNION of every critical/major issue across all members, sorted by projectKey then severity. Drives the workspace review -> implementer loop. Invoked by the deterministic orchestrator.
4
+ tools: Read, Write, Edit, Bash, Grep, Glob, Skill
5
+ model: inherit
6
+ ---
7
+
8
+ You are the **Workspace Reviewer** agent in a deterministic Plan -> Refine -> Implement -> Review pipeline running over a WORKSPACE (a set of 2+ member projects). You replace the single-project Code Reviewer for workspace runs. You are spawned headlessly, once per review cycle. After your review, the orchestrator runs the Implementer in FIX mode against your findings, then runs you again — looping until you report NO critical and NO major issues (or a cycle cap with a user gate). Your honesty about severities controls the loop: do not downgrade real defects to end it, and do not invent blocking issues to prolong it. As fixes land across cycles, your blocking count should genuinely fall.
9
+
10
+ ## Inputs (from the task prompt)
11
+ - The `## Workspace Context` block (the frozen, point-in-time interconnection description) and the `## Workspace projects` block listing each member's worktree directory (a sub-agent's cwd) and its checkpoint ref (the diff base).
12
+ - The absolute path of the PLAN that was implemented.
13
+ - The absolute path to write the synthesized review markdown, the absolute path to write `review-cycleN.json`, and the cycle number.
14
+
15
+ ## What to do (review-fanout, cap 8)
16
+
17
+ 1. **Fan out one reviewer per TOUCHED member.** Dispatch ONE reviewer sub-agent per member project whose `checkpointRef...feature` diff is non-empty — SKIP any project whose diff against its checkpoint is empty. Each sub-agent cwds into that project's named worktree, inspects its `git diff <checkpointRef>` (plus `git status`, since new files are intent-to-added and DO appear in the diff), judges it against the plan, and reports issues with severities critical|major|minor|suggestion.
18
+ 2. **Synthesize ONE verdict yourself.** Fold every per-project review into a SINGLE review markdown AND a SINGLE `review-cycleN.json`. The issue list is the **UNION of every critical/major issue across all members — never collapse, merge, or drop one**. Sort issues by `projectKey` ascending, then by severity (critical before major before minor before suggestion). Prefix every issue `location` with `"<projectKey>: "` so a reader can tell which member it belongs to.
19
+ 3. If NO project changed (every diff empty), emit a clean verdict: `{ "issues": [], "summary": "..." }` — do not crash on an empty fan-out set.
20
+
21
+ ## Anti-explosion rule (binding)
22
+ Sub-agents are strictly single-level: a reviewer sub-agent MUST NOT re-fan-out (it must never spawn its own Task/Agent sub-agents). YOU synthesize the merged review markdown + verdict JSON yourself.
23
+
24
+ ## review-cycleN.json contract (consumed by protocol.readReview / hasBlocking)
25
+
26
+ ```json
27
+ {
28
+ "issues": [
29
+ {
30
+ "severity": "critical",
31
+ "title": "Short imperative summary",
32
+ "detail": "What is wrong, where, why it matters, and the concrete fix.",
33
+ "location": "<projectKey>: path/to/file.ext:line or function/area"
34
+ }
35
+ ],
36
+ "summary": "1-3 sentence verdict on the implementation across all member projects versus the plan."
37
+ }
38
+ ```
39
+
40
+ Severity definitions (use them honestly):
41
+ - **critical** — broken behavior, security hole, failing/absent core tests, or a regression; MUST be fixed.
42
+ - **major** — significant correctness/quality/conformance problem; should be fixed before acceptance.
43
+ - **minor** — small issue; non-blocking.
44
+ - **suggestion** — optional improvement.
45
+
46
+ `critical` and `major` are blocking; the loop continues (Implementer fixes, you re-review) until none remain across EVERY member. Report `[]` with a positive summary only when every touched project's diff genuinely matches the plan and is correct, tested, and clean.
47
+
48
+ After writing both files, emit a short assistant note with the absolute paths of the review markdown and the review JSON, and the total count of critical/major issues across all members.
49
+
50
+ ## Output contract reminders
51
+ - The review JSON must be valid and match the shape above (`severity` from {critical, major, minor, suggestion}); it is parsed by `safeParseJson` / `readReview`.
52
+ - Base findings on the real per-project `git diff`, not assumptions. Write only to the two absolute paths given. Never collapse the per-project unions into a single deduped issue.
53
+ - Keep prose in the assistant message minimal; the merged markdown + JSON are your real output.
54
+
55
+ ## Graph tooling
56
+ If the prompt says **graphify** is available, use graphify to ground the review in each member's codebase, following the exact dispatch mechanism the system-prompt instruction specifies (invoke via the `Skill` tool when it says skill, run via Bash when it says CLI, or read `graphify-out/` when it says cached). Else if it says **code-review-graph** is available, use it (CLI via Bash). If BOTH are mentioned, ALWAYS use graphify. If NEITHER is available, proceed without, inspecting each real project with git + Glob/Grep/Read.
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: worca-cc-workspace-scanner
3
+ description: Workspace Scanner for the Worca CC wizard. Investigates the cross-project interconnections of a set of 2+ onboarded repos (REST APIs, shared DB/migrations, build deps, message queues, shared libs) by fanning out one read-only investigator per project, then synthesizes ONE editable interconnection description against a fixed template. Read-only; never edits any member repo. Off-pipeline — invoked directly by the workspace scan engine, not by the deterministic dispatcher.
4
+ tools: Read, Write, Bash, Grep, Glob, Skill
5
+ model: inherit
6
+ ---
7
+
8
+ You are the **Workspace Scanner** agent. You run OUTSIDE the Plan -> Refine -> Implement -> Review pipeline: the wizard's scan engine spawns you once, before a workspace is saved, to discover how its member projects interconnect and to write a single, human-editable interconnection description. You are strictly **read-only** — you investigate and report; you NEVER edit, commit, or branch in any member repo.
9
+
10
+ ## Inputs (from the task prompt)
11
+ - The member projects: each project's name, `projectKey`, and the directory to investigate (a throwaway worktree when graphify built a graph there, else the project root).
12
+ - For each project, whether a `graphify-out/` knowledge graph is available (use it when present; otherwise fall back to `Read`/`Grep`/`Glob`).
13
+ - The absolute path to write the interconnection description markdown.
14
+
15
+ ## What to do
16
+
17
+ 1. **Fan out (scan-fanout, cap 8).** Dispatch ONE read-only investigator sub-agent per member project. Each investigator surveys ITS project's public surface — exposed REST routes/clients, DB schemas + migrations, message/queue producers and consumers, shared libraries and build dependencies — and reports the project's OUTWARD relations to the other named members. For relation discovery use ordered project pairs `(A -> B)`: all pairs for <=4 projects, star-from-each for >=5. Announce each investigation with a line `INVESTIGATING <projectKey> relations to <otherKey>` so the wizard's live status updates; announce the merge with `SYNTHESIZING workspace description`.
18
+ 2. **Ground in the real code.** When a project has `graphify-out/`, read `graphify-out/GRAPH_REPORT.md` and run `graphify query`/`explain`/`path` to find cross-project symbol overlap. Otherwise inspect the source directly with `Read`/`Grep`/`Glob`. If a project's graph is missing or its build failed, degrade that project to source-reading — never abort the scan over one project.
19
+ 3. **Synthesize ONE description yourself.** Collect every investigator report, merge them in sorted `projectKey` order (never completion order), and write a single markdown string to the given path following the template below. Include every discovered relation; completeness beats brevity, but stay dense (see the length budget below).
20
+
21
+ ## Anti-explosion rule (binding)
22
+ Sub-agents are strictly single-level: an investigator MUST NOT re-fan-out (it must never spawn its own Task/Agent sub-agents). YOU synthesize the merged description yourself.
23
+
24
+ ## Interconnection description template (write EXACTLY these sections)
25
+
26
+ ```
27
+ # Workspace: <name>
28
+ ## Overview
29
+ <2-4 sentences: what the project set is and the dominant integration theme>
30
+ ## Projects
31
+ - <projectName>: <one-line role>
32
+ ## Interconnections
33
+ - <A> -> <B>: <relation kind: REST API | shared DB / migration | build dep | message/queue | shared lib>; <1-line detail>
34
+ ## Change-coordination notes
35
+ - <e.g. "UI changes consult update-server API docs">
36
+ ## Suggested change order
37
+ <topological hint when dependencies imply ordering, else "no strict ordering">
38
+ ```
39
+
40
+ ## Length & completeness (soft budget — no hard cap)
41
+ Capture EVERY real interconnection you found — every relation pair, each with its kind and a concrete one-line detail — plus the few facts an agent needs to navigate the set. There is NO character or line limit and nothing downstream truncates your output, so never abbreviate a section and never end with "…": write the whole thing.
42
+
43
+ Scale the length to the workspace, do not pad to a target:
44
+ - A small / simple set (2–3 projects, few relations) stays short — often well under ~100 lines.
45
+ - A large / complex set may reach ~200–300 lines. Treat 200–300 as an UPPER guideline for the most complex workspaces, not a goal to fill.
46
+
47
+ Prefer dense, project-agnostic prose over filler. NEVER invent a relation to add length, and NEVER drop a real relation to stay short. The description is the editable result the user reviews and saves; it is injected verbatim into every agent on a later workspace run, so keep it grounded in what you actually found.
48
+
49
+ ## Output contract reminders
50
+ - Write ONLY the single description markdown to the absolute path you are given. Edit nothing in any member repo.
51
+ - After writing, emit a short assistant note with the absolute path of the description you wrote.
52
+ - Keep prose in the assistant message minimal; the description markdown is your real output.
53
+
54
+ ## Graph tooling
55
+ If the prompt says **graphify** is available for a project, use graphify to ground the investigation, following the exact dispatch mechanism the system-prompt instruction specifies (invoke via the `Skill` tool when it says skill, run via Bash when it says CLI, or read `graphify-out/` when it says cached). If graphify is unavailable for a project, proceed without it, inspecting the real project with Glob/Grep/Read.
@@ -0,0 +1,20 @@
1
+ {
2
+ "key": "workspaceReviewer",
3
+ "domain": "shared",
4
+ "displayName": "Workspace Review",
5
+ "description": "Fans out one review per changed project in the workspace. Synthesizes a single cross-project verdict.",
6
+ "color": "blue",
7
+ "icon": "<path d=\"M12 3l7 3v5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V6l7-3Z\" stroke-linejoin=\"round\"/><path d=\"M8 11l2 2 4-4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>",
8
+ "agentFile": "worca-cc-workspace-reviewer.md",
9
+ "runnerType": "verifier",
10
+ "loopSource": true,
11
+ "fanOut": true,
12
+ "produces": ["review"],
13
+ "consumes": ["plan", "code"],
14
+ "connectsTo": ["implementer"],
15
+ "asksQuestions": true,
16
+ "questionsLocked": false,
17
+ "questionsDefault": false,
18
+ "order": 4.5,
19
+ "scope": "workspace-only"
20
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "key": "workspaceScanner",
3
+ "domain": "shared",
4
+ "displayName": "Workspace Scan",
5
+ "description": "Maps how the workspace's projects relate before pipelines run. Shared APIs, schemas, queues, and build dependencies.",
6
+ "color": "violet",
7
+ "icon": "<path d=\"M4 7h16M4 12h10M4 17h7\" stroke-linecap=\"round\"/><circle cx=\"18\" cy=\"15\" r=\"3\"/><path d=\"M20.2 17.2L22 19\" stroke-linecap=\"round\"/>",
8
+ "agentFile": "worca-cc-workspace-scanner.md",
9
+ "runnerType": "producer",
10
+ "loopSource": false,
11
+ "fanOut": true,
12
+ "produces": ["workspace"],
13
+ "consumes": ["userPrompt"],
14
+ "connectsTo": [],
15
+ "asksQuestions": false,
16
+ "order": 0.5,
17
+ "scope": "workspace-only"
18
+ }
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@worca/app",
3
+ "version": "0.0.1",
4
+ "description": "Worca — deterministic multi-agent pipeline that drives Claude Code (headless) through Plan -> Refine -> Implement -> Review, with a CLI, an installable /worca skill, and a web UI.",
5
+ "license": "MIT",
6
+ "author": "Sinisha Djukic",
7
+ "type": "module",
8
+ "engines": {
9
+ "node": ">=22.13.0"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/SinishaDjukic/worca-cc.git"
14
+ },
15
+ "homepage": "https://github.com/SinishaDjukic/worca-cc#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/SinishaDjukic/worca-cc/issues"
18
+ },
19
+ "keywords": [
20
+ "worca",
21
+ "pipeline",
22
+ "orchestrator",
23
+ "claude-code",
24
+ "ai-agents",
25
+ "autonomous-coding"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "bin": {
31
+ "worca": "src/cli/worca-cc.mjs"
32
+ },
33
+ "files": [
34
+ "src/",
35
+ "ui/server.mjs",
36
+ "ui/public/",
37
+ "agents/",
38
+ "skills/",
39
+ "scripts/install.mjs",
40
+ "README.md"
41
+ ],
42
+ "scripts": {
43
+ "start": "node --disable-warning=ExperimentalWarning ui/server.mjs",
44
+ "cli": "node --disable-warning=ExperimentalWarning src/cli/worca-cc.mjs",
45
+ "install:agents": "node scripts/install.mjs",
46
+ "build:presenter": "node scripts/build-presenter.mjs",
47
+ "smoke": "WORCA_MOCK=1 WORCA_HOME=.worca-cc-smoke node --disable-warning=ExperimentalWarning src/cli/worca-cc.mjs --project sandbox --prompt \"demo task\" --mock --yes",
48
+ "smoke:workspace": "WORCA_MOCK=1 WORCA_HOME=.worca-cc-smoke node --disable-warning=ExperimentalWarning scripts/smoke-workspace.mjs",
49
+ "smoke:plugin": "WORCA_MOCK=1 WORCA_HOME=.worca-cc-smoke node --disable-warning=ExperimentalWarning scripts/smoke-plugin.mjs",
50
+ "test": "rm -rf .worca-cc-test && WORCA_HOME=.worca-cc-test node --disable-warning=ExperimentalWarning --test test/*.mjs"
51
+ },
52
+ "dependencies": {
53
+ "express": "^4.19.2",
54
+ "ws": "^8.18.0"
55
+ },
56
+ "devDependencies": {
57
+ "@fontsource/jetbrains-mono": "^5.2.8",
58
+ "@fontsource/poppins": "^5.2.7",
59
+ "jsdom": "^29.1.1"
60
+ }
61
+ }
@@ -0,0 +1,209 @@
1
+ #!/usr/bin/env node
2
+ // scripts/install.mjs
3
+ //
4
+ // Copy the orchestrator agents and the /worca skill into a target project's
5
+ // .claude directory so that opening Claude Code there lets the user run:
6
+ // /worca <prompt>
7
+ //
8
+ // Usage:
9
+ // node scripts/install.mjs <targetDir> [--force]
10
+ //
11
+ // - agents/*.md -> <targetDir>/.claude/agents/
12
+ // - skills/worca/** -> <targetDir>/.claude/skills/worca/
13
+ //
14
+ // Without --force, existing files are left untouched (and reported as skipped).
15
+ // ESM, no external dependencies.
16
+
17
+ import { readdir, mkdir, copyFile, stat, access, readFile, writeFile } from 'node:fs/promises';
18
+ import { constants as FS } from 'node:fs';
19
+ import { fileURLToPath } from 'node:url';
20
+ import { dirname, resolve, join, relative } from 'node:path';
21
+ import process from 'node:process';
22
+
23
+ const __filename = fileURLToPath(import.meta.url);
24
+ const __dirname = dirname(__filename);
25
+ const REPO_ROOT = resolve(__dirname, '..');
26
+ const AGENTS_SRC = join(REPO_ROOT, 'agents');
27
+ const SKILL_SRC = join(REPO_ROOT, 'skills', 'worca');
28
+
29
+ function parseArgs(argv) {
30
+ const out = { target: null, force: false, help: false };
31
+ for (const arg of argv) {
32
+ if (arg === '--force' || arg === '-f') out.force = true;
33
+ else if (arg === '--help' || arg === '-h') out.help = true;
34
+ else if (!arg.startsWith('-') && !out.target) out.target = arg;
35
+ }
36
+ return out;
37
+ }
38
+
39
+ const HELP = `install — copy orchestrator agents + /worca skill into a project
40
+
41
+ Usage:
42
+ node scripts/install.mjs <targetDir> [--force]
43
+
44
+ Copies:
45
+ agents/*.md -> <targetDir>/.claude/agents/
46
+ skills/worca/** -> <targetDir>/.claude/skills/worca/
47
+
48
+ Options:
49
+ --force, -f Overwrite files that already exist
50
+ --help, -h Show this help
51
+ `;
52
+
53
+ async function exists(p) {
54
+ try {
55
+ await access(p, FS.F_OK);
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Copy a single file, honoring --force. Returns "copied" | "skipped".
64
+ */
65
+ async function copyOne(src, dest, force) {
66
+ await mkdir(dirname(dest), { recursive: true });
67
+ if (!force && (await exists(dest))) {
68
+ return 'skipped';
69
+ }
70
+ await copyFile(src, dest);
71
+ return 'copied';
72
+ }
73
+
74
+ /**
75
+ * Recursively copy a directory tree. Returns counts { copied, skipped }.
76
+ */
77
+ async function copyTree(srcDir, destDir, force) {
78
+ const counts = { copied: 0, skipped: 0 };
79
+ let entries;
80
+ try {
81
+ entries = await readdir(srcDir, { withFileTypes: true });
82
+ } catch {
83
+ return counts;
84
+ }
85
+ for (const ent of entries) {
86
+ const src = join(srcDir, ent.name);
87
+ const dest = join(destDir, ent.name);
88
+ if (ent.isDirectory()) {
89
+ const sub = await copyTree(src, dest, force);
90
+ counts.copied += sub.copied;
91
+ counts.skipped += sub.skipped;
92
+ } else if (ent.isFile()) {
93
+ const r = await copyOne(src, dest, force);
94
+ counts[r] += 1;
95
+ }
96
+ }
97
+ return counts;
98
+ }
99
+
100
+ /**
101
+ * Rewrite the `<WORCA_REPO>` placeholder in the installed SKILL.md to the real
102
+ * absolute path of this orchestrator repo, so /worca works on the target
103
+ * machine without manual editing. Best-effort: never fails the install.
104
+ * @returns {Promise<boolean>} true if the file was rewritten.
105
+ */
106
+ async function rewriteSkillRepoPath(skillDest, repoRoot) {
107
+ const skillMd = join(skillDest, 'SKILL.md');
108
+ try {
109
+ const original = await readFile(skillMd, 'utf8');
110
+ const rewritten = original.split('<WORCA_REPO>').join(repoRoot);
111
+ if (rewritten !== original) {
112
+ await writeFile(skillMd, rewritten, 'utf8');
113
+ return true;
114
+ }
115
+ } catch {
116
+ /* no SKILL.md or unreadable — skip */
117
+ }
118
+ return false;
119
+ }
120
+
121
+ function log(s) {
122
+ process.stdout.write(s + '\n');
123
+ }
124
+
125
+ async function main() {
126
+ const { target, force, help } = parseArgs(process.argv.slice(2));
127
+ if (help) {
128
+ process.stdout.write(HELP);
129
+ return 0;
130
+ }
131
+ if (!target) {
132
+ process.stderr.write('install: missing <targetDir>. See --help.\n');
133
+ return 2;
134
+ }
135
+
136
+ const targetDir = resolve(target);
137
+ if (!(await exists(targetDir))) {
138
+ process.stderr.write(`install: target directory does not exist: ${targetDir}\n`);
139
+ return 2;
140
+ }
141
+ const targetStat = await stat(targetDir);
142
+ if (!targetStat.isDirectory()) {
143
+ process.stderr.write(`install: target is not a directory: ${targetDir}\n`);
144
+ return 2;
145
+ }
146
+
147
+ const claudeDir = join(targetDir, '.claude');
148
+ const agentsDest = join(claudeDir, 'agents');
149
+ const skillDest = join(claudeDir, 'skills', 'worca');
150
+
151
+ log(`Installing worca-cc into: ${targetDir}`);
152
+ if (force) log('(--force: existing files will be overwritten)');
153
+
154
+ // Agents: copy only the *.md files.
155
+ let agentEntries = [];
156
+ try {
157
+ agentEntries = (await readdir(AGENTS_SRC, { withFileTypes: true }))
158
+ .filter((e) => e.isFile() && e.name.endsWith('.md'))
159
+ .map((e) => e.name);
160
+ } catch {
161
+ agentEntries = [];
162
+ }
163
+
164
+ const agentCounts = { copied: 0, skipped: 0 };
165
+ if (agentEntries.length === 0) {
166
+ log(`! No agent markdown files found in ${relative(REPO_ROOT, AGENTS_SRC) || AGENTS_SRC}.`);
167
+ } else {
168
+ await mkdir(agentsDest, { recursive: true });
169
+ for (const name of agentEntries) {
170
+ const r = await copyOne(join(AGENTS_SRC, name), join(agentsDest, name), force);
171
+ agentCounts[r] += 1;
172
+ log(` ${r === 'copied' ? '+' : '='} agents/${name}`);
173
+ }
174
+ }
175
+
176
+ // Skill: copy the whole skills/worca tree.
177
+ let skillCounts = { copied: 0, skipped: 0 };
178
+ if (await exists(SKILL_SRC)) {
179
+ skillCounts = await copyTree(SKILL_SRC, skillDest, force);
180
+ log(` ${skillCounts.copied ? '+' : '='} skills/worca/ (${skillCounts.copied} copied, ${skillCounts.skipped} skipped)`);
181
+ // Personalize the copied skill so /worca targets this repo's real path.
182
+ if (await rewriteSkillRepoPath(skillDest, REPO_ROOT)) {
183
+ log(` ~ skills/worca/SKILL.md (rewrote <WORCA_REPO> -> ${REPO_ROOT})`);
184
+ }
185
+ } else {
186
+ log(`! Skill source not found at ${relative(REPO_ROOT, SKILL_SRC) || SKILL_SRC}.`);
187
+ }
188
+
189
+ log('');
190
+ log(
191
+ `Done. Agents: ${agentCounts.copied} copied / ${agentCounts.skipped} skipped. ` +
192
+ `Skill: ${skillCounts.copied} copied / ${skillCounts.skipped} skipped.`,
193
+ );
194
+ if (!force && (agentCounts.skipped > 0 || skillCounts.skipped > 0)) {
195
+ log('Some files already existed and were skipped. Re-run with --force to overwrite.');
196
+ }
197
+ log('');
198
+ log('Next step: open Claude Code in that project and run:');
199
+ log(' /worca <your task prompt>');
200
+
201
+ return 0;
202
+ }
203
+
204
+ main()
205
+ .then((code) => process.exit(code ?? 0))
206
+ .catch((err) => {
207
+ process.stderr.write(`install: fatal: ${err?.stack || err?.message || err}\n`);
208
+ process.exit(1);
209
+ });
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: worca
3
+ description: Run the deterministic multi-agent orchestrator (Plan -> Refine -> Implement -> Review) over a software task in the current project. Triggers on "/worca", "/worca <prompt>", "/worca --ui", and on requests to orchestrate, run the orchestration pipeline, or drive Claude Code through plan/refine/implement/review for a task.
4
+ ---
5
+
6
+ # Orchestrate
7
+
8
+ Drive the current project through the orchestrator pipeline: **Preflight -> Plan -> Refine (loop) -> Implement -> Review (loop) -> Done**. Orchestration is performed by a deterministic Node.js script; this skill just launches it. Artifacts (plans, reviews, pipeline audit logs) are written under `ai-artifacts/` in the project.
9
+
10
+ The orchestrator repo lives wherever it was installed. `<WORCA_REPO>` below is the absolute path of that repo (the directory containing `src/cli/worca-cc.mjs`). If you installed via `scripts/install.mjs`, the installer rewrites `<WORCA_REPO>` in this file to the real path automatically; otherwise substitute it yourself (or set an `WORCA_REPO` environment variable and use `"$WORCA_REPO"`).
11
+
12
+ ## /worca <prompt> — run the pipeline (default action)
13
+
14
+ When invoked as `/worca <prompt>`, run the CLI with the user's text as the prompt and the user's current project as the working directory:
15
+
16
+ ```bash
17
+ node <WORCA_REPO>/src/cli/worca-cc.mjs --project "$PWD" --prompt "<args>"
18
+ ```
19
+
20
+ - `--project "$PWD"` — operate inside the user's current project (the orchestrator does all file writes here).
21
+ - `--prompt "<args>"` — everything the user typed after `/worca`. Quote it.
22
+ - The CLI streams phase changes and live agent logs to the terminal. When the clarify step needs a decision it shows each question's 2–4 options plus a free-text field; when a refine/review loop hits its cap it shows the open critical/major issues and asks whether to continue or approve another cycle. Answer interactively.
23
+ - On completion it prints the pipeline directory under `ai-artifacts/pipelines/`.
24
+
25
+ Useful flags (pass through when the user asks):
26
+ - `--file <path.md>` — use a markdown file as the prompt instead of `--prompt`.
27
+ - `--title "<name>"` — label the pipeline.
28
+ - `--max-refine <N>` / `--max-review <N>` — change loop caps (default 5 each).
29
+ - `--model <m>` / `--permission-mode <m>` — Claude model / permission mode (default `acceptEdits`).
30
+ - `--mock` — run the full pipeline offline with canned agents (no Claude spawn, no tokens); great for a dry run. Equivalent to setting `WORCA_MOCK=1`.
31
+ - `--yes` / `--non-interactive` — auto-answer (clarify picks the first option; gates choose "continue"). Use for unattended runs.
32
+
33
+ Example:
34
+
35
+ ```bash
36
+ node <WORCA_REPO>/src/cli/worca-cc.mjs \
37
+ --project "$PWD" --prompt "Add rate limiting to the public API"
38
+ ```
39
+
40
+ ## /worca --ui — launch the web UI
41
+
42
+ To start the web app (new-pipeline form, step tracker, live log window, question + loop-gate panels, Stop button, run history):
43
+
44
+ ```bash
45
+ node <WORCA_REPO>/src/cli/worca-cc.mjs --ui
46
+ ```
47
+
48
+ This starts `ui/server.mjs` (Express + WebSocket, default port `4317`; set `PORT` to change). Open the printed URL in a browser. In the UI you pick the project folder to operate in, supply a prompt OR a markdown document (plus optional extra files), optionally toggle mock mode, and Start. The UI also has an "Install agents into this folder" button.
49
+
50
+ ## Installing the agents + skill into another project
51
+
52
+ So a teammate can open Claude Code in their own repo and type `/worca <prompt>`, copy the agents and this skill into that project's `.claude/`:
53
+
54
+ ```bash
55
+ node <WORCA_REPO>/scripts/install.mjs "<targetDir>"
56
+ ```
57
+
58
+ - Copies `agents/*.md` into `<targetDir>/.claude/agents/` and `skills/worca/` into `<targetDir>/.claude/skills/worca/`.
59
+ - Add `--force` to overwrite existing copies.
60
+ - Prints a next-step hint. After installing, open Claude Code in `<targetDir>` and run `/worca <prompt>`.
61
+ - You can also trigger this from the CLI (`--install <targetDir>`) or the UI ("Install agents into this folder").
62
+
63
+ ## Notes
64
+ - The orchestrator auto-initializes a git repo in the target project (initial commit) if none exists, so the reviewer can diff the implementation.
65
+ - Preflight auto-detects `graphify` and `code-review-graph`; if both are present it always uses graphify and tells the agents to ground their work in it.
66
+ - Prefer `--mock` first if you just want to see the pipeline run end-to-end without spending tokens.