k-harness 0.5.0 → 0.7.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/README.md CHANGED
@@ -59,7 +59,7 @@ npx k-harness init --ide antigravity
59
59
  | **Augment Code** | `.augment/rules/core.md` | `.augment/rules/*.md` | `.augment/skills/*/SKILL.md` | `.augment/skills/*/SKILL.md` |
60
60
  | **Google Antigravity** | `.agent/rules/core.md` | `.agent/rules/*.md` | `.agent/skills/*/SKILL.md` | `.agent/skills/*/SKILL.md` |
61
61
 
62
- All IDEs also get `project-state.md`, `project-brief.md`, `features.md`, `failure-patterns.md`, and `dependency-map.md` at the project root.
62
+ All IDEs also get state files (`project-state.md`, `project-brief.md`, `features.md`, `failure-patterns.md`, `dependency-map.md`) in the `docs/` directory.
63
63
 
64
64
  ## What Gets Installed
65
65
 
@@ -125,7 +125,7 @@ See [docs/reference.md](docs/reference.md) for detailed descriptions of every sk
125
125
  | | BMAD v6.2.2 | gstack v0.15.1 | K-Harness |
126
126
  |---|---|---|---|
127
127
  | Focus | Enterprise SDLC methodology | 1-person software factory | Project direction management |
128
- | Files | 200+ | ~40 | 15 |
128
+ | Files | 200+ | ~40 | ~20 |
129
129
  | Dependencies | Node 20+ | Bun + Node + Playwright | Zero |
130
130
  | IDE support | 20+ (installer) | 5 (setup --host) | 7 (native format) |
131
131
  | Direction management | ❌ | ❌ | ✅ (Direction Guard + pivot + Decision Log) |
@@ -42,9 +42,9 @@ If `docs/project-brief.md` alone is empty → Warn the user but proceed (the pla
42
42
 
43
43
  1. Read `docs/project-brief.md` to understand project vision, goals, **non-goals**, and **Decision Log**
44
44
  2. **Direction Alignment**: Verify the requested feature against three checkpoints:
45
- - **Goal Alignment**: Does it serve a listed Goal? If no clear link, warn the user.
46
- - **Non-Goal Violation**: Does it fall into Non-Goals? If yes, **stop and ask** this may be a pivot.
47
- - **Decision Consistency**: Does it contradict any Decision Log entry? If yes, warn that a previous decision conflicts — recommend running the `pivot` skill before proceeding.
45
+ - **Goal Alignment**: Does it serve a listed Goal? If no clear link → **warn but proceed**. Include the warning in the plan output.
46
+ - **Non-Goal Violation**: Does it fall into Non-Goals? If yes **stop and ask the user**. Do not proceed until the user confirms this is intentional (may need `pivot` skill).
47
+ - **Decision Consistency**: Does it contradict any Decision Log entry? If yes **stop and warn**. Recommend running the `pivot` skill before proceeding.
48
48
  If the request represents a clear direction change → recommend running the `pivot` skill instead of proceeding with planning.
49
49
  3. Read `docs/features.md` to understand what already exists
50
50
  4. Read `docs/dependency-map.md` to understand current architecture
@@ -75,6 +75,7 @@ Verify that state file updates actually happened. Check each:
75
75
  - [ ] **docs/dependency-map.md**: If new modules were created, are they registered? If dependencies changed, are relationships updated?
76
76
  - [ ] **docs/failure-patterns.md**: If a bug was fixed that matched a pattern, was frequency incremented?
77
77
  - [ ] **docs/project-brief.md**: If a technology or architectural decision was made, is it in Decision Log?
78
+ - [ ] **docs/agent-memory/*.md**: If an agent (reviewer/planner/sprint-manager) was used this session, was its memory updated by the learn skill?
78
79
 
79
80
  For each missing update: flag as `[STATE-AUDIT]` in the output and provide the exact update that should be made.
80
81
 
@@ -81,6 +81,15 @@ When starting a NEW chat session, read these files in order before doing any wor
81
81
 
82
82
  If ALL state files are empty (only TODOs/placeholders), run the `bootstrap` skill before doing anything else.
83
83
 
84
+ ### Health Check (every session start)
85
+
86
+ After reading state files, also check this file for unfilled placeholders:
87
+ - If the `## Architecture` section still has `<!-- TODO -->` → warn: **"Core rules are incomplete. Run `bootstrap` to auto-fill."**
88
+ - If the `## Test Rules` section still has `<!-- TODO -->` for test command → warn the same
89
+ - If any rules file has globs that don't match the project language (e.g., `src/**/*.ts` for a Python project) → warn: **"Rules globs don't match your project language. Run `bootstrap` to fix."**
90
+
91
+ Do NOT proceed with work until the user acknowledges or resolves these warnings.
92
+
84
93
  ## Workflow Pipeline
85
94
 
86
95
  Follow this order for different workflows. Each step's output feeds the next.
@@ -14,6 +14,12 @@ Keep resolved patterns for regression prevention.
14
14
  - **Applied in**: testing rules, test-integrity skill, reviewer agent
15
15
  - **Status**: Template — activate when first occurrence is logged
16
16
 
17
+ <!-- Activation example: When this pattern first occurs, update like this:
18
+ - **Occurred**: S1-2
19
+ - **Frequency**: 1
20
+ - **Status**: Active
21
+ On subsequent occurrences, increment Frequency and append to Occurred (e.g., S1-2, S2-1) -->
22
+
17
23
  ---
18
24
 
19
25
  ## FP-002: Type confusion (enum vs union, wrong parameter count)
@@ -2,8 +2,9 @@
2
2
 
3
3
  ## Purpose
4
4
 
5
- Onboard a new or existing project into K-Harness by filling state files automatically.
5
+ Onboard a new or existing project into K-Harness by filling **state files AND rules files** automatically.
6
6
  Solves the cold-start problem: users don't know which `.md` files to fill or how.
7
+ One command does everything — no manual editing required.
7
8
 
8
9
  ## When to Apply
9
10
 
@@ -41,6 +42,7 @@ Ask the user these questions (skip any already answered by Phase 1):
41
42
  3. "What is explicitly OUT of scope? (non-goals)"
42
43
  4. "What architecture pattern are you using?" (show detected pattern if found)
43
44
  5. "Are there any type decisions or conventions the AI should know about?"
45
+ 6. "What is your test command?" (show detected command if found, e.g., `npm test`, `pytest`, `go test ./...`)
44
46
 
45
47
  ### Phase 3: Fill State Files
46
48
 
@@ -73,6 +75,55 @@ Using data from Phase 1 + Phase 2, fill the following files:
73
75
  - Keep FP-001 through FP-004 as templates (Frequency: 0)
74
76
  - No changes unless user reports known issues
75
77
 
78
+ ### Phase 3.5: Rules Auto-Configuration
79
+
80
+ Using language/framework detected in Phase 1 + user answers from Phase 2, auto-configure the project's rules files.
81
+
82
+ 1. **Find the core rules file** — Search for the file containing `<!-- TODO: Describe your project's architecture here -->`:
83
+ - VS Code: `.github/copilot-instructions.md`
84
+ - Claude: `CLAUDE.md`
85
+ - Cursor: `.cursor/rules/core.mdc`
86
+ - Codex: `AGENTS.md`
87
+ - Windsurf: `.windsurfrules`
88
+ - Augment: `.augment/rules/core.md`
89
+ - Antigravity: `.agent/rules/core.md`
90
+
91
+ 2. **Fill `## Architecture` section** — Replace the TODO with detected tech stack:
92
+ ```
93
+ ## Architecture
94
+ [Language] / [Framework] / [Database if detected]
95
+ [Architecture pattern from user answer #4]
96
+ ```
97
+
98
+ 3. **Fill `## Directory Structure` section** — Replace the TODO with actual tree from Phase 1:
99
+ ```
100
+ ## Directory Structure
101
+ project-root/
102
+ ├── src/ # [purpose from scan]
103
+ ├── tests/ # [purpose from scan]
104
+ └── ...
105
+ ```
106
+
107
+ 4. **Fill `## Core Type Rules` section** — Replace the TODO with user answer #5 plus language defaults:
108
+ - Python: `Use Pydantic models for API schemas, not plain dicts.`
109
+ - TypeScript: `Prefer union types ("a" | "b") over enums.`
110
+ - Go: `Use interfaces for dependency injection.`
111
+ - Java: `Use records for DTOs.`
112
+ - Rust: `Use enum variants, not string constants.`
113
+
114
+ 5. **Fill `## Test Rules`** — Set test command (from user answer #6) and mock location (from Phase 1):
115
+ ```
116
+ - Test command: [detected or user-provided, e.g. pytest, npm test, go test ./...]
117
+ - Mock location: [detected, e.g. tests/conftest.py, tests/__mocks__/]
118
+ ```
119
+
120
+ 6. **Verify globs** — Check backend and testing rules files have correct globs for the detected language:
121
+ - Python: backend `**/*.py`, testing `**/test_*.py,**/tests/**/*.py`
122
+ - TypeScript: backend `src/**/*.ts,src/**/*.js`, testing `**/*.test.*,**/*.spec.*`
123
+ - Go: backend `**/*.go`, testing `**/*_test.go`
124
+ - Java: backend `src/main/**/*.java`, testing `src/test/**/*.java`
125
+ - If globs don't match → **edit the file directly** to set correct globs
126
+
76
127
  ### Phase 4: Verify
77
128
 
78
129
  1. Present a summary of all filled state files to the user
@@ -87,6 +138,7 @@ Using data from Phase 1 + Phase 2, fill the following files:
87
138
 
88
139
  ### Project: [name]
89
140
  ### Tech Stack: [detected stack]
141
+ ### Language: [detected language]
90
142
  ### Modules Found: [count]
91
143
  ### Features Mapped: [count]
92
144
  ### Dependency Links: [count]
@@ -98,15 +150,22 @@ Using data from Phase 1 + Phase 2, fill the following files:
98
150
  - [x]docs/project-state.md — Sprint 1 initialized
99
151
  - [ ]docs/failure-patterns.md — templates only (no changes)
100
152
 
153
+ ### Rules Files Configured:
154
+ - [x] Core rules — Architecture, Directory Structure, Type Rules filled
155
+ - [x] Test command — [detected command]
156
+ - [x] Backend globs — [globs set]
157
+ - [x] Testing globs — [globs set]
158
+
101
159
  STATUS: DONE
102
160
  ```
103
161
 
104
162
  ## Rules
105
163
 
106
- - Never modify source code — this skill only writes to state files
164
+ - Never modify source code — this skill only writes to state files and rules files
107
165
  - Always show the user what was discovered BEFORE writing files
108
166
  - If the project has 0 source files, skip Phase 1 scan and go straight to Phase 2
109
167
  - If a state file already has content, ask before overwriting
168
+ - Rules file TODO sections can be overwritten without asking (they are placeholders)
110
169
  - Run this skill only once per project (or when explicitly requested for refresh)
111
170
 
112
171
  ## Anti-patterns
@@ -117,3 +176,6 @@ STATUS: DONE
117
176
  | Skip user interview | Phase 1 scan alone is insufficient — always confirm with user |
118
177
  | Overwrite existing state files silently | Ask before overwriting non-empty files |
119
178
  | Create perfect dependency map on first try | Start with what's detectable, refine over time |
179
+ | Leave rules file TODOs unfilled | Phase 3.5 fills ALL TODO sections — no manual editing needed |
180
+ | Use TypeScript globs for non-TS projects | Detect language in Phase 1 and set correct globs |
181
+ | Only fill state files, skip rules | Bootstrap fills BOTH — state files AND rules files |
@@ -61,7 +61,7 @@ Plan: 4 files to update, all within S3-2 scope
61
61
 
62
62
  After completing the analysis, update these files:
63
63
 
64
- - [ ] **docs/dependency-map.md**: Update the Interface Change Log table with: Date, Module, Change description, Affected Modules, Status.
64
+ - [ ] **docs/dependency-map.md**: Update the Interface Change Log table with: Date, Module, Change description, Affected Modules, Status. **This is mandatory for ALL interface changes** — do not skip even if the change seems minor.
65
65
  - [ ] **docs/project-state.md**: If scope exceeds current Story, add a note to Recent Changes.
66
66
 
67
67
  ## Related Failure Patterns
@@ -8,11 +8,13 @@ This is K-Harness's memory mechanism — without it, the same mistakes repeat ac
8
8
 
9
9
  ## When to Apply
10
10
 
11
- - Before ending a chat session (recommended as the LAST skill invoked)
11
+ - Before ending a chat session (recommended as the LAST skill invoked, **once per session**)
12
12
  - After a debugging session where a non-obvious fix was found
13
13
  - After a review revealed a repeated mistake
14
14
  - When the user explicitly asks to record a lesson
15
15
 
16
+ > **Timing**: Invoke this skill **once at session end**, not after each individual skill. It aggregates the entire session's work into state files.
17
+
16
18
  ## Procedure
17
19
 
18
20
  ### Step 1: Review Session Activity
@@ -63,7 +65,10 @@ For each issue/error that occurred in this session:
63
65
  If an agent (reviewer, planner, sprint-manager) was used in this session, update its memory file in `docs/agent-memory/`:
64
66
 
65
67
  1. Read `docs/agent-memory/{agent-name}.md`
66
- 2. Add session-specific learnings to the appropriate section:
68
+ 2. If the file only contains placeholder comments (`<!-- 예시:... -->`), initialize it by replacing the comments with actual entries. Example:
69
+ - Before: `<!-- 예시: Wave 1 추정: 정확 -->`
70
+ - After: `- [S1-2] Wave 1 추정: 정확 (3 tasks, 실제 소요 1일)`
71
+ 3. Add session-specific learnings to the appropriate section:
67
72
  - **reviewer.md**: Review patterns, frequently missed items, statistics
68
73
  - **planner.md**: Estimation accuracy, architecture insights, repeated patterns
69
74
  - **sprint-manager.md**: Velocity data, scope drift incidents, sizing recommendations
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "k-harness",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "LLM Development Harness — IDE-agnostic rules, skills, and agents that prevent common AI coding failures",
5
5
  "keywords": [
6
6
  "llm",
package/src/init.js CHANGED
@@ -59,6 +59,50 @@ const AGENT_MEMORY_FILES = [
59
59
 
60
60
  const STATE_DEST_DIR = 'docs';
61
61
 
62
+ // ─── Language detection ──────────────────────────────────────
63
+ function detectLanguage(targetDir) {
64
+ const markers = [
65
+ ['python', ['requirements.txt', 'pyproject.toml', 'setup.py', 'Pipfile', 'setup.cfg']],
66
+ ['go', ['go.mod']],
67
+ ['java', ['pom.xml', 'build.gradle', 'build.gradle.kts']],
68
+ ['rust', ['Cargo.toml']],
69
+ ['ruby', ['Gemfile']],
70
+ ];
71
+ for (const [lang, files] of markers) {
72
+ for (const f of files) {
73
+ if (fs.existsSync(path.join(targetDir, f))) return lang;
74
+ }
75
+ }
76
+ return 'typescript';
77
+ }
78
+
79
+ const LANG_GLOBS = {
80
+ typescript: {
81
+ backend: 'src/**/*.ts,src/**/*.js',
82
+ testing: '**/*.test.ts,**/*.test.js,**/*.spec.ts,**/*.spec.js,**/__mocks__/**,**/__tests__/**',
83
+ },
84
+ python: {
85
+ backend: '**/*.py',
86
+ testing: '**/test_*.py,**/tests/**/*.py,**/*_test.py,**/conftest.py',
87
+ },
88
+ go: {
89
+ backend: '**/*.go',
90
+ testing: '**/*_test.go',
91
+ },
92
+ java: {
93
+ backend: 'src/main/**/*.java',
94
+ testing: 'src/test/**/*.java',
95
+ },
96
+ rust: {
97
+ backend: 'src/**/*.rs',
98
+ testing: 'tests/**/*.rs,**/tests.rs',
99
+ },
100
+ ruby: {
101
+ backend: '**/*.rb',
102
+ testing: 'spec/**/*.rb,test/**/*.rb',
103
+ },
104
+ };
105
+
62
106
  // ─── Shared writers ──────────────────────────────────────────
63
107
 
64
108
  function writeStateFiles(targetDir, overwrite) {
@@ -93,6 +137,8 @@ function writeAgentsAsSkills(targetDir, skillsDir, overwrite) {
93
137
  // ─── IDE Generators ──────────────────────────────────────────
94
138
 
95
139
  function generateVscode(targetDir, overwrite) {
140
+ const lang = detectLanguage(targetDir);
141
+ const globs = LANG_GLOBS[lang];
96
142
  const coreRules = readTemplate('core-rules.md');
97
143
  const testingRules = readTemplate('testing-rules.md');
98
144
  const backendRules = readTemplate('backend-rules.md');
@@ -102,12 +148,12 @@ function generateVscode(targetDir, overwrite) {
102
148
 
103
149
  // File-scoped instructions (add VS Code applyTo frontmatter)
104
150
  const testingWithFrontmatter =
105
- '---\napplyTo: "**/*.test.ts,**/*.test.js,**/*.spec.ts,**/*.spec.js,**/__mocks__/**,**/__tests__/**"\n---\n\n' +
151
+ `---\napplyTo: "${globs.testing}"\n---\n\n` +
106
152
  testingRules;
107
153
  writeFile(targetDir, '.vscode/instructions/testing.instructions.md', testingWithFrontmatter, overwrite);
108
154
 
109
155
  const backendWithFrontmatter =
110
- '---\napplyTo: "src/**/*.ts,src/**/*.js"\n---\n\n' +
156
+ `---\napplyTo: "${globs.backend}"\n---\n\n` +
111
157
  backendRules;
112
158
  writeFile(targetDir, '.vscode/instructions/backend.instructions.md', backendWithFrontmatter, overwrite);
113
159
 
@@ -146,6 +192,8 @@ function generateClaude(targetDir, overwrite) {
146
192
  }
147
193
 
148
194
  function generateCursor(targetDir, overwrite) {
195
+ const lang = detectLanguage(targetDir);
196
+ const globs = LANG_GLOBS[lang];
149
197
  // .cursor/rules/*.mdc — each needs frontmatter
150
198
  const coreRules = readTemplate('core-rules.md');
151
199
  const coreMdc =
@@ -155,13 +203,13 @@ function generateCursor(targetDir, overwrite) {
155
203
 
156
204
  const testingRules = readTemplate('testing-rules.md');
157
205
  const testingMdc =
158
- '---\ndescription: Testing rules — mock sync, forbidden patterns\nglobs: "**/*.test.*,**/*.spec.*,**/__mocks__/**,**/__tests__/**"\nalwaysApply: false\n---\n\n' +
206
+ `---\ndescription: Testing rules — mock sync, forbidden patterns\nglobs: "${globs.testing}"\nalwaysApply: false\n---\n\n` +
159
207
  testingRules;
160
208
  writeFile(targetDir, '.cursor/rules/testing.mdc', testingMdc, overwrite);
161
209
 
162
210
  const backendRules = readTemplate('backend-rules.md');
163
211
  const backendMdc =
164
- '---\ndescription: Backend code rules — architecture enforcement, type safety\nglobs: "src/**/*.ts,src/**/*.js"\nalwaysApply: false\n---\n\n' +
212
+ `---\ndescription: Backend code rules — architecture enforcement, type safety\nglobs: "${globs.backend}"\nalwaysApply: false\n---\n\n` +
165
213
  backendRules;
166
214
  writeFile(targetDir, '.cursor/rules/backend.mdc', backendMdc, overwrite);
167
215
 
@@ -227,6 +275,8 @@ function generateWindsurf(targetDir, overwrite) {
227
275
  }
228
276
 
229
277
  function generateAugment(targetDir, overwrite) {
278
+ const lang = detectLanguage(targetDir);
279
+ const globs = LANG_GLOBS[lang];
230
280
  // .augment/rules/ — Always-type rules for core, testing, backend
231
281
  const coreRules = readTemplate('core-rules.md');
232
282
  const coreRule =
@@ -236,13 +286,13 @@ function generateAugment(targetDir, overwrite) {
236
286
 
237
287
  const testingRules = readTemplate('testing-rules.md');
238
288
  const testingRule =
239
- '---\ndescription: Testing rules — mock sync, forbidden patterns\ntype: auto\nglobs: "**/*.test.*,**/*.spec.*,**/__mocks__/**,**/__tests__/**"\n---\n\n' +
289
+ `---\ndescription: Testing rules — mock sync, forbidden patterns\ntype: auto\nglobs: "${globs.testing}"\n---\n\n` +
240
290
  testingRules;
241
291
  writeFile(targetDir, '.augment/rules/testing.md', testingRule, overwrite);
242
292
 
243
293
  const backendRules = readTemplate('backend-rules.md');
244
294
  const backendRule =
245
- '---\ndescription: Backend code rules — architecture enforcement, type safety\ntype: auto\nglobs: "src/**/*.ts,src/**/*.js"\n---\n\n' +
295
+ `---\ndescription: Backend code rules — architecture enforcement, type safety\ntype: auto\nglobs: "${globs.backend}"\n---\n\n` +
246
296
  backendRules;
247
297
  writeFile(targetDir, '.augment/rules/backend.md', backendRule, overwrite);
248
298
 
@@ -255,6 +305,8 @@ function generateAugment(targetDir, overwrite) {
255
305
  }
256
306
 
257
307
  function generateAntigravity(targetDir, overwrite) {
308
+ const lang = detectLanguage(targetDir);
309
+ const globs = LANG_GLOBS[lang];
258
310
  // .agent/rules/ — Always-type rules (same as Augment format, read by Antigravity)
259
311
  const coreRules = readTemplate('core-rules.md');
260
312
  const coreRule =
@@ -264,13 +316,13 @@ function generateAntigravity(targetDir, overwrite) {
264
316
 
265
317
  const testingRules = readTemplate('testing-rules.md');
266
318
  const testingRule =
267
- '---\ndescription: Testing rules — mock sync, forbidden patterns\ntype: auto\nglobs: "**/*.test.*,**/*.spec.*,**/__mocks__/**,**/__tests__/**"\n---\n\n' +
319
+ `---\ndescription: Testing rules — mock sync, forbidden patterns\ntype: auto\nglobs: "${globs.testing}"\n---\n\n` +
268
320
  testingRules;
269
321
  writeFile(targetDir, '.agent/rules/testing.md', testingRule, overwrite);
270
322
 
271
323
  const backendRules = readTemplate('backend-rules.md');
272
324
  const backendRule =
273
- '---\ndescription: Backend code rules — architecture enforcement, type safety\ntype: auto\nglobs: "src/**/*.ts,src/**/*.js"\n---\n\n' +
325
+ `---\ndescription: Backend code rules — architecture enforcement, type safety\ntype: auto\nglobs: "${globs.backend}"\n---\n\n` +
274
326
  backendRules;
275
327
  writeFile(targetDir, '.agent/rules/backend.md', backendRule, overwrite);
276
328
 
@@ -378,10 +430,11 @@ async function run(argv) {
378
430
  }
379
431
 
380
432
  const gen = GENERATORS[ide];
381
- console.log(`\n Installing for ${gen.name}...\n`);
433
+ const lang = detectLanguage(args.dir);
434
+ console.log(`\n Installing for ${gen.name}... (detected language: ${lang})\n`);
382
435
  gen.fn(args.dir, args.overwrite);
383
- console.log(`\n Done! Edit docs/project-state.md to set up your first sprint.\n`);
436
+ console.log(`\n Done! Run "bootstrap" in your AI chat to auto-fill state files and rules.\n`);
384
437
  }
385
438
  }
386
439
 
387
- module.exports = { run };
440
+ module.exports = { run, detectLanguage, LANG_GLOBS };