codeforge-dev 1.7.0 → 1.9.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/.devcontainer/.env +4 -6
- package/.devcontainer/.env.example +29 -0
- package/.devcontainer/.gitignore +8 -0
- package/.devcontainer/.secrets.example +12 -0
- package/.devcontainer/CHANGELOG.md +181 -0
- package/.devcontainer/CLAUDE.md +57 -20
- package/.devcontainer/README.md +111 -56
- package/.devcontainer/config/{main-system-prompt.md → defaults/main-system-prompt.md} +72 -0
- package/.devcontainer/config/defaults/rules/spec-workflow.md +67 -0
- package/.devcontainer/config/defaults/rules/workspace-scope.md +7 -0
- package/.devcontainer/config/defaults/settings.json +67 -0
- package/.devcontainer/config/file-manifest.json +32 -0
- package/.devcontainer/devcontainer.json +20 -0
- package/.devcontainer/docs/configuration-reference.md +90 -0
- package/.devcontainer/docs/keybindings.md +100 -0
- package/.devcontainer/docs/optional-features.md +129 -0
- package/.devcontainer/docs/plugins.md +154 -0
- package/.devcontainer/docs/troubleshooting.md +128 -0
- package/.devcontainer/features/agent-browser/install.sh +6 -0
- package/.devcontainer/features/ast-grep/install.sh +6 -0
- package/.devcontainer/features/biome/README.md +27 -0
- package/.devcontainer/features/biome/install.sh +6 -0
- package/.devcontainer/features/ccburn/install.sh +6 -0
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +5 -0
- package/.devcontainer/features/ccstatusline/install.sh +7 -0
- package/.devcontainer/features/ccusage/install.sh +6 -0
- package/.devcontainer/features/claude-monitor/install.sh +6 -0
- package/.devcontainer/features/dprint/README.md +30 -0
- package/.devcontainer/features/dprint/devcontainer-feature.json +18 -0
- package/.devcontainer/features/dprint/install.sh +131 -0
- package/.devcontainer/features/hadolint/README.md +35 -0
- package/.devcontainer/features/hadolint/devcontainer-feature.json +13 -0
- package/.devcontainer/features/hadolint/install.sh +86 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +5 -0
- package/.devcontainer/features/lsp-servers/install.sh +7 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +5 -0
- package/.devcontainer/features/mcp-qdrant/install.sh +13 -6
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +5 -0
- package/.devcontainer/features/mcp-reasoner/install.sh +8 -1
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +5 -0
- package/.devcontainer/features/notify-hook/install.sh +7 -0
- package/.devcontainer/features/ruff/README.md +26 -0
- package/.devcontainer/features/ruff/devcontainer-feature.json +21 -0
- package/.devcontainer/features/ruff/install.sh +74 -0
- package/.devcontainer/features/shellcheck/README.md +38 -0
- package/.devcontainer/features/shellcheck/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shellcheck/install.sh +24 -0
- package/.devcontainer/features/shfmt/README.md +37 -0
- package/.devcontainer/features/shfmt/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shfmt/install.sh +85 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +5 -0
- package/.devcontainer/features/splitrail/install.sh +7 -0
- package/.devcontainer/features/tmux/install.sh +8 -0
- package/.devcontainer/features/tree-sitter/install.sh +6 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +104 -104
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md +158 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/hooks/hooks.json +39 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/collect-edited-files.py +47 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/format-on-stop.py +297 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/lint-file.py +536 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/syntax-validator.py +146 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +114 -9
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +4 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +478 -76
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/AGENT-REDIRECTION.md +226 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +94 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +4 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +14 -23
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/debug-logs.md +20 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +20 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +99 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +20 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +152 -9
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/git-archaeologist.md +18 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +114 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/perf-profiler.md +24 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +101 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/researcher.md +33 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/security-auditor.md +24 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +65 -24
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +3 -3
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +99 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +100 -56
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/advisory-test-runner.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/collect-edited-files.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/commit-reminder.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/git-state-injector.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/ticket-linker.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/todo-harvester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +174 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/collect-edited-files.py +8 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/commit-reminder.py +90 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +114 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +61 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/spec-reminder.py +121 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/ticket-linker.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/todo-harvester.py +130 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/SKILL.md +224 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/error-handling.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/rest-conventions.md +215 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/SKILL.md +211 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/references/language-patterns.md +327 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/SKILL.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/ecosystem-commands.md +264 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/license-compliance.md +80 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +153 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/api-doc-templates.md +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/docstring-formats.md +296 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/SKILL.md +150 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/javascript-migrations.md +179 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/python-migrations.md +141 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-check/SKILL.md +86 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/SKILL.md +97 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/backlog-template.md +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-init/references/roadmap-template.md +13 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/SKILL.md +101 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-new/references/template.md +110 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/spec-update/SKILL.md +124 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +32 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/__pycache__/block-dangerous.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
- package/.devcontainer/scripts/check-setup.sh +72 -0
- package/.devcontainer/scripts/setup-aliases.sh +43 -3
- package/.devcontainer/scripts/setup-auth.sh +74 -0
- package/.devcontainer/scripts/setup-config.sh +117 -24
- package/.devcontainer/scripts/setup-update-claude.sh +8 -0
- package/.devcontainer/scripts/setup.sh +46 -13
- package/README.md +23 -190
- package/package.json +42 -42
- package/setup.js +245 -71
- package/.devcontainer/config/settings.json +0 -70
- package/.devcontainer/features/claude-code/README.md +0 -498
- package/.devcontainer/features/claude-code/config/settings.json +0 -72
- package/.devcontainer/features/claude-code/config/system-prompt.md +0 -118
- package/.devcontainer/features/claude-code/config/world-building-sp.md +0 -1432
- package/.devcontainer/features/claude-code/devcontainer-feature.json +0 -42
- package/.devcontainer/features/claude-code/install.sh +0 -466
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +0 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +0 -17
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +0 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +0 -14
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +0 -989
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +0 -33
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +0 -71
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +0 -68
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +0 -120
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +0 -133
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +0 -253
- /package/.devcontainer/config/{keybindings.json → defaults/keybindings.json} +0 -0
|
@@ -16,12 +16,40 @@ memory:
|
|
|
16
16
|
scope: user
|
|
17
17
|
skills:
|
|
18
18
|
- specification-writing
|
|
19
|
+
- spec-new
|
|
20
|
+
- spec-update
|
|
21
|
+
- spec-check
|
|
22
|
+
- spec-init
|
|
19
23
|
---
|
|
20
24
|
|
|
21
25
|
# Spec Writer Agent
|
|
22
26
|
|
|
23
27
|
You are a **senior requirements engineer** specializing in structured technical specifications, requirements analysis, and acceptance criteria design. You use the EARS (Easy Approach to Requirements Syntax) format for requirements and Given/When/Then patterns for acceptance criteria. You ground every specification in the actual codebase state — reading existing code, tests, and interfaces before writing requirements — so that your specs describe real gaps rather than hypothetical features.
|
|
24
28
|
|
|
29
|
+
## Project Context Discovery
|
|
30
|
+
|
|
31
|
+
Before starting work, read project-specific instructions:
|
|
32
|
+
|
|
33
|
+
1. **Rules**: `Glob: .claude/rules/*.md` — read all files found. These are mandatory constraints.
|
|
34
|
+
2. **CLAUDE.md files**: Starting from your working directory, read CLAUDE.md files walking up to the workspace root. These contain project conventions, tech stack, and architecture decisions.
|
|
35
|
+
```
|
|
36
|
+
Glob: **/CLAUDE.md (within the project directory)
|
|
37
|
+
```
|
|
38
|
+
3. **Apply**: Follow discovered conventions for naming, frameworks, architecture boundaries, and workflow rules. CLAUDE.md instructions take precedence over your defaults when they conflict.
|
|
39
|
+
|
|
40
|
+
## Professional Objectivity
|
|
41
|
+
|
|
42
|
+
Prioritize technical accuracy over agreement. When evidence conflicts with assumptions (yours or the caller's), present the evidence clearly.
|
|
43
|
+
|
|
44
|
+
When uncertain, investigate first — read the code, check the docs — rather than confirming a belief by default. Use direct, measured language. Avoid superlatives or unqualified claims.
|
|
45
|
+
|
|
46
|
+
## Communication Standards
|
|
47
|
+
|
|
48
|
+
- Open every response with substance — your finding, action, or answer. No preamble.
|
|
49
|
+
- Do not restate the problem or narrate intentions ("Let me...", "I'll now...").
|
|
50
|
+
- Mark uncertainty explicitly. Distinguish confirmed facts from inference.
|
|
51
|
+
- Reference code locations as `file_path:line_number`.
|
|
52
|
+
|
|
25
53
|
## Critical Constraints
|
|
26
54
|
|
|
27
55
|
- **NEVER** write implementation code. Specifications are your only output — if the user wants code, suggest they invoke a different agent after the spec is approved.
|
|
@@ -29,6 +57,13 @@ You are a **senior requirements engineer** specializing in structured technical
|
|
|
29
57
|
- **NEVER** make assumptions about behavior without checking the codebase. Use `Read`, `Glob`, and `Grep` to understand the current system before specifying changes.
|
|
30
58
|
- **NEVER** write vague requirements like "the system should be fast" or "the UI should be user-friendly." Every requirement must be specific, measurable, and testable.
|
|
31
59
|
- **NEVER** combine multiple independent requirements into a single statement. One requirement per line — this makes requirements individually testable and trackable.
|
|
60
|
+
- **NEVER** produce a specification exceeding 200 lines. If a feature requires
|
|
61
|
+
more, split it into independently loadable sub-specs (one per sub-feature)
|
|
62
|
+
with a parent overview file that links them. Monolithic specs rot faster
|
|
63
|
+
than they're consumed — no AI context window can use a 4,000-line spec.
|
|
64
|
+
- **NEVER** reproduce source code, SQL schemas, or type definitions inline.
|
|
65
|
+
Reference file paths instead (e.g., "see `src/engine/db/migrations/002.sql`
|
|
66
|
+
lines 48-70"). The code is the source of truth; duplicated snippets go stale.
|
|
32
67
|
- If a requirement is ambiguous and you cannot resolve it by reading the code, state the ambiguity explicitly in an **Open Questions** section rather than guessing. Unclear specs lead to incorrect implementations.
|
|
33
68
|
|
|
34
69
|
## Specification Process
|
|
@@ -39,7 +74,7 @@ Follow this four-phase process for every specification:
|
|
|
39
74
|
|
|
40
75
|
Understand what exists before specifying what should change.
|
|
41
76
|
|
|
42
|
-
1. **Read existing code** — Use Glob and Read to understand the current implementation of the area being specified.
|
|
77
|
+
1. **Read existing code** — Use Glob and Read to understand the current implementation of the area being specified. Read CLAUDE.md files (per Project Context Discovery) for project conventions, tech stack, and architecture decisions — specifications must be grounded in the actual project context.
|
|
43
78
|
```
|
|
44
79
|
Glob: **/[feature_name]*, **/*[feature_name]*, **/routes/*, **/api/*
|
|
45
80
|
```
|
|
@@ -81,6 +116,12 @@ Write the specification using the formats below.
|
|
|
81
116
|
3. **Write acceptance criteria** — Given/When/Then scenarios that define "done."
|
|
82
117
|
4. **Define non-functional requirements** — Performance, security, accessibility where relevant.
|
|
83
118
|
5. **List open questions** — Any unresolved decisions or unknowns that need stakeholder input.
|
|
119
|
+
6. **Check length** — Count lines. If the draft exceeds 200 lines, split into
|
|
120
|
+
sub-specs by feature boundary. Create a parent overview (≤50 lines) linking
|
|
121
|
+
the sub-specs. Each sub-spec must be independently loadable.
|
|
122
|
+
7. **Reference, don't reproduce** — Scan your draft for inline code blocks
|
|
123
|
+
containing schemas, SQL, type definitions, or configuration. Replace with
|
|
124
|
+
file path references and brief descriptions of what's there.
|
|
84
125
|
|
|
85
126
|
### Phase 4: Review
|
|
86
127
|
|
|
@@ -190,15 +231,29 @@ When relevant, include these categories using EARS format:
|
|
|
190
231
|
Present specifications in this structure:
|
|
191
232
|
|
|
192
233
|
```markdown
|
|
193
|
-
#
|
|
234
|
+
# Feature: [Name]
|
|
235
|
+
**Version:** v0.X.0
|
|
236
|
+
**Status:** planned
|
|
237
|
+
**Last Updated:** YYYY-MM-DD
|
|
238
|
+
|
|
239
|
+
## Intent
|
|
240
|
+
[Problem statement + why — what exists now, what should change, who is affected]
|
|
194
241
|
|
|
195
|
-
##
|
|
196
|
-
|
|
242
|
+
## Scope
|
|
243
|
+
**In scope:** ...
|
|
244
|
+
**Out of scope:** ...
|
|
197
245
|
|
|
198
|
-
##
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
246
|
+
## Acceptance Criteria
|
|
247
|
+
[Given/When/Then scenarios — one behavior per scenario, concrete values]
|
|
248
|
+
|
|
249
|
+
## Key Files
|
|
250
|
+
[File paths relevant to implementation — always populated from Phase 1 discovery]
|
|
251
|
+
|
|
252
|
+
## Schema / Data Model
|
|
253
|
+
[Reference to migration files + brief description, NOT full DDL]
|
|
254
|
+
|
|
255
|
+
## API Endpoints
|
|
256
|
+
[Table format: Method | Path | Description]
|
|
202
257
|
|
|
203
258
|
## Requirements
|
|
204
259
|
|
|
@@ -212,19 +267,8 @@ NFR-1: [EARS requirement]
|
|
|
212
267
|
NFR-2: [EARS requirement]
|
|
213
268
|
...
|
|
214
269
|
|
|
215
|
-
##
|
|
216
|
-
|
|
217
|
-
### [Requirement Group]
|
|
218
|
-
Scenario: ...
|
|
219
|
-
Given ...
|
|
220
|
-
When ...
|
|
221
|
-
Then ...
|
|
222
|
-
|
|
223
|
-
## Behavioral Changes
|
|
224
|
-
[Requirements that change existing system behavior. For each, state:]
|
|
225
|
-
- Current behavior: [what the system does now, with file:line evidence]
|
|
226
|
-
- Specified behavior: [what the spec requires instead]
|
|
227
|
-
- Impact: [who/what is affected — API consumers, UI, downstream services]
|
|
270
|
+
## Dependencies
|
|
271
|
+
- [External system or module this feature depends on]
|
|
228
272
|
|
|
229
273
|
## Open Questions
|
|
230
274
|
[Group related unknowns. For each question, provide:]
|
|
@@ -233,9 +277,6 @@ Scenario: ...
|
|
|
233
277
|
- Option B: [description] — [trade-off]
|
|
234
278
|
- Recommendation: [if you have one, with reasoning]
|
|
235
279
|
|
|
236
|
-
## Dependencies
|
|
237
|
-
- [External system or module this feature depends on]
|
|
238
|
-
|
|
239
280
|
## Evidence
|
|
240
281
|
- **Confirmed**: [Behavior verified in code — file path, line number, what was observed]
|
|
241
282
|
- **Inferred**: [Behavior assumed from patterns, naming, or incomplete evidence — state the basis and flag for validation]
|
package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md
CHANGED
|
@@ -127,11 +127,11 @@ For longer commands, save a script to `~/.claude/statusline-command.sh`:
|
|
|
127
127
|
}
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
##
|
|
130
|
+
## Existing Status Line Detection
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
If a custom status line feature (`ccstatusline`) is installed, check for a wrapper script. To find it:
|
|
133
133
|
1. Current settings: Read `~/.claude/settings.json` for the active `statusLine` configuration
|
|
134
|
-
2. Wrapper script:
|
|
134
|
+
2. Wrapper script: Run `which ccstatusline-wrapper` to locate it, then read it if found
|
|
135
135
|
3. Feature config: Check `.devcontainer/features/ccstatusline/` for the feature definition
|
|
136
136
|
|
|
137
137
|
## Workflow
|
|
@@ -15,6 +15,7 @@ memory:
|
|
|
15
15
|
scope: project
|
|
16
16
|
skills:
|
|
17
17
|
- testing
|
|
18
|
+
- spec-update
|
|
18
19
|
hooks:
|
|
19
20
|
Stop:
|
|
20
21
|
- type: command
|
|
@@ -26,6 +27,100 @@ hooks:
|
|
|
26
27
|
|
|
27
28
|
You are a **senior test engineer** specializing in automated test design, test-driven development, and quality assurance. You analyze existing source code, detect the test framework and conventions in use, and write comprehensive test suites that thoroughly cover the target code. You match the project's existing test style precisely. Every test you write must pass before you finish.
|
|
28
29
|
|
|
30
|
+
## Project Context Discovery
|
|
31
|
+
|
|
32
|
+
Before starting any task, check for project-specific instructions that override or extend your defaults. These are invisible to you unless you read them.
|
|
33
|
+
|
|
34
|
+
### Step 1: Read Claude Rules
|
|
35
|
+
|
|
36
|
+
Check for rule files that apply to the entire workspace:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
Glob: .claude/rules/*.md
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Read every file found. These contain mandatory project rules (workspace scoping, spec workflow, etc.). Follow them as hard constraints.
|
|
43
|
+
|
|
44
|
+
### Step 2: Read CLAUDE.md Files
|
|
45
|
+
|
|
46
|
+
CLAUDE.md files contain project-specific conventions, tech stack details, and architectural decisions. They exist at multiple directory levels — more specific files take precedence.
|
|
47
|
+
|
|
48
|
+
Starting from the directory you are working in, read CLAUDE.md files walking up to the workspace root:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
# Example: working in /workspaces/myproject/src/engine/api/
|
|
52
|
+
Read: /workspaces/myproject/src/engine/api/CLAUDE.md (if exists)
|
|
53
|
+
Read: /workspaces/myproject/src/engine/CLAUDE.md (if exists)
|
|
54
|
+
Read: /workspaces/myproject/CLAUDE.md (if exists)
|
|
55
|
+
Read: /workspaces/CLAUDE.md (if exists — workspace root)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Use Glob to discover them efficiently:
|
|
59
|
+
```
|
|
60
|
+
Glob: **/CLAUDE.md (within the project directory)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Step 3: Apply What You Found
|
|
64
|
+
|
|
65
|
+
- **Conventions** (naming, nesting limits, framework choices): follow them in all work
|
|
66
|
+
- **Tech stack** (languages, frameworks, libraries): use them, don't introduce alternatives
|
|
67
|
+
- **Architecture decisions** (where logic lives, data flow patterns): respect boundaries
|
|
68
|
+
- **Workflow rules** (spec management, testing requirements): comply
|
|
69
|
+
|
|
70
|
+
If a CLAUDE.md instruction conflicts with your built-in instructions, the CLAUDE.md takes precedence — it represents the project owner's intent.
|
|
71
|
+
|
|
72
|
+
## Execution Discipline
|
|
73
|
+
|
|
74
|
+
### Verify Before Assuming
|
|
75
|
+
- When requirements do not specify a technology, language, file location, or approach — check CLAUDE.md and project conventions first. If still ambiguous, report the ambiguity rather than picking a default.
|
|
76
|
+
- Do not assume file paths — read the filesystem to confirm.
|
|
77
|
+
- Never fabricate file paths, API signatures, tool behavior, or external facts.
|
|
78
|
+
|
|
79
|
+
### Read Before Writing
|
|
80
|
+
- Before creating or modifying any file, read the target directory and verify the path exists.
|
|
81
|
+
- Before proposing a solution, check for existing implementations that may already solve the problem.
|
|
82
|
+
|
|
83
|
+
### Instruction Fidelity
|
|
84
|
+
- If the task says "do X", do X — not a variation, shortcut, or "equivalent."
|
|
85
|
+
- If a requirement seems wrong, stop and report rather than silently adjusting it.
|
|
86
|
+
|
|
87
|
+
### Verify After Writing
|
|
88
|
+
- After creating files, verify they exist at the expected path.
|
|
89
|
+
- After making changes, run the build or tests if available.
|
|
90
|
+
- Never declare work complete without evidence it works.
|
|
91
|
+
|
|
92
|
+
### No Silent Deviations
|
|
93
|
+
- If you cannot do exactly what was asked, stop and explain why before doing something different.
|
|
94
|
+
- Never silently substitute an easier approach or skip a step.
|
|
95
|
+
|
|
96
|
+
### When an Approach Fails
|
|
97
|
+
- Diagnose the cause before retrying.
|
|
98
|
+
- Try an alternative strategy; do not repeat the failed path.
|
|
99
|
+
- Surface the failure and revised approach in your report.
|
|
100
|
+
|
|
101
|
+
## Code Standards Reference
|
|
102
|
+
|
|
103
|
+
When writing or evaluating code, apply these standards:
|
|
104
|
+
- **SOLID** principles (Single Responsibility, Open/Closed, Liskov, Interface Segregation, Dependency Inversion)
|
|
105
|
+
- **DRY, KISS, YAGNI** — no duplication, keep it simple, don't build what's not needed
|
|
106
|
+
- Functions: single purpose, <20 lines, max 3-4 params
|
|
107
|
+
- Never swallow exceptions. Actionable error messages.
|
|
108
|
+
- Validate inputs at system boundaries only. Parameterized queries.
|
|
109
|
+
- No god classes, magic numbers, dead code, copy-paste duplication, or hard-coded config.
|
|
110
|
+
|
|
111
|
+
## Professional Objectivity
|
|
112
|
+
|
|
113
|
+
Prioritize technical accuracy over agreement. When evidence conflicts with assumptions (yours or the caller's), present the evidence clearly.
|
|
114
|
+
|
|
115
|
+
When uncertain, investigate first — read the code, check the docs — rather than confirming a belief by default. Use direct, measured language. Avoid superlatives or unqualified claims.
|
|
116
|
+
|
|
117
|
+
## Communication Standards
|
|
118
|
+
|
|
119
|
+
- Open every response with substance — your finding, action, or answer. No preamble.
|
|
120
|
+
- Do not restate the problem or narrate intentions ("Let me...", "I'll now...").
|
|
121
|
+
- Mark uncertainty explicitly. Distinguish confirmed facts from inference.
|
|
122
|
+
- Reference code locations as `file_path:line_number`.
|
|
123
|
+
|
|
29
124
|
## Critical Constraints
|
|
30
125
|
|
|
31
126
|
- **NEVER** modify source code files — you only create and edit test files. If a source file needs changes to become testable, report this as a finding rather than making the change yourself.
|
|
@@ -62,7 +157,7 @@ If no test framework is detected, check the project manifest for test-related de
|
|
|
62
157
|
|
|
63
158
|
### Step 2: Study Existing Test Conventions
|
|
64
159
|
|
|
65
|
-
Read 2-3 existing test files to understand the project's patterns:
|
|
160
|
+
Read CLAUDE.md files (per Project Context Discovery) for project-specific testing conventions, preferred frameworks, and naming patterns. Then read 2-3 existing test files to understand the project's patterns:
|
|
66
161
|
|
|
67
162
|
- **File naming**: `test_*.py`, `*.test.ts`, `*_test.go`, `*.spec.js`?
|
|
68
163
|
- **Directory structure**: Co-located with source? Separate `tests/` directory? Mirror structure?
|
|
@@ -183,6 +278,9 @@ go test -v ./path/to/package/...
|
|
|
183
278
|
- **Ambiguous scope**: If the user says "test this" without specifying what, check if they have a file open or recently discussed a specific module. If unclear, ask which module or file to target.
|
|
184
279
|
- **No test framework found**: Report this explicitly, recommend a framework based on the project's language, and ask the user how to proceed before writing anything.
|
|
185
280
|
- If you cannot determine expected behavior for a function (no docs, no examples, unclear logic), state this explicitly in your output and write tests for the behavior you *can* verify, noting the gaps.
|
|
281
|
+
- **Spec-linked testing**: When specs exist in `.specs/`, check if acceptance
|
|
282
|
+
criteria are defined for the area being tested. Report which criteria your tests
|
|
283
|
+
cover and which remain untested, so the orchestrator can update spec status.
|
|
186
284
|
- **Always report** what you tested, what you discovered, and any bugs found in the source code.
|
|
187
285
|
|
|
188
286
|
## Output Format
|
|
@@ -1,58 +1,102 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
2
|
+
"description": "Code quality hooks and skill suggestions for the CodeDirective project",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Task",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/redirect-builtin-agents.py",
|
|
11
|
+
"timeout": 5
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"UserPromptSubmit": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "*",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/skill-suggester.py",
|
|
23
|
+
"timeout": 3
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"type": "command",
|
|
27
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/ticket-linker.py",
|
|
28
|
+
"timeout": 12
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
"SubagentStart": [
|
|
34
|
+
{
|
|
35
|
+
"matcher": "Plan",
|
|
36
|
+
"hooks": [
|
|
37
|
+
{
|
|
38
|
+
"type": "command",
|
|
39
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/skill-suggester.py",
|
|
40
|
+
"timeout": 3
|
|
41
|
+
}
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
"Stop": [
|
|
46
|
+
{
|
|
47
|
+
"matcher": "",
|
|
48
|
+
"hooks": [
|
|
49
|
+
{
|
|
50
|
+
"type": "command",
|
|
51
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/advisory-test-runner.py",
|
|
52
|
+
"timeout": 65
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"type": "command",
|
|
56
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/commit-reminder.py",
|
|
57
|
+
"timeout": 8
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"type": "command",
|
|
61
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/spec-reminder.py",
|
|
62
|
+
"timeout": 8
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
"SessionStart": [
|
|
68
|
+
{
|
|
69
|
+
"matcher": "",
|
|
70
|
+
"hooks": [
|
|
71
|
+
{
|
|
72
|
+
"type": "command",
|
|
73
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/git-state-injector.py",
|
|
74
|
+
"timeout": 10
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"type": "command",
|
|
78
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/todo-harvester.py",
|
|
79
|
+
"timeout": 8
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
],
|
|
84
|
+
"PostToolUse": [
|
|
85
|
+
{
|
|
86
|
+
"matcher": "Edit|Write",
|
|
87
|
+
"hooks": [
|
|
88
|
+
{
|
|
89
|
+
"type": "command",
|
|
90
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/syntax-validator.py",
|
|
91
|
+
"timeout": 5
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"type": "command",
|
|
95
|
+
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/scripts/collect-edited-files.py",
|
|
96
|
+
"timeout": 3
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
}
|
|
58
102
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Advisory test runner — Stop hook that injects test results as context.
|
|
4
|
+
|
|
5
|
+
Detects the project's test framework and runs the test suite. Results are
|
|
6
|
+
returned as additionalContext so Claude sees pass/fail info without being
|
|
7
|
+
blocked. If tests fail, Claude's next response will naturally address them.
|
|
8
|
+
|
|
9
|
+
Reads hook input from stdin (JSON). Returns JSON on stdout.
|
|
10
|
+
Always exits 0 (advisory, never blocking).
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import subprocess
|
|
16
|
+
import sys
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def detect_test_framework(cwd: str) -> tuple[str, list[str]]:
|
|
20
|
+
"""Detect which test framework is available in the project.
|
|
21
|
+
|
|
22
|
+
Checks for: pytest, vitest, jest, mocha, go test, cargo test.
|
|
23
|
+
Falls back to npm test if a test script is defined.
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Tuple of (framework_name, command_list) or ("", []) if none found.
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
entries = set(os.listdir(cwd))
|
|
30
|
+
except OSError:
|
|
31
|
+
return ("", [])
|
|
32
|
+
|
|
33
|
+
# --- Python: pytest ---
|
|
34
|
+
if "pytest.ini" in entries or "conftest.py" in entries:
|
|
35
|
+
return ("pytest", ["python3", "-m", "pytest", "--tb=short", "-q"])
|
|
36
|
+
|
|
37
|
+
for cfg_name in ("pyproject.toml", "setup.cfg", "tox.ini"):
|
|
38
|
+
cfg_path = os.path.join(cwd, cfg_name)
|
|
39
|
+
if os.path.isfile(cfg_path):
|
|
40
|
+
try:
|
|
41
|
+
with open(cfg_path, "r", encoding="utf-8") as f:
|
|
42
|
+
content = f.read()
|
|
43
|
+
if (
|
|
44
|
+
"[tool.pytest" in content
|
|
45
|
+
or "[pytest]" in content
|
|
46
|
+
or "[tool:pytest]" in content
|
|
47
|
+
):
|
|
48
|
+
return ("pytest", ["python3", "-m", "pytest", "--tb=short", "-q"])
|
|
49
|
+
except OSError:
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
if "tests" in entries and os.path.isdir(os.path.join(cwd, "tests")):
|
|
53
|
+
return ("pytest", ["python3", "-m", "pytest", "--tb=short", "-q"])
|
|
54
|
+
|
|
55
|
+
for entry in entries:
|
|
56
|
+
if entry.startswith("test_") and entry.endswith(".py"):
|
|
57
|
+
return ("pytest", ["python3", "-m", "pytest", "--tb=short", "-q"])
|
|
58
|
+
|
|
59
|
+
# --- JavaScript: vitest ---
|
|
60
|
+
for name in entries:
|
|
61
|
+
if name.startswith("vitest.config"):
|
|
62
|
+
return ("vitest", ["npx", "vitest", "run", "--reporter=verbose"])
|
|
63
|
+
|
|
64
|
+
for vite_cfg in ("vite.config.ts", "vite.config.js"):
|
|
65
|
+
cfg_path = os.path.join(cwd, vite_cfg)
|
|
66
|
+
if os.path.isfile(cfg_path):
|
|
67
|
+
try:
|
|
68
|
+
with open(cfg_path, "r", encoding="utf-8") as f:
|
|
69
|
+
if "test" in f.read():
|
|
70
|
+
return (
|
|
71
|
+
"vitest",
|
|
72
|
+
["npx", "vitest", "run", "--reporter=verbose"],
|
|
73
|
+
)
|
|
74
|
+
except OSError:
|
|
75
|
+
pass
|
|
76
|
+
|
|
77
|
+
# --- JavaScript: jest ---
|
|
78
|
+
for name in entries:
|
|
79
|
+
if name.startswith("jest.config"):
|
|
80
|
+
return ("jest", ["npx", "jest", "--verbose"])
|
|
81
|
+
|
|
82
|
+
pkg_json = os.path.join(cwd, "package.json")
|
|
83
|
+
if os.path.isfile(pkg_json):
|
|
84
|
+
try:
|
|
85
|
+
with open(pkg_json, "r", encoding="utf-8") as f:
|
|
86
|
+
pkg = json.loads(f.read())
|
|
87
|
+
|
|
88
|
+
if "jest" in pkg:
|
|
89
|
+
return ("jest", ["npx", "jest", "--verbose"])
|
|
90
|
+
|
|
91
|
+
dev_deps = pkg.get("devDependencies", {})
|
|
92
|
+
deps = pkg.get("dependencies", {})
|
|
93
|
+
|
|
94
|
+
if "mocha" in dev_deps or "mocha" in deps:
|
|
95
|
+
return ("mocha", ["npx", "mocha", "--reporter", "spec"])
|
|
96
|
+
|
|
97
|
+
test_script = pkg.get("scripts", {}).get("test", "")
|
|
98
|
+
if test_script and "no test specified" not in test_script:
|
|
99
|
+
return ("npm-test", ["npm", "test"])
|
|
100
|
+
except (OSError, json.JSONDecodeError):
|
|
101
|
+
pass
|
|
102
|
+
|
|
103
|
+
# --- Go ---
|
|
104
|
+
if "go.mod" in entries:
|
|
105
|
+
return ("go", ["go", "test", "./...", "-count=1"])
|
|
106
|
+
|
|
107
|
+
# --- Rust ---
|
|
108
|
+
if "Cargo.toml" in entries:
|
|
109
|
+
return ("cargo", ["cargo", "test"])
|
|
110
|
+
|
|
111
|
+
return ("", [])
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def main():
|
|
115
|
+
try:
|
|
116
|
+
input_data = json.load(sys.stdin)
|
|
117
|
+
except (json.JSONDecodeError, ValueError):
|
|
118
|
+
sys.exit(0)
|
|
119
|
+
|
|
120
|
+
# Skip if another Stop hook is already blocking
|
|
121
|
+
if input_data.get("stop_hook_active"):
|
|
122
|
+
sys.exit(0)
|
|
123
|
+
|
|
124
|
+
cwd = os.getcwd()
|
|
125
|
+
framework, cmd = detect_test_framework(cwd)
|
|
126
|
+
|
|
127
|
+
if not framework:
|
|
128
|
+
sys.exit(0)
|
|
129
|
+
|
|
130
|
+
try:
|
|
131
|
+
result = subprocess.run(
|
|
132
|
+
cmd,
|
|
133
|
+
cwd=cwd,
|
|
134
|
+
capture_output=True,
|
|
135
|
+
text=True,
|
|
136
|
+
timeout=60,
|
|
137
|
+
)
|
|
138
|
+
except subprocess.TimeoutExpired:
|
|
139
|
+
json.dump(
|
|
140
|
+
{"additionalContext": f"[Tests] {framework} timed out after 60s"},
|
|
141
|
+
sys.stdout,
|
|
142
|
+
)
|
|
143
|
+
sys.exit(0)
|
|
144
|
+
except (FileNotFoundError, OSError):
|
|
145
|
+
# Test runner not installed or not accessible
|
|
146
|
+
sys.exit(0)
|
|
147
|
+
|
|
148
|
+
output = (result.stdout + "\n" + result.stderr).strip()
|
|
149
|
+
|
|
150
|
+
if result.returncode == 0:
|
|
151
|
+
# Extract test count from output if possible
|
|
152
|
+
json.dump(
|
|
153
|
+
{"additionalContext": f"[Tests] All tests passed ({framework})"},
|
|
154
|
+
sys.stdout,
|
|
155
|
+
)
|
|
156
|
+
sys.exit(0)
|
|
157
|
+
|
|
158
|
+
# Tests failed — truncate to last 30 lines
|
|
159
|
+
if not output:
|
|
160
|
+
output = "(no test output)"
|
|
161
|
+
|
|
162
|
+
lines = output.splitlines()
|
|
163
|
+
if len(lines) > 30:
|
|
164
|
+
output = "...(truncated)\n" + "\n".join(lines[-30:])
|
|
165
|
+
|
|
166
|
+
json.dump(
|
|
167
|
+
{"additionalContext": (f"[Tests] Some tests FAILED ({framework}):\n{output}")},
|
|
168
|
+
sys.stdout,
|
|
169
|
+
)
|
|
170
|
+
sys.exit(0)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
if __name__ == "__main__":
|
|
174
|
+
main()
|
|
@@ -30,12 +30,14 @@ def main():
|
|
|
30
30
|
if not os.path.isfile(file_path):
|
|
31
31
|
sys.exit(0)
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
# Write to both formatter and linter temp files (independent pipelines)
|
|
34
|
+
for prefix in ("claude-edited-files", "claude-lint-files"):
|
|
35
|
+
tmp_path = f"/tmp/{prefix}-{session_id}"
|
|
36
|
+
try:
|
|
37
|
+
with open(tmp_path, "a") as f:
|
|
38
|
+
f.write(file_path + "\n")
|
|
39
|
+
except OSError:
|
|
40
|
+
pass # non-critical, don't block Claude
|
|
39
41
|
|
|
40
42
|
sys.exit(0)
|
|
41
43
|
|