azclaude-copilot 0.4.8 → 0.4.10
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
|
@@ -477,11 +477,11 @@ See [SECURITY.md](SECURITY.md) for full details.
|
|
|
477
477
|
|
|
478
478
|
## Verified
|
|
479
479
|
|
|
480
|
-
|
|
480
|
+
1196 tests. Every template, command, capability, agent, hook, and CLI feature verified.
|
|
481
481
|
|
|
482
482
|
```bash
|
|
483
483
|
bash tests/test-features.sh
|
|
484
|
-
# Results:
|
|
484
|
+
# Results: 1196 passed, 0 failed, 1196 total
|
|
485
485
|
```
|
|
486
486
|
|
|
487
487
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "azclaude-copilot",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.10",
|
|
4
4
|
"description": "AI coding environment — 26 commands, 8 skills, 10 agents, memory, reflexes, evolution. Install: npm install -g azclaude-copilot@latest, then in Claude Code: azclaude-copilot setup --full",
|
|
5
5
|
"bin": {
|
|
6
6
|
"azclaude": "bin/cli.js",
|
|
@@ -16,6 +16,26 @@ If `.claude/agents/orchestrator.md` does not exist (fallback — run built-in lo
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
+
## Step 0: Intent Check
|
|
20
|
+
|
|
21
|
+
Check if `.claude/copilot-intent.md` exists:
|
|
22
|
+
```bash
|
|
23
|
+
ls .claude/copilot-intent.md 2>/dev/null && echo "intent=found" || echo "intent=missing"
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
If `intent=missing`:
|
|
27
|
+
```
|
|
28
|
+
⚠ No copilot-intent.md found.
|
|
29
|
+
|
|
30
|
+
Run /dream first to define your product? (recommended — provides test strategy, done criteria, deployment target)
|
|
31
|
+
Or continue inferring intent from CLAUDE.md? (faster, less precise for complex projects)
|
|
32
|
+
|
|
33
|
+
Proceeding without copilot-intent.md — inferring from CLAUDE.md and plan.md.
|
|
34
|
+
```
|
|
35
|
+
Continue to Step 1 either way — do NOT block. Log the absence in goals.md as a note.
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
19
39
|
## Step 1: Read State
|
|
20
40
|
|
|
21
41
|
Read these files (skip any that don't exist):
|
|
@@ -35,7 +35,7 @@ ls .claude/agents/loop-controller.md 2>/dev/null
|
|
|
35
35
|
**If loop-controller.md exists**: delegate evolution work to it via Agent tool:
|
|
36
36
|
```
|
|
37
37
|
Run a full evolution cycle: re-derivation check, then Cycle 1 (detect/generate/evaluate),
|
|
38
|
-
Cycle 2 (knowledge consolidation if
|
|
38
|
+
Cycle 2 (knowledge consolidation if 2+ sessions), Cycle 3 (topology if friction detected).
|
|
39
39
|
Show the full cycle report when done.
|
|
40
40
|
```
|
|
41
41
|
**After loop-controller finishes**: continue to Step 7 (Generate Project-Specific Skills and Agents).
|
|
@@ -30,13 +30,8 @@ ls .claude/agents/security-auditor.md 2>/dev/null && echo "agent=found" || echo
|
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
If `agent=found`:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
Task: Full security scan — all 5 categories, 102 rules
|
|
36
|
-
Scope: $ARGUMENTS (default: --all)
|
|
37
|
-
Return: Security Report in standard format
|
|
38
|
-
```
|
|
39
|
-
Display the returned Security Report and **ExitPlanMode**. Done — do not run layers below.
|
|
33
|
+
Read `.claude/agents/security-auditor.md` and execute the full scan inline using the agent's instructions and rule set. This gives the full 102-rule scan without requiring a subprocess.
|
|
34
|
+
Display the Security Report and **ExitPlanMode**. Done — do not run layers below.
|
|
40
35
|
|
|
41
36
|
If `agent=missing`: continue with manual layers below.
|
|
42
37
|
|
|
@@ -63,7 +58,12 @@ Check if hooks were modified outside of AZCLAUDE.
|
|
|
63
58
|
|
|
64
59
|
```bash
|
|
65
60
|
INTEGRITY="$HOME/.claude/.azclaude-integrity"
|
|
66
|
-
|
|
61
|
+
# Windows stores settings at %APPDATA%\Claude\settings.json, Unix/Mac at ~/.claude/settings.json
|
|
62
|
+
if [ -n "$APPDATA" ]; then
|
|
63
|
+
SETTINGS="$APPDATA/Claude/settings.json"
|
|
64
|
+
else
|
|
65
|
+
SETTINGS="$HOME/.claude/settings.json"
|
|
66
|
+
fi
|
|
67
67
|
[ -f "$INTEGRITY" ] && echo "integrity_file=found" || echo "integrity_file=missing"
|
|
68
68
|
[ -f "$SETTINGS" ] && echo "settings_file=found" || echo "settings_file=missing"
|
|
69
69
|
```
|
|
@@ -77,6 +77,8 @@ Compute SHA-256 of the `hooks` key in settings.json and compare.
|
|
|
77
77
|
- Mismatch → +0 pts — **BLOCK** "Hook integrity mismatch — hooks modified outside AZCLAUDE"
|
|
78
78
|
- Missing integrity file → +15 pts — "No integrity baseline (run `npx azclaude install` to establish one)"
|
|
79
79
|
|
|
80
|
+
Note: AZCLAUDE registers hooks in `.claude/settings.local.json` (project-level), not `~/.claude/settings.json` (global). The integrity baseline must be computed against `settings.local.json` — comparing against global settings will always produce a hash mismatch (MEDIUM finding).
|
|
81
|
+
|
|
80
82
|
Check each hook script for dangerous patterns:
|
|
81
83
|
```bash
|
|
82
84
|
ls .claude/hooks/ 2>/dev/null || ls "$HOME/.claude/hooks/" 2>/dev/null
|
|
@@ -95,7 +97,10 @@ For each `.js` / `.sh` hook found, flag:
|
|
|
95
97
|
Check Claude Code settings for over-permissioned configurations.
|
|
96
98
|
|
|
97
99
|
```bash
|
|
98
|
-
|
|
100
|
+
# Windows: %APPDATA%\Claude\settings.json — Unix/Mac: ~/.claude/settings.json
|
|
101
|
+
SETTINGS="${APPDATA:+$APPDATA/Claude/settings.json}"
|
|
102
|
+
SETTINGS="${SETTINGS:-$HOME/.claude/settings.json}"
|
|
103
|
+
cat "$SETTINGS" 2>/dev/null | head -80
|
|
99
104
|
cat .claude/settings.local.json 2>/dev/null
|
|
100
105
|
```
|
|
101
106
|
|
|
@@ -116,7 +121,10 @@ Score: start at 20, subtract per finding: HIGH −8, MEDIUM −3, LOW −1 (floo
|
|
|
116
121
|
|
|
117
122
|
```bash
|
|
118
123
|
cat .mcp.json 2>/dev/null
|
|
119
|
-
|
|
124
|
+
# Windows: %APPDATA%\Claude\mcp.json — Unix/Mac: ~/.claude/mcp.json
|
|
125
|
+
MCP_GLOBAL="${APPDATA:+$APPDATA/Claude/mcp.json}"
|
|
126
|
+
MCP_GLOBAL="${MCP_GLOBAL:-$HOME/.claude/mcp.json}"
|
|
127
|
+
cat "$MCP_GLOBAL" 2>/dev/null
|
|
120
128
|
```
|
|
121
129
|
|
|
122
130
|
For each MCP server entry, check:
|
|
@@ -178,6 +186,10 @@ Also scan for:
|
|
|
178
186
|
- `sk_live_` (Stripe secret), `SG\.` (SendGrid)
|
|
179
187
|
- `-----BEGIN.*PRIVATE KEY` (private keys)
|
|
180
188
|
|
|
189
|
+
**IMPORTANT — Secret redaction in output:** Never print full secret values in the report.
|
|
190
|
+
Always truncate: show first 8 chars + `...` + last 3 chars. Example: `AIzaSyCM...VNM`.
|
|
191
|
+
The report may be logged, shared, or appear in conversation transcripts.
|
|
192
|
+
|
|
181
193
|
If `.env` exists: check it is in `.gitignore`:
|
|
182
194
|
```bash
|
|
183
195
|
grep -q "\.env" .gitignore 2>/dev/null && echo ".env gitignored: yes" || echo ".env gitignored: NO"
|
|
@@ -41,7 +41,7 @@ If problem-architect not installed OR git diff is only docs/config: skip and pro
|
|
|
41
41
|
```bash
|
|
42
42
|
ls .claude/agents/security-auditor.md 2>/dev/null && echo "agent=found" || echo "agent=missing"
|
|
43
43
|
```
|
|
44
|
-
If `agent=found`:
|
|
44
|
+
If `agent=found`: read `.claude/agents/security-auditor.md` and execute the secrets scan inline using its rules. If verdict is `BLOCKED` → STOP.
|
|
45
45
|
```
|
|
46
46
|
✗ Pre-ship blocked: security-auditor found BLOCKED findings. Run /sentinel for details.
|
|
47
47
|
```
|
|
@@ -221,3 +221,26 @@ try { fs.writeFileSync(counterPath, String(editCount)); } catch (_) {}
|
|
|
221
221
|
if (editCount > 0 && editCount % 15 === 0) {
|
|
222
222
|
process.stdout.write(`\n⚠ ${editCount} edits this session — run /snapshot before context compaction loses your reasoning\n`);
|
|
223
223
|
}
|
|
224
|
+
|
|
225
|
+
// ── Rapid-edit detection — same file edited 5+ times in <5 min ───────────────
|
|
226
|
+
// Signal: unclear spec before coding. Warn once, suggest /blueprint.
|
|
227
|
+
if (isFileTool && rel) {
|
|
228
|
+
const rapidPath = path.join(os.tmpdir(), `.azclaude-rapid-${process.ppid || process.pid}`);
|
|
229
|
+
let rapidLog = {};
|
|
230
|
+
try { rapidLog = JSON.parse(fs.readFileSync(rapidPath, 'utf8')); } catch (_) {}
|
|
231
|
+
const fileLog = rapidLog[rel] || { count: 0, firstTs: Date.now(), warned: false };
|
|
232
|
+
const elapsed = Date.now() - fileLog.firstTs;
|
|
233
|
+
if (elapsed > 5 * 60 * 1000) {
|
|
234
|
+
// Reset window
|
|
235
|
+
rapidLog[rel] = { count: 1, firstTs: Date.now(), warned: false };
|
|
236
|
+
} else {
|
|
237
|
+
fileLog.count += 1;
|
|
238
|
+
if (fileLog.count >= 5 && !fileLog.warned) {
|
|
239
|
+
fileLog.warned = true;
|
|
240
|
+
const shortName = path.basename(rel);
|
|
241
|
+
process.stdout.write(`\n⚠ ${fileLog.count} edits to ${shortName} in ${Math.round(elapsed/60000)}min — unclear spec? Consider /blueprint before continuing\n`);
|
|
242
|
+
}
|
|
243
|
+
rapidLog[rel] = fileLog;
|
|
244
|
+
}
|
|
245
|
+
try { fs.writeFileSync(rapidPath, JSON.stringify(rapidLog)); } catch (_) {}
|
|
246
|
+
}
|