cclaw-cli 7.7.1 → 8.1.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 +211 -134
- package/dist/artifact-frontmatter.d.ts +51 -0
- package/dist/artifact-frontmatter.js +131 -0
- package/dist/artifact-paths.d.ts +7 -27
- package/dist/artifact-paths.js +20 -249
- package/dist/cancel.d.ts +16 -0
- package/dist/cancel.js +66 -0
- package/dist/cli.d.ts +2 -27
- package/dist/cli.js +107 -511
- package/dist/compound.d.ts +26 -0
- package/dist/compound.js +96 -0
- package/dist/config.d.ts +14 -51
- package/dist/config.js +23 -359
- package/dist/constants.d.ts +11 -18
- package/dist/constants.js +19 -106
- package/dist/content/antipatterns.d.ts +1 -0
- package/dist/content/antipatterns.js +109 -0
- package/dist/content/artifact-templates.d.ts +10 -0
- package/dist/content/artifact-templates.js +550 -0
- package/dist/content/cancel-command.d.ts +2 -2
- package/dist/content/cancel-command.js +25 -17
- package/dist/content/core-agents.d.ts +9 -233
- package/dist/content/core-agents.js +39 -768
- package/dist/content/decision-protocol.d.ts +1 -12
- package/dist/content/decision-protocol.js +27 -20
- package/dist/content/examples.d.ts +8 -42
- package/dist/content/examples.js +293 -425
- package/dist/content/idea-command.d.ts +2 -0
- package/dist/content/idea-command.js +38 -0
- package/dist/content/iron-laws.d.ts +4 -138
- package/dist/content/iron-laws.js +18 -197
- package/dist/content/meta-skill.d.ts +1 -3
- package/dist/content/meta-skill.js +57 -134
- package/dist/content/node-hooks.d.ts +12 -8
- package/dist/content/node-hooks.js +188 -838
- package/dist/content/recovery.d.ts +8 -0
- package/dist/content/recovery.js +179 -0
- package/dist/content/reference-patterns.d.ts +4 -13
- package/dist/content/reference-patterns.js +260 -389
- package/dist/content/research-playbooks.d.ts +8 -8
- package/dist/content/research-playbooks.js +108 -121
- package/dist/content/review-loop.d.ts +6 -192
- package/dist/content/review-loop.js +29 -731
- package/dist/content/skills.d.ts +8 -38
- package/dist/content/skills.js +681 -732
- package/dist/content/specialist-prompts/architect.d.ts +1 -0
- package/dist/content/specialist-prompts/architect.js +225 -0
- package/dist/content/specialist-prompts/brainstormer.d.ts +1 -0
- package/dist/content/specialist-prompts/brainstormer.js +168 -0
- package/dist/content/specialist-prompts/index.d.ts +2 -0
- package/dist/content/specialist-prompts/index.js +14 -0
- package/dist/content/specialist-prompts/planner.d.ts +1 -0
- package/dist/content/specialist-prompts/planner.js +182 -0
- package/dist/content/specialist-prompts/reviewer.d.ts +1 -0
- package/dist/content/specialist-prompts/reviewer.js +193 -0
- package/dist/content/specialist-prompts/security-reviewer.d.ts +1 -0
- package/dist/content/specialist-prompts/security-reviewer.js +133 -0
- package/dist/content/specialist-prompts/slice-builder.d.ts +1 -0
- package/dist/content/specialist-prompts/slice-builder.js +232 -0
- package/dist/content/stage-playbooks.d.ts +8 -0
- package/dist/content/stage-playbooks.js +404 -0
- package/dist/content/start-command.d.ts +2 -12
- package/dist/content/start-command.js +221 -207
- package/dist/flow-state.d.ts +21 -178
- package/dist/flow-state.js +67 -170
- package/dist/fs-utils.d.ts +6 -26
- package/dist/fs-utils.js +29 -162
- package/dist/gitignore.d.ts +2 -1
- package/dist/gitignore.js +51 -34
- package/dist/harness-detect.d.ts +10 -0
- package/dist/harness-detect.js +29 -0
- package/dist/harness-prompt.d.ts +26 -0
- package/dist/harness-prompt.js +142 -0
- package/dist/install.d.ts +35 -15
- package/dist/install.js +238 -1347
- package/dist/knowledge-store.d.ts +19 -163
- package/dist/knowledge-store.js +56 -590
- package/dist/logger.d.ts +8 -3
- package/dist/logger.js +13 -4
- package/dist/orchestrator-routing.d.ts +29 -0
- package/dist/orchestrator-routing.js +156 -0
- package/dist/run-persistence.d.ts +7 -118
- package/dist/run-persistence.js +29 -845
- package/dist/runtime/run-hook.entry.d.ts +1 -3
- package/dist/runtime/run-hook.entry.js +19 -4
- package/dist/runtime/run-hook.mjs +13 -1024
- package/dist/types.d.ts +25 -261
- package/dist/types.js +8 -36
- package/package.json +6 -3
- package/dist/artifact-linter/brainstorm.d.ts +0 -2
- package/dist/artifact-linter/brainstorm.js +0 -353
- package/dist/artifact-linter/design.d.ts +0 -18
- package/dist/artifact-linter/design.js +0 -444
- package/dist/artifact-linter/findings-dedup.d.ts +0 -56
- package/dist/artifact-linter/findings-dedup.js +0 -232
- package/dist/artifact-linter/plan.d.ts +0 -2
- package/dist/artifact-linter/plan.js +0 -826
- package/dist/artifact-linter/review-army.d.ts +0 -49
- package/dist/artifact-linter/review-army.js +0 -520
- package/dist/artifact-linter/review.d.ts +0 -2
- package/dist/artifact-linter/review.js +0 -113
- package/dist/artifact-linter/scope.d.ts +0 -2
- package/dist/artifact-linter/scope.js +0 -158
- package/dist/artifact-linter/shared.d.ts +0 -637
- package/dist/artifact-linter/shared.js +0 -2163
- package/dist/artifact-linter/ship.d.ts +0 -2
- package/dist/artifact-linter/ship.js +0 -250
- package/dist/artifact-linter/spec.d.ts +0 -2
- package/dist/artifact-linter/spec.js +0 -176
- package/dist/artifact-linter/tdd.d.ts +0 -118
- package/dist/artifact-linter/tdd.js +0 -1404
- package/dist/artifact-linter.d.ts +0 -15
- package/dist/artifact-linter.js +0 -517
- package/dist/codex-feature-flag.d.ts +0 -58
- package/dist/codex-feature-flag.js +0 -193
- package/dist/content/closeout-guidance.d.ts +0 -14
- package/dist/content/closeout-guidance.js +0 -44
- package/dist/content/diff-command.d.ts +0 -1
- package/dist/content/diff-command.js +0 -43
- package/dist/content/harness-doc.d.ts +0 -1
- package/dist/content/harness-doc.js +0 -65
- package/dist/content/hook-events.d.ts +0 -9
- package/dist/content/hook-events.js +0 -23
- package/dist/content/hook-manifest.d.ts +0 -81
- package/dist/content/hook-manifest.js +0 -156
- package/dist/content/hooks.d.ts +0 -11
- package/dist/content/hooks.js +0 -1972
- package/dist/content/idea.d.ts +0 -60
- package/dist/content/idea.js +0 -416
- package/dist/content/language-policy.d.ts +0 -2
- package/dist/content/language-policy.js +0 -13
- package/dist/content/learnings.d.ts +0 -6
- package/dist/content/learnings.js +0 -141
- package/dist/content/observe.d.ts +0 -19
- package/dist/content/observe.js +0 -86
- package/dist/content/opencode-plugin.d.ts +0 -1
- package/dist/content/opencode-plugin.js +0 -635
- package/dist/content/review-prompts.d.ts +0 -1
- package/dist/content/review-prompts.js +0 -104
- package/dist/content/runtime-shared-snippets.d.ts +0 -8
- package/dist/content/runtime-shared-snippets.js +0 -80
- package/dist/content/session-hooks.d.ts +0 -7
- package/dist/content/session-hooks.js +0 -107
- package/dist/content/skills-elicitation.d.ts +0 -1
- package/dist/content/skills-elicitation.js +0 -167
- package/dist/content/stage-command.d.ts +0 -2
- package/dist/content/stage-command.js +0 -17
- package/dist/content/stage-schema.d.ts +0 -117
- package/dist/content/stage-schema.js +0 -955
- package/dist/content/stages/_lint-metadata/index.d.ts +0 -2
- package/dist/content/stages/_lint-metadata/index.js +0 -97
- package/dist/content/stages/brainstorm.d.ts +0 -2
- package/dist/content/stages/brainstorm.js +0 -184
- package/dist/content/stages/design.d.ts +0 -2
- package/dist/content/stages/design.js +0 -288
- package/dist/content/stages/index.d.ts +0 -8
- package/dist/content/stages/index.js +0 -11
- package/dist/content/stages/plan.d.ts +0 -2
- package/dist/content/stages/plan.js +0 -191
- package/dist/content/stages/review.d.ts +0 -2
- package/dist/content/stages/review.js +0 -240
- package/dist/content/stages/schema-types.d.ts +0 -203
- package/dist/content/stages/schema-types.js +0 -1
- package/dist/content/stages/scope.d.ts +0 -2
- package/dist/content/stages/scope.js +0 -254
- package/dist/content/stages/ship.d.ts +0 -2
- package/dist/content/stages/ship.js +0 -159
- package/dist/content/stages/spec.d.ts +0 -2
- package/dist/content/stages/spec.js +0 -170
- package/dist/content/stages/tdd.d.ts +0 -4
- package/dist/content/stages/tdd.js +0 -273
- package/dist/content/state-contracts.d.ts +0 -1
- package/dist/content/state-contracts.js +0 -63
- package/dist/content/status-command.d.ts +0 -4
- package/dist/content/status-command.js +0 -109
- package/dist/content/subagent-context-skills.d.ts +0 -4
- package/dist/content/subagent-context-skills.js +0 -279
- package/dist/content/subagents.d.ts +0 -3
- package/dist/content/subagents.js +0 -997
- package/dist/content/templates.d.ts +0 -26
- package/dist/content/templates.js +0 -1692
- package/dist/content/track-render-context.d.ts +0 -18
- package/dist/content/track-render-context.js +0 -53
- package/dist/content/tree-command.d.ts +0 -1
- package/dist/content/tree-command.js +0 -64
- package/dist/content/utility-skills.d.ts +0 -30
- package/dist/content/utility-skills.js +0 -160
- package/dist/content/view-command.d.ts +0 -2
- package/dist/content/view-command.js +0 -92
- package/dist/delegation.d.ts +0 -649
- package/dist/delegation.js +0 -1539
- package/dist/early-loop.d.ts +0 -70
- package/dist/early-loop.js +0 -302
- package/dist/execution-topology.d.ts +0 -44
- package/dist/execution-topology.js +0 -95
- package/dist/gate-evidence.d.ts +0 -85
- package/dist/gate-evidence.js +0 -631
- package/dist/harness-adapters.d.ts +0 -151
- package/dist/harness-adapters.js +0 -756
- package/dist/harness-selection.d.ts +0 -31
- package/dist/harness-selection.js +0 -214
- package/dist/hook-schema.d.ts +0 -6
- package/dist/hook-schema.js +0 -114
- package/dist/hook-schemas/claude-hooks.v1.json +0 -10
- package/dist/hook-schemas/codex-hooks.v1.json +0 -10
- package/dist/hook-schemas/cursor-hooks.v1.json +0 -13
- package/dist/init-detect.d.ts +0 -2
- package/dist/init-detect.js +0 -50
- package/dist/internal/advance-stage/advance.d.ts +0 -89
- package/dist/internal/advance-stage/advance.js +0 -655
- package/dist/internal/advance-stage/cancel-run.d.ts +0 -8
- package/dist/internal/advance-stage/cancel-run.js +0 -19
- package/dist/internal/advance-stage/flow-state-coercion.d.ts +0 -3
- package/dist/internal/advance-stage/flow-state-coercion.js +0 -81
- package/dist/internal/advance-stage/helpers.d.ts +0 -14
- package/dist/internal/advance-stage/helpers.js +0 -145
- package/dist/internal/advance-stage/hook.d.ts +0 -8
- package/dist/internal/advance-stage/hook.js +0 -40
- package/dist/internal/advance-stage/parsers.d.ts +0 -72
- package/dist/internal/advance-stage/parsers.js +0 -357
- package/dist/internal/advance-stage/proactive-delegation-trace.d.ts +0 -24
- package/dist/internal/advance-stage/proactive-delegation-trace.js +0 -56
- package/dist/internal/advance-stage/review-loop.d.ts +0 -16
- package/dist/internal/advance-stage/review-loop.js +0 -199
- package/dist/internal/advance-stage/rewind.d.ts +0 -14
- package/dist/internal/advance-stage/rewind.js +0 -108
- package/dist/internal/advance-stage/start-flow.d.ts +0 -13
- package/dist/internal/advance-stage/start-flow.js +0 -241
- package/dist/internal/advance-stage/verify.d.ts +0 -21
- package/dist/internal/advance-stage/verify.js +0 -185
- package/dist/internal/advance-stage.d.ts +0 -7
- package/dist/internal/advance-stage.js +0 -138
- package/dist/internal/cohesion-contract-stub.d.ts +0 -24
- package/dist/internal/cohesion-contract-stub.js +0 -148
- package/dist/internal/compound-readiness.d.ts +0 -23
- package/dist/internal/compound-readiness.js +0 -102
- package/dist/internal/detect-public-api-changes.d.ts +0 -5
- package/dist/internal/detect-public-api-changes.js +0 -45
- package/dist/internal/detect-supply-chain-changes.d.ts +0 -6
- package/dist/internal/detect-supply-chain-changes.js +0 -138
- package/dist/internal/early-loop-status.d.ts +0 -7
- package/dist/internal/early-loop-status.js +0 -93
- package/dist/internal/envelope-validate.d.ts +0 -7
- package/dist/internal/envelope-validate.js +0 -66
- package/dist/internal/flow-state-repair.d.ts +0 -20
- package/dist/internal/flow-state-repair.js +0 -104
- package/dist/internal/plan-split-waves.d.ts +0 -190
- package/dist/internal/plan-split-waves.js +0 -764
- package/dist/internal/runtime-integrity.d.ts +0 -7
- package/dist/internal/runtime-integrity.js +0 -268
- package/dist/internal/slice-commit.d.ts +0 -7
- package/dist/internal/slice-commit.js +0 -619
- package/dist/internal/tdd-loop-status.d.ts +0 -14
- package/dist/internal/tdd-loop-status.js +0 -68
- package/dist/internal/tdd-red-evidence.d.ts +0 -7
- package/dist/internal/tdd-red-evidence.js +0 -153
- package/dist/internal/waiver-grant.d.ts +0 -62
- package/dist/internal/waiver-grant.js +0 -294
- package/dist/internal/wave-status.d.ts +0 -74
- package/dist/internal/wave-status.js +0 -506
- package/dist/managed-resources.d.ts +0 -53
- package/dist/managed-resources.js +0 -313
- package/dist/policy.d.ts +0 -10
- package/dist/policy.js +0 -167
- package/dist/retro-gate.d.ts +0 -9
- package/dist/retro-gate.js +0 -47
- package/dist/run-archive.d.ts +0 -61
- package/dist/run-archive.js +0 -391
- package/dist/runs.d.ts +0 -2
- package/dist/runs.js +0 -2
- package/dist/stack-detection.d.ts +0 -116
- package/dist/stack-detection.js +0 -489
- package/dist/streaming/event-stream.d.ts +0 -31
- package/dist/streaming/event-stream.js +0 -114
- package/dist/tdd-cycle.d.ts +0 -107
- package/dist/tdd-cycle.js +0 -289
- package/dist/tdd-verification-evidence.d.ts +0 -17
- package/dist/tdd-verification-evidence.js +0 -122
- package/dist/track-heuristics.d.ts +0 -27
- package/dist/track-heuristics.js +0 -154
- package/dist/util/slice-id.d.ts +0 -58
- package/dist/util/slice-id.js +0 -89
- package/dist/worktree-manager.d.ts +0 -20
- package/dist/worktree-manager.js +0 -108
package/dist/cli.js
CHANGED
|
@@ -1,530 +1,126 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { existsSync, realpathSync } from "node:fs";
|
|
5
|
-
import { createInterface } from "node:readline/promises";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { CCLAW_VERSION } from "./constants.js";
|
|
7
3
|
import { initCclaw, syncCclaw, uninstallCclaw, upgradeCclaw } from "./install.js";
|
|
8
|
-
import { error, info } from "./logger.js";
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
import { CCLAW_VERSION, RUNTIME_ROOT } from "./constants.js";
|
|
12
|
-
import { createDefaultConfig, readConfig } from "./config.js";
|
|
13
|
-
import { detectHarnesses } from "./init-detect.js";
|
|
14
|
-
import { HARNESS_ADAPTERS } from "./harness-adapters.js";
|
|
15
|
-
import { promptHarnessSelectionChecklist } from "./harness-selection.js";
|
|
16
|
-
export { parseHarnessSelectionAnswer } from "./harness-selection.js";
|
|
17
|
-
import { classifyCodexHooksFlag, codexConfigPath, patchCodexHooksFlag, readCodexConfig, writeCodexConfig } from "./codex-feature-flag.js";
|
|
18
|
-
import { runInternalCommand } from "./internal/advance-stage.js";
|
|
19
|
-
const INSTALLER_COMMANDS = [
|
|
20
|
-
"init",
|
|
21
|
-
"sync",
|
|
22
|
-
"upgrade",
|
|
23
|
-
"uninstall",
|
|
24
|
-
"archive",
|
|
25
|
-
"internal"
|
|
26
|
-
];
|
|
27
|
-
export function usage() {
|
|
28
|
-
return `cclaw - installer-first flow toolkit
|
|
4
|
+
import { configureLogger, error as logError, info } from "./logger.js";
|
|
5
|
+
import { HARNESS_IDS } from "./types.js";
|
|
6
|
+
const HELP_BODY = `cclaw v${CCLAW_VERSION} — harness installer / sync.
|
|
29
7
|
|
|
30
|
-
Usage:
|
|
31
|
-
npx cclaw-cli # launch setup or print "already installed" hint
|
|
32
|
-
npx cclaw-cli <command> [flags]
|
|
33
|
-
npx cclaw-cli --help | -h
|
|
34
|
-
npx cclaw-cli --version | -v
|
|
8
|
+
Usage: cclaw <command> [options]
|
|
35
9
|
|
|
36
10
|
Commands:
|
|
37
|
-
init
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
--check Verify managed hook files are byte-identical to canonical generators.
|
|
44
|
-
upgrade Refresh generated files in .cclaw. Preserves your config.yaml.
|
|
45
|
-
archive Archive the active run and reset flow state for the next run.
|
|
46
|
-
Flags: --name=<slug> Override archive folder suffix.
|
|
47
|
-
--skip-retro Skip retro gate only when runtime allows it.
|
|
48
|
-
--retro-reason=<txt> Required rationale with --skip-retro.
|
|
49
|
-
--disposition=<completed|cancelled|abandoned>
|
|
50
|
-
--reason=<txt> Required for cancelled/abandoned archives.
|
|
51
|
-
uninstall Remove .cclaw runtime and the generated harness shim files.
|
|
11
|
+
init Install cclaw assets in the current project.
|
|
12
|
+
sync Reapply cclaw assets to match the current code (idempotent).
|
|
13
|
+
upgrade Sync after upgrading the cclaw-cli npm package.
|
|
14
|
+
uninstall Remove cclaw assets from the current project.
|
|
15
|
+
help Show this help.
|
|
16
|
+
version Print the version.
|
|
52
17
|
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
18
|
+
Harness selection:
|
|
19
|
+
- If --harness=<id>[,<id>] is passed, install for those.
|
|
20
|
+
- Otherwise, the existing .cclaw/config.yaml (if any) wins.
|
|
21
|
+
- Otherwise, in an interactive TTY, cclaw shows a checkbox picker
|
|
22
|
+
(auto-detected harnesses pre-selected; Up/Down · Space · Enter).
|
|
23
|
+
- In non-TTY (CI, npx --yes, piped input), cclaw auto-detects from project
|
|
24
|
+
root markers (.claude/, .cursor/, .opencode/, .codex/, .agents/skills/,
|
|
25
|
+
CLAUDE.md, opencode.json) and exits with an error if nothing is found.
|
|
56
26
|
|
|
57
|
-
|
|
58
|
-
npx cclaw-cli
|
|
59
|
-
npx cclaw-cli init --harnesses=claude,cursor --no-interactive
|
|
60
|
-
npx cclaw-cli sync --interactive
|
|
61
|
-
npx cclaw-cli sync --check
|
|
62
|
-
npx cclaw-cli archive --name=my-run
|
|
63
|
-
npx cclaw-cli archive --disposition=cancelled --reason="deprioritized"
|
|
64
|
-
npx cclaw-cli upgrade
|
|
27
|
+
Flow control (plan / build / review / ship) lives inside the harness via the /cc command, not in this CLI. There is no \`cclaw plan\`, \`cclaw status\`, \`cclaw ship\`, or \`cclaw migrate\` — by design.
|
|
65
28
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
plus explicit archive actions.
|
|
69
|
-
|
|
70
|
-
Docs: https://github.com/zuevrs/cclaw
|
|
71
|
-
Local: README.md and generated .cclaw/skills/*.md
|
|
72
|
-
Issues: https://github.com/zuevrs/cclaw/issues
|
|
29
|
+
Options:
|
|
30
|
+
--harness=<id>[,<id>] Comma-separated list. Supported: ${HARNESS_IDS.join(", ")}.
|
|
73
31
|
`;
|
|
74
|
-
}
|
|
75
|
-
function parseHarnesses(raw) {
|
|
76
|
-
const requested = raw
|
|
77
|
-
.split(",")
|
|
78
|
-
.map((item) => item.trim())
|
|
79
|
-
.filter(Boolean);
|
|
80
|
-
if (requested.length === 0) {
|
|
81
|
-
throw new Error("Select at least one harness.");
|
|
82
|
-
}
|
|
83
|
-
const invalid = requested.filter((item) => !HARNESS_IDS.includes(item));
|
|
84
|
-
if (invalid.length > 0) {
|
|
85
|
-
throw new Error(`Unknown harnesses: ${invalid.join(", ")}`);
|
|
86
|
-
}
|
|
87
|
-
return requested;
|
|
88
|
-
}
|
|
89
|
-
function parseTrack(raw) {
|
|
90
|
-
const trimmed = raw.trim();
|
|
91
|
-
if (!FLOW_TRACKS.includes(trimmed)) {
|
|
92
|
-
throw new Error(`Unknown track: ${trimmed}. Supported: ${FLOW_TRACKS.join(", ")}`);
|
|
93
|
-
}
|
|
94
|
-
return trimmed;
|
|
95
|
-
}
|
|
96
|
-
function parseArchiveDisposition(raw) {
|
|
97
|
-
const trimmed = raw.trim();
|
|
98
|
-
if (!ARCHIVE_DISPOSITIONS.includes(trimmed)) {
|
|
99
|
-
throw new Error(`Unknown archive disposition: ${trimmed}. Supported: ${ARCHIVE_DISPOSITIONS.join(", ")}`);
|
|
100
|
-
}
|
|
101
|
-
return trimmed;
|
|
102
|
-
}
|
|
103
|
-
function isInitPromptAllowed(ctx) {
|
|
104
|
-
return Boolean(process.stdin.isTTY && ctx.stdout.isTTY);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Print a short, friendly hint when the user runs `cclaw-cli` with no
|
|
108
|
-
* arguments. Does not read or mutate flow state — only checks whether
|
|
109
|
-
* `.cclaw/config.yaml` exists to branch between "installed" and
|
|
110
|
-
* "not-installed" messaging. Keeps exit 0 in both cases: users discover
|
|
111
|
-
* the tool through this path, not through an error.
|
|
112
|
-
*/
|
|
113
|
-
function printNoArgsHint(ctx) {
|
|
114
|
-
const installed = existsSync(path.join(ctx.cwd, RUNTIME_ROOT, "config.yaml"));
|
|
115
|
-
if (installed) {
|
|
116
|
-
ctx.stdout.write("cclaw is installed in this project. Open your harness (Claude Code, " +
|
|
117
|
-
"Cursor, OpenCode, or Codex) and type `/cc` to start.\n");
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
ctx.stdout.write("cclaw is not installed in this project yet.\n" +
|
|
121
|
-
"Run `npx cclaw-cli init` to bootstrap .cclaw and the harness shims.\n" +
|
|
122
|
-
"For help: `npx cclaw-cli --help`.\n");
|
|
123
|
-
}
|
|
124
|
-
return 0;
|
|
125
|
-
}
|
|
126
|
-
function buildInitSurfacePreview(harnesses) {
|
|
127
|
-
const lines = [
|
|
128
|
-
".cclaw/config.yaml",
|
|
129
|
-
".cclaw/commands/*.md",
|
|
130
|
-
".cclaw/skills/*/SKILL.md",
|
|
131
|
-
".cclaw/templates/*",
|
|
132
|
-
".cclaw/agents/*.md",
|
|
133
|
-
".cclaw/hooks/*",
|
|
134
|
-
".cclaw/rules/**",
|
|
135
|
-
".cclaw/archive/**",
|
|
136
|
-
".cclaw/artifacts/**",
|
|
137
|
-
".cclaw/knowledge.jsonl",
|
|
138
|
-
".cclaw/state/*.json|*.jsonl",
|
|
139
|
-
"AGENTS.md (managed block)"
|
|
140
|
-
];
|
|
141
|
-
for (const harness of harnesses) {
|
|
142
|
-
const adapter = HARNESS_ADAPTERS[harness];
|
|
143
|
-
if (adapter.shimKind === "skill") {
|
|
144
|
-
lines.push(`${adapter.commandDir}/cc*/SKILL.md`);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
lines.push(`${adapter.commandDir}/cc*.md`);
|
|
148
|
-
}
|
|
149
|
-
if (harness === "claude") {
|
|
150
|
-
lines.push(".claude/hooks/hooks.json");
|
|
151
|
-
}
|
|
152
|
-
if (harness === "cursor") {
|
|
153
|
-
lines.push(".cursor/hooks.json");
|
|
154
|
-
lines.push(".cursor/rules/cclaw-workflow.mdc");
|
|
155
|
-
}
|
|
156
|
-
if (harness === "codex") {
|
|
157
|
-
// .codex/hooks.json is managed because Codex CLI
|
|
158
|
-
// grew a real hooks API (v0.114+, behind the `codex_hooks`
|
|
159
|
-
// feature flag). Legacy `.codex/commands/*` is still auto-cleaned.
|
|
160
|
-
lines.push(".codex/hooks.json (requires `codex_hooks = true` in ~/.codex/config.toml)");
|
|
161
|
-
}
|
|
162
|
-
if (harness === "opencode") {
|
|
163
|
-
lines.push(".opencode/plugins/cclaw-plugin.mjs");
|
|
164
|
-
lines.push("opencode.json(.c) plugin registration");
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return lines;
|
|
168
|
-
}
|
|
169
|
-
async function promptInitConfig(defaults, ctx) {
|
|
170
|
-
const harnesses = await promptHarnessSelectionChecklist(defaults, ctx, "Initial cclaw harnesses");
|
|
171
|
-
return { harnesses };
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* When Codex is one of the installed harnesses, check the Codex CLI
|
|
175
|
-
* config file for the `codex_hooks` feature flag. If it is missing or
|
|
176
|
-
* disabled, offer to patch it in with the user's explicit consent.
|
|
177
|
-
*
|
|
178
|
-
* The function is deliberately advisory: it never fails init — the worst
|
|
179
|
-
* case is that Codex runs without the hooks engine, which is exactly
|
|
180
|
-
* how v0.39.x already shipped. We always print a resolution hint so
|
|
181
|
-
* the user knows what to do next regardless of which branch was taken.
|
|
182
|
-
*/
|
|
183
|
-
async function maybeEnableCodexHooksFlag(harnesses, parsed, ctx) {
|
|
184
|
-
if (!harnesses || !harnesses.includes("codex"))
|
|
185
|
-
return;
|
|
186
|
-
const configPath = codexConfigPath();
|
|
187
|
-
let existing;
|
|
188
|
-
try {
|
|
189
|
-
existing = await readCodexConfig(configPath);
|
|
190
|
-
}
|
|
191
|
-
catch (err) {
|
|
192
|
-
ctx.stdout.write(`note: Could not read ${configPath} to check the codex_hooks flag: ` +
|
|
193
|
-
`${err instanceof Error ? err.message : String(err)}\n`);
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
196
|
-
const state = classifyCodexHooksFlag(existing);
|
|
197
|
-
if (state === "enabled") {
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
const humanState = state === "missing-file"
|
|
201
|
-
? "Codex config file does not exist yet"
|
|
202
|
-
: state === "missing-section"
|
|
203
|
-
? "no [features] section"
|
|
204
|
-
: state === "missing-key"
|
|
205
|
-
? "no codex_hooks key"
|
|
206
|
-
: "codex_hooks is not enabled";
|
|
207
|
-
const instructions = `To enable Codex hooks manually later, ensure ${configPath} contains:\n` +
|
|
208
|
-
` [features]\n codex_hooks = true\n`;
|
|
209
|
-
if (parsed.interactive === false) {
|
|
210
|
-
ctx.stdout.write(`note: codex_hooks feature flag is not enabled (${humanState}).\n` +
|
|
211
|
-
` cclaw wrote .codex/hooks.json, but Codex will ignore it until you enable the flag.\n` +
|
|
212
|
-
` ${instructions}`);
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
if (!isInitPromptAllowed(ctx)) {
|
|
216
|
-
ctx.stdout.write(`note: codex_hooks feature flag is not enabled (${humanState}).\n` +
|
|
217
|
-
` cclaw wrote .codex/hooks.json, but Codex will ignore it until you enable the flag.\n` +
|
|
218
|
-
` ${instructions}`);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
const rl = createInterface({
|
|
222
|
-
input: process.stdin,
|
|
223
|
-
output: ctx.stdout
|
|
224
|
-
});
|
|
225
|
-
try {
|
|
226
|
-
const answer = (await rl.question(`\nCodex CLI hooks are off (${humanState}).\n` +
|
|
227
|
-
`Enable [features] codex_hooks = true in ${configPath} now? [y/N]: `)).trim().toLowerCase();
|
|
228
|
-
const yes = answer === "y" || answer === "yes";
|
|
229
|
-
if (!yes) {
|
|
230
|
-
ctx.stdout.write(`Leaving ${configPath} untouched. ${instructions}`);
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
-
const { updated, changed } = patchCodexHooksFlag(existing);
|
|
234
|
-
if (!changed) {
|
|
235
|
-
ctx.stdout.write(`codex_hooks is already enabled — no changes written.\n`);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
try {
|
|
239
|
-
await writeCodexConfig(configPath, updated);
|
|
240
|
-
ctx.stdout.write(`Enabled [features] codex_hooks = true in ${configPath}.\n`);
|
|
241
|
-
}
|
|
242
|
-
catch (err) {
|
|
243
|
-
ctx.stdout.write(`Could not write ${configPath}: ` +
|
|
244
|
-
`${err instanceof Error ? err.message : String(err)}\n` +
|
|
245
|
-
`${instructions}`);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
finally {
|
|
249
|
-
rl.close();
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
async function resolveInitInputs(parsed, ctx) {
|
|
253
|
-
const detectedHarnesses = parsed.harnesses ? [] : await detectHarnesses(ctx.cwd);
|
|
254
|
-
const autoHarnesses = parsed.harnesses
|
|
255
|
-
? parsed.harnesses
|
|
256
|
-
: (detectedHarnesses.length > 0 ? detectedHarnesses : undefined);
|
|
257
|
-
const promptRequested = parsed.interactive === true;
|
|
258
|
-
const promptForbidden = parsed.interactive === false;
|
|
259
|
-
const implicitPrompt = !promptForbidden &&
|
|
260
|
-
isInitPromptAllowed(ctx) &&
|
|
261
|
-
parsed.track === undefined &&
|
|
262
|
-
parsed.harnesses === undefined;
|
|
263
|
-
const shouldPrompt = promptRequested || implicitPrompt;
|
|
264
|
-
if (!shouldPrompt) {
|
|
265
|
-
return {
|
|
266
|
-
track: parsed.track,
|
|
267
|
-
harnesses: autoHarnesses,
|
|
268
|
-
detectedHarnesses
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
if (!isInitPromptAllowed(ctx)) {
|
|
272
|
-
throw new Error("Interactive init requires a TTY. Remove --interactive or run in a terminal.");
|
|
273
|
-
}
|
|
274
|
-
const defaults = {
|
|
275
|
-
harnesses: autoHarnesses ?? HARNESS_IDS.slice()
|
|
276
|
-
};
|
|
277
|
-
const prompted = await promptInitConfig({ ...defaults, detectedHarnesses }, ctx);
|
|
278
|
-
return {
|
|
279
|
-
track: parsed.track,
|
|
280
|
-
harnesses: prompted.harnesses,
|
|
281
|
-
detectedHarnesses
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
async function resolveSyncInputs(parsed, ctx) {
|
|
285
|
-
const explicitHarnesses = parsed.harnesses;
|
|
286
|
-
if (explicitHarnesses && explicitHarnesses.length > 0) {
|
|
287
|
-
return { harnesses: explicitHarnesses };
|
|
288
|
-
}
|
|
289
|
-
if (parsed.interactive !== true) {
|
|
290
|
-
return {};
|
|
291
|
-
}
|
|
292
|
-
if (!isInitPromptAllowed(ctx)) {
|
|
293
|
-
throw new Error("Interactive sync requires a TTY. Remove --interactive or run in a terminal.");
|
|
294
|
-
}
|
|
295
|
-
let currentHarnesses = [];
|
|
296
|
-
try {
|
|
297
|
-
currentHarnesses = (await readConfig(ctx.cwd)).harnesses;
|
|
298
|
-
}
|
|
299
|
-
catch {
|
|
300
|
-
currentHarnesses = [];
|
|
301
|
-
}
|
|
302
|
-
const detectedHarnesses = await detectHarnesses(ctx.cwd);
|
|
303
|
-
const defaults = detectedHarnesses.length > 0 ? detectedHarnesses : currentHarnesses.length > 0 ? currentHarnesses : HARNESS_IDS.slice();
|
|
304
|
-
return {
|
|
305
|
-
harnesses: await promptHarnessSelectionChecklist({
|
|
306
|
-
harnesses: defaults,
|
|
307
|
-
detectedHarnesses,
|
|
308
|
-
currentHarnesses
|
|
309
|
-
}, ctx, "Sync harness reconfiguration")
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
32
|
function parseArgs(argv) {
|
|
313
|
-
const
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
const filteredArgv = argv.filter((arg) => arg !== "--help" && arg !== "-h" && arg !== "--version" && arg !== "-v");
|
|
323
|
-
const [commandRaw, ...rest] = filteredArgv;
|
|
324
|
-
parsed.command = INSTALLER_COMMANDS.includes(commandRaw)
|
|
325
|
-
? commandRaw
|
|
326
|
-
: undefined;
|
|
327
|
-
// Hidden maintainer surface for runtime guards/helpers. Keep raw positional
|
|
328
|
-
// args untouched so subcommand-level parsing can evolve independently.
|
|
329
|
-
if (parsed.command === "internal") {
|
|
330
|
-
parsed.internalArgs = [...rest];
|
|
331
|
-
return parsed;
|
|
332
|
-
}
|
|
333
|
-
const flags = rest;
|
|
334
|
-
const isAllowedForCommand = (flag) => {
|
|
335
|
-
if (parsed.command === "init" || parsed.command === "sync") {
|
|
336
|
-
return flag.startsWith("--harnesses=") ||
|
|
337
|
-
(parsed.command === "init" && flag.startsWith("--track=")) ||
|
|
338
|
-
(parsed.command === "init" && flag.startsWith("--profile=")) ||
|
|
339
|
-
(parsed.command === "sync" && flag === "--check") ||
|
|
340
|
-
flag === "--interactive" ||
|
|
341
|
-
flag === "--no-interactive" ||
|
|
342
|
-
(parsed.command === "init" && flag === "--dry-run");
|
|
343
|
-
}
|
|
344
|
-
if (parsed.command === "archive") {
|
|
345
|
-
return flag.startsWith("--name=") ||
|
|
346
|
-
flag === "--skip-retro" ||
|
|
347
|
-
flag.startsWith("--retro-reason=") ||
|
|
348
|
-
flag.startsWith("--disposition=") ||
|
|
349
|
-
flag.startsWith("--reason=");
|
|
350
|
-
}
|
|
351
|
-
return false;
|
|
352
|
-
};
|
|
353
|
-
for (const flag of flags) {
|
|
354
|
-
if (!isAllowedForCommand(flag)) {
|
|
355
|
-
throw new Error(`Flag ${flag} is not supported for ${parsed.command ?? "this command"}.`);
|
|
356
|
-
}
|
|
357
|
-
if (flag.startsWith("--harnesses=")) {
|
|
358
|
-
parsed.harnesses = parseHarnesses(flag.replace("--harnesses=", ""));
|
|
359
|
-
continue;
|
|
360
|
-
}
|
|
361
|
-
if (flag.startsWith("--track=")) {
|
|
362
|
-
parsed.track = parseTrack(flag.replace("--track=", ""));
|
|
363
|
-
continue;
|
|
364
|
-
}
|
|
365
|
-
if (flag.startsWith("--profile=")) {
|
|
366
|
-
continue;
|
|
367
|
-
}
|
|
368
|
-
if (flag === "--interactive") {
|
|
369
|
-
parsed.interactive = true;
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
|
-
if (flag === "--no-interactive") {
|
|
373
|
-
parsed.interactive = false;
|
|
374
|
-
continue;
|
|
375
|
-
}
|
|
376
|
-
if (flag === "--dry-run") {
|
|
377
|
-
parsed.dryRun = true;
|
|
378
|
-
continue;
|
|
379
|
-
}
|
|
380
|
-
if (flag === "--check") {
|
|
381
|
-
parsed.syncCheck = true;
|
|
382
|
-
continue;
|
|
383
|
-
}
|
|
384
|
-
if (flag.startsWith("--name=")) {
|
|
385
|
-
parsed.archiveName = flag.replace("--name=", "").trim();
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
if (flag === "--skip-retro") {
|
|
389
|
-
parsed.archiveSkipRetro = true;
|
|
390
|
-
continue;
|
|
391
|
-
}
|
|
392
|
-
if (flag.startsWith("--retro-reason=")) {
|
|
393
|
-
parsed.archiveSkipRetroReason = flag.replace("--retro-reason=", "").trim();
|
|
394
|
-
continue;
|
|
395
|
-
}
|
|
396
|
-
if (flag.startsWith("--disposition=")) {
|
|
397
|
-
parsed.archiveDisposition = parseArchiveDisposition(flag.replace("--disposition=", ""));
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
if (flag.startsWith("--reason=")) {
|
|
401
|
-
parsed.archiveDispositionReason = flag.replace("--reason=", "").trim();
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
return parsed;
|
|
406
|
-
}
|
|
407
|
-
async function runCommand(parsed, ctx) {
|
|
408
|
-
if (parsed.showHelp) {
|
|
409
|
-
ctx.stdout.write(usage());
|
|
410
|
-
return 0;
|
|
411
|
-
}
|
|
412
|
-
if (parsed.showVersion) {
|
|
413
|
-
ctx.stdout.write(`cclaw ${CCLAW_VERSION}\n`);
|
|
414
|
-
return 0;
|
|
415
|
-
}
|
|
416
|
-
const command = parsed.command;
|
|
417
|
-
if (!command) {
|
|
418
|
-
return printNoArgsHint(ctx);
|
|
419
|
-
}
|
|
420
|
-
if (command === "internal") {
|
|
421
|
-
return runInternalCommand(ctx.cwd, parsed.internalArgs ?? [], ctx);
|
|
422
|
-
}
|
|
423
|
-
if (command === "init") {
|
|
424
|
-
const resolved = await resolveInitInputs(parsed, ctx);
|
|
425
|
-
const effectiveTrack = resolved.track;
|
|
426
|
-
const effectiveHarnesses = resolved.harnesses;
|
|
427
|
-
if (parsed.dryRun === true) {
|
|
428
|
-
const previewConfig = createDefaultConfig(effectiveHarnesses, effectiveTrack);
|
|
429
|
-
const previewSurfaces = buildInitSurfacePreview(previewConfig.harnesses);
|
|
430
|
-
info(ctx, "Dry run: no files were written.");
|
|
431
|
-
if (resolved.detectedHarnesses.length > 0 && parsed.harnesses === undefined) {
|
|
432
|
-
info(ctx, `Detected harnesses from repo: ${resolved.detectedHarnesses.join(", ")}`);
|
|
33
|
+
const [command = "help", ...rest] = argv;
|
|
34
|
+
const flags = {};
|
|
35
|
+
let harnesses;
|
|
36
|
+
for (const arg of rest) {
|
|
37
|
+
if (arg.startsWith("--harness=")) {
|
|
38
|
+
const list = arg.slice("--harness=".length).split(",").map((value) => value.trim()).filter(Boolean);
|
|
39
|
+
const invalid = list.filter((value) => !HARNESS_IDS.includes(value));
|
|
40
|
+
if (invalid.length > 0) {
|
|
41
|
+
throw new Error(`Unknown harnesses: ${invalid.join(", ")}. Supported: ${HARNESS_IDS.join(", ")}`);
|
|
433
42
|
}
|
|
434
|
-
|
|
435
|
-
track: effectiveTrack ?? "standard",
|
|
436
|
-
harnesses: previewConfig.harnesses,
|
|
437
|
-
generatedSurfaces: previewSurfaces
|
|
438
|
-
}, null, 2)}\n`);
|
|
439
|
-
return 0;
|
|
43
|
+
harnesses = list;
|
|
440
44
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
track: effectiveTrack
|
|
445
|
-
});
|
|
446
|
-
if (resolved.detectedHarnesses.length > 0 && parsed.harnesses === undefined) {
|
|
447
|
-
info(ctx, `Detected harnesses from repo: ${resolved.detectedHarnesses.join(", ")}`);
|
|
45
|
+
else if (arg.startsWith("--")) {
|
|
46
|
+
const [name, ...value] = arg.slice(2).split("=");
|
|
47
|
+
flags[name] = value.length === 0 ? true : value.join("=");
|
|
448
48
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
49
|
+
else {
|
|
50
|
+
flags._ = arg;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { command, harnesses, flags };
|
|
54
|
+
}
|
|
55
|
+
export async function runCli(argv, context) {
|
|
56
|
+
configureLogger(context.stdout, context.stderr);
|
|
57
|
+
const args = parseArgs(argv);
|
|
58
|
+
switch (args.command) {
|
|
59
|
+
case "init": {
|
|
60
|
+
const result = await initCclaw({
|
|
61
|
+
cwd: context.cwd,
|
|
62
|
+
harnesses: args.harnesses,
|
|
63
|
+
interactive: true
|
|
64
|
+
});
|
|
65
|
+
info(`[cclaw] init complete. Harnesses: ${result.installedHarnesses.join(", ")}`);
|
|
459
66
|
return 0;
|
|
460
67
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
info(ctx, "Upgraded .cclaw runtime and regenerated generated files");
|
|
470
|
-
return 0;
|
|
471
|
-
}
|
|
472
|
-
if (command === "archive") {
|
|
473
|
-
const archived = await archiveRun(ctx.cwd, parsed.archiveName, {
|
|
474
|
-
skipRetro: parsed.archiveSkipRetro === true,
|
|
475
|
-
skipRetroReason: parsed.archiveSkipRetroReason,
|
|
476
|
-
disposition: parsed.archiveDisposition,
|
|
477
|
-
dispositionReason: parsed.archiveDispositionReason
|
|
478
|
-
});
|
|
479
|
-
const snapshotSummary = archived.snapshottedStateFiles.length > 0
|
|
480
|
-
? ` Snapshotted ${archived.snapshottedStateFiles.length} state file(s) under ${archived.archivePath}/state and wrote archive-manifest.json.`
|
|
481
|
-
: "";
|
|
482
|
-
info(ctx, `Archived active artifacts to ${archived.archivePath} (${archived.disposition}). Flow state reset to brainstorm.${snapshotSummary}`);
|
|
483
|
-
const k = archived.knowledge;
|
|
484
|
-
if (k.overThreshold) {
|
|
485
|
-
info(ctx, `Knowledge curation recommended: ${k.knowledgePath} now has ${k.activeEntryCount} active entries (soft threshold ${k.softThreshold}). Ask your harness to curate cclaw knowledge and plan a soft-archive of stale/duplicate entries to ${RUNTIME_ROOT}/knowledge.archive.jsonl.`);
|
|
68
|
+
case "sync": {
|
|
69
|
+
const result = await syncCclaw({
|
|
70
|
+
cwd: context.cwd,
|
|
71
|
+
harnesses: args.harnesses,
|
|
72
|
+
interactive: true
|
|
73
|
+
});
|
|
74
|
+
info(`[cclaw] sync complete. Harnesses: ${result.installedHarnesses.join(", ")}`);
|
|
75
|
+
return 0;
|
|
486
76
|
}
|
|
487
|
-
|
|
488
|
-
|
|
77
|
+
case "upgrade": {
|
|
78
|
+
const result = await upgradeCclaw({
|
|
79
|
+
cwd: context.cwd,
|
|
80
|
+
harnesses: args.harnesses,
|
|
81
|
+
interactive: true
|
|
82
|
+
});
|
|
83
|
+
info(`[cclaw] upgrade complete. Harnesses: ${result.installedHarnesses.join(", ")}`);
|
|
84
|
+
return 0;
|
|
489
85
|
}
|
|
490
|
-
|
|
491
|
-
|
|
86
|
+
case "uninstall": {
|
|
87
|
+
await uninstallCclaw({ cwd: context.cwd });
|
|
88
|
+
info("[cclaw] uninstall complete.");
|
|
89
|
+
return 0;
|
|
492
90
|
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
void main();
|
|
91
|
+
case "version":
|
|
92
|
+
case "--version":
|
|
93
|
+
case "-v":
|
|
94
|
+
info(CCLAW_VERSION);
|
|
95
|
+
return 0;
|
|
96
|
+
case "help":
|
|
97
|
+
case "--help":
|
|
98
|
+
case "-h":
|
|
99
|
+
info(HELP_BODY);
|
|
100
|
+
return 0;
|
|
101
|
+
case "plan":
|
|
102
|
+
case "status":
|
|
103
|
+
case "ship":
|
|
104
|
+
case "migrate":
|
|
105
|
+
case "build":
|
|
106
|
+
case "review":
|
|
107
|
+
logError(`[cclaw] '${args.command}' is not a CLI command in v8. Flow control happens via /cc inside your harness.`);
|
|
108
|
+
return 2;
|
|
109
|
+
default:
|
|
110
|
+
logError(`[cclaw] unknown command: ${args.command}`);
|
|
111
|
+
logError(HELP_BODY);
|
|
112
|
+
return 2;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const isMain = import.meta.url === `file://${process.argv[1]}`;
|
|
116
|
+
if (isMain) {
|
|
117
|
+
runCli(process.argv.slice(2), { cwd: process.cwd(), stdout: process.stdout, stderr: process.stderr })
|
|
118
|
+
.then((code) => {
|
|
119
|
+
process.exit(code);
|
|
120
|
+
})
|
|
121
|
+
.catch((err) => {
|
|
122
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
+
process.stderr.write(`[cclaw] ${message}\n`);
|
|
124
|
+
process.exit(1);
|
|
125
|
+
});
|
|
529
126
|
}
|
|
530
|
-
export { parseArgs, parseArchiveDisposition, parseHarnesses, parseTrack };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ArtifactStage } from "./artifact-paths.js";
|
|
2
|
+
import { type KnowledgeEntry } from "./knowledge-store.js";
|
|
3
|
+
export interface CompoundQualitySignals {
|
|
4
|
+
hasArchitectDecision: boolean;
|
|
5
|
+
reviewIterations: number;
|
|
6
|
+
securityFlag: boolean;
|
|
7
|
+
userRequestedCapture: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface CompoundRunOptions {
|
|
10
|
+
shipCommit: string;
|
|
11
|
+
signals: CompoundQualitySignals;
|
|
12
|
+
refines?: string | null;
|
|
13
|
+
notes?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface CompoundRunResult {
|
|
16
|
+
slug: string;
|
|
17
|
+
shippedDir: string;
|
|
18
|
+
learningCaptured: boolean;
|
|
19
|
+
movedArtifacts: ArtifactStage[];
|
|
20
|
+
knowledgeEntry?: KnowledgeEntry;
|
|
21
|
+
}
|
|
22
|
+
export declare class CompoundError extends Error {
|
|
23
|
+
}
|
|
24
|
+
export declare function shouldCaptureLearning(signals: CompoundQualitySignals): boolean;
|
|
25
|
+
export declare function runCompoundAndShip(projectRoot: string, options: CompoundRunOptions): Promise<CompoundRunResult>;
|
|
26
|
+
export declare function defaultPathsToCheck(projectRoot: string): Promise<string[]>;
|