legion-cc 0.1.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/LICENSE +21 -0
- package/README.md +269 -0
- package/VERSION +1 -0
- package/agents/legion-orchestrator.md +95 -0
- package/bin/install.js +898 -0
- package/bin/legion-tools.cjs +421 -0
- package/bin/lib/config.cjs +141 -0
- package/bin/lib/core.cjs +216 -0
- package/bin/lib/domain.cjs +107 -0
- package/bin/lib/init.cjs +184 -0
- package/bin/lib/session.cjs +140 -0
- package/bin/lib/state.cjs +280 -0
- package/commands/legion/devops/architect.md +44 -0
- package/commands/legion/devops/build.md +52 -0
- package/commands/legion/devops/cycle.md +52 -0
- package/commands/legion/devops/execute.md +52 -0
- package/commands/legion/devops/plan.md +51 -0
- package/commands/legion/devops/quick.md +45 -0
- package/commands/legion/devops/review.md +52 -0
- package/commands/legion/resume.md +52 -0
- package/commands/legion/status.md +53 -0
- package/hooks/legion-context-monitor.js +180 -0
- package/hooks/legion-statusline.js +191 -0
- package/package.json +48 -0
- package/references/agent-routing.md +64 -0
- package/references/devops/agent-map.md +61 -0
- package/references/devops/pipeline-patterns.md +87 -0
- package/references/domain-registry.md +63 -0
- package/references/ui-brand.md +102 -0
- package/templates/config.json +25 -0
- package/templates/devops/architect-output.md +28 -0
- package/templates/devops/execution-report.md +23 -0
- package/templates/devops/plan-output.md +33 -0
- package/templates/devops/review-checklist.md +35 -0
- package/templates/session.md +17 -0
- package/templates/state.md +17 -0
- package/templates/task-record.md +19 -0
- package/workflows/core/completion.md +70 -0
- package/workflows/core/context-load.md +57 -0
- package/workflows/core/init.md +52 -0
- package/workflows/devops/architect.md +91 -0
- package/workflows/devops/build.md +92 -0
- package/workflows/devops/cycle.md +237 -0
- package/workflows/devops/execute.md +118 -0
- package/workflows/devops/plan.md +108 -0
- package/workflows/devops/quick.md +107 -0
- package/workflows/devops/review.md +112 -0
- package/workflows/resume.md +88 -0
- package/workflows/status.md +72 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: legion:status
|
|
3
|
+
description: "Show current Legion state, active work, task history, and route to next action"
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Glob
|
|
7
|
+
- Grep
|
|
8
|
+
- Bash
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Legion Status
|
|
12
|
+
|
|
13
|
+
Display the current state of Legion across all domains.
|
|
14
|
+
|
|
15
|
+
## Execution
|
|
16
|
+
|
|
17
|
+
Follow the workflow at @~/.claude/legion/workflows/status.md
|
|
18
|
+
|
|
19
|
+
### Process
|
|
20
|
+
|
|
21
|
+
1. Run `node ~/.claude/legion/bin/legion-tools.cjs status`
|
|
22
|
+
2. Read `.planning/legion/STATE.md` if it exists
|
|
23
|
+
3. Display:
|
|
24
|
+
- Current domain and pipeline stage
|
|
25
|
+
- Active work description
|
|
26
|
+
- Recent task history (last 10 entries)
|
|
27
|
+
- Last session info
|
|
28
|
+
4. Route to next action:
|
|
29
|
+
- If pipeline in progress → suggest next stage command
|
|
30
|
+
- If no active work → suggest `/legion:devops:quick` or `/legion:devops:architect`
|
|
31
|
+
- If no Legion state found → suggest initializing with `/legion:devops:build`
|
|
32
|
+
|
|
33
|
+
### Display Format
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
37
|
+
LEGION ► STATUS
|
|
38
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
39
|
+
|
|
40
|
+
Domain: devops
|
|
41
|
+
Stage: plan (waiting)
|
|
42
|
+
Pipeline: architect → [plan] → execute → review
|
|
43
|
+
Last: 001-architect-eks-migration (done)
|
|
44
|
+
Next: /legion:devops:plan
|
|
45
|
+
|
|
46
|
+
─── Task History ───────────────────────────────
|
|
47
|
+
| # | Type | Description | Status |
|
|
48
|
+
|---|------|-------------|--------|
|
|
49
|
+
| 001 | architect | EKS migration design | done |
|
|
50
|
+
|
|
51
|
+
─── Session ────────────────────────────────────
|
|
52
|
+
Last: 2026-02-26 14:30
|
|
53
|
+
```
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Context Monitor — Legion PostToolUse hook
|
|
3
|
+
//
|
|
4
|
+
// Reads context metrics from the statusline bridge file and injects
|
|
5
|
+
// warnings into the agent conversation when context usage is high.
|
|
6
|
+
// The statusline hook writes metrics; this hook reads them after each tool use.
|
|
7
|
+
//
|
|
8
|
+
// How it works:
|
|
9
|
+
// 1. The statusline hook writes /tmp/legion-ctx-{session_id}.json each render
|
|
10
|
+
// 2. This hook reads that file after every tool call
|
|
11
|
+
// 3. When remaining context drops below thresholds, it injects a warning
|
|
12
|
+
// via hookSpecificOutput.additionalContext (the agent sees this in-context)
|
|
13
|
+
//
|
|
14
|
+
// Thresholds:
|
|
15
|
+
// WARNING (remaining <= 35 %): wrap up current task, save state
|
|
16
|
+
// CRITICAL (remaining <= 25 %): stop immediately, save state NOW
|
|
17
|
+
//
|
|
18
|
+
// Debounce: 5 tool calls between repeated warnings at the same severity
|
|
19
|
+
// Severity escalation (WARNING → CRITICAL) bypasses debounce
|
|
20
|
+
//
|
|
21
|
+
// GSD co-existence: if a GSD context monitor already warned this session,
|
|
22
|
+
// Legion skips its own warning to avoid double-flooding the agent context.
|
|
23
|
+
|
|
24
|
+
'use strict';
|
|
25
|
+
|
|
26
|
+
const fs = require('fs');
|
|
27
|
+
const os = require('os');
|
|
28
|
+
const path = require('path');
|
|
29
|
+
|
|
30
|
+
// ─── Thresholds ───────────────────────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
const WARNING_THRESHOLD = 35; // remaining_percentage <= 35 %
|
|
33
|
+
const CRITICAL_THRESHOLD = 25; // remaining_percentage <= 25 %
|
|
34
|
+
const STALE_SECONDS = 60; // ignore bridge files older than 60 s
|
|
35
|
+
const DEBOUNCE_CALLS = 5; // min tool calls between same-level warnings
|
|
36
|
+
|
|
37
|
+
// ─── GSD co-existence check ──────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Return true if GSD context monitor has already written a warning state file
|
|
41
|
+
* for this session. We check whether the GSD warned-state file exists so we
|
|
42
|
+
* don't emit a duplicate warning on top of GSD's own message.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} sessionId
|
|
45
|
+
* @returns {boolean}
|
|
46
|
+
*/
|
|
47
|
+
function gsdAlreadyWarned(sessionId) {
|
|
48
|
+
const tmpDir = os.tmpdir();
|
|
49
|
+
try {
|
|
50
|
+
// GSD writes both claude-ctx-{session}-warned.json (debounce state) and
|
|
51
|
+
// claude-ctx-{session}.json (bridge metrics). If the warned file exists
|
|
52
|
+
// and was updated recently, GSD is active for this session.
|
|
53
|
+
const gsdWarnPath = path.join(tmpDir, `claude-ctx-${sessionId}-warned.json`);
|
|
54
|
+
if (fs.existsSync(gsdWarnPath)) {
|
|
55
|
+
const stat = fs.statSync(gsdWarnPath);
|
|
56
|
+
const ageSeconds = (Date.now() - stat.mtimeMs) / 1000;
|
|
57
|
+
if (ageSeconds < STALE_SECONDS * 2) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} catch (_e) { /* ignore */ }
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
66
|
+
|
|
67
|
+
let input = '';
|
|
68
|
+
process.stdin.setEncoding('utf8');
|
|
69
|
+
process.stdin.on('data', chunk => { input += chunk; });
|
|
70
|
+
process.stdin.on('end', () => {
|
|
71
|
+
try {
|
|
72
|
+
const data = JSON.parse(input);
|
|
73
|
+
const sessionId = data.session_id;
|
|
74
|
+
|
|
75
|
+
if (!sessionId) {
|
|
76
|
+
process.exit(0);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const tmpDir = os.tmpdir();
|
|
80
|
+
const bridgePath = path.join(tmpDir, `legion-ctx-${sessionId}.json`);
|
|
81
|
+
|
|
82
|
+
// No bridge file means the statusline hook hasn't run yet (subagent or
|
|
83
|
+
// fresh session without Legion statusline configured) — exit silently.
|
|
84
|
+
if (!fs.existsSync(bridgePath)) {
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ── Read bridge metrics ───────────────────────────────────────────────────
|
|
89
|
+
let metrics;
|
|
90
|
+
try {
|
|
91
|
+
metrics = JSON.parse(fs.readFileSync(bridgePath, 'utf8'));
|
|
92
|
+
} catch (_e) {
|
|
93
|
+
process.exit(0);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const now = Math.floor(Date.now() / 1000);
|
|
97
|
+
|
|
98
|
+
// Ignore stale bridge data (statusline hook stopped running)
|
|
99
|
+
if (metrics.timestamp && (now - metrics.timestamp) > STALE_SECONDS) {
|
|
100
|
+
process.exit(0);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const remaining = metrics.remaining_percentage;
|
|
104
|
+
const usedPct = metrics.used_pct;
|
|
105
|
+
|
|
106
|
+
// Nothing to warn about
|
|
107
|
+
if (remaining == null || remaining > WARNING_THRESHOLD) {
|
|
108
|
+
process.exit(0);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ── GSD co-existence: skip if GSD already warned ──────────────────────────
|
|
112
|
+
if (gsdAlreadyWarned(sessionId)) {
|
|
113
|
+
process.exit(0);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// ── Debounce ──────────────────────────────────────────────────────────────
|
|
117
|
+
const warnPath = path.join(tmpDir, `legion-ctx-${sessionId}-warned.json`);
|
|
118
|
+
let warnData = { callsSinceWarn: 0, lastLevel: null };
|
|
119
|
+
let firstWarn = true;
|
|
120
|
+
|
|
121
|
+
if (fs.existsSync(warnPath)) {
|
|
122
|
+
try {
|
|
123
|
+
warnData = JSON.parse(fs.readFileSync(warnPath, 'utf8'));
|
|
124
|
+
firstWarn = false;
|
|
125
|
+
} catch (_e) {
|
|
126
|
+
// Corrupted file — reset to defaults (firstWarn stays true)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
warnData.callsSinceWarn = (warnData.callsSinceWarn || 0) + 1;
|
|
131
|
+
|
|
132
|
+
const isCritical = remaining <= CRITICAL_THRESHOLD;
|
|
133
|
+
const currentLevel = isCritical ? 'critical' : 'warning';
|
|
134
|
+
const severityEscalated = currentLevel === 'critical' && warnData.lastLevel === 'warning';
|
|
135
|
+
|
|
136
|
+
// Emit on first warning; then debounce unless severity just escalated
|
|
137
|
+
if (!firstWarn && warnData.callsSinceWarn < DEBOUNCE_CALLS && !severityEscalated) {
|
|
138
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
139
|
+
process.exit(0);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Reset debounce counter and persist level
|
|
143
|
+
warnData.callsSinceWarn = 0;
|
|
144
|
+
warnData.lastLevel = currentLevel;
|
|
145
|
+
fs.writeFileSync(warnPath, JSON.stringify(warnData));
|
|
146
|
+
|
|
147
|
+
// ── Build warning message ─────────────────────────────────────────────────
|
|
148
|
+
const domain = metrics.domain || '';
|
|
149
|
+
const stage = metrics.stage || '';
|
|
150
|
+
const ctxTag = domain && stage ? `[LEGION:${domain}:${stage}] ` : '[LEGION] ';
|
|
151
|
+
|
|
152
|
+
let message;
|
|
153
|
+
if (isCritical) {
|
|
154
|
+
message =
|
|
155
|
+
`${ctxTag}CONTEXT CRITICAL: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
156
|
+
'STOP all new work immediately. Save state NOW and inform the user that ' +
|
|
157
|
+
'context is nearly exhausted. Run /legion:status to snapshot current state ' +
|
|
158
|
+
'and resume in a fresh session with /legion:resume.';
|
|
159
|
+
} else {
|
|
160
|
+
message =
|
|
161
|
+
`${ctxTag}CONTEXT WARNING: Usage at ${usedPct}%. Remaining: ${remaining}%. ` +
|
|
162
|
+
'Begin wrapping up the current task. Do not start new complex work. ' +
|
|
163
|
+
'Run /legion:status to review state, or save progress before context runs out.';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// ── Emit output (Claude Code PostToolUse protocol) ────────────────────────
|
|
167
|
+
const output = {
|
|
168
|
+
hookSpecificOutput: {
|
|
169
|
+
hookEventName: 'PostToolUse',
|
|
170
|
+
additionalContext: message,
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
process.stdout.write(JSON.stringify(output));
|
|
175
|
+
|
|
176
|
+
} catch (_e) {
|
|
177
|
+
// Silent fail — never block tool execution
|
|
178
|
+
process.exit(0);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Claude Code Statusline — Legion Edition
|
|
3
|
+
// Shows: LEGION:{domain}:{stage} | {dir} | ctx {bar} {usage}%
|
|
4
|
+
//
|
|
5
|
+
// How it works:
|
|
6
|
+
// 1. Reads .planning/legion/STATE.md (walks up from cwd) to get domain + stage
|
|
7
|
+
// 2. Reads context_window data from stdin (Claude Code hook protocol)
|
|
8
|
+
// 3. Writes a bridge file /tmp/legion-ctx-{session_id}.json for the
|
|
9
|
+
// context-monitor PostToolUse hook to read agent-facing warnings from
|
|
10
|
+
// 4. Outputs a plain-text statusline to stdout
|
|
11
|
+
|
|
12
|
+
'use strict';
|
|
13
|
+
|
|
14
|
+
const fs = require('fs');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const os = require('os');
|
|
17
|
+
|
|
18
|
+
// ─── STATE.md Parser ─────────────────────────────────────────────────────────
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Walk up the directory tree from `startDir` looking for `.planning/legion/`.
|
|
22
|
+
* Returns the absolute path if found, null otherwise.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} startDir
|
|
25
|
+
* @returns {string|null}
|
|
26
|
+
*/
|
|
27
|
+
function findPlanningDir(startDir) {
|
|
28
|
+
let dir = path.resolve(startDir || process.cwd());
|
|
29
|
+
const root = path.parse(dir).root;
|
|
30
|
+
|
|
31
|
+
while (true) {
|
|
32
|
+
const candidate = path.join(dir, '.planning', 'legion');
|
|
33
|
+
try {
|
|
34
|
+
const stat = fs.statSync(candidate);
|
|
35
|
+
if (stat.isDirectory()) return candidate;
|
|
36
|
+
} catch (_e) { /* not found, keep climbing */ }
|
|
37
|
+
|
|
38
|
+
if (dir === root) return null;
|
|
39
|
+
dir = path.dirname(dir);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Parse the minimal fields we need out of STATE.md.
|
|
45
|
+
* Returns { domain, stage } or null if the file cannot be read.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} planningDir - Absolute path to `.planning/legion/`
|
|
48
|
+
* @returns {{ domain: string, stage: string }|null}
|
|
49
|
+
*/
|
|
50
|
+
function parseState(planningDir) {
|
|
51
|
+
const statePath = path.join(planningDir, 'STATE.md');
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = fs.readFileSync(statePath, 'utf8');
|
|
55
|
+
} catch (_e) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let domain = '';
|
|
60
|
+
let stage = '';
|
|
61
|
+
let section = '';
|
|
62
|
+
|
|
63
|
+
for (const line of raw.split('\n')) {
|
|
64
|
+
if (line.startsWith('## Project')) { section = 'project'; continue; }
|
|
65
|
+
if (line.startsWith('## Current Work')){ section = 'currentWork'; continue; }
|
|
66
|
+
|
|
67
|
+
if (section === 'project') {
|
|
68
|
+
const m = line.match(/^Domain:\s*(.+)$/);
|
|
69
|
+
if (m) domain = m[1].trim();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (section === 'currentWork') {
|
|
73
|
+
const m = line.match(/^Stage:\s*(.+)$/);
|
|
74
|
+
if (m) stage = m[1].trim();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Stop early if we have both values
|
|
78
|
+
if (domain && stage) break;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (!domain && !stage) return null;
|
|
82
|
+
return { domain, stage };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ─── Context bar helper ───────────────────────────────────────────────────────
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Build an ANSI-coloured progress bar string.
|
|
89
|
+
* GSD scaling is preserved: real 80% usage displays as 100%.
|
|
90
|
+
*
|
|
91
|
+
* @param {number} remaining - remaining_percentage from Claude Code
|
|
92
|
+
* @returns {{ bar: string, used: number }}
|
|
93
|
+
*/
|
|
94
|
+
function buildCtxBar(remaining) {
|
|
95
|
+
const rawUsed = Math.max(0, Math.min(100, 100 - remaining));
|
|
96
|
+
// Scale so 80 % real usage == 100 % displayed (matches Claude Code's 80 % limit)
|
|
97
|
+
const used = Math.min(100, Math.round((rawUsed / 80) * 100));
|
|
98
|
+
const filled = Math.floor(used / 10);
|
|
99
|
+
const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(10 - filled);
|
|
100
|
+
|
|
101
|
+
let coloured;
|
|
102
|
+
if (used < 63) { // ~50 % real — green
|
|
103
|
+
coloured = ` \x1b[32m${bar} ${used}%\x1b[0m`;
|
|
104
|
+
} else if (used < 81) { // ~65 % real — yellow
|
|
105
|
+
coloured = ` \x1b[33m${bar} ${used}%\x1b[0m`;
|
|
106
|
+
} else if (used < 95) { // ~76 % real — orange
|
|
107
|
+
coloured = ` \x1b[38;5;208m${bar} ${used}%\x1b[0m`;
|
|
108
|
+
} else { // critical — blinking red skull
|
|
109
|
+
coloured = ` \x1b[5;31m\u{1F480} ${bar} ${used}%\x1b[0m`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return { bar: coloured, used };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
116
|
+
|
|
117
|
+
let input = '';
|
|
118
|
+
process.stdin.setEncoding('utf8');
|
|
119
|
+
process.stdin.on('data', chunk => { input += chunk; });
|
|
120
|
+
process.stdin.on('end', () => {
|
|
121
|
+
try {
|
|
122
|
+
const data = JSON.parse(input);
|
|
123
|
+
const sessionId = data.session_id || '';
|
|
124
|
+
const cwd = (data.workspace && data.workspace.current_dir) || process.cwd();
|
|
125
|
+
const dirName = path.basename(cwd);
|
|
126
|
+
const model = (data.model && data.model.display_name) || 'Claude';
|
|
127
|
+
const remaining = data.context_window && data.context_window.remaining_percentage != null
|
|
128
|
+
? data.context_window.remaining_percentage
|
|
129
|
+
: null;
|
|
130
|
+
|
|
131
|
+
// ── Legion state ──────────────────────────────────────────────────────────
|
|
132
|
+
let domain = '';
|
|
133
|
+
let stage = '';
|
|
134
|
+
|
|
135
|
+
const planningDir = findPlanningDir(cwd);
|
|
136
|
+
if (planningDir) {
|
|
137
|
+
const stateData = parseState(planningDir);
|
|
138
|
+
if (stateData) {
|
|
139
|
+
domain = stateData.domain || '';
|
|
140
|
+
stage = stateData.stage || '';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// ── Context bar & bridge file ─────────────────────────────────────────────
|
|
145
|
+
let ctxBar = '';
|
|
146
|
+
let usedPct = null;
|
|
147
|
+
|
|
148
|
+
if (remaining != null) {
|
|
149
|
+
const { bar, used } = buildCtxBar(remaining);
|
|
150
|
+
ctxBar = bar;
|
|
151
|
+
usedPct = used;
|
|
152
|
+
|
|
153
|
+
// Write bridge file so context-monitor PostToolUse hook can read metrics
|
|
154
|
+
if (sessionId) {
|
|
155
|
+
try {
|
|
156
|
+
const bridgePath = path.join(os.tmpdir(), `legion-ctx-${sessionId}.json`);
|
|
157
|
+
const bridgeData = JSON.stringify({
|
|
158
|
+
session_id: sessionId,
|
|
159
|
+
remaining_percentage: remaining,
|
|
160
|
+
used_pct: usedPct,
|
|
161
|
+
domain,
|
|
162
|
+
stage,
|
|
163
|
+
cwd,
|
|
164
|
+
timestamp: Math.floor(Date.now() / 1000),
|
|
165
|
+
});
|
|
166
|
+
fs.writeFileSync(bridgePath, bridgeData);
|
|
167
|
+
} catch (_e) {
|
|
168
|
+
// Silent fail — bridge is best-effort, don't break statusline
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ── Compose statusline ────────────────────────────────────────────────────
|
|
174
|
+
// Format: LEGION:devops:architect | bt-pay-infra | ctx bar
|
|
175
|
+
// Falls back to: model | dir | ctx bar when no Legion state found
|
|
176
|
+
|
|
177
|
+
let line;
|
|
178
|
+
if (domain && stage) {
|
|
179
|
+
const legionTag = `\x1b[1mLEGION:${domain}:${stage}\x1b[0m`;
|
|
180
|
+
line = `${legionTag} \u2502 \x1b[2m${dirName}\x1b[0m${ctxBar}`;
|
|
181
|
+
} else {
|
|
182
|
+
// No Legion state — show model + dir (same minimal fallback as GSD)
|
|
183
|
+
line = `\x1b[2m${model}\x1b[0m \u2502 \x1b[2m${dirName}\x1b[0m${ctxBar}`;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
process.stdout.write(line);
|
|
187
|
+
|
|
188
|
+
} catch (_e) {
|
|
189
|
+
// Silent fail — never break the statusline
|
|
190
|
+
}
|
|
191
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "legion-cc",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Legion — multi-agent orchestration framework for Claude Code",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "bin/legion-tools.cjs",
|
|
7
|
+
"bin": {
|
|
8
|
+
"legion-cc": "bin/install.js"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"registry": "https://registry.npmjs.org",
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin/",
|
|
16
|
+
"commands/",
|
|
17
|
+
"workflows/",
|
|
18
|
+
"templates/",
|
|
19
|
+
"references/",
|
|
20
|
+
"agents/",
|
|
21
|
+
"hooks/",
|
|
22
|
+
"VERSION",
|
|
23
|
+
"README.md",
|
|
24
|
+
"LICENSE"
|
|
25
|
+
],
|
|
26
|
+
"scripts": {
|
|
27
|
+
"test": "node bin/legion-tools.cjs status",
|
|
28
|
+
"postinstall": "node bin/install.js 2>/dev/null || true"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"claude-code",
|
|
32
|
+
"agents",
|
|
33
|
+
"orchestration",
|
|
34
|
+
"devops",
|
|
35
|
+
"infrastructure",
|
|
36
|
+
"legion"
|
|
37
|
+
],
|
|
38
|
+
"author": "Vladyslav Blackmoore",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "git+https://github.com/vladyslavblackmoore/legion.git"
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18.0.0"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {}
|
|
48
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Legion — Agent Routing Guide
|
|
2
|
+
|
|
3
|
+
## How Agent Routing Works
|
|
4
|
+
|
|
5
|
+
Legion commands invoke specialized agents via the Task tool. Each domain defines a mapping from pipeline stages to agents.
|
|
6
|
+
|
|
7
|
+
## Routing Resolution Order
|
|
8
|
+
|
|
9
|
+
1. **Explicit**: User specifies which command to run (e.g., `/legion:devops:architect`)
|
|
10
|
+
2. **Pipeline**: Previous stage determines next agent (architect → planner → executor)
|
|
11
|
+
3. **Auto-classify**: `/legion:devops:quick` analyzes the task and routes automatically
|
|
12
|
+
|
|
13
|
+
## DevOps Domain Agent Map
|
|
14
|
+
|
|
15
|
+
| Pipeline Stage | Agent Name | subagent_type | Model | File |
|
|
16
|
+
|---------------|------------|---------------|-------|------|
|
|
17
|
+
| architect | devops-architect | devops-architect | opus | ~/.claude/agents/devops-architect.md |
|
|
18
|
+
| plan | delivery-planner | delivery-planner | sonnet | ~/.claude/agents/delivery-planner.md |
|
|
19
|
+
| execute | infra-executor | infra-executor | opus | ~/.claude/agents/infra-executor.md |
|
|
20
|
+
| build | codebase-builder | codebase-builder | opus | ~/.claude/agents/codebase-builder.md |
|
|
21
|
+
| review | devops-architect | devops-architect | sonnet | ~/.claude/agents/devops-architect.md |
|
|
22
|
+
|
|
23
|
+
## Quick Classification Rules
|
|
24
|
+
|
|
25
|
+
For `/legion:devops:quick`, classify tasks by keywords:
|
|
26
|
+
|
|
27
|
+
| Keywords | Route To |
|
|
28
|
+
|----------|----------|
|
|
29
|
+
| design, architect, propose, evaluate, strategy, HA, DR, migration design | architect |
|
|
30
|
+
| plan, decompose, break down, tasks, phases, implementation plan | planner |
|
|
31
|
+
| implement, create, add, write, fix, update, change, terraform, pipeline | executor |
|
|
32
|
+
| scaffold, init, setup, create project, .codebase/ | builder |
|
|
33
|
+
| review, audit, check, validate, security review | reviewer |
|
|
34
|
+
|
|
35
|
+
## Spawning Pattern
|
|
36
|
+
|
|
37
|
+
All agents are spawned with this Task tool pattern:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Task(
|
|
41
|
+
prompt="<legion_context>
|
|
42
|
+
{context + task}
|
|
43
|
+
</legion_context>",
|
|
44
|
+
subagent_type="{agent_name}",
|
|
45
|
+
model="{model}",
|
|
46
|
+
description="{Action}: {short description}"
|
|
47
|
+
)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Agent Prompt Structure
|
|
51
|
+
|
|
52
|
+
Every agent prompt includes:
|
|
53
|
+
1. `## Project Context` — compiled from .codebase/ and .planning/
|
|
54
|
+
2. `## Current State` — from STATE.md
|
|
55
|
+
3. `## Task` — the user's actual request
|
|
56
|
+
4. `## Instructions` — agent-specific directives
|
|
57
|
+
|
|
58
|
+
## Adding Agents to a Domain
|
|
59
|
+
|
|
60
|
+
To add a new agent to the devops domain:
|
|
61
|
+
1. Create agent definition at `~/.claude/agents/{agent-name}.md`
|
|
62
|
+
2. Register in `references/devops/agent-map.md`
|
|
63
|
+
3. Add routing keywords in quick classification
|
|
64
|
+
4. Optionally extend the pipeline in config.json
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# DevOps Domain — Agent Map
|
|
2
|
+
|
|
3
|
+
## Agents
|
|
4
|
+
|
|
5
|
+
### devops-architect
|
|
6
|
+
- **File**: ~/.claude/agents/devops-architect.md
|
|
7
|
+
- **Role**: Senior/Lead DevOps Architect (Principal level, 15+ years)
|
|
8
|
+
- **Used by**: /legion:devops:architect, /legion:devops:review, /legion:devops:cycle
|
|
9
|
+
- **Model**: opus (architect mode), sonnet (review mode)
|
|
10
|
+
- **Capabilities**: Infrastructure design, architecture review, security assessment, technology evaluation, migration planning, DR/HA design
|
|
11
|
+
- **Output**: 9-section format (Task Understanding → Next Action)
|
|
12
|
+
|
|
13
|
+
### delivery-planner
|
|
14
|
+
- **File**: ~/.claude/agents/delivery-planner.md
|
|
15
|
+
- **Role**: Senior Delivery Planner
|
|
16
|
+
- **Used by**: /legion:devops:plan, /legion:devops:cycle
|
|
17
|
+
- **Model**: sonnet
|
|
18
|
+
- **Capabilities**: Work decomposition, phased planning, dependency mapping, risk assessment, task definition with full metadata
|
|
19
|
+
- **Output**: 8-section format (Planning Input → Next Action)
|
|
20
|
+
|
|
21
|
+
### infra-executor
|
|
22
|
+
- **File**: ~/.claude/agents/infra-executor.md
|
|
23
|
+
- **Role**: Elite Infrastructure Execution Specialist
|
|
24
|
+
- **Used by**: /legion:devops:execute, /legion:devops:cycle
|
|
25
|
+
- **Model**: opus
|
|
26
|
+
- **Capabilities**: Terraform implementation, CI/CD changes, Kubernetes configuration, AWS resource management, validation
|
|
27
|
+
- **Output**: 7-section format (Execution Context → Next Step)
|
|
28
|
+
- **Restrictions**: NEVER uses `make apply` or `terraform apply`
|
|
29
|
+
|
|
30
|
+
### codebase-builder
|
|
31
|
+
- **File**: ~/.claude/agents/codebase-builder.md
|
|
32
|
+
- **Role**: Elite Codebase Builder / Senior Software Architect
|
|
33
|
+
- **Used by**: /legion:devops:build
|
|
34
|
+
- **Model**: opus
|
|
35
|
+
- **Capabilities**: Project scaffolding, .codebase/ documentation creation, existing project analysis
|
|
36
|
+
- **Output**: 8-section format (Build Context → Next Action)
|
|
37
|
+
|
|
38
|
+
## Pipeline Flow
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
┌──────────────────────────────────────────────────┐
|
|
42
|
+
│ │
|
|
43
|
+
│ ┌─────────┐ ┌──────┐ ┌─────────┐ ┌──────────┐
|
|
44
|
+
│ │Architect│──►│Planner│──►│Executor │──►│Reviewer │
|
|
45
|
+
│ │ (opus) │ │(sonnet)│ │ (opus) │ │(sonnet) │
|
|
46
|
+
│ └─────────┘ └──────┘ └─────────┘ └──────────┘
|
|
47
|
+
│ │
|
|
48
|
+
│ ┌─────────┐ │
|
|
49
|
+
│ │Builder │ (standalone or before pipeline) │
|
|
50
|
+
│ │ (opus) │ │
|
|
51
|
+
│ └─────────┘ │
|
|
52
|
+
└──────────────────────────────────────────────────┘
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Common Rules (All Agents)
|
|
56
|
+
|
|
57
|
+
1. MCP tools are MANDATORY for all operations
|
|
58
|
+
2. If unsure, say "я не знаю" — never generate random code
|
|
59
|
+
3. `make apply` and `terraform apply` are FORBIDDEN
|
|
60
|
+
4. Always read .codebase/ and .planning/codebase/ before working
|
|
61
|
+
5. Report results using the standard output format
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# DevOps Domain — Pipeline Patterns
|
|
2
|
+
|
|
3
|
+
## Standard Pipeline
|
|
4
|
+
|
|
5
|
+
The default DevOps pipeline follows four stages:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
architect → plan → execute → review
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### When to Use Each Stage
|
|
12
|
+
|
|
13
|
+
| Scenario | Start From |
|
|
14
|
+
|----------|-----------|
|
|
15
|
+
| New infrastructure design | `/legion:devops:architect` |
|
|
16
|
+
| Architecture exists, need plan | `/legion:devops:plan` |
|
|
17
|
+
| Plan exists, need implementation | `/legion:devops:execute` |
|
|
18
|
+
| Changes made, need validation | `/legion:devops:review` |
|
|
19
|
+
| New/existing project needs docs | `/legion:devops:build` |
|
|
20
|
+
| Quick standalone task | `/legion:devops:quick` |
|
|
21
|
+
| Full end-to-end | `/legion:devops:cycle` |
|
|
22
|
+
|
|
23
|
+
## Pipeline Patterns
|
|
24
|
+
|
|
25
|
+
### Pattern 1: Full Cycle
|
|
26
|
+
Best for new, complex infrastructure work.
|
|
27
|
+
```
|
|
28
|
+
/legion:devops:cycle "Add ElastiCache Redis for session management"
|
|
29
|
+
```
|
|
30
|
+
Runs: architect → (checkpoint) → plan → (checkpoint) → execute → review
|
|
31
|
+
|
|
32
|
+
### Pattern 2: Iterative Design
|
|
33
|
+
Best when exploring options.
|
|
34
|
+
```
|
|
35
|
+
/legion:devops:architect "Evaluate options for message queue"
|
|
36
|
+
/legion:devops:architect "Refine: use SQS with DLQ pattern"
|
|
37
|
+
/legion:devops:plan # uses latest architect output
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Pattern 3: Quick Fix
|
|
41
|
+
Best for small, well-understood changes.
|
|
42
|
+
```
|
|
43
|
+
/legion:devops:quick "Add ingress rule for port 8443 to eks-node SG"
|
|
44
|
+
```
|
|
45
|
+
Auto-routes to infra-executor.
|
|
46
|
+
|
|
47
|
+
### Pattern 4: Documentation First
|
|
48
|
+
Best for existing projects without docs.
|
|
49
|
+
```
|
|
50
|
+
/legion:devops:build # create .codebase/ docs
|
|
51
|
+
/legion:devops:architect "migration plan" # now with full context
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Pattern 5: Review-Only
|
|
55
|
+
Best for code review or security audit.
|
|
56
|
+
```
|
|
57
|
+
/legion:devops:review ./aws/modules/rds/
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Artifact Chain
|
|
61
|
+
|
|
62
|
+
Each pipeline stage produces an artifact that feeds the next:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
001-architect-eks-migration.md
|
|
66
|
+
↓ (input to planner)
|
|
67
|
+
002-plan-eks-migration.md
|
|
68
|
+
↓ (input to executor)
|
|
69
|
+
003-execution-eks-migration.md
|
|
70
|
+
↓ (input to reviewer)
|
|
71
|
+
004-review-eks-migration.md
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Checkpoint Behavior
|
|
75
|
+
|
|
76
|
+
Checkpoints pause execution and ask the user:
|
|
77
|
+
- **Approve** — continue to next stage
|
|
78
|
+
- **Revise** — re-run current stage with feedback
|
|
79
|
+
- **Stop** — save state, exit (resume later with `/legion:resume`)
|
|
80
|
+
|
|
81
|
+
Default checkpoints:
|
|
82
|
+
- After architect: ON
|
|
83
|
+
- After plan: ON
|
|
84
|
+
- After execute: OFF
|
|
85
|
+
- After review: OFF
|
|
86
|
+
|
|
87
|
+
Configurable in `.planning/legion/config.json`.
|