mulch-cli 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 +104 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +30 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/edit.d.ts +3 -0
- package/dist/commands/edit.d.ts.map +1 -0
- package/dist/commands/edit.js +128 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +20 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/onboard.d.ts +8 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +144 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/prime.d.ts +3 -0
- package/dist/commands/prime.d.ts.map +1 -0
- package/dist/commands/prime.js +107 -0
- package/dist/commands/prime.js.map +1 -0
- package/dist/commands/prune.d.ts +3 -0
- package/dist/commands/prune.d.ts.map +1 -0
- package/dist/commands/prune.js +71 -0
- package/dist/commands/prune.js.map +1 -0
- package/dist/commands/query.d.ts +3 -0
- package/dist/commands/query.d.ts.map +1 -0
- package/dist/commands/query.js +58 -0
- package/dist/commands/query.js.map +1 -0
- package/dist/commands/record.d.ts +3 -0
- package/dist/commands/record.d.ts.map +1 -0
- package/dist/commands/record.js +206 -0
- package/dist/commands/record.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +80 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup.d.ts +29 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +497 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +32 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +62 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/config.d.ts +17 -0
- package/dist/schemas/config.d.ts.map +1 -0
- package/dist/schemas/config.js +16 -0
- package/dist/schemas/config.js.map +1 -0
- package/dist/schemas/index.d.ts +4 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/record-schema.d.ts +230 -0
- package/dist/schemas/record-schema.d.ts.map +1 -0
- package/dist/schemas/record-schema.js +111 -0
- package/dist/schemas/record-schema.js.map +1 -0
- package/dist/schemas/record.d.ts +49 -0
- package/dist/schemas/record.d.ts.map +1 -0
- package/dist/schemas/record.js +2 -0
- package/dist/schemas/record.js.map +1 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +83 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/expertise.d.ts +14 -0
- package/dist/utils/expertise.d.ts.map +1 -0
- package/dist/utils/expertise.js +107 -0
- package/dist/utils/expertise.js.map +1 -0
- package/dist/utils/format.d.ts +28 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +373 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jaymin West
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Mulch — Growing Expertise for Coding Agents
|
|
2
|
+
|
|
3
|
+
Structured expertise files that accumulate over time, live in git, work with any agent, and run locally with zero dependencies.
|
|
4
|
+
|
|
5
|
+
Agents start every session from zero. The pattern your agent discovered yesterday is forgotten today. Mulch fixes this: agents call `mulch record` to write learnings, and `mulch query` to read them. Expertise compounds across sessions, domains, and teammates.
|
|
6
|
+
|
|
7
|
+
**Mulch is a passive layer.** It does not contain an LLM. Agents use Mulch — Mulch does not use agents.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx mulch-cli init # Create .mulch/ in your project
|
|
13
|
+
mulch add database # Add a domain
|
|
14
|
+
mulch record database --type convention "Use WAL mode for SQLite"
|
|
15
|
+
mulch record database --type failure \
|
|
16
|
+
--description "VACUUM inside a transaction causes silent corruption" \
|
|
17
|
+
--resolution "Always run VACUUM outside transaction boundaries"
|
|
18
|
+
mulch query database # See accumulated expertise
|
|
19
|
+
mulch prime # Get full context for agent injection
|
|
20
|
+
mulch prime database # Get context for one domain only
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## How It Works
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
1. mulch init → Creates .mulch/ with domain JSONL files
|
|
27
|
+
2. Agent reads expertise → Grounded in everything the project has learned
|
|
28
|
+
3. Agent does work → Normal task execution
|
|
29
|
+
4. Agent calls mulch record → Writes structured learnings back to .mulch/
|
|
30
|
+
5. git push → Teammates' agents get smarter too
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The critical insight: step 4 is **agent-driven**. The agent decides what's worth recording. Mulch provides the schema and file structure so those learnings land in a consistent, queryable format.
|
|
34
|
+
|
|
35
|
+
## What's in `.mulch/`
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
.mulch/
|
|
39
|
+
├── expertise/
|
|
40
|
+
│ ├── database.jsonl # All database knowledge
|
|
41
|
+
│ ├── api.jsonl # One JSONL file per domain
|
|
42
|
+
│ └── testing.jsonl # Each line is a typed, structured record
|
|
43
|
+
└── mulch.config.yaml # Config: domains, governance settings
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Everything is git-tracked. Clone a repo and your agents immediately have the project's accumulated expertise.
|
|
47
|
+
|
|
48
|
+
## CLI Reference
|
|
49
|
+
|
|
50
|
+
| Command | Description |
|
|
51
|
+
|---------|-------------|
|
|
52
|
+
| `mulch init` | Initialize `.mulch/` in the current project |
|
|
53
|
+
| `mulch add <domain>` | Add a new expertise domain |
|
|
54
|
+
| `mulch record <domain> --type <type>` | Record an expertise entry |
|
|
55
|
+
| `mulch query [domain]` | Query expertise (use `--all` for all domains) |
|
|
56
|
+
| `mulch prime [domain]` | Output AI-optimized expertise context (optionally scoped) |
|
|
57
|
+
| `mulch search <query>` | Search records across domains (`--domain`, `--type` filters) |
|
|
58
|
+
| `mulch status` | Show expertise freshness and counts |
|
|
59
|
+
| `mulch validate` | Schema validation across all files |
|
|
60
|
+
| `mulch setup <provider>` | Install provider-specific hooks |
|
|
61
|
+
| `mulch onboard` | Generate AGENTS.md/CLAUDE.md snippet |
|
|
62
|
+
| `mulch prune` | Remove stale tactical entries |
|
|
63
|
+
|
|
64
|
+
## Record Types
|
|
65
|
+
|
|
66
|
+
| Type | Required Fields | Use Case |
|
|
67
|
+
|------|----------------|----------|
|
|
68
|
+
| `convention` | content | "Use WAL mode for SQLite connections" |
|
|
69
|
+
| `pattern` | name, description | Named patterns with optional file references |
|
|
70
|
+
| `failure` | description, resolution | What went wrong and how to avoid it |
|
|
71
|
+
| `decision` | title, rationale | Architectural decisions and their reasoning |
|
|
72
|
+
|
|
73
|
+
All records support optional `--classification` (foundational / tactical / observational) and evidence flags (`--evidence-commit`, `--evidence-issue`, `--evidence-file`).
|
|
74
|
+
|
|
75
|
+
## Example Output
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
$ mulch query database
|
|
79
|
+
|
|
80
|
+
## database (6 entries, updated 2h ago)
|
|
81
|
+
|
|
82
|
+
### Conventions
|
|
83
|
+
- Use WAL mode for all SQLite connections
|
|
84
|
+
- Migrations are sequential, never concurrent
|
|
85
|
+
|
|
86
|
+
### Known Failures
|
|
87
|
+
- VACUUM inside a transaction causes silent corruption
|
|
88
|
+
→ Always run VACUUM outside transaction boundaries
|
|
89
|
+
|
|
90
|
+
### Decisions
|
|
91
|
+
- **SQLite over PostgreSQL**: Local-only product, no network dependency acceptable
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Design Principles
|
|
95
|
+
|
|
96
|
+
- **Zero LLM dependency** — Mulch makes no LLM calls. Quality equals agent quality.
|
|
97
|
+
- **Provider-agnostic** — Any agent with bash access can call the CLI.
|
|
98
|
+
- **Git-native** — Everything lives in `.mulch/`, tracked in version control.
|
|
99
|
+
- **Append-only JSONL** — Zero merge conflicts, trivial schema validation.
|
|
100
|
+
- **Storage ≠ Delivery** — JSONL on disk, optimized markdown/XML for agents.
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { registerInitCommand } from "./commands/init.js";
|
|
4
|
+
import { registerAddCommand } from "./commands/add.js";
|
|
5
|
+
import { registerRecordCommand } from "./commands/record.js";
|
|
6
|
+
import { registerEditCommand } from "./commands/edit.js";
|
|
7
|
+
import { registerQueryCommand } from "./commands/query.js";
|
|
8
|
+
import { registerSetupCommand } from "./commands/setup.js";
|
|
9
|
+
import { registerPrimeCommand } from "./commands/prime.js";
|
|
10
|
+
import { registerOnboardCommand } from "./commands/onboard.js";
|
|
11
|
+
import { registerStatusCommand } from "./commands/status.js";
|
|
12
|
+
import { registerValidateCommand } from "./commands/validate.js";
|
|
13
|
+
import { registerPruneCommand } from "./commands/prune.js";
|
|
14
|
+
import { registerSearchCommand } from "./commands/search.js";
|
|
15
|
+
const program = new Command();
|
|
16
|
+
program
|
|
17
|
+
.name("mulch")
|
|
18
|
+
.description("Growing Expertise for Coding Agents")
|
|
19
|
+
.version("0.1.0");
|
|
20
|
+
registerInitCommand(program);
|
|
21
|
+
registerAddCommand(program);
|
|
22
|
+
registerRecordCommand(program);
|
|
23
|
+
registerEditCommand(program);
|
|
24
|
+
registerQueryCommand(program);
|
|
25
|
+
registerSetupCommand(program);
|
|
26
|
+
registerPrimeCommand(program);
|
|
27
|
+
registerOnboardCommand(program);
|
|
28
|
+
registerStatusCommand(program);
|
|
29
|
+
registerValidateCommand(program);
|
|
30
|
+
registerPruneCommand(program);
|
|
31
|
+
registerSearchCommand(program);
|
|
32
|
+
program.parse();
|
|
33
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,qCAAqC,CAAC;KAClD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAE/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkCzD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { getMulchDir, readConfig, writeConfig, getExpertisePath } from "../utils/config.js";
|
|
4
|
+
import { createExpertiseFile } from "../utils/expertise.js";
|
|
5
|
+
export function registerAddCommand(program) {
|
|
6
|
+
program
|
|
7
|
+
.command("add")
|
|
8
|
+
.argument("<domain>", "expertise domain to add")
|
|
9
|
+
.description("Add a new expertise domain")
|
|
10
|
+
.action(async (domain) => {
|
|
11
|
+
const mulchDir = getMulchDir();
|
|
12
|
+
if (!existsSync(mulchDir)) {
|
|
13
|
+
console.error(chalk.red("No .mulch/ directory found. Run `mulch init` first."));
|
|
14
|
+
process.exitCode = 1;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const config = await readConfig();
|
|
18
|
+
if (config.domains.includes(domain)) {
|
|
19
|
+
console.error(chalk.red(`Domain "${domain}" already exists.`));
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const expertisePath = getExpertisePath(domain);
|
|
24
|
+
await createExpertiseFile(expertisePath);
|
|
25
|
+
config.domains.push(domain);
|
|
26
|
+
await writeConfig(config);
|
|
27
|
+
console.log(chalk.green(`Added domain "${domain}".`));
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,UAAU,EAAE,yBAAyB,CAAC;SAC/C,WAAW,CAAC,4BAA4B,CAAC;SACzC,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,EAAE;QAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAE/B,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CACjE,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAElC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,WAAW,MAAM,mBAAmB,CAAC,CAChD,CAAC;YACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,mBAAmB,CAAC,aAAa,CAAC,CAAC;QAEzC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5B,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAE1B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,iBAAiB,MAAM,IAAI,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AAY5C,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgK1D"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Option } from "commander";
|
|
2
|
+
import _Ajv from "ajv";
|
|
3
|
+
const Ajv = _Ajv.default ?? _Ajv;
|
|
4
|
+
import chalk from "chalk";
|
|
5
|
+
import { readConfig, getExpertisePath } from "../utils/config.js";
|
|
6
|
+
import { readExpertiseFile, writeExpertiseFile, } from "../utils/expertise.js";
|
|
7
|
+
import { recordSchema } from "../schemas/record-schema.js";
|
|
8
|
+
export function registerEditCommand(program) {
|
|
9
|
+
program
|
|
10
|
+
.command("edit")
|
|
11
|
+
.argument("<domain>", "expertise domain")
|
|
12
|
+
.argument("<index>", "1-based record index")
|
|
13
|
+
.description("Edit an existing expertise record")
|
|
14
|
+
.addOption(new Option("--classification <classification>", "update classification").choices(["foundational", "tactical", "observational"]))
|
|
15
|
+
.option("--content <content>", "update content (convention)")
|
|
16
|
+
.option("--name <name>", "update name (pattern)")
|
|
17
|
+
.option("--description <description>", "update description")
|
|
18
|
+
.option("--resolution <resolution>", "update resolution (failure)")
|
|
19
|
+
.option("--title <title>", "update title (decision)")
|
|
20
|
+
.option("--rationale <rationale>", "update rationale (decision)")
|
|
21
|
+
.option("--files <files>", "update related files (comma-separated)")
|
|
22
|
+
.action(async (domain, indexStr, options) => {
|
|
23
|
+
try {
|
|
24
|
+
const config = await readConfig();
|
|
25
|
+
if (!config.domains.includes(domain)) {
|
|
26
|
+
console.error(chalk.red(`Error: domain "${domain}" not found in config.`));
|
|
27
|
+
console.error(chalk.red(`Available domains: ${config.domains.join(", ") || "(none)"}`));
|
|
28
|
+
process.exitCode = 1;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const index = parseInt(indexStr, 10);
|
|
32
|
+
if (isNaN(index) || index < 1) {
|
|
33
|
+
console.error(chalk.red("Error: index must be a positive integer (1-based)."));
|
|
34
|
+
process.exitCode = 1;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const filePath = getExpertisePath(domain);
|
|
38
|
+
const records = await readExpertiseFile(filePath);
|
|
39
|
+
if (index > records.length) {
|
|
40
|
+
console.error(chalk.red(`Error: index ${index} out of range. Domain "${domain}" has ${records.length} record(s).`));
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const record = { ...records[index - 1] };
|
|
45
|
+
// Apply updates based on record type
|
|
46
|
+
if (options.classification) {
|
|
47
|
+
record.classification = options.classification;
|
|
48
|
+
}
|
|
49
|
+
switch (record.type) {
|
|
50
|
+
case "convention":
|
|
51
|
+
if (options.content) {
|
|
52
|
+
record.content = options.content;
|
|
53
|
+
}
|
|
54
|
+
break;
|
|
55
|
+
case "pattern":
|
|
56
|
+
if (options.name) {
|
|
57
|
+
record.name = options.name;
|
|
58
|
+
}
|
|
59
|
+
if (options.description) {
|
|
60
|
+
record.description = options.description;
|
|
61
|
+
}
|
|
62
|
+
if (typeof options.files === "string") {
|
|
63
|
+
record.files = options.files.split(",");
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
case "failure":
|
|
67
|
+
if (options.description) {
|
|
68
|
+
record.description = options.description;
|
|
69
|
+
}
|
|
70
|
+
if (options.resolution) {
|
|
71
|
+
record.resolution = options.resolution;
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
case "decision":
|
|
75
|
+
if (options.title) {
|
|
76
|
+
record.title = options.title;
|
|
77
|
+
}
|
|
78
|
+
if (options.rationale) {
|
|
79
|
+
record.rationale = options.rationale;
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case "reference":
|
|
83
|
+
if (options.name) {
|
|
84
|
+
record.name = options.name;
|
|
85
|
+
}
|
|
86
|
+
if (options.description) {
|
|
87
|
+
record.description = options.description;
|
|
88
|
+
}
|
|
89
|
+
if (typeof options.files === "string") {
|
|
90
|
+
record.files = options.files.split(",");
|
|
91
|
+
}
|
|
92
|
+
break;
|
|
93
|
+
case "guide":
|
|
94
|
+
if (options.name) {
|
|
95
|
+
record.name = options.name;
|
|
96
|
+
}
|
|
97
|
+
if (options.description) {
|
|
98
|
+
record.description = options.description;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
// Validate the updated record
|
|
103
|
+
const ajv = new Ajv();
|
|
104
|
+
const validate = ajv.compile(recordSchema);
|
|
105
|
+
if (!validate(record)) {
|
|
106
|
+
console.error(chalk.red("Error: updated record failed schema validation:"));
|
|
107
|
+
for (const err of validate.errors ?? []) {
|
|
108
|
+
console.error(chalk.red(` ${err.instancePath} ${err.message}`));
|
|
109
|
+
}
|
|
110
|
+
process.exitCode = 1;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
records[index - 1] = record;
|
|
114
|
+
await writeExpertiseFile(filePath, records);
|
|
115
|
+
console.log(chalk.green(`\u2714 Updated ${record.type} #${index} in ${domain}`));
|
|
116
|
+
}
|
|
117
|
+
catch (err) {
|
|
118
|
+
if (err.code === "ENOENT") {
|
|
119
|
+
console.error("Error: No .mulch/ directory found. Run `mulch init` first.");
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
console.error(`Error: ${err.message}`);
|
|
123
|
+
}
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/commands/edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkB1D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { getMulchDir, initMulchDir } from "../utils/config.js";
|
|
4
|
+
export function registerInitCommand(program) {
|
|
5
|
+
program
|
|
6
|
+
.command("init")
|
|
7
|
+
.description("Initialize .mulch/ in the current project")
|
|
8
|
+
.action(async () => {
|
|
9
|
+
const mulchDir = getMulchDir();
|
|
10
|
+
const alreadyExists = existsSync(mulchDir);
|
|
11
|
+
await initMulchDir();
|
|
12
|
+
if (alreadyExists) {
|
|
13
|
+
console.log(chalk.green("Updated .mulch/ — filled in any missing artifacts."));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.log(chalk.green(`Initialized .mulch/ in ${process.cwd()}`));
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE/D,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,2CAA2C,CAAC;SACxD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;QAC/B,MAAM,aAAa,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QAE3C,MAAM,YAAY,EAAE,CAAC;QAErB,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAClE,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
export declare function runOnboard(options: {
|
|
3
|
+
stdout?: boolean;
|
|
4
|
+
provider?: string;
|
|
5
|
+
cwd?: string;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function registerOnboardCommand(program: Command): void;
|
|
8
|
+
//# sourceMappingURL=onboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA6GpC,wBAAsB,UAAU,CAAC,OAAO,EAAE;IACxC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BhB;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB7D"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { readFile, writeFile, access } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import chalk from "chalk";
|
|
4
|
+
const SNIPPET_DEFAULT = `## Project Expertise (Mulch)
|
|
5
|
+
|
|
6
|
+
This project uses [Mulch](https://github.com/jayminwest/mulch) for structured expertise management.
|
|
7
|
+
|
|
8
|
+
**Before starting work**, run:
|
|
9
|
+
\`\`\`bash
|
|
10
|
+
mulch prime
|
|
11
|
+
\`\`\`
|
|
12
|
+
|
|
13
|
+
**After completing work**, record learnings:
|
|
14
|
+
\`\`\`bash
|
|
15
|
+
mulch record <domain> --type <convention|pattern|failure|decision> --description "..."
|
|
16
|
+
\`\`\`
|
|
17
|
+
|
|
18
|
+
Run \`mulch status\` to see available domains and expertise health.
|
|
19
|
+
|
|
20
|
+
### Session Completion Checklist
|
|
21
|
+
|
|
22
|
+
1. Record learnings:
|
|
23
|
+
\`\`\`bash
|
|
24
|
+
mulch record <domain> --type <convention|pattern|failure|decision> --description "..."
|
|
25
|
+
\`\`\`
|
|
26
|
+
2. Validate records:
|
|
27
|
+
\`\`\`bash
|
|
28
|
+
mulch validate
|
|
29
|
+
\`\`\`
|
|
30
|
+
3. Commit changes:
|
|
31
|
+
\`\`\`bash
|
|
32
|
+
git add .mulch/ && git commit -m "Update expertise"
|
|
33
|
+
\`\`\`
|
|
34
|
+
4. Push to share:
|
|
35
|
+
\`\`\`bash
|
|
36
|
+
git push
|
|
37
|
+
\`\`\`
|
|
38
|
+
`;
|
|
39
|
+
function getSnippet(provider) {
|
|
40
|
+
if (!provider || provider === "default") {
|
|
41
|
+
return SNIPPET_DEFAULT;
|
|
42
|
+
}
|
|
43
|
+
// Provider-specific snippets customize the phrasing slightly
|
|
44
|
+
if (provider === "claude") {
|
|
45
|
+
return `## Project Expertise (Mulch)
|
|
46
|
+
|
|
47
|
+
This project uses [Mulch](https://github.com/jayminwest/mulch) for structured expertise management.
|
|
48
|
+
|
|
49
|
+
**At the start of every session**, run:
|
|
50
|
+
\`\`\`bash
|
|
51
|
+
mulch prime
|
|
52
|
+
\`\`\`
|
|
53
|
+
|
|
54
|
+
This injects project-specific conventions, patterns, and decisions into your context.
|
|
55
|
+
|
|
56
|
+
**After completing work**, record what you learned:
|
|
57
|
+
\`\`\`bash
|
|
58
|
+
mulch record <domain> --type <convention|pattern|failure|decision> --description "..."
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
Run \`mulch status\` to check domain health and entry counts.
|
|
62
|
+
|
|
63
|
+
### Session Completion Checklist
|
|
64
|
+
|
|
65
|
+
1. Record learnings:
|
|
66
|
+
\`\`\`bash
|
|
67
|
+
mulch record <domain> --type <convention|pattern|failure|decision> --description "..."
|
|
68
|
+
\`\`\`
|
|
69
|
+
2. Validate records:
|
|
70
|
+
\`\`\`bash
|
|
71
|
+
mulch validate
|
|
72
|
+
\`\`\`
|
|
73
|
+
3. Commit changes:
|
|
74
|
+
\`\`\`bash
|
|
75
|
+
git add .mulch/ && git commit -m "Update expertise"
|
|
76
|
+
\`\`\`
|
|
77
|
+
4. Push to share:
|
|
78
|
+
\`\`\`bash
|
|
79
|
+
git push
|
|
80
|
+
\`\`\`
|
|
81
|
+
`;
|
|
82
|
+
}
|
|
83
|
+
// For any other provider, use the default snippet
|
|
84
|
+
return SNIPPET_DEFAULT;
|
|
85
|
+
}
|
|
86
|
+
async function fileExists(filePath) {
|
|
87
|
+
try {
|
|
88
|
+
await access(filePath);
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function detectTargetFile(cwd) {
|
|
96
|
+
// If CLAUDE.md exists, prefer it
|
|
97
|
+
if (await fileExists(join(cwd, "CLAUDE.md"))) {
|
|
98
|
+
return "CLAUDE.md";
|
|
99
|
+
}
|
|
100
|
+
// Otherwise default to AGENTS.md
|
|
101
|
+
return "AGENTS.md";
|
|
102
|
+
}
|
|
103
|
+
export async function runOnboard(options) {
|
|
104
|
+
const cwd = options.cwd ?? process.cwd();
|
|
105
|
+
const snippet = getSnippet(options.provider);
|
|
106
|
+
if (options.stdout) {
|
|
107
|
+
process.stdout.write(snippet);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const targetFileName = await detectTargetFile(cwd);
|
|
111
|
+
const targetPath = join(cwd, targetFileName);
|
|
112
|
+
// Check if snippet is already present
|
|
113
|
+
if (await fileExists(targetPath)) {
|
|
114
|
+
const existing = await readFile(targetPath, "utf-8");
|
|
115
|
+
if (existing.includes("## Project Expertise (Mulch)")) {
|
|
116
|
+
console.log(chalk.yellow(`Mulch snippet already exists in ${targetFileName}. No changes made.`));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Append to existing file
|
|
120
|
+
await writeFile(targetPath, existing + "\n" + snippet, "utf-8");
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
// Create new file
|
|
124
|
+
await writeFile(targetPath, snippet, "utf-8");
|
|
125
|
+
}
|
|
126
|
+
console.log(chalk.green(`Mulch onboarding snippet written to ${targetFileName}`));
|
|
127
|
+
}
|
|
128
|
+
export function registerOnboardCommand(program) {
|
|
129
|
+
program
|
|
130
|
+
.command("onboard")
|
|
131
|
+
.description("Generate an AGENTS.md/CLAUDE.md snippet pointing to mulch prime")
|
|
132
|
+
.option("--stdout", "print snippet to stdout instead of writing to file")
|
|
133
|
+
.option("--provider <provider>", "customize snippet for a specific provider (e.g. claude)")
|
|
134
|
+
.action(async (options) => {
|
|
135
|
+
try {
|
|
136
|
+
await runOnboard(options);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
console.error(`Error: ${err.message}`);
|
|
140
|
+
process.exitCode = 1;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=onboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prime.d.ts","sourceRoot":"","sources":["../../src/commands/prime.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAC;AA0B5C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiH3D"}
|