harnessed 3.2.0 → 3.3.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 +36 -35
- package/dist/cli.mjs +10 -38
- 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/auto/SKILL.md +4 -6
- package/workflows/auto/workflow.yaml +1 -1
package/README.md
CHANGED
|
@@ -344,6 +344,42 @@ planning-with-files /plan (cross-cutting tool) → write artifacts to .planning/
|
|
|
344
344
|
|
|
345
345
|
---
|
|
346
346
|
|
|
347
|
+
## 🛠️ 维护命令 (Operational)
|
|
348
|
+
|
|
349
|
+
> 这些是 harnessed 自身维护命令(setup / 健康检查 / 备份回滚 / 状态恢复等),日常 feature 开发用上面的 slash command 即可,这块通常不需要。
|
|
350
|
+
|
|
351
|
+
### CLI 命令
|
|
352
|
+
|
|
353
|
+
| 命令 | 说明 |
|
|
354
|
+
| ---- | ---- |
|
|
355
|
+
| `harnessed setup` | 一次性 setup,装 workflow skills 到 `~/.claude/skills/` + MCP 到 `~/.claude.json` |
|
|
356
|
+
| `harnessed resume` | session 中断后恢复至最近 checkpoint |
|
|
357
|
+
| `harnessed status` | 当前 phase + lock holder |
|
|
358
|
+
| `harnessed doctor` | 8-check 健康检查 (Node / MCP / jq / Win bash / 路由 / token budget 等) |
|
|
359
|
+
| `harnessed install <name>` | 装上游 manifest |
|
|
360
|
+
| `harnessed uninstall <name>` | 反向卸载 |
|
|
361
|
+
| `harnessed backup` | snapshot 备份管理 |
|
|
362
|
+
| `harnessed rollback <timestamp>` | 一行回滚 (EOL preserve + sha1 verify) |
|
|
363
|
+
| `harnessed gc` | 清理过期 backups |
|
|
364
|
+
| `harnessed audit-log` | 路由透明日志 query (支持 `--filter` jq 表达式) |
|
|
365
|
+
|
|
366
|
+
### 参数 (Flags)
|
|
367
|
+
|
|
368
|
+
> 所有命令默认 **apply (immediate write)**,无需加 flag。高级用户可加 `--dry-run` 预览。
|
|
369
|
+
|
|
370
|
+
| Flag | 说明 |
|
|
371
|
+
| ---- | ---- |
|
|
372
|
+
| `--dry-run` | 预览不写盘 (高级用户 opt-in) |
|
|
373
|
+
| `--non-interactive` | CI / 脚本场景 |
|
|
374
|
+
| `--system` | L4 全局装允许 (否则降级 L1 npx ephemeral) |
|
|
375
|
+
| `--yes` | uninstall 跳过交互 confirm |
|
|
376
|
+
| `--full-diff` | 展开 > 200 行的 diff 折叠 |
|
|
377
|
+
| `--no-color` | 强制 nocolor (即使 TTY) |
|
|
378
|
+
|
|
379
|
+
> `--apply` flag 仍保留为向后兼容 alias (no-op, 旧脚本不破)。
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
347
383
|
## ❓ FAQ
|
|
348
384
|
|
|
349
385
|
<details>
|
|
@@ -423,41 +459,6 @@ harnessed setup --apply # 自动装齐 gstack + GSD + superpowers + planning-wi
|
|
|
423
459
|
|
|
424
460
|
---
|
|
425
461
|
|
|
426
|
-
## 🛠️ 维护命令 (Operational)
|
|
427
|
-
|
|
428
|
-
> 这些是 harnessed 自身维护命令(setup / 健康检查 / 备份回滚 / 状态恢复等),日常 feature 开发用上面的 slash command 即可,这块通常不需要。
|
|
429
|
-
|
|
430
|
-
### CLI 命令
|
|
431
|
-
|
|
432
|
-
| 命令 | 说明 |
|
|
433
|
-
| ---- | ---- |
|
|
434
|
-
| `harnessed setup` | 一次性 setup,装 workflow skills 到 `~/.claude/skills/` + MCP 到 `~/.claude.json` |
|
|
435
|
-
| `harnessed resume` | session 中断后恢复至最近 checkpoint |
|
|
436
|
-
| `harnessed status` | 当前 phase + lock holder |
|
|
437
|
-
| `harnessed doctor` | 8-check 健康检查 (Node / MCP / jq / Win bash / 路由 / token budget 等) |
|
|
438
|
-
| `harnessed install <name>` | 装上游 manifest |
|
|
439
|
-
| `harnessed uninstall <name>` | 反向卸载 |
|
|
440
|
-
| `harnessed backup` | snapshot 备份管理 |
|
|
441
|
-
| `harnessed rollback <timestamp>` | 一行回滚 (EOL preserve + sha1 verify) |
|
|
442
|
-
| `harnessed gc` | 清理过期 backups |
|
|
443
|
-
| `harnessed audit-log` | 路由透明日志 query (支持 `--filter` jq 表达式) |
|
|
444
|
-
|
|
445
|
-
### 参数 (Flags)
|
|
446
|
-
|
|
447
|
-
> 所有命令默认 **apply (immediate write)**,无需加 flag。高级用户可加 `--dry-run` 预览。
|
|
448
|
-
|
|
449
|
-
| Flag | 说明 |
|
|
450
|
-
| ---- | ---- |
|
|
451
|
-
| `--dry-run` | 预览不写盘 (高级用户 opt-in) |
|
|
452
|
-
| `--non-interactive` | CI / 脚本场景 |
|
|
453
|
-
| `--system` | L4 全局装允许 (否则降级 L1 npx ephemeral) |
|
|
454
|
-
| `--yes` | uninstall 跳过交互 confirm |
|
|
455
|
-
| `--full-diff` | 展开 > 200 行的 diff 折叠 |
|
|
456
|
-
| `--no-color` | 强制 nocolor (即使 TTY) |
|
|
457
|
-
|
|
458
|
-
> `--apply` flag 仍保留为向后兼容 alias (no-op, 旧脚本不破)。
|
|
459
|
-
|
|
460
|
-
---
|
|
461
462
|
|
|
462
463
|
## License
|
|
463
464
|
|
package/dist/cli.mjs
CHANGED
|
@@ -847,7 +847,7 @@ var init_resume = __esm({
|
|
|
847
847
|
|
|
848
848
|
// package.json
|
|
849
849
|
var package_default = {
|
|
850
|
-
version: "3.
|
|
850
|
+
version: "3.3.0"};
|
|
851
851
|
|
|
852
852
|
// src/manifest/errors.ts
|
|
853
853
|
function instancePathToKeyPath(instancePath) {
|
|
@@ -2999,26 +2999,11 @@ function loadPhases(yamlPath, vars) {
|
|
|
2999
2999
|
return validated;
|
|
3000
3000
|
}
|
|
3001
3001
|
|
|
3002
|
-
// src/cli/lib/validateFlags.ts
|
|
3003
|
-
function validateNonInteractiveFlags(raw, cmdName) {
|
|
3004
|
-
if (raw.nonInteractive && !raw.apply && !raw.dryRun) {
|
|
3005
|
-
console.error(
|
|
3006
|
-
`error: --non-interactive requires --apply or --dry-run
|
|
3007
|
-
fix: 'harnessed ${cmdName} --non-interactive --dry-run' or '--apply'`
|
|
3008
|
-
);
|
|
3009
|
-
process.exit(2);
|
|
3010
|
-
}
|
|
3011
|
-
}
|
|
3012
|
-
|
|
3013
3002
|
// src/cli/execute-task.ts
|
|
3014
3003
|
function registerExecuteTask(program2) {
|
|
3015
3004
|
program2.command("execute-task").description(
|
|
3016
3005
|
"Run execute-task workflow (4-phase chain \u2192 ralph-loop COMPLETE; immediate by default \u2014 use --dry-run for preview)"
|
|
3017
|
-
).requiredOption("--task <text>", "task description (required)").option("--workflow <name>", "workflow name", "execute-task").option(
|
|
3018
|
-
"--apply",
|
|
3019
|
-
"(deprecated; kept for backward compat \u2014 execute-task spawns immediately by default)"
|
|
3020
|
-
).option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "CI / scripts \u2014 requires --apply or --dry-run").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").option("--model-tier <tier>", "override: 'inherit' bypasses per-phase phase.model (B-10)").option("--max-iterations <n>", "ralph-loop max iter (default 20)", (v) => parseInt(v, 10)).action(async (raw) => {
|
|
3021
|
-
validateNonInteractiveFlags(raw, "execute-task --task <text>");
|
|
3006
|
+
).requiredOption("--task <text>", "task description (required)").option("--workflow <name>", "workflow name", "execute-task").option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "CI / scripts").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").option("--model-tier <tier>", "override: 'inherit' bypasses per-phase phase.model (B-10)").option("--max-iterations <n>", "ralph-loop max iter (default 20)", (v) => parseInt(v, 10)).action(async (raw) => {
|
|
3022
3007
|
if (!raw.task) {
|
|
3023
3008
|
console.error("error: --task <text> is required");
|
|
3024
3009
|
process.exit(2);
|
|
@@ -3065,7 +3050,7 @@ function registerExecuteTask(program2) {
|
|
|
3065
3050
|
packageRoot: process.cwd(),
|
|
3066
3051
|
cmdType: "git-commit",
|
|
3067
3052
|
hasUserApproval: true
|
|
3068
|
-
//
|
|
3053
|
+
// apply-immediate default
|
|
3069
3054
|
});
|
|
3070
3055
|
} catch (err2) {
|
|
3071
3056
|
console.warn(
|
|
@@ -3120,7 +3105,7 @@ async function dirSizeKb(dir) {
|
|
|
3120
3105
|
function registerGc(program2) {
|
|
3121
3106
|
program2.command("gc").description(
|
|
3122
3107
|
"Garbage-collect old backup snapshots (immediate by default \u2014 use --dry-run for preview)"
|
|
3123
|
-
).option("--older-than <duration>", "delete snapshots older than (e.g. 30d / 24h / 4w)", "30d").option("--keep-last <N>", "always keep the most recent N snapshots", "0").option("--
|
|
3108
|
+
).option("--older-than <duration>", "delete snapshots older than (e.g. 30d / 24h / 4w)", "30d").option("--keep-last <N>", "always keep the most recent N snapshots", "0").option("--dry-run", "preview only \u2014 do not delete (opt-in for advanced users)").action(async (opts) => {
|
|
3124
3109
|
const dryRun = opts.dryRun === true;
|
|
3125
3110
|
const olderMs = parseDuration(opts.olderThan ?? "30d");
|
|
3126
3111
|
if (olderMs == null) {
|
|
@@ -4475,11 +4460,10 @@ function formatError(e) {
|
|
|
4475
4460
|
return `${head}${where}${tip}`;
|
|
4476
4461
|
}
|
|
4477
4462
|
function registerInstall(program2) {
|
|
4478
|
-
program2.command("install <name>").description("Install an upstream (immediate by default \u2014 use --dry-run for preview)").option("--
|
|
4463
|
+
program2.command("install <name>").description("Install an upstream (immediate by default \u2014 use --dry-run for preview)").option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").option("--system", "allow L4 system-wide install (e.g. global npm install)").option("--non-interactive", "skip all prompts (CI / scripts)").option("--full-diff", "expand diffs longer than 200 lines").option("--no-color", "disable ANSI colors (auto-detected when piped)").option(
|
|
4479
4464
|
"--known-good",
|
|
4480
4465
|
"use known-good version lock from versions/<harnessed-ver>-known-good.yaml"
|
|
4481
4466
|
).action(async (name, raw) => {
|
|
4482
|
-
validateNonInteractiveFlags(raw, "install <name>");
|
|
4483
4467
|
const { resolveAlias: resolveAlias2 } = await Promise.resolve().then(() => (init_aliases(), aliases_exports));
|
|
4484
4468
|
const resolvedName = resolveAlias2(name) ?? name;
|
|
4485
4469
|
checkPathSafe(resolvedName);
|
|
@@ -4558,11 +4542,7 @@ async function listBaseManifests(cwd) {
|
|
|
4558
4542
|
function registerInstallBase(program2) {
|
|
4559
4543
|
program2.command("install-base").description(
|
|
4560
4544
|
"Install the phase 1.3 base profile (immediate by default \u2014 use --dry-run for preview)"
|
|
4561
|
-
).option(
|
|
4562
|
-
"--apply",
|
|
4563
|
-
"(deprecated; kept for backward compat \u2014 install-base is immediate by default)"
|
|
4564
|
-
).option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts) \u2014 requires --apply or --dry-run").action(async (raw) => {
|
|
4565
|
-
validateNonInteractiveFlags(raw, "install-base");
|
|
4545
|
+
).option("--dry-run", "preview only \u2014 do not write to disk (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts)").action(async (raw) => {
|
|
4566
4546
|
const dryRun = raw.dryRun === true;
|
|
4567
4547
|
const opts = {
|
|
4568
4548
|
apply: !dryRun,
|
|
@@ -4628,11 +4608,7 @@ function basename(upstream) {
|
|
|
4628
4608
|
function registerManifestAdd(program2) {
|
|
4629
4609
|
program2.command("manifest-add <upstream>").description(
|
|
4630
4610
|
"Add a new upstream adapter (EE-5 5-question merge gate; immediate by default \u2014 use --dry-run for preview)"
|
|
4631
|
-
).option("--category <cat>", "manifest category (skill-packs | tools)", "skill-packs").option("--name <name>", "short adapter name (defaults to <upstream> basename)").option(
|
|
4632
|
-
"--apply",
|
|
4633
|
-
"(deprecated; kept for backward compat \u2014 manifest-add persists immediately by default)"
|
|
4634
|
-
).option("--dry-run", "preview only \u2014 do not write JSON (opt-in for advanced users)").option("--non-interactive", "CI/scripts \u2014 requires --apply or --dry-run; WARN-only dry-run").action(async (upstream, raw) => {
|
|
4635
|
-
validateNonInteractiveFlags(raw, "manifest-add <upstream>");
|
|
4611
|
+
).option("--category <cat>", "manifest category (skill-packs | tools)", "skill-packs").option("--name <name>", "short adapter name (defaults to <upstream> basename)").option("--dry-run", "preview only \u2014 do not write JSON (opt-in for advanced users)").option("--non-interactive", "CI/scripts \u2014 WARN-only dry-run").action(async (upstream, raw) => {
|
|
4636
4612
|
const name = raw.name ?? basename(upstream);
|
|
4637
4613
|
const category = raw.category ?? "skill-packs";
|
|
4638
4614
|
const outPath = `manifests/${category}/${name}.ee5-answers.json`;
|
|
@@ -4677,11 +4653,7 @@ function registerManifestAdd(program2) {
|
|
|
4677
4653
|
function registerResearch(program2) {
|
|
4678
4654
|
program2.command("research").description(
|
|
4679
4655
|
"Run research workflow (search category sub-routing \u2192 spawn \u2192 verbatim COMPLETE; immediate by default \u2014 use --dry-run for preview)"
|
|
4680
|
-
).requiredOption("--query <text>", "research prompt (required)").option(
|
|
4681
|
-
"--apply",
|
|
4682
|
-
"(deprecated; kept for backward compat \u2014 research spawns immediately by default)"
|
|
4683
|
-
).option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts) \u2014 requires --apply or --dry-run").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").action(async (raw) => {
|
|
4684
|
-
validateNonInteractiveFlags(raw, "research --query <text>");
|
|
4656
|
+
).requiredOption("--query <text>", "research prompt (required)").option("--dry-run", "preview only \u2014 do not spawn subagent (opt-in for advanced users)").option("--non-interactive", "skip all prompts (CI / scripts)").option("--model <model>", "subagent model: 'haiku' | 'sonnet' | 'opus'").action(async (raw) => {
|
|
4685
4657
|
if (!raw.query) {
|
|
4686
4658
|
console.error("error: --query <text> is required");
|
|
4687
4659
|
process.exit(2);
|
|
@@ -4720,7 +4692,7 @@ function registerResearch(program2) {
|
|
|
4720
4692
|
if ("ok" in result && result.ok === false) {
|
|
4721
4693
|
console.error(`error: ${result.phase} \u2014 ${result.error.message}`);
|
|
4722
4694
|
if (result.phase === "install") {
|
|
4723
|
-
console.error(` fix: 'harnessed install <skill>
|
|
4695
|
+
console.error(` fix: 'harnessed install <skill>' (see error above)`);
|
|
4724
4696
|
}
|
|
4725
4697
|
process.exit(1);
|
|
4726
4698
|
}
|
|
@@ -5355,7 +5327,7 @@ async function runUninstall(manifest, opts) {
|
|
|
5355
5327
|
|
|
5356
5328
|
// src/cli/uninstall.ts
|
|
5357
5329
|
function registerUninstall(program2) {
|
|
5358
|
-
program2.command("uninstall <name>").description("Uninstall an upstream (immediate by default \u2014 use --dry-run for preview)").option("--
|
|
5330
|
+
program2.command("uninstall <name>").description("Uninstall an upstream (immediate by default \u2014 use --dry-run for preview)").option("--dry-run", "preview only \u2014 do not delete files (opt-in for advanced users)").option("--yes", "skip interactive confirm (CI / scripts) \u2014 fatal with --dry-run").option("--non-interactive", "alias for --yes (CI compat)").action(async (name, raw) => {
|
|
5359
5331
|
const yes = raw.yes === true || raw.nonInteractive === true;
|
|
5360
5332
|
if (yes && raw.dryRun) {
|
|
5361
5333
|
console.error(
|