harnessed 1.0.1 → 1.0.2
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 +5 -5
- package/dist/cli.mjs +76 -11
- package/dist/cli.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/workflows/plan-feature/SKILL.md +56 -0
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
- **不 vendor 上游** — manifest describe install/check;上游升级用户 re-install 即获最新版
|
|
24
24
|
- **Composition Skill** — 自家 workflow skill 当指挥棒,调度多个上游协同 (research / execute-task / plan-feature 三 MVP workflow)
|
|
25
25
|
- **包管理器思维** — install dependency graph 自动解析, doctor 健康检查, install-base 一键装齐
|
|
26
|
-
- **统一入口** — 用户面对 `/
|
|
26
|
+
- **统一入口** — 用户面对 `/plan-feature` / `/execute-task` 等 slash command,不需学每家上游术语
|
|
27
27
|
|
|
28
28
|
---
|
|
29
29
|
|
|
@@ -74,7 +74,7 @@ npx harnessed@latest <command>
|
|
|
74
74
|
|
|
75
75
|
## ⚡ 使用流程
|
|
76
76
|
|
|
77
|
-
`/
|
|
77
|
+
`/plan-feature "新功能 X"` 一行触发 CLAUDE.md 4-stage 三层栈方法论:
|
|
78
78
|
|
|
79
79
|
```
|
|
80
80
|
① Discuss → ② Plan → ③ Execute → ④ Verify
|
|
@@ -94,7 +94,7 @@ npx harnessed@latest <command>
|
|
|
94
94
|
harnessed install plan-feature
|
|
95
95
|
|
|
96
96
|
# 2. 在 Claude Code 内跑
|
|
97
|
-
/
|
|
97
|
+
/plan-feature "新功能 X"
|
|
98
98
|
|
|
99
99
|
# 3. 中断后恢复 (任何时候)
|
|
100
100
|
harnessed resume
|
|
@@ -166,7 +166,7 @@ harnessed install plan-feature # 自动装齐 gstack + GSD + superpowers + plan
|
|
|
166
166
|
| Orchestration | GSD | 高层 phase 任务图 + 依赖分析 |
|
|
167
167
|
| Persistence | planning-with-files | 持久化 `task_plan.md` / `progress.md` / `findings.md` |
|
|
168
168
|
|
|
169
|
-
`/
|
|
169
|
+
`/plan-feature` 把 4 阶段串起来 — 每个阶段做不同事,输出喂给下一阶段。**没有合并**。
|
|
170
170
|
|
|
171
171
|
</details>
|
|
172
172
|
|
|
@@ -193,7 +193,7 @@ harnessed install plan-feature # 自动装齐 gstack + GSD + superpowers + plan
|
|
|
193
193
|
|
|
194
194
|
- `npx harnessed@latest setup` 跑的是 **Node.js CLI** (`bin/harnessed`)
|
|
195
195
|
- setup 装的 **workflow skills** (markdown) 进 `~/.claude/skills/`,由 Claude Code 运行时加载
|
|
196
|
-
- `/
|
|
196
|
+
- `/plan-feature` / `/execute-task` 等是 CC 内的 slash command,触发 skill 执行
|
|
197
197
|
- CLI 和 CC skill 共享 `.harnessed/checkpoints/` 状态目录
|
|
198
198
|
|
|
199
199
|
</details>
|
package/dist/cli.mjs
CHANGED
|
@@ -670,7 +670,7 @@ var init_resume = __esm({
|
|
|
670
670
|
|
|
671
671
|
// package.json
|
|
672
672
|
var package_default = {
|
|
673
|
-
version: "1.0.
|
|
673
|
+
version: "1.0.2"};
|
|
674
674
|
|
|
675
675
|
// src/manifest/errors.ts
|
|
676
676
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -4288,12 +4288,30 @@ function registerRollback(program2) {
|
|
|
4288
4288
|
console.log(`restored ${meta.files.length} file(s) from ${timestamp}`);
|
|
4289
4289
|
});
|
|
4290
4290
|
}
|
|
4291
|
+
var PHASE_212 = /* @__PURE__ */ new Set([
|
|
4292
|
+
"cc-plugin-marketplace",
|
|
4293
|
+
"git-clone-with-setup",
|
|
4294
|
+
"npx-skill-installer",
|
|
4295
|
+
"mcp-http-add"
|
|
4296
|
+
]);
|
|
4297
|
+
async function listBaseManifests2(pkgRoot) {
|
|
4298
|
+
const out = [];
|
|
4299
|
+
for (const d of ["manifests/tools", "manifests/skill-packs"]) {
|
|
4300
|
+
try {
|
|
4301
|
+
const entries = await readdir(resolve(pkgRoot, d));
|
|
4302
|
+
for (const f of entries.sort()) if (f.endsWith(".yaml")) out.push(resolve(pkgRoot, d, f));
|
|
4303
|
+
} catch {
|
|
4304
|
+
}
|
|
4305
|
+
}
|
|
4306
|
+
return out;
|
|
4307
|
+
}
|
|
4291
4308
|
function registerSetup(program2) {
|
|
4292
4309
|
program2.command("setup").description(
|
|
4293
|
-
"One-
|
|
4294
|
-
).option("--
|
|
4295
|
-
const dryRun = raw.
|
|
4296
|
-
const
|
|
4310
|
+
"One-shot onboarding: install workflow skills + base manifests to ~/.claude/ (immediate by default \u2014 use --dry-run for preview)"
|
|
4311
|
+
).option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").action(async (raw) => {
|
|
4312
|
+
const dryRun = raw.dryRun === true;
|
|
4313
|
+
const pkgRoot = getPackageRoot();
|
|
4314
|
+
const workflowsDir = resolve(pkgRoot, "workflows");
|
|
4297
4315
|
const skillsBase = resolve(homedir(), ".claude", "skills");
|
|
4298
4316
|
let entries;
|
|
4299
4317
|
try {
|
|
@@ -4324,24 +4342,71 @@ function registerSetup(program2) {
|
|
|
4324
4342
|
for (const name of toInstall) {
|
|
4325
4343
|
console.log(` ${name} \u2192 ${join(skillsBase, name)}`);
|
|
4326
4344
|
}
|
|
4327
|
-
console.log(` run
|
|
4345
|
+
console.log(` run without --dry-run to execute`);
|
|
4328
4346
|
process.exit(0);
|
|
4329
4347
|
}
|
|
4330
|
-
let
|
|
4348
|
+
let skillsInstalled = 0;
|
|
4331
4349
|
for (const name of toInstall) {
|
|
4332
4350
|
const src = join(workflowsDir, name);
|
|
4333
4351
|
const dst = join(skillsBase, name);
|
|
4334
4352
|
try {
|
|
4335
4353
|
await cp(src, dst, { recursive: true, force: true });
|
|
4336
|
-
console.log(` installed ${name} \u2192 ${dst}`);
|
|
4337
|
-
|
|
4354
|
+
console.log(` [A] installed ${name} \u2192 ${dst}`);
|
|
4355
|
+
skillsInstalled++;
|
|
4338
4356
|
} catch (e) {
|
|
4339
4357
|
console.error(` error: failed to copy ${name}: ${e.message}`);
|
|
4340
4358
|
process.exit(1);
|
|
4341
4359
|
}
|
|
4342
4360
|
}
|
|
4343
|
-
console.log(
|
|
4344
|
-
|
|
4361
|
+
console.log(
|
|
4362
|
+
`
|
|
4363
|
+
Step A complete: ${skillsInstalled} workflow skill(s) installed to ${skillsBase}`
|
|
4364
|
+
);
|
|
4365
|
+
const opts = {
|
|
4366
|
+
apply: true,
|
|
4367
|
+
dryRun: false,
|
|
4368
|
+
system: false,
|
|
4369
|
+
nonInteractive: true,
|
|
4370
|
+
fullDiff: false,
|
|
4371
|
+
color: "auto"
|
|
4372
|
+
};
|
|
4373
|
+
const baseInstalled = [];
|
|
4374
|
+
const baseSkipped = [];
|
|
4375
|
+
const baseFailed = [];
|
|
4376
|
+
for (const path of await listBaseManifests2(pkgRoot)) {
|
|
4377
|
+
let yamlSrc;
|
|
4378
|
+
try {
|
|
4379
|
+
yamlSrc = await readFile(path, "utf8");
|
|
4380
|
+
} catch (e) {
|
|
4381
|
+
baseFailed.push(`${path}: read: ${e.message}`);
|
|
4382
|
+
continue;
|
|
4383
|
+
}
|
|
4384
|
+
const v = validateManifestFile(yamlSrc, path);
|
|
4385
|
+
if (!v.ok) {
|
|
4386
|
+
baseFailed.push(`${path}: validate: ${v.errors[0]?.message ?? "unknown"}`);
|
|
4387
|
+
continue;
|
|
4388
|
+
}
|
|
4389
|
+
const name = v.manifest.metadata.name;
|
|
4390
|
+
const method = v.manifest.spec.install.method;
|
|
4391
|
+
if (PHASE_212.has(method)) {
|
|
4392
|
+
baseSkipped.push(name);
|
|
4393
|
+
continue;
|
|
4394
|
+
}
|
|
4395
|
+
const r = await runInstall(v.manifest, opts);
|
|
4396
|
+
if ("aborted" in r) baseSkipped.push(name);
|
|
4397
|
+
else if (r.ok) baseInstalled.push(name);
|
|
4398
|
+
else baseFailed.push(`${name}: ${r.error.message}`);
|
|
4399
|
+
}
|
|
4400
|
+
console.log(
|
|
4401
|
+
`Step B complete: ${baseInstalled.length} manifest(s) installed / ${baseSkipped.length} skipped / ${baseFailed.length} failed`
|
|
4402
|
+
);
|
|
4403
|
+
for (const n of baseInstalled) console.log(` [B] installed ${n}`);
|
|
4404
|
+
for (const n of baseSkipped) console.log(` [B] skipped ${n}`);
|
|
4405
|
+
for (const n of baseFailed) console.error(` [B] failed ${n}`);
|
|
4406
|
+
console.log(
|
|
4407
|
+
`
|
|
4408
|
+
setup complete: ${skillsInstalled} workflow skill(s) + ${baseInstalled.length} base manifest(s) installed`
|
|
4409
|
+
);
|
|
4345
4410
|
process.exit(0);
|
|
4346
4411
|
});
|
|
4347
4412
|
}
|