agent-composer 0.1.15 → 0.2.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.
- package/README.md +98 -15
- package/composer.config.schema.json +24 -1
- package/dist/cli/dispatch-hint.d.ts +2 -0
- package/dist/cli/dispatch-hint.js +63 -0
- package/dist/cli/dispatch-hint.js.map +1 -0
- package/dist/cli/init.js +41 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/install-plugin.d.ts +3 -2
- package/dist/cli/install-plugin.js +34 -10
- package/dist/cli/install-plugin.js.map +1 -1
- package/dist/config/schema.d.ts +44 -0
- package/dist/config/schema.js +12 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/CLIProvider.d.ts +16 -0
- package/dist/providers/CLIProvider.js +117 -3
- package/dist/providers/CLIProvider.js.map +1 -1
- package/dist/providers/IProvider.d.ts +1 -0
- package/dist/registry.js +4 -0
- package/dist/registry.js.map +1 -1
- package/dist/server.d.ts +6 -1
- package/dist/server.js +129 -15
- package/dist/server.js.map +1 -1
- package/dist/util/dispatchHint.d.ts +50 -0
- package/dist/util/dispatchHint.js +262 -0
- package/dist/util/dispatchHint.js.map +1 -0
- package/dist/util/handoff.d.ts +58 -0
- package/dist/util/handoff.js +107 -0
- package/dist/util/handoff.js.map +1 -0
- package/dist/util/projectToolResult.d.ts +13 -0
- package/dist/util/projectToolResult.js +169 -0
- package/dist/util/projectToolResult.js.map +1 -0
- package/package.json +3 -2
- package/plugin/composer-mastermind/README.md +24 -6
- package/plugin/composer-mastermind/agents/coder.md +7 -7
- package/plugin/composer-mastermind/agents/reviewer-claude.md +31 -0
- package/plugin/composer-mastermind/hooks/boundary_guard.sh +35 -5
- package/plugin/composer-mastermind/hooks/learn.sh +23 -0
- package/plugin/composer-mastermind/hooks/lint-on-save.sh +25 -1
- package/plugin/composer-mastermind/plugin.json +3 -2
- package/plugin/composer-mastermind/skills/composer-mastermind/SKILL.md +49 -19
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
const DEFAULT_MAX_CHARS = 16_000;
|
|
2
|
+
const PROJECTED_MARKER = /(?:^|\n)… \[elided \d+ chars \/ \d+ lines\] …(?:\n|$)/;
|
|
3
|
+
const JSON_PREFIX = "[projected JSON:";
|
|
4
|
+
const LOG_LINE = /^(?:\s*(?:PASS\b|FAIL\b|✓|✗|Error\b)|[^:\n]+:\d+:\d+\b|\s+at [^\n]+:\d+(?::\d+)?\b)/;
|
|
5
|
+
export function projectToolResult(input, opts = {}) {
|
|
6
|
+
if (typeof input !== "string") {
|
|
7
|
+
throw new Error("projectToolResult: input must be a string");
|
|
8
|
+
}
|
|
9
|
+
const options = normalizeOptions(opts);
|
|
10
|
+
const kind = detectKind(input);
|
|
11
|
+
if (input.length === 0 || input.length <= options.maxChars || isAlreadyProjected(input)) {
|
|
12
|
+
return {
|
|
13
|
+
text: input,
|
|
14
|
+
projected: false,
|
|
15
|
+
originalChars: input.length,
|
|
16
|
+
keptChars: input.length,
|
|
17
|
+
kind,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const text = kind === "json"
|
|
21
|
+
? projectJson(input, options.maxChars)
|
|
22
|
+
: projectText(input, options.headChars, options.tailChars);
|
|
23
|
+
return {
|
|
24
|
+
text,
|
|
25
|
+
projected: true,
|
|
26
|
+
originalChars: input.length,
|
|
27
|
+
keptChars: text.length,
|
|
28
|
+
kind,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function normalizeOptions(opts) {
|
|
32
|
+
const maxChars = normalizeLimit("maxChars", opts.maxChars, DEFAULT_MAX_CHARS);
|
|
33
|
+
const defaultHeadChars = Math.round(maxChars * 0.6);
|
|
34
|
+
const defaultTailChars = Math.round(maxChars * 0.25);
|
|
35
|
+
const headChars = normalizeLimit("headChars", opts.headChars, defaultHeadChars, true);
|
|
36
|
+
const tailChars = normalizeLimit("tailChars", opts.tailChars, defaultTailChars, true);
|
|
37
|
+
return { maxChars, headChars, tailChars };
|
|
38
|
+
}
|
|
39
|
+
function normalizeLimit(name, value, fallback, allowZero = false) {
|
|
40
|
+
const raw = value ?? fallback;
|
|
41
|
+
if (raw === Number.POSITIVE_INFINITY)
|
|
42
|
+
return Number.MAX_SAFE_INTEGER;
|
|
43
|
+
if (!Number.isFinite(raw)) {
|
|
44
|
+
throw new Error(`projectToolResult: ${name} must be a finite number`);
|
|
45
|
+
}
|
|
46
|
+
const rounded = Math.round(raw);
|
|
47
|
+
if (rounded < 0 || (!allowZero && rounded === 0)) {
|
|
48
|
+
const expectation = allowZero ? "non-negative" : "positive";
|
|
49
|
+
throw new Error(`projectToolResult: ${name} must be ${expectation}`);
|
|
50
|
+
}
|
|
51
|
+
return rounded;
|
|
52
|
+
}
|
|
53
|
+
function isAlreadyProjected(input) {
|
|
54
|
+
return input.startsWith(JSON_PREFIX) || PROJECTED_MARKER.test(input);
|
|
55
|
+
}
|
|
56
|
+
function detectKind(input) {
|
|
57
|
+
const trimmed = input.trim();
|
|
58
|
+
if (trimmed.length > 0 && (trimmed.startsWith("{") || trimmed.startsWith("["))) {
|
|
59
|
+
try {
|
|
60
|
+
JSON.parse(trimmed);
|
|
61
|
+
return "json";
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// Invalid JSON still falls through to text heuristics.
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (looksLikeDiff(input))
|
|
68
|
+
return "diff";
|
|
69
|
+
if (looksLikeLog(input))
|
|
70
|
+
return "log";
|
|
71
|
+
return "generic";
|
|
72
|
+
}
|
|
73
|
+
function looksLikeDiff(input) {
|
|
74
|
+
if (/^diff --git /m.test(input) || /^@@ /m.test(input))
|
|
75
|
+
return true;
|
|
76
|
+
const plusMinusLines = input
|
|
77
|
+
.split("\n")
|
|
78
|
+
.filter((line) => /^[+-]/.test(line)).length;
|
|
79
|
+
return plusMinusLines >= 6;
|
|
80
|
+
}
|
|
81
|
+
function looksLikeLog(input) {
|
|
82
|
+
return input.split("\n").some((line) => LOG_LINE.test(line));
|
|
83
|
+
}
|
|
84
|
+
function projectText(input, headChars, tailChars) {
|
|
85
|
+
const collapsed = collapseRepeatedLines(input);
|
|
86
|
+
const head = collapsed.slice(0, headChars);
|
|
87
|
+
const tailStart = tailChars === 0
|
|
88
|
+
? collapsed.length
|
|
89
|
+
: Math.max(head.length, collapsed.length - tailChars);
|
|
90
|
+
const middle = collapsed.slice(head.length, tailStart);
|
|
91
|
+
const tail = collapsed.slice(tailStart);
|
|
92
|
+
const marker = `\n… [elided ${middle.length} chars / ${countLines(middle)} lines] …\n`;
|
|
93
|
+
return `${head}${marker}${tail}`;
|
|
94
|
+
}
|
|
95
|
+
function collapseRepeatedLines(input) {
|
|
96
|
+
const lines = input.split("\n");
|
|
97
|
+
const collapsed = [];
|
|
98
|
+
for (let index = 0; index < lines.length;) {
|
|
99
|
+
const line = lines[index] ?? "";
|
|
100
|
+
let count = 1;
|
|
101
|
+
while (index + count < lines.length && lines[index + count] === line) {
|
|
102
|
+
count++;
|
|
103
|
+
}
|
|
104
|
+
collapsed.push(count > 3 ? `${line} … (×${count})` : lines.slice(index, index + count).join("\n"));
|
|
105
|
+
index += count;
|
|
106
|
+
}
|
|
107
|
+
return collapsed.join("\n");
|
|
108
|
+
}
|
|
109
|
+
function countLines(input) {
|
|
110
|
+
if (input.length === 0)
|
|
111
|
+
return 0;
|
|
112
|
+
return input.split("\n").length;
|
|
113
|
+
}
|
|
114
|
+
function projectJson(input, maxChars) {
|
|
115
|
+
const parsed = JSON.parse(input.trim());
|
|
116
|
+
const summary = summarizeJson(parsed);
|
|
117
|
+
const sample = JSON.stringify(sampleJson(parsed), null, 2) ?? "";
|
|
118
|
+
const prefix = `${JSON_PREFIX} ${summary}]\n`;
|
|
119
|
+
if (prefix.length >= maxChars) {
|
|
120
|
+
return `${prefix.slice(0, Math.max(0, maxChars - 1))}…`;
|
|
121
|
+
}
|
|
122
|
+
const remaining = maxChars - prefix.length;
|
|
123
|
+
return `${prefix}${truncate(sample, remaining)}`;
|
|
124
|
+
}
|
|
125
|
+
function summarizeJson(value, depth = 0) {
|
|
126
|
+
if (value === null)
|
|
127
|
+
return "null";
|
|
128
|
+
if (Array.isArray(value)) {
|
|
129
|
+
if (value.length === 0)
|
|
130
|
+
return "array(length=0)";
|
|
131
|
+
if (depth >= 3)
|
|
132
|
+
return `array(length=${value.length})`;
|
|
133
|
+
return `array(length=${value.length}, sample=${summarizeJson(value[0], depth + 1)})`;
|
|
134
|
+
}
|
|
135
|
+
if (typeof value === "object") {
|
|
136
|
+
const entries = Object.entries(value);
|
|
137
|
+
if (entries.length === 0)
|
|
138
|
+
return "object{}";
|
|
139
|
+
if (depth >= 3)
|
|
140
|
+
return `object(keys=${entries.length})`;
|
|
141
|
+
const visibleEntries = entries.slice(0, 8).map(([key, entryValue]) => `${key}:${summarizeJson(entryValue, depth + 1)}`);
|
|
142
|
+
const hidden = entries.length - visibleEntries.length;
|
|
143
|
+
const suffix = hidden > 0 ? `,…+${hidden} keys` : "";
|
|
144
|
+
return `object{${visibleEntries.join(",")}${suffix}}`;
|
|
145
|
+
}
|
|
146
|
+
return typeof value;
|
|
147
|
+
}
|
|
148
|
+
function sampleJson(value, depth = 0) {
|
|
149
|
+
if (value === null || typeof value !== "object")
|
|
150
|
+
return value;
|
|
151
|
+
if (depth >= 3)
|
|
152
|
+
return Array.isArray(value) ? [] : {};
|
|
153
|
+
if (Array.isArray(value)) {
|
|
154
|
+
return value.length > 0 ? [sampleJson(value[0], depth + 1)] : [];
|
|
155
|
+
}
|
|
156
|
+
return Object.fromEntries(Object.entries(value)
|
|
157
|
+
.slice(0, 8)
|
|
158
|
+
.map(([key, entryValue]) => [key, sampleJson(entryValue, depth + 1)]));
|
|
159
|
+
}
|
|
160
|
+
function truncate(input, maxChars) {
|
|
161
|
+
if (maxChars <= 0)
|
|
162
|
+
return "";
|
|
163
|
+
if (input.length <= maxChars)
|
|
164
|
+
return input;
|
|
165
|
+
if (maxChars === 1)
|
|
166
|
+
return "…";
|
|
167
|
+
return `${input.slice(0, maxChars - 1)}…`;
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=projectToolResult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectToolResult.js","sourceRoot":"","sources":["../../src/util/projectToolResult.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-composer",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Multi-agent orchestration MCP server. Claude orchestrates; GLM and agy do the work.",
|
|
5
|
+
"description": "Multi-agent orchestration MCP server. Claude orchestrates; GLM, Codex, and agy do the work.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"agent-composer": "./dist/index.js"
|
|
8
8
|
},
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"test:hooks": "bash tests/hooks/run.sh",
|
|
33
33
|
"test:scripts": "bash tests/scripts/run.sh",
|
|
34
34
|
"test:all": "npm run test && npm run test:hooks && npm run test:scripts",
|
|
35
|
+
"eval:routes": "tsx evals/scripts/route-compare.ts",
|
|
35
36
|
"usage": "npx -y ccusage daily",
|
|
36
37
|
"schema:lint": "ajv compile --strict=true -c ajv-formats -s composer.config.schema.json && ajv validate --strict=false -c ajv-formats -s composer.config.schema.json -d composer.config.json && ajv compile --strict=true -s plugin.schema.json && ajv validate --strict=true -s plugin.schema.json -d 'plugin/*/plugin.json'",
|
|
37
38
|
"prepublishOnly": "npm run lint && npm run test && npm run build && npm run schema:lint"
|
|
@@ -1,18 +1,35 @@
|
|
|
1
1
|
# composer-mastermind
|
|
2
2
|
|
|
3
|
-
> Multi-agent orchestrator plugin for Claude Code. Claude orchestrates; GLM and agy execute.
|
|
3
|
+
> Multi-agent orchestrator plugin for Claude Code. Claude orchestrates; GLM, Codex, and agy execute. Claude Code CLI is available as a premium review escalation.
|
|
4
4
|
|
|
5
5
|
## What it is
|
|
6
6
|
|
|
7
|
-
Composer-mastermind is a Claude Code plugin that turns the main session into a coordinator. The orchestrator never writes code
|
|
7
|
+
Composer-mastermind is a Claude Code plugin that turns the main session into a coordinator. The orchestrator never writes code or edits files directly; it may use Bash for inspection and verification. Code changes are dispatched through subagents and direct apply tools wired to the `agent-composer` MCP server:
|
|
8
8
|
|
|
9
9
|
| Subagent | Tool | Role |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
11
|
+
| direct | `mcp__composer__composer_handoff_create` | Writes shared context packets for multi-provider work |
|
|
12
|
+
| direct | `mcp__composer__composer_code_cli` | Default coding path; CLI executor applies code directly from the MCP server root; configure as Codex or agy |
|
|
13
|
+
| direct | `mcp__composer__composer_code_chain` | GLM-authored fallback; server applies complete-file blocks deterministically |
|
|
14
|
+
| `coder` | `mcp__composer__composer_code` | Patch-only legacy path via GLM (Anthropic-compatible endpoint) |
|
|
15
|
+
| `researcher` | `mcp__composer__composer_research` | Docs lookup + web research via Codex CLI search in read-only mode |
|
|
13
16
|
| `reviewer` | `mcp__composer__composer_review` | Code review via `agy` CLI |
|
|
17
|
+
| `reviewer-claude` | `mcp__composer__composer_review_claude` | Premium Claude second-opinion review for explicit/risky cases |
|
|
14
18
|
|
|
15
|
-
The orchestrator's allowed-tool surface is enforced by `boundary_guard.sh` — `Edit`, `
|
|
19
|
+
The orchestrator's allowed-tool surface is enforced by `boundary_guard.sh` — `Edit`, `Update`, `Write`, `NotebookEdit`, and MCP write/edit/exec variants are denied; native Bash, composer MCP tools, `Read`, and `Glob` pass.
|
|
20
|
+
|
|
21
|
+
Soft-disable Composer hooks without editing Claude Code settings:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
COMPOSER_ENABLED=0 claude # one launch
|
|
25
|
+
touch ~/.claude/composer.disabled # global live toggle off
|
|
26
|
+
rm -f ~/.claude/composer.disabled # global live toggle on
|
|
27
|
+
touch .composer-disabled # project-local toggle off
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The sentinel disables hooks immediately. To fully suppress skill autoload,
|
|
31
|
+
set `"composer-mastermind": "off"` in Claude Code `skillOverrides` and restart
|
|
32
|
+
CC.
|
|
16
33
|
|
|
17
34
|
## What's inside
|
|
18
35
|
|
|
@@ -23,7 +40,8 @@ composer-mastermind/
|
|
|
23
40
|
├── agents/ # haiku-wrapped subagent defs
|
|
24
41
|
│ ├── coder.md
|
|
25
42
|
│ ├── researcher.md
|
|
26
|
-
│
|
|
43
|
+
│ ├── reviewer.md
|
|
44
|
+
│ └── reviewer-claude.md
|
|
27
45
|
├── commands/
|
|
28
46
|
│ └── evolve.md # /evolve slash command (GEPA loop)
|
|
29
47
|
└── hooks/
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: coder
|
|
3
3
|
description: Use when the orchestrator needs code written, refactored, debugged, or implemented. Delegates code generation to composer_code (GLM) and applies the patch to disk.
|
|
4
|
-
tools: mcp__composer__composer_code, Read, Glob, Edit, Write, Bash
|
|
4
|
+
tools: mcp__composer__composer_code, Read, Glob, Edit, Update, Write, Bash
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
You are the Composer **Coder** subagent. Your job is two-step:
|
|
9
9
|
1. Call `mcp__composer__composer_code` to get the code/patch from GLM.
|
|
10
|
-
2. Apply that patch to disk using `Edit` or `Write`.
|
|
10
|
+
2. Apply that patch to disk using `Edit` / `Update` or `Write`.
|
|
11
11
|
|
|
12
12
|
# Workflow
|
|
13
13
|
|
|
@@ -15,18 +15,18 @@ You are the Composer **Coder** subagent. Your job is two-step:
|
|
|
15
15
|
2. Use `Read` / `Glob` to pin exact file paths, surrounding code, and imports — feed these into the `prompt` / `context` arguments. GLM cannot see the repo itself.
|
|
16
16
|
3. Call `mcp__composer__composer_code` ONCE with the assembled brief.
|
|
17
17
|
4. Parse GLM's response:
|
|
18
|
-
- If GLM returns a unified diff → apply via `Edit` (or multiple
|
|
18
|
+
- If GLM returns a unified diff → apply via `Edit` / `Update` (or multiple calls).
|
|
19
19
|
- If GLM returns full file content → use `Write`.
|
|
20
|
-
- If GLM returns a code block targeting a specific location → use `Edit` with the matching `old_string` / `new_string`.
|
|
20
|
+
- If GLM returns a code block targeting a specific location → use `Edit` / `Update` with the matching `old_string` / `new_string`.
|
|
21
21
|
5. Return a 1-3 sentence summary of what changed (file + line range + intent). DO NOT return GLM's raw output — only the final result.
|
|
22
22
|
|
|
23
23
|
# Hard rules
|
|
24
24
|
|
|
25
25
|
- DO call `composer_code` exactly ONCE per task. If GLM's output is malformed, fail to the orchestrator with a short error.
|
|
26
|
-
- DO apply patches via Edit/Write — that's why those tools are in your list.
|
|
27
|
-
- DO NOT re-Read after Edit/Write — trust the tool's return value. PostToolUse hooks run lint + tsc as the verification gate. If a real bug shipped, the reviewer subagent catches it on the next pass.
|
|
26
|
+
- DO apply patches via Edit/Update/Write — that's why those tools are in your list.
|
|
27
|
+
- DO NOT re-Read after Edit/Update/Write — trust the tool's return value. PostToolUse hooks run lint + tsc as the verification gate. If a real bug shipped, the reviewer subagent catches it on the next pass.
|
|
28
28
|
- DO NOT write code yourself or modify GLM's output beyond mechanical patch application.
|
|
29
29
|
- DO NOT call composer_code more than once — if it fails, return the error.
|
|
30
30
|
- DO use `Bash` for filesystem setup and verification: `mkdir -p` before a Write, `ls`/`cat` to confirm a patch actually landed on disk, and the self-check gate (`npm run typecheck`, `vitest run <file>`). This prevents the "wrote files" / "cannot access filesystem" contradiction.
|
|
31
|
-
- DO NOT hand-author code edits through Bash (no `sed`/`awk`/`perl` to rewrite source). Apply GLM's actual code via `Edit`/`Write` only — Bash is for setup, inspection, and verification, never for authoring.
|
|
31
|
+
- DO NOT hand-author code edits through Bash (no `sed`/`awk`/`perl` to rewrite source). Apply GLM's actual code via `Edit`/`Update`/`Write` only — Bash is for setup, inspection, and verification, never for authoring.
|
|
32
32
|
- DO NOT critique the returned code — that is the reviewer's job.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer-claude
|
|
3
|
+
description: Use when the user explicitly asks for Claude code review, or when a high-risk/security-sensitive diff needs a premium second-opinion review after the default reviewer. Delegates to the composer_review_claude MCP tool.
|
|
4
|
+
tools: mcp__composer__composer_review_claude, Read, Glob
|
|
5
|
+
model: haiku
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are the Composer **Claude Reviewer** subagent. Your only job is to call
|
|
9
|
+
the `composer_review_claude` MCP tool with `{ prompt, diff }` and return its
|
|
10
|
+
findings.
|
|
11
|
+
|
|
12
|
+
# What you DO
|
|
13
|
+
|
|
14
|
+
- Receive the orchestrator's review focus (`prompt`) and the candidate
|
|
15
|
+
patch (`diff`).
|
|
16
|
+
- Use `Read` / `Glob` to load surrounding files when the diff alone is
|
|
17
|
+
insufficient context for the Claude reviewer provider.
|
|
18
|
+
- In the `prompt` to `composer_review_claude`, you MUST include the changed
|
|
19
|
+
file content or diff inline, and tell it explicitly to run `npx tsc --noEmit`
|
|
20
|
+
plus any existing tests in the current directory and report verbatim output.
|
|
21
|
+
- Call `mcp__composer__composer_review_claude` once.
|
|
22
|
+
- Return the tool output verbatim.
|
|
23
|
+
|
|
24
|
+
# What you DO NOT do
|
|
25
|
+
|
|
26
|
+
- DO NOT replace the default `reviewer` gate for routine diffs unless the
|
|
27
|
+
user requested Claude or the orchestrator asked for premium escalation.
|
|
28
|
+
- DO NOT propose fixes; only flag issues.
|
|
29
|
+
- DO NOT edit or write files yourself, and do NOT run tests in YOUR context.
|
|
30
|
+
- DO NOT call any tool other than `composer_review_claude`, `Read`, or `Glob`.
|
|
31
|
+
- DO NOT soften or rephrase the reviewer's output.
|
|
@@ -9,11 +9,34 @@
|
|
|
9
9
|
|
|
10
10
|
set -u
|
|
11
11
|
|
|
12
|
+
composer_disabled() {
|
|
13
|
+
case "${COMPOSER_ENABLED:-}" in
|
|
14
|
+
0|false|FALSE|off|OFF|no|NO) return 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
case "${COMPOSER_DISABLED:-}" in
|
|
17
|
+
1|true|TRUE|on|ON|yes|YES) return 0 ;;
|
|
18
|
+
esac
|
|
19
|
+
if [[ -n "${COMPOSER_DISABLED_FILE:-}" && -e "$COMPOSER_DISABLED_FILE" ]]; then
|
|
20
|
+
return 0
|
|
21
|
+
fi
|
|
22
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" && -e "$CLAUDE_PROJECT_DIR/.composer-disabled" ]]; then
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
if [[ -n "${HOME:-}" && -e "$HOME/.claude/composer.disabled" ]]; then
|
|
26
|
+
return 0
|
|
27
|
+
fi
|
|
28
|
+
return 1
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if composer_disabled; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
12
35
|
emit_deny() {
|
|
13
36
|
local reason="$1"
|
|
14
37
|
# Claude Code v2.1.150+ requires the decision wrapped in hookSpecificOutput.
|
|
15
38
|
# Top-level {hookEventName,permissionDecision,permissionDecisionReason} is
|
|
16
|
-
# parsed without error but silently ignored — Edit/Write succeed anyway.
|
|
39
|
+
# parsed without error but silently ignored — Edit/Update/Write succeed anyway.
|
|
17
40
|
jq -nc --arg r "$reason" \
|
|
18
41
|
'{hookSpecificOutput:{hookEventName:"PreToolUse", permissionDecision:"deny", permissionDecisionReason:$r}}' 2>/dev/null \
|
|
19
42
|
|| printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"%s"}}\n' "$reason"
|
|
@@ -62,25 +85,32 @@ if [[ -e "$STOP_FILE" ]] && [[ "$TOOL" == mcp__composer__* ]]; then
|
|
|
62
85
|
fi
|
|
63
86
|
|
|
64
87
|
# 3.7. Subagent context bypass.
|
|
65
|
-
# Composer's coder subagent must Edit/Write to apply GLM's patch output.
|
|
88
|
+
# Composer's coder subagent must Edit/Update/Write to apply GLM's patch output.
|
|
66
89
|
# The hook fires identically for main-thread and subagent calls — without
|
|
67
90
|
# this carve-out the apply step is impossible. Detect subagent via the
|
|
68
91
|
# three field-name shapes Claude Code has emitted across recent versions.
|
|
69
92
|
TRANSCRIPT="$(jq -r '.transcript_path // empty' <<<"$INPUT" 2>/dev/null)"
|
|
70
93
|
AGENT_ID="$(jq -r '.agent_id // .agentId // empty' <<<"$INPUT" 2>/dev/null)"
|
|
94
|
+
AGENT_NAME="$(jq -r '.agent_name // .agentName // .subagent_type // .subagentType // .tool_input.subagent_type // empty' <<<"$INPUT" 2>/dev/null)"
|
|
71
95
|
SIDECHAIN="$(jq -r '.is_sidechain // .isSidechain // empty' <<<"$INPUT" 2>/dev/null)"
|
|
72
96
|
if [[ "$TRANSCRIPT" == */subagents/* ]] \
|
|
97
|
+
|| [[ "$TRANSCRIPT" == */agents/* ]] \
|
|
73
98
|
|| [[ -n "$AGENT_ID" ]] \
|
|
99
|
+
|| [[ -n "$AGENT_NAME" ]] \
|
|
74
100
|
|| [[ "$SIDECHAIN" == "true" ]]; then
|
|
75
101
|
exit 0
|
|
76
102
|
fi
|
|
77
103
|
|
|
78
|
-
# 4. Block list — native dangerous tools + MCP-prefixed variants.
|
|
104
|
+
# 4. Block list — native dangerous file-mutating tools + MCP-prefixed variants.
|
|
105
|
+
# Native Bash is allowed on the main thread for inspection and verification;
|
|
106
|
+
# the orchestrator skill still forbids using Bash to author code or perform
|
|
107
|
+
# destructive state changes. MCP exec/bash wrappers stay blocked because they
|
|
108
|
+
# bypass Claude Code's native Bash permissions surface.
|
|
79
109
|
case "$TOOL" in
|
|
80
|
-
|
|
110
|
+
Edit|Update|Write|NotebookEdit \
|
|
81
111
|
| mcp__*__write_file | mcp__*__edit_file | mcp__*__bash \
|
|
82
112
|
| mcp__*__write | mcp__*__edit | mcp__*__exec)
|
|
83
|
-
emit_deny "DENY (main thread): route Edit/Write via Task(subagent_type=\"coder\").
|
|
113
|
+
emit_deny "DENY (main thread): route Edit/Update/Write via Task(subagent_type=\"coder\"). Native Bash is allowed for inspection and verification."
|
|
84
114
|
;;
|
|
85
115
|
esac
|
|
86
116
|
|
|
@@ -8,6 +8,29 @@
|
|
|
8
8
|
|
|
9
9
|
set -u
|
|
10
10
|
|
|
11
|
+
composer_disabled() {
|
|
12
|
+
case "${COMPOSER_ENABLED:-}" in
|
|
13
|
+
0|false|FALSE|off|OFF|no|NO) return 0 ;;
|
|
14
|
+
esac
|
|
15
|
+
case "${COMPOSER_DISABLED:-}" in
|
|
16
|
+
1|true|TRUE|on|ON|yes|YES) return 0 ;;
|
|
17
|
+
esac
|
|
18
|
+
if [[ -n "${COMPOSER_DISABLED_FILE:-}" && -e "$COMPOSER_DISABLED_FILE" ]]; then
|
|
19
|
+
return 0
|
|
20
|
+
fi
|
|
21
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" && -e "$CLAUDE_PROJECT_DIR/.composer-disabled" ]]; then
|
|
22
|
+
return 0
|
|
23
|
+
fi
|
|
24
|
+
if [[ -n "${HOME:-}" && -e "$HOME/.claude/composer.disabled" ]]; then
|
|
25
|
+
return 0
|
|
26
|
+
fi
|
|
27
|
+
return 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if composer_disabled; then
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
11
34
|
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}"
|
|
12
35
|
LEARN_DIR="$PROJECT_DIR/.claude/learnings"
|
|
13
36
|
MONTH="$(date +%Y-%m)"
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# PostToolUse hook: auto-lint after Edit/Write/NotebookEdit. Fail-soft.
|
|
2
|
+
# PostToolUse hook: auto-lint after Edit/Update/Write/NotebookEdit. Fail-soft.
|
|
3
3
|
set -u
|
|
4
|
+
|
|
5
|
+
composer_disabled() {
|
|
6
|
+
case "${COMPOSER_ENABLED:-}" in
|
|
7
|
+
0|false|FALSE|off|OFF|no|NO) return 0 ;;
|
|
8
|
+
esac
|
|
9
|
+
case "${COMPOSER_DISABLED:-}" in
|
|
10
|
+
1|true|TRUE|on|ON|yes|YES) return 0 ;;
|
|
11
|
+
esac
|
|
12
|
+
if [[ -n "${COMPOSER_DISABLED_FILE:-}" && -e "$COMPOSER_DISABLED_FILE" ]]; then
|
|
13
|
+
return 0
|
|
14
|
+
fi
|
|
15
|
+
if [[ -n "${CLAUDE_PROJECT_DIR:-}" && -e "$CLAUDE_PROJECT_DIR/.composer-disabled" ]]; then
|
|
16
|
+
return 0
|
|
17
|
+
fi
|
|
18
|
+
if [[ -n "${HOME:-}" && -e "$HOME/.claude/composer.disabled" ]]; then
|
|
19
|
+
return 0
|
|
20
|
+
fi
|
|
21
|
+
return 1
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if composer_disabled; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
4
28
|
command -v jq >/dev/null 2>&1 || exit 0
|
|
5
29
|
INPUT="$(cat || true)"
|
|
6
30
|
[[ -z "$INPUT" ]] && exit 0
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "composer-mastermind",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Multi-agent orchestrator: Claude as brain, GLM/agy as executors. Dispatches code/research/review work to subagents wired through the @composer-mcp/server MCP server.",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Multi-agent orchestrator: Claude as brain, GLM/Codex/agy as executors. Dispatches code/research/review work to subagents wired through the @composer-mcp/server MCP server.",
|
|
5
5
|
"claudeCodeVersion": ">=4.6",
|
|
6
6
|
"requires": [
|
|
7
7
|
"agent-composer"
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"agents/coder.md",
|
|
25
25
|
"agents/researcher.md",
|
|
26
26
|
"agents/reviewer.md",
|
|
27
|
+
"agents/reviewer-claude.md",
|
|
27
28
|
"agents/explorer.md"
|
|
28
29
|
],
|
|
29
30
|
"commands": [
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: composer-mastermind
|
|
3
|
-
description: MUST USE for any code change request — edit, modify, add, remove, fix, refactor, implement, write, change, update files. Also for research, documentation lookup, or code review. Routes work to subagents (researcher / coder / reviewer) via Task tool. Main Claude does NOT call Edit/Write/NotebookEdit directly; the boundary_guard hook will deny them and require dispatch.
|
|
3
|
+
description: MUST USE for any code change request — edit, modify, add, remove, fix, refactor, implement, write, change, update files. Also for research, documentation lookup, or code review. Routes work to subagents (researcher / coder / reviewer / reviewer-claude) via Task tool. Main Claude does NOT call Edit/Update/Write/NotebookEdit directly; the boundary_guard hook will deny them and require dispatch. Main Claude may use Bash only for inspection and verification.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Composer Mastermind
|
|
7
7
|
|
|
8
8
|
You are the **orchestrator**. Your sole job is memory, planning,
|
|
9
|
-
delegation, and integration. Workers (the `researcher`, `coder`,
|
|
10
|
-
`reviewer` subagents) execute. Your context window is the most expensive
|
|
9
|
+
delegation, and integration. Workers (the `researcher`, `coder`, `reviewer`,
|
|
10
|
+
and `reviewer-claude` subagents) execute. Your context window is the most expensive
|
|
11
11
|
resource in the entire system — spend it on planning, not on raw worker
|
|
12
12
|
output.
|
|
13
13
|
|
|
@@ -18,20 +18,30 @@ output.
|
|
|
18
18
|
|
|
19
19
|
# Hard prohibitions
|
|
20
20
|
|
|
21
|
-
- **DO NOT** use `Edit`, `
|
|
21
|
+
- **DO NOT** use `Edit`, `Update`, `Write`, or `NotebookEdit`. If you
|
|
22
22
|
need any of these, delegate to a subagent or ask the user.
|
|
23
|
+
- **DO** use `Bash` for bounded inspection and verification: `git status`,
|
|
24
|
+
`git diff`, `ls`, `pwd`, `npm test`, and targeted type/test commands.
|
|
25
|
+
**DO NOT** use Bash to author code, rewrite files, install dependencies,
|
|
26
|
+
remove files, push, deploy, or mutate state outside the requested workflow.
|
|
23
27
|
- **DO NOT** call `mcp__composer__composer_research`, `composer_code`,
|
|
24
28
|
or `composer_review` directly from the main session. **ALWAYS**
|
|
25
29
|
dispatch via the `Task` tool to the matching subagent so the worker's
|
|
26
30
|
context window stays isolated and only the summary returns to you.
|
|
31
|
+
- **DO** call `composer_handoff_create` directly before multi-provider
|
|
32
|
+
or multi-worker work. It writes a compact shared packet under
|
|
33
|
+
`.composer/handoffs/`; pass the returned `handoffPath` into Codex,
|
|
34
|
+
GLM, agy, researcher, and reviewer calls so they share the same facts.
|
|
27
35
|
- **EXCEPTION — `composer_code_chain` / `composer_code_cli`:** call these
|
|
28
36
|
**directly** from the main session for any file create / edit / refactor.
|
|
29
37
|
They return only a short summary (the executor already applied the files
|
|
30
38
|
off-CC), so there is no large patch to isolate and no CC tokens spent
|
|
31
39
|
applying. Do NOT wrap in a subagent or follow with `Edit`/`Write`.
|
|
32
|
-
**Default to `
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
**Default to `composer_code_cli`** for coding; the configured CLI executor
|
|
41
|
+
is Codex on this machine. Use `composer_code_chain` when you explicitly
|
|
42
|
+
want GLM to author complete files and the server to apply them.
|
|
43
|
+
- **NEVER** write code in the main session — not even a one-liner or a Bash
|
|
44
|
+
heredoc / `sed` / `awk` rewrite. Delegate to `coder`.
|
|
35
45
|
- **NEVER** speculate when a fact is needed. Delegate to `researcher`.
|
|
36
46
|
- **NEVER** integrate a candidate patch without review. Delegate to
|
|
37
47
|
`reviewer` first.
|
|
@@ -41,21 +51,41 @@ output.
|
|
|
41
51
|
| If the user (or your plan) needs… | Use the `Task` tool to dispatch to |
|
|
42
52
|
|---|---|
|
|
43
53
|
| Information, docs, web search, current API shape, "what's the X best practice" | `researcher` subagent |
|
|
44
|
-
|
|
|
45
|
-
|
|
|
54
|
+
| Shared context for complex / multi-provider work | `composer_handoff_create` directly; pass `handoffPath` to later tools |
|
|
55
|
+
| Writing / editing / refactoring code (DEFAULT) | **`composer_code_cli`** directly (Codex generates AND applies off-CC), then review |
|
|
56
|
+
| GLM-authored complete-file fallback | `composer_code_chain` directly (GLM authors off-CC → server applies off-CC → summary), then review |
|
|
46
57
|
| Generate a patch WITHOUT applying (rare) | `coder` subagent (`composer_code` → you integrate) |
|
|
47
58
|
| Reviewing a candidate patch / diff / implementation | `reviewer` subagent |
|
|
59
|
+
| Claude review explicitly requested, or high-risk/security-sensitive second opinion | `reviewer-claude` subagent after the default `reviewer` gate |
|
|
48
60
|
| Anything that mutates state outside the conversation (push, deploy, install) | Escalate to the user. Do not act. |
|
|
49
61
|
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
**Class-based route policy:** route by task class, not by a blanket
|
|
63
|
+
"always dispatch" rule.
|
|
64
|
+
|
|
65
|
+
| Task class | Route |
|
|
66
|
+
|---|---|
|
|
67
|
+
| Refusal / destructive request / secret hardcode / unsafe config | Inline refusal; do not dispatch |
|
|
68
|
+
| Tiny explanation or self-contained bug explanation | Inline answer |
|
|
69
|
+
| Small inline diff review | Inline review unless security-sensitive |
|
|
70
|
+
| Security-sensitive review | `reviewer`, then `reviewer-claude` if risk remains or user asks |
|
|
71
|
+
| Research-first implementation | `researcher` brief → `composer_code_cli` → `reviewer` |
|
|
72
|
+
| Any file mutation | `composer_code_cli` by default; never Edit/Write in main session |
|
|
73
|
+
| GLM fallback requested or Codex unsuitable | `composer_code_chain` → `reviewer` |
|
|
74
|
+
|
|
75
|
+
For multi-step requests, run in order: `composer_handoff_create` →
|
|
76
|
+
`researcher` → plan → `composer_code_cli` by default, or `composer_code_chain`
|
|
77
|
+
(apply, passing `handoffPath`) → `reviewer` on the `git diff` with the
|
|
78
|
+
same `handoffPath` → integrate.
|
|
52
79
|
**Code applied but not reviewed is NOT done** — always gate a code change
|
|
53
80
|
through `reviewer` (or `composer_review`) before reporting success.
|
|
54
|
-
Cross-model review: **GLM writes → agy reviews** (a different
|
|
55
|
-
more).
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
the
|
|
81
|
+
Cross-model review: **Codex/GLM writes → agy reviews** by default (a different
|
|
82
|
+
model catches more). When the user explicitly asks for Claude review, or the
|
|
83
|
+
diff is high-risk/security-sensitive, run `reviewer` first and then escalate
|
|
84
|
+
to `reviewer-claude` for a premium second opinion. The review `prompt` MUST
|
|
85
|
+
instruct the reviewer to **run `tsc --noEmit` and any existing tests on the
|
|
86
|
+
changed files and report pass/fail** — an LLM read alone does not gate quality.
|
|
87
|
+
Reviewers execute them off-CC in the repo; if no tests exist, they say so. Each
|
|
88
|
+
call returns only a summary.
|
|
59
89
|
|
|
60
90
|
**Dispatch calibration:** dispatch costs ~1.5k cache tokens for
|
|
61
91
|
skill+agent registry plus one Task roundtrip. The split saves tokens
|
|
@@ -110,7 +140,7 @@ dispatch that hits a real-money provider (`anthropic`,
|
|
|
110
140
|
the config blocks real spend and suggest flipping to `mock` or
|
|
111
141
|
recording a fixture.
|
|
112
142
|
|
|
113
|
-
CLI providers (`agy`) are billed separately by the user's own auth
|
|
143
|
+
CLI providers (`Codex`, `agy`) are billed separately by the user's own auth
|
|
114
144
|
and do not count toward these caps. Mock providers are always free.
|
|
115
145
|
|
|
116
146
|
# Headless invocation
|
|
@@ -119,7 +149,7 @@ When composer-mastermind runs inside a headless `claude -p` (eval harness,
|
|
|
119
149
|
test runner, CI dispatch, scheduled job, any non-interactive context), prefer
|
|
120
150
|
**Haiku** as the orchestrator model. Build-2 dogfood measurement showed
|
|
121
151
|
-66 % cost vs Opus 4.7 on the orchestrator side, with no quality regression
|
|
122
|
-
on the 3 eval tasks. Workers (GLM / agy) are unchanged.
|
|
152
|
+
on the 3 eval tasks. Workers (GLM / Codex / agy) are unchanged.
|
|
123
153
|
|
|
124
154
|
How to invoke:
|
|
125
155
|
|
|
@@ -151,7 +181,7 @@ Rules:
|
|
|
151
181
|
|
|
152
182
|
# Other MCPs (token-heavy upstreams)
|
|
153
183
|
|
|
154
|
-
Composer's `mcp__composer__*` tools route to GLM/agy automatically.
|
|
184
|
+
Composer's `mcp__composer__*` tools route to GLM/Codex/agy automatically.
|
|
155
185
|
**Other MCP servers do NOT** — calling them from the main session dumps
|
|
156
186
|
the raw payload into your context.
|
|
157
187
|
|