@codeenginestudio/harness-creator 1.0.1
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 +287 -0
- package/package.json +20 -0
- package/scripts/install.mjs +57 -0
- package/scripts/lib/install-utils.mjs +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# ces-harness-creator
|
|
2
|
+
|
|
3
|
+
> A Claude Code plugin that scaffolds a complete, production-grade harness around any software project — so coding agents can start, stay in scope, verify work, document decisions, and resume across sessions reliably.
|
|
4
|
+
|
|
5
|
+
Built by **Code Engine Studio** (CES). An evolution of [walkinglabs/harness-creator](https://github.com/walkinglabs/learn-harness-engineering), extended with architecture docs, enforcement workflows, a rules library.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it builds
|
|
10
|
+
|
|
11
|
+
One command turns any repo into a harness-equipped project:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
your-project/
|
|
15
|
+
├── CLAUDE.md ← agent instruction file (links to docs/)
|
|
16
|
+
├── feature_list.json ← feature tracker with acceptance criteria + ADR refs
|
|
17
|
+
├── progress.md ← session restart state
|
|
18
|
+
├── session-handoff.md ← context for the next session / agent
|
|
19
|
+
├── init.sh ← single verification entrypoint
|
|
20
|
+
├── docs/
|
|
21
|
+
│ ├── adr/ ← Architecture Decision Records
|
|
22
|
+
│ └── architecture/ ← C4 model in LikeC4 DSL
|
|
23
|
+
├── lefthook.yml ← git hooks: lint / typecheck / tests
|
|
24
|
+
├── .claude/
|
|
25
|
+
│ ├── settings.json ← Claude Code hooks (Tier 2)
|
|
26
|
+
│ ├── hooks/ ← Tier 1 scripts + Tier 3 nudge scripts
|
|
27
|
+
│ ├── workflows/ ← on-demand verification workflows (Tier 3)
|
|
28
|
+
│ ├── rules/ ← curated guardrails (.md files)
|
|
29
|
+
│ └── skills/ ← project-specific agent workflows
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
Requires an SSH key configured for GitHub (Code Engine Studio org members only).
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx @codeenginestudio/harness-creator@latest
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The wizard will:
|
|
43
|
+
1. Check for `claude` CLI (install [Claude Code](https://claude.ai/code) if missing)
|
|
44
|
+
2. Ask whether to install for **user** scope (all projects) or **project** scope (current directory)
|
|
45
|
+
3. Detect if `superpowers` is missing and offer to install it automatically
|
|
46
|
+
4. Install `ces-harness-creator` from the private GitHub repo via SSH
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Usage
|
|
51
|
+
|
|
52
|
+
Invoke the main skill in any project:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
/ces-harness-creator
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Eight phases run in sequence with a human-approval checkpoint after each.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## The 8 Phases
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
flowchart TD
|
|
66
|
+
P1["Phase 1\nPrerequisites\nSuperpowers check\nDetect new/existing/harness"]
|
|
67
|
+
P2["Phase 2\nDiscovery\nNew → brainstorming\nExisting → scan report"]
|
|
68
|
+
P3["Phase 3\nArchitecture\nADRs + C4 model\nnpx likec4 serve"]
|
|
69
|
+
P4["Phase 4\nHarness Files\nCLAUDE.md · feature_list.json\nprogress.md · init.sh"]
|
|
70
|
+
P5["Phase 5\nWorkflows ✦\nPropose 4 dynamic-workflow\nenforcement scripts"]
|
|
71
|
+
P6["Phase 6\nHooks ✦\nlefthook + Claude Code hooks\n3-tier enforcement wired"]
|
|
72
|
+
P7["Phase 7\nRules ○\n42 curated templates\n+ scan-generated + interview"]
|
|
73
|
+
P8["Phase 8\nSkills ○\nStack-matched templates\n+ custom workflow interview"]
|
|
74
|
+
|
|
75
|
+
P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7 --> P8
|
|
76
|
+
|
|
77
|
+
style P7 stroke-dasharray:5,5
|
|
78
|
+
style P8 stroke-dasharray:5,5
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
> **✦ required ○ optional (user-gated)**
|
|
82
|
+
|
|
83
|
+
### What each phase produces
|
|
84
|
+
|
|
85
|
+
| Phase | Key outputs |
|
|
86
|
+
| ----------------- | ------------------------------------------------------------------------------------------- |
|
|
87
|
+
| 1 — Prerequisites | Mode: `new` / `existing` / `existing-with-harness` |
|
|
88
|
+
| 2 — Discovery | Scan report (stack, tooling, missing artifacts). New projects → `superpowers:brainstorming` |
|
|
89
|
+
| 3 — Architecture | `docs/adr/` (3 seed ADRs) · `docs/architecture/*.c4` (LikeC4 C4 model, localhost preview) |
|
|
90
|
+
| 4 — Harness Files | `CLAUDE.md` · `feature_list.json` · `progress.md` · `session-handoff.md` · `init.sh` |
|
|
91
|
+
| 5 — Workflows | `.claude/workflows/*.js` — adapted from 4 generic templates |
|
|
92
|
+
| 6 — Hooks | `lefthook.yml` · `.claude/settings.json` · `.claude/hooks/*.sh` |
|
|
93
|
+
| 7 — Rules | `.claude/rules/*.md` — 42-template library, propose-and-select |
|
|
94
|
+
| 8 — Skills | `.claude/skills/*/SKILL.md` — per-stack templates, tailored to real conventions |
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Enforcement: 3-Tier Model
|
|
99
|
+
|
|
100
|
+
Every harness wires three escalating tiers of enforcement:
|
|
101
|
+
|
|
102
|
+
```mermaid
|
|
103
|
+
flowchart LR
|
|
104
|
+
subgraph T1["Tier 1 — Free, automatic"]
|
|
105
|
+
C1["lefthook\ngit hooks\nlint · typecheck · test"]
|
|
106
|
+
C2["precommit-check.sh\n(exit 2 = blocks commit)"]
|
|
107
|
+
end
|
|
108
|
+
subgraph T2["Tier 2 — Low cost, automatic"]
|
|
109
|
+
C3["Claude Code\nPreToolUse agent hook\non every git commit"]
|
|
110
|
+
end
|
|
111
|
+
subgraph T3["Tier 3 — Higher cost, prompted"]
|
|
112
|
+
C4["Dynamic workflows\n.claude/workflows/*.js\nfan-out verifiers\n+ adversarial skeptic"]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
GC["git commit"] --> T1 --> T2
|
|
116
|
+
GP["git push / gh pr create"] -->|"nudge hook\nadditionalContext"| T3
|
|
117
|
+
SE["SessionEnd"] -->|"suggest rule-miner"| T3
|
|
118
|
+
T3 -->|"user approves"| WF["Workflow tool\nlaunches workflow"]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
> Hooks cannot launch workflows directly. `suggest-deep-pass.sh` exits 0 and injects `additionalContext`; Claude — which holds the Workflow tool — offers the relevant workflow and launches it on approval. Tier 3 is prompted, never auto-fired.
|
|
122
|
+
|
|
123
|
+
### The 4 Enforcement Workflows
|
|
124
|
+
|
|
125
|
+
| Workflow | Pattern | What it checks |
|
|
126
|
+
| ---------------------------------- | --------------------------------------------------------- | ----------------------------------------- |
|
|
127
|
+
| `pre-commit-verification` | Classify-and-act → fan-out verify → synthesize | Staged diff vs init.sh / tests |
|
|
128
|
+
| `rules-adherence-checker` | Fan-out (1 agent/rule) → adversarial skeptic | `.claude/rules/` + CLAUDE.md |
|
|
129
|
+
| `architecture-consistency-checker` | Multi-angle analyzers → adversarial panel | `docs/architecture/*.c4` + `docs/adr/` |
|
|
130
|
+
| `rule-miner` | Mine corrections → cluster → adversarial verify → distill | git history + review comments → new rules |
|
|
131
|
+
|
|
132
|
+
Workflows are **templates, not verbatim scripts**. At generation time, Claude adapts each to the project — injecting real rule names, choosing models for the stack, and adding project-specific checks.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Rules Library (42 templates)
|
|
137
|
+
|
|
138
|
+
Six rules are enabled by default; the rest are proposed-and-selected:
|
|
139
|
+
|
|
140
|
+
| Category | Templates (count) | Default-on |
|
|
141
|
+
| ---------------- | ----------------- | ---------------------------------------- |
|
|
142
|
+
| Git & Commits | 5 | `semantic-commits`, `no-agent-coauthor` |
|
|
143
|
+
| Agent Behavior | 5 | `verify-before-done`, `surgical-changes` |
|
|
144
|
+
| Security | 4 | `no-secrets-in-code` |
|
|
145
|
+
| Documentation | 3 | `adr-for-decisions` |
|
|
146
|
+
| Code Quality | 5 | — |
|
|
147
|
+
| Testing | 4 | — |
|
|
148
|
+
| PR Workflow | 2 | — |
|
|
149
|
+
| Harness Design | 5 | — |
|
|
150
|
+
| Memory & Context | 9 | — |
|
|
151
|
+
|
|
152
|
+
> `no-agent-coauthor` encodes the CES preference: humans own the commit record; no AI co-author trailers.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Plugin Architecture
|
|
157
|
+
|
|
158
|
+
```mermaid
|
|
159
|
+
flowchart TB
|
|
160
|
+
subgraph Plugin["ces-harness-creator plugin repo"]
|
|
161
|
+
PM[".claude-plugin/plugin.json\n(declares superpowers dep)"]
|
|
162
|
+
SK["skills/\nOrchestrator SKILL.md\n+ 7 sub-skills"]
|
|
163
|
+
SC["scripts/\nNode.js ES modules\n(no npm deps)"]
|
|
164
|
+
TM["templates/\nhooks/ · adr/ · c4/\nclaude.md · feature-list"]
|
|
165
|
+
RL["rules-library/\n42 × .md templates\n9 categories"]
|
|
166
|
+
SL["skills-library/\n5 × stack skill templates"]
|
|
167
|
+
WL["workflows-library/\n4 × .js workflow templates"]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
subgraph Target["target project (any repo)"]
|
|
171
|
+
HF["Harness files\nCLAUDE.md · init.sh · …"]
|
|
172
|
+
DA["docs/adr/ · docs/architecture/"]
|
|
173
|
+
WF[".claude/workflows/*.js"]
|
|
174
|
+
HK[".claude/hooks/ · lefthook.yml\n.claude/settings.json"]
|
|
175
|
+
RU[".claude/rules/*.md"]
|
|
176
|
+
SP[".claude/skills/*/SKILL.md"]
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
SK -->|"phase 1-2: detect + scan"| SC
|
|
180
|
+
SC -->|"planArchitecture()"| DA
|
|
181
|
+
SC -->|"planCoreHarness()"| HF
|
|
182
|
+
SC -->|"planWorkflows()"| WF
|
|
183
|
+
SC -->|"planHooks()"| HK
|
|
184
|
+
SC -->|"planRules()"| RU
|
|
185
|
+
SC -->|"planSkillsGen()"| SP
|
|
186
|
+
TM -.->|fill templates| SC
|
|
187
|
+
RL -.->|readFileSync + substitute| SC
|
|
188
|
+
SL -.->|readFileSync + substitute| SC
|
|
189
|
+
WL -.->|readFileSync + substitute| SC
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### scripts/lib/ map
|
|
193
|
+
|
|
194
|
+
| Module | Exports | Used by |
|
|
195
|
+
| ------------------------- | ----------------------------------------------------------- | ------------------------- |
|
|
196
|
+
| `harness-utils.mjs` | barrel re-export | all orchestrators |
|
|
197
|
+
| `fs-utils.mjs` | `parseArgs`, `exists`, `writeText`, `readJson`, `listFiles` | everything |
|
|
198
|
+
| `detect.mjs` | `detectProject`, `detectPackageManager` | scan, harness, hooks |
|
|
199
|
+
| `verification.mjs` | `verificationCommands`, `initScriptFromCommands` | harness, hooks, workflows |
|
|
200
|
+
| `detect-mode.mjs` | `classifyProjectMode` | Phase 1 |
|
|
201
|
+
| `scan-report.mjs` | `buildScanReport` | Phase 2 |
|
|
202
|
+
| `adr.mjs` | `adrDoc`, `adrIndex`, `adrFilename` | Phase 3 |
|
|
203
|
+
| `c4.mjs` | `c4Model`, `c4Views`, `c4Workspace`, `inferContainers` | Phase 3 |
|
|
204
|
+
| `score.mjs` | `scoreHarness`, `loadHarnessFiles` | validate sub-skill |
|
|
205
|
+
| `workflows.mjs` | `planWorkflows`, `WORKFLOW_NAMES` | Phase 5 |
|
|
206
|
+
| `hooks.mjs` | `planHooks` | Phase 6 |
|
|
207
|
+
| `enforcement-audit.mjs` | `auditEnforcement` | validate |
|
|
208
|
+
| `rules-gen.mjs` | `planRules`, `DEFAULT_RULES`, `ALL_RULE_NAMES` | Phase 7 |
|
|
209
|
+
| `skills-gen.mjs` | `planSkillsGen`, `opportunitiesForStack` | Phase 8 |
|
|
210
|
+
| `customization-audit.mjs` | `auditCustomization` | validate |
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Harness Validation
|
|
215
|
+
|
|
216
|
+
Audit any harness (including the ones this plugin generates):
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
node scripts/validate.mjs --target /path/to/project
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Output: 5-subsystem score (0–100) + enforcement tier audit + customization summary.
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
Harness validation for /path/to/project
|
|
226
|
+
Overall: 95/100 Bottleneck: lifecycle
|
|
227
|
+
|
|
228
|
+
instructions: 5/5
|
|
229
|
+
state: 4/5
|
|
230
|
+
verification: 5/5
|
|
231
|
+
scope: 5/5
|
|
232
|
+
lifecycle: 4/5
|
|
233
|
+
|
|
234
|
+
Enforcement:
|
|
235
|
+
Tier 1 (git hooks + precommit): present
|
|
236
|
+
Tier 2 (Claude hooks settings): present
|
|
237
|
+
Tier 3 (workflows): 4 installed
|
|
238
|
+
|
|
239
|
+
Customization:
|
|
240
|
+
Rules: 8 installed (defaults present)
|
|
241
|
+
Skills: 2 installed
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Sub-skills
|
|
247
|
+
|
|
248
|
+
| Sub-skill | Command | Purpose |
|
|
249
|
+
| -------------------------------- | --------------------------------- | --------------------------------------------- |
|
|
250
|
+
| `ces-harness-creator:scan` | `/ces-harness-creator:scan` | Scan only — stack, tooling, missing artifacts |
|
|
251
|
+
| `ces-harness-creator:arch` | `/ces-harness-creator:arch` | ADR + C4 generation only |
|
|
252
|
+
| `ces-harness-creator:validate` | `/ces-harness-creator:validate` | Audit an existing harness |
|
|
253
|
+
| `ces-harness-creator:workflows` | `/ces-harness-creator:workflows` | Phase 5 only — propose + install workflows |
|
|
254
|
+
| `ces-harness-creator:hooks` | `/ces-harness-creator:hooks` | Phase 6 only — wire enforcement hooks |
|
|
255
|
+
| `ces-harness-creator:rules` | `/ces-harness-creator:rules` | Phase 7 only — propose + install rules |
|
|
256
|
+
| `ces-harness-creator:skills-gen` | `/ces-harness-creator:skills-gen` | Phase 8 only — propose + install skills |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Resumability
|
|
261
|
+
|
|
262
|
+
Phase state is saved to `.claude/harness-state.json`. Re-running `/ces-harness-creator` on a partial harness offers: **"Resume from Phase N or start fresh?"** Each emitter is non-destructive by default (skips existing files); use `--force` to overwrite.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## Design Principles
|
|
267
|
+
|
|
268
|
+
Every generated harness propagates these principles into the target project:
|
|
269
|
+
|
|
270
|
+
1. **State assumptions explicitly** — ask when uncertain, never silently assume
|
|
271
|
+
2. **Minimal scope** — generate only what was requested; nothing speculative
|
|
272
|
+
3. **Surgical changes** — in existing repos, touch only what serves the goal
|
|
273
|
+
4. **Verification-first** — define "done" as testable criteria before acting
|
|
274
|
+
5. **Evidence required** — no "done" claim without tool output
|
|
275
|
+
6. **Propose before create** — rules, skills, and workflows need human approval first
|
|
276
|
+
7. **Traceability** — every generated artifact traces to a requirement or detected fact
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## References
|
|
281
|
+
|
|
282
|
+
- [Learn Harness Engineering](https://github.com/walkinglabs/learn-harness-engineering) — 12-lecture course; original `harness-creator`
|
|
283
|
+
- [Superpowers](https://github.com/obra/superpowers) — required plugin dependency
|
|
284
|
+
- [LikeC4](https://likec4.dev) — C4 architecture DSL and viewer
|
|
285
|
+
- [Dynamic Workflows](https://code.claude.com/docs/en/workflows) — Claude Code workflow API
|
|
286
|
+
- [Claude Code Hooks](https://code.claude.com/docs/en/hooks) — hook schema reference
|
|
287
|
+
- "A harness for every task: dynamic workflows in Claude Code" — Thariq Shihipar & Sid Bidasaria (source of canonical workflow patterns)
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@codeenginestudio/harness-creator",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "CES Harness Creator — install wizard",
|
|
7
|
+
"bin": {
|
|
8
|
+
"harness-creator": "scripts/install.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"scripts/install.mjs",
|
|
12
|
+
"scripts/lib/install-utils.mjs"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "node --test \"scripts/__tests__/**/*.test.mjs\""
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@clack/prompts": "^0.9.0"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import {
|
|
4
|
+
checkClaude,
|
|
5
|
+
isPluginInstalled,
|
|
6
|
+
isSelfRepo,
|
|
7
|
+
runClaudeCommand,
|
|
8
|
+
PLUGIN_PATH,
|
|
9
|
+
} from './lib/install-utils.mjs';
|
|
10
|
+
|
|
11
|
+
async function promptScope() {
|
|
12
|
+
const scope = await p.select({
|
|
13
|
+
message: 'Install for:',
|
|
14
|
+
options: [
|
|
15
|
+
{ value: 'user', label: 'User', hint: '~/.claude — available in all projects' },
|
|
16
|
+
{ value: 'project', label: 'Project', hint: `${process.cwd()} — current directory only` },
|
|
17
|
+
],
|
|
18
|
+
});
|
|
19
|
+
if (p.isCancel(scope)) { p.cancel('Cancelled.'); process.exit(1); }
|
|
20
|
+
if (scope === 'project' && isSelfRepo()) {
|
|
21
|
+
const ok = await p.confirm({ message: 'CWD is the ces-harness-creator repo itself. Continue?', initialValue: false });
|
|
22
|
+
if (p.isCancel(ok) || !ok) { p.cancel('Aborted. cd to your target project and re-run.'); process.exit(1); }
|
|
23
|
+
}
|
|
24
|
+
return scope;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function ensureSuperpowers() {
|
|
28
|
+
if (isPluginInstalled('superpowers')) return;
|
|
29
|
+
const install = await p.confirm({ message: 'superpowers is required. Install it?' });
|
|
30
|
+
if (p.isCancel(install) || !install) { p.cancel('Cannot continue without superpowers.'); process.exit(1); }
|
|
31
|
+
const s = p.spinner();
|
|
32
|
+
s.start('Installing superpowers...');
|
|
33
|
+
try {
|
|
34
|
+
runClaudeCommand('plugin marketplace add obra/superpowers');
|
|
35
|
+
s.stop('superpowers installed');
|
|
36
|
+
} catch (err) { s.stop('superpowers install failed'); throw err; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function installPlugin() {
|
|
40
|
+
const s = p.spinner();
|
|
41
|
+
s.start('Installing ces-harness-creator...');
|
|
42
|
+
try {
|
|
43
|
+
runClaudeCommand(`plugin marketplace add ${PLUGIN_PATH}`);
|
|
44
|
+
s.stop('ces-harness-creator installed');
|
|
45
|
+
} catch (err) { s.stop('ces-harness-creator install failed'); throw err; }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function main() {
|
|
49
|
+
p.intro('CES Harness Creator — Install Wizard');
|
|
50
|
+
if (!checkClaude()) { p.cancel('Claude Code not found. Install from: https://claude.ai/code'); process.exit(1); }
|
|
51
|
+
await promptScope();
|
|
52
|
+
await ensureSuperpowers();
|
|
53
|
+
await installPlugin();
|
|
54
|
+
p.outro('Done. Open Claude Code and run /ces-harness-creator');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main().catch((err) => { console.error(err.message); process.exit(1); });
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import { join, resolve, dirname } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const _packageRoot = resolve(__dirname, '../..');
|
|
9
|
+
export const PLUGIN_PATH = existsSync(join(_packageRoot, '.claude-plugin', 'plugin.json'))
|
|
10
|
+
? _packageRoot
|
|
11
|
+
: 'Code-Engine-Studio/ces-harness-creator';
|
|
12
|
+
|
|
13
|
+
export function checkClaude(exec = (cmd) => execSync(cmd, { stdio: 'ignore' })) {
|
|
14
|
+
try { exec('claude --version'); return true; } catch { return false; }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function isPluginInstalled(name, exec = (cmd) => execSync(cmd, { encoding: 'utf8', stdio: 'pipe' })) {
|
|
18
|
+
try {
|
|
19
|
+
const cacheDir = join(homedir(), '.claude', 'plugins', 'cache');
|
|
20
|
+
return exec(`find "${cacheDir}" -maxdepth 4 -type d -name "${name}"`).trim().length > 0;
|
|
21
|
+
} catch { return false; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isSelfRepo(exists = (p) => existsSync(p)) {
|
|
25
|
+
return exists(join(process.cwd(), '.claude-plugin', 'plugin.json'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function runClaudeCommand(args, exec = (cmd) => execSync(cmd, { stdio: 'inherit' })) {
|
|
29
|
+
exec(`claude ${args}`);
|
|
30
|
+
}
|