azclaude-copilot 0.7.6 → 0.7.7

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 CHANGED
@@ -637,11 +637,11 @@ AZCLAUDE is a lazy-loaded environment of 48 capability modules. It only loads wh
637
637
 
638
638
  ## Verified
639
639
 
640
- 1967 tests. Every template, command, capability, agent, hook, and CLI feature verified.
640
+ 1998 tests. Every template, command, capability, agent, hook, and CLI feature verified.
641
641
 
642
642
  ```bash
643
643
  bash tests/test-features.sh
644
- # Results: 1967 passed, 0 failed, 1967 total
644
+ # Results: 1998 passed, 0 failed, 1998 total
645
645
  ```
646
646
 
647
647
  ---
package/bin/cli.js CHANGED
@@ -6,6 +6,14 @@ const os = require('os');
6
6
  const crypto = require('crypto');
7
7
  const { execSync } = require('child_process');
8
8
 
9
+ // Strip --cli <value> from argv early so it doesn't interfere with positional args
10
+ const cliArgIdx = process.argv.indexOf('--cli');
11
+ let CLI_OVERRIDE = null;
12
+ if (cliArgIdx !== -1 && process.argv[cliArgIdx + 1]) {
13
+ CLI_OVERRIDE = process.argv[cliArgIdx + 1];
14
+ process.argv.splice(cliArgIdx, 2); // remove --cli and its value from argv
15
+ }
16
+
9
17
  const TEMPLATE_DIR = path.join(__dirname, '..', 'templates');
10
18
  const CORE_COMMANDS = ['setup', 'fix', 'add', 'audit', 'test', 'blueprint', 'ship', 'pulse', 'explain', 'snapshot', 'persist'];
11
19
  const EXTENDED_COMMANDS = ['dream', 'refactor', 'doc', 'loop', 'migrate', 'deps', 'find', 'create', 'reflect', 'hookify', 'sentinel', 'clarify', 'spec', 'analyze', 'constitute', 'tasks', 'issues', 'driven', 'mcp', 'verify', 'inoculate', 'ghost-test', 'visualize'];
@@ -73,7 +81,19 @@ const CLI_TABLE = [
73
81
  ];
74
82
 
75
83
  function detectCLI() {
76
- // 0. Env override (for testing / explicit selection)
84
+ // 0. --cli flag override (stripped from argv at top of file)
85
+ if (CLI_OVERRIDE) {
86
+ const v = CLI_OVERRIDE.toLowerCase();
87
+ const forced = CLI_TABLE.find(c =>
88
+ c.name.toLowerCase().replace(/\s/g,'') === v
89
+ || c.exe === v
90
+ || c.cfg === `.${v}`
91
+ );
92
+ if (forced) return forced;
93
+ console.log(` ⚠ Unknown CLI "${CLI_OVERRIDE}". Valid: ${CLI_TABLE.map(c => c.exe).join(', ')}`);
94
+ }
95
+
96
+ // 0a. Env override (for testing / explicit selection)
77
97
  if (process.env.AZCLAUDE_CLI) {
78
98
  const forced = CLI_TABLE.find(c => c.name.toLowerCase().replace(/\s/g,'') === process.env.AZCLAUDE_CLI.toLowerCase());
79
99
  if (forced) return forced;
@@ -116,6 +136,36 @@ function substitutePaths(content, cfg) {
116
136
  return content.replace(/\.claude\//g, `${cfg}/`);
117
137
  }
118
138
 
139
+ // Adapt command frontmatter for non-Claude CLIs.
140
+ // Claude Code: keeps all fields as-is.
141
+ // OpenCode: keeps description, strips Claude-specific fields (allowed-tools, disable-model-invocation, argument-hint).
142
+ // Codex CLI: keeps description, strips Claude-specific fields.
143
+ // Gemini CLI: converts to TOML format (handled separately in installCommandsGemini).
144
+ function adaptCommandContent(content, cliName) {
145
+ if (cliName === 'Claude Code') return content;
146
+
147
+ // Parse frontmatter
148
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
149
+ if (!fmMatch) return content; // no frontmatter, return as-is
150
+
151
+ const fmBlock = fmMatch[1];
152
+ const body = fmMatch[2];
153
+
154
+ // Extract description (may be multi-line with >)
155
+ const descMatch = fmBlock.match(/description:\s*>?\s*\n?([\s\S]*?)(?=\n\w|\n---|\s*$)/);
156
+ const descSimple = fmBlock.match(/description:\s*"?([^"\n]+)"?\s*$/m);
157
+ let description = '';
158
+ if (descMatch) {
159
+ description = descMatch[1].split('\n').map(l => l.trim()).filter(Boolean).join(' ');
160
+ } else if (descSimple) {
161
+ description = descSimple[1].trim();
162
+ }
163
+
164
+ // For OpenCode / Codex: rebuild frontmatter with only supported fields
165
+ const newFm = description ? `---\ndescription: ${description}\n---` : '---\n---';
166
+ return `${newFm}\n${body}`;
167
+ }
168
+
119
169
  // ─── Hook Scripts ─────────────────────────────────────────────────────────────
120
170
 
121
171
  const HOOK_SCRIPTS = ['user-prompt.js', 'stop.js', 'post-tool-use.js', 'pre-tool-use.js', 'visualizer-hook.js'];
@@ -365,7 +415,7 @@ function installCapabilities(projectDir, cfg, full) {
365
415
 
366
416
  // ─── Commands (Skills) ────────────────────────────────────────────────────────
367
417
 
368
- function installCommands(projectDir, cfg) {
418
+ function installCommands(projectDir, cfg, cliName) {
369
419
  const commandsDir = path.join(projectDir, cfg, 'commands');
370
420
  fs.mkdirSync(commandsDir, { recursive: true });
371
421
 
@@ -374,14 +424,19 @@ function installCommands(projectDir, cfg) {
374
424
  const dst = path.join(commandsDir, `${cmd}.md`);
375
425
  if (!fs.existsSync(src)) continue;
376
426
  if (!fs.existsSync(dst)) {
377
- fs.copyFileSync(src, dst);
427
+ let content = fs.readFileSync(src, 'utf8');
428
+ content = substitutePaths(content, cfg);
429
+ content = adaptCommandContent(content, cliName || 'Claude Code');
430
+ fs.writeFileSync(dst, content);
378
431
  ok(`/${cmd} installed`);
379
432
  } else if (forceUpdate) {
380
433
  // --update: overwrite with latest template
381
- const srcContent = fs.readFileSync(src, 'utf8');
434
+ let srcContent = fs.readFileSync(src, 'utf8');
435
+ srcContent = substitutePaths(srcContent, cfg);
436
+ srcContent = adaptCommandContent(srcContent, cliName || 'Claude Code');
382
437
  const dstContent = fs.readFileSync(dst, 'utf8');
383
438
  if (srcContent !== dstContent) {
384
- fs.copyFileSync(src, dst);
439
+ fs.writeFileSync(dst, srcContent);
385
440
  ok(`/${cmd} updated (--update)`);
386
441
  }
387
442
  } else {
@@ -1273,7 +1328,7 @@ if (cli.cfg === '.claude') {
1273
1328
  installGlobalHooks(cli);
1274
1329
  }
1275
1330
  installCapabilities(projectDir, cli.cfg, fullInstall);
1276
- installCommands(projectDir, cli.cfg);
1331
+ installCommands(projectDir, cli.cfg, cli.name);
1277
1332
  installSkills(projectDir, cli.cfg);
1278
1333
  installScripts(projectDir, cli.cfg);
1279
1334
  installVisualizer(projectDir, cli.cfg);
@@ -1401,4 +1456,6 @@ console.log('');
1401
1456
  console.log(' ─────────────────────────────────────────────');
1402
1457
  console.log(' all commands: /help · docs: github.com/haytamAroui/AZ-CLAUDE-COPILOT');
1403
1458
  console.log(' upgrade: npx azclaude-copilot@latest');
1459
+ console.log(' other CLI: npx azclaude-copilot --cli opencode');
1460
+ console.log(' (claude, opencode, gemini, codex, cursor)');
1404
1461
  console.log('════════════════════════════════════════════════\n');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "azclaude-copilot",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
4
4
  "description": "AI coding environment — 40 commands, 10 skills, 15 agents, real-time visualizer, memory, reflexes, evolution. Install: npx azclaude-copilot@latest, then open Claude Code.",
5
5
  "bin": {
6
6
  "azclaude": "bin/cli.js",
@@ -30,6 +30,7 @@ Read these files (skip if absent):
30
30
  - `.claude/memory/decisions.md` — prior architecture choices
31
31
  - `.claude/memory/patterns.md` — established conventions
32
32
  - `.claude/constitution.md` — non-negotiables and required patterns (if present)
33
+ - `capabilities/shared/strategies.md` — load if plan.md has `strategy:` field (dispatch ordering)
33
34
 
34
35
  If no plan.md → run `/blueprint` first.
35
36
  If CLAUDE.md unfilled → run `/setup` with intent from copilot-intent.md first.
@@ -130,7 +131,20 @@ If any two candidates share a written file → dispatch the conflicting one sequ
130
131
  | Standard | Writes to unique files | Parallel with worktree isolation |
131
132
 
132
133
  **Max parallel agents:** 6 (default). Override with `max_parallel` in plan.md frontmatter.
133
- If ready milestones exceed max_parallel → dispatch highest-priority first, queue the rest.
134
+
135
+ **Strategy-based dispatch ordering:**
136
+ Check plan.md frontmatter for `strategy:` field (risk_first, value_first, simple_first, complex_first).
137
+ If present → load `capabilities/shared/strategies.md`, score each ready milestone, sort descending.
138
+ If absent → dispatch by milestone ID order (M2 before M3).
139
+
140
+ ```bash
141
+ grep -m1 "^strategy:" .claude/plan.md 2>/dev/null || echo "no strategy"
142
+ ```
143
+
144
+ Scoring uses each milestone's `Risk:`, `Value:`, and `Complexity:` fields from plan.md.
145
+ If a milestone is missing an attribute, default: Risk=3, Value=3, Complexity=MEDIUM.
146
+
147
+ If ready milestones exceed max_parallel → dispatch highest-scored first, queue the rest.
134
148
 
135
149
  - All done → SHIP
136
150
  - All remaining blocked → BLOCKER RECOVERY
@@ -31,6 +31,7 @@ Load only the files that match the current task. Never load the full list.
31
31
  | shared/ultrathink.md | $ARGUMENTS contains --deep, or command needs extended thinking for complex analysis | ~80 |
32
32
  | shared/context-relay.md | About to spawn a subagent — pass pre-read files to eliminate redundant reads across agent boundaries | ~300 |
33
33
  | shared/toolchain-gate.md | /copilot dispatch, /parallel, agent verify, env-scan — stack detection, verify commands, toolchain bootstrap, 3-tier verification, log protocol | ~500 |
34
+ | shared/strategies.md | /tasks --strategy flag, or orchestrator reading plan.md with strategy: field — milestone dispatch ordering within waves | ~120 |
34
35
 
35
36
  ## Level Builders — load ONE at a time
36
37
  | File | When to load | Tokens |
@@ -23,6 +23,8 @@ Every plan.md must follow this structure exactly. The copilot runner parses it.
23
23
  - Dirs: {top-level directories this milestone owns — e.g. src/auth/, tests/auth/}
24
24
  - Depends: {M-numbers this depends on, or "none"}
25
25
  - Parallel: {yes|no} — yes = safe to run alongside other same-wave milestones
26
+ - Risk: {1-5} — failure cost (5 = highest risk, run first in risk_first strategy)
27
+ - Value: {1-5} — business impact (5 = core feature, run first in value_first strategy)
26
28
  - Commit: {expected commit message}
27
29
 
28
30
  ### M2: {title}
@@ -32,6 +34,8 @@ Every plan.md must follow this structure exactly. The copilot runner parses it.
32
34
  - Dirs: src/users/, tests/users/
33
35
  - Depends: M1
34
36
  - Parallel: yes
37
+ - Risk: {1-5}
38
+ - Value: {1-5}
35
39
  - Commit: ...
36
40
 
37
41
  ## Summary
@@ -51,6 +55,8 @@ Waves: {N} (max parallel in one wave: {N})
51
55
  | `Files:` | Expected file paths to create/modify. Blueprint's estimate — problem-architect refines to `Files Written:`. |
52
56
  | `Parallel: yes` | Orchestrator may dispatch with worktree isolation alongside other Wave N milestones. |
53
57
  | `Parallel: no` | Reasons: touches shared config, schema change, or has runtime dep on sibling milestone. |
58
+ | `Risk: 1-5` | Dispatch priority score. 5 = highest risk (fail fast in `risk_first` strategy). Default: 3. |
59
+ | `Value: 1-5` | Business value score. 5 = highest value (ship first in `value_first` strategy). Default: 3. |
54
60
 
55
61
  ## Status Values
56
62
 
@@ -0,0 +1,90 @@
1
+ ---
2
+ name: dispatch-strategies
3
+ description: >
4
+ Pluggable scoring strategies for milestone dispatch ordering within the same wave.
5
+ Load when: orchestrator reads plan.md with strategy: field set, or /tasks called with --strategy flag.
6
+ NOT loaded by default — only when strategy-based ranking is active.
7
+ tokens: ~120
8
+ ---
9
+
10
+ # Dispatch Strategies
11
+
12
+ Milestones in the same wave have no dependency between them — they CAN run in any order.
13
+ Strategies decide which order is BEST by scoring each milestone on its attributes.
14
+
15
+ ---
16
+
17
+ ## Milestone Attributes (scored by problem-architect or /blueprint)
18
+
19
+ | Attribute | Scale | Meaning |
20
+ |-----------|-------|---------|
21
+ | `Risk: 1-5` | 1 = safe, 5 = likely to fail or cascade | Failure cost. Higher = more dangerous. |
22
+ | `Value: 1-5` | 1 = nice-to-have, 5 = core feature | Business impact. Higher = more important. |
23
+ | `Complexity:` | SIMPLE / MEDIUM / COMPLEX | Effort estimate. Maps to 1 / 2 / 3 for scoring. |
24
+
25
+ If a milestone is missing an attribute, default: Risk=3, Value=3, Complexity=MEDIUM.
26
+
27
+ ---
28
+
29
+ ## Strategies
30
+
31
+ ### risk_first (default for /copilot)
32
+
33
+ ```
34
+ score = Risk × 2 + Complexity_int
35
+ ```
36
+
37
+ Dispatch highest score first. Surfaces dangerous milestones early — fail fast while there's still room to pivot. If M3 has Risk:5 and M4 has Risk:2, run M3 first.
38
+
39
+ ### value_first
40
+
41
+ ```
42
+ score = Value × 2 + (6 - Risk)
43
+ ```
44
+
45
+ Dispatch highest score first. Delivers the most impactful features early. Low-risk, high-value milestones rank highest — ship what matters.
46
+
47
+ ### simple_first
48
+
49
+ ```
50
+ score = (4 - Complexity_int) × 2 + (6 - Risk)
51
+ ```
52
+
53
+ Dispatch highest score first. Clears easy wins, builds momentum, unblocks dependents cheaply. Best for greenfield projects where early confidence matters.
54
+
55
+ ### complex_first
56
+
57
+ ```
58
+ score = Complexity_int × 2 + Risk
59
+ ```
60
+
61
+ Dispatch highest score first. Front-loads the hardest work while energy and context are fresh. Best for late-stage projects where derisking matters most.
62
+
63
+ ---
64
+
65
+ ## How to Set a Strategy
66
+
67
+ **In plan.md frontmatter:**
68
+ ```markdown
69
+ ---
70
+ strategy: risk_first
71
+ ---
72
+ ```
73
+
74
+ **Via /tasks flag:**
75
+ ```
76
+ /tasks --strategy value_first
77
+ ```
78
+
79
+ **Orchestrator behavior:**
80
+ - If plan.md has `strategy:` → use it for all wave dispatch ordering
81
+ - If no `strategy:` field → no scoring, dispatch by milestone ID order (current default)
82
+ - Strategy applies ONLY within a wave — cross-wave ordering is always dependency-driven
83
+
84
+ ---
85
+
86
+ ## Tie-Breaking
87
+
88
+ When two milestones have the same score:
89
+ 1. Higher Risk breaks the tie (surface problems early)
90
+ 2. If still tied, lower milestone ID first (M2 before M3)
@@ -414,6 +414,8 @@ When running inside `/copilot` (detected by: `.claude/copilot-intent.md` exists)
414
414
  - Each milestone = one logical unit of work (1-3 files, one commit)
415
415
  - Include `Depends:` for milestones that require prior work
416
416
  - Include `Files:` with expected paths
417
+ - Include `Risk: 1-5` — failure cost (1=safe, 5=likely to fail or cascade). Score based on: touches shared state? new pattern? external dependency?
418
+ - Include `Value: 1-5` — business impact (1=nice-to-have, 5=core feature). Score based on: user-facing? blocks other features? revenue impact?
417
419
  - Include `Commit:` with conventional commit format
418
420
  - Write `## Summary` with counts at the bottom
419
421
 
@@ -24,6 +24,19 @@ $ARGUMENTS
24
24
 
25
25
  ---
26
26
 
27
+ ## Strategy Detection
28
+
29
+ If `$ARGUMENTS` contains `--strategy`:
30
+ 1. Strip `--strategy {name}` from arguments before processing
31
+ 2. Valid strategies: `risk_first`, `value_first`, `simple_first`, `complex_first`
32
+ 3. Load `capabilities/shared/strategies.md` for scoring formulas
33
+ 4. Apply strategy scoring in Step 4b (after wave grouping, before output)
34
+
35
+ If no `--strategy` flag → check plan.md frontmatter for `strategy:` field.
36
+ If neither → no scoring, display milestones in ID order within each wave (current default).
37
+
38
+ ---
39
+
27
40
  ## Step 1: Find the Source
28
41
 
29
42
  ```bash
@@ -87,6 +100,24 @@ Algorithm:
87
100
 
88
101
  ---
89
102
 
103
+ ## Step 4b: Strategy Scoring (if active)
104
+
105
+ If a strategy was detected (from `--strategy` flag or plan.md `strategy:` field):
106
+
107
+ For each pending milestone, read its `Risk:`, `Value:`, and `Complexity:` fields.
108
+ Map Complexity to integer: SIMPLE=1, MEDIUM=2, COMPLEX=3. Default missing values: Risk=3, Value=3, Complexity=MEDIUM.
109
+
110
+ Apply the scoring formula from `capabilities/shared/strategies.md`:
111
+ - `risk_first`: score = Risk × 2 + Complexity_int
112
+ - `value_first`: score = Value × 2 + (6 - Risk)
113
+ - `simple_first`: score = (4 - Complexity_int) × 2 + (6 - Risk)
114
+ - `complex_first`: score = Complexity_int × 2 + Risk
115
+
116
+ Sort milestones within each wave by score (descending). Ties broken by higher Risk, then lower ID.
117
+ Add a `Score: {N}` column to the output in Step 5.
118
+
119
+ ---
120
+
90
121
  ## Step 5: Output the Task Graph
91
122
 
92
123
  ```
@@ -96,13 +127,13 @@ Source: {file}
96
127
  Total tasks: {N} | Done: {N} | Pending: {N} | Blocked: {N}
97
128
 
98
129
  ── Wave 1 (can start now) ──────────────────────────────────────
99
- ▶ M1 {title} [Files: src/auth/login.ts]
100
- ▶ M2 {title} [Files: src/models/user.ts]
101
- ▶ M3 {title} [Files: tests/auth/]
130
+ ▶ M1 {title} [Files: src/auth/login.ts] {Score: N — if strategy active}
131
+ ▶ M2 {title} [Files: src/models/user.ts] {Score: N — if strategy active}
132
+ ▶ M3 {title} [Files: tests/auth/] {Score: N — if strategy active}
102
133
 
103
134
  ── Wave 2 (after Wave 1) ───────────────────────────────────────
104
- ▶ M4 {title} ←depends M1 [Files: src/api/routes.ts]
105
- ▶ M5 {title} ←depends M2 [Files: src/services/]
135
+ ▶ M4 {title} ←depends M1 [Files: src/api/routes.ts] {Score: N}
136
+ ▶ M5 {title} ←depends M2 [Files: src/services/] {Score: N}
106
137
 
107
138
  ── Wave 3 (after Wave 2) ───────────────────────────────────────
108
139
  ▶ M6 {title} ←depends M4,M5 [Files: src/app.ts]
@@ -126,10 +157,13 @@ Critical path length: {N waves minimum to complete}
126
157
  File collision pairs: {N pairs that cannot run simultaneously}
127
158
  DAG dispatch mode: merge-on-complete (agents unblock dependents immediately)
128
159
 
160
+ Dispatch strategy: {strategy name or "none (ID order)"}
161
+
129
162
  Suggested dispatch order for /copilot:
130
163
  1. Foundation first (shared files: models, schemas) — sequential
131
164
  2. Launch all ready tasks simultaneously (DAG readiness, not wave number)
132
- 3. As each task completes merge check for newly-unblocked → dispatch immediately
165
+ 3. Within each wave, dispatch by strategy score (highest first)
166
+ 4. As each task completes → merge → check for newly-unblocked → dispatch immediately
133
167
  ```
134
168
 
135
169
  ---