cclaw-cli 0.5.17 → 0.6.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/dist/cli.d.ts +4 -2
- package/dist/cli.js +18 -4
- package/dist/config.d.ts +2 -2
- package/dist/config.js +19 -5
- package/dist/constants.d.ts +2 -2
- package/dist/constants.js +3 -2
- package/dist/content/hooks.d.ts +1 -0
- package/dist/content/hooks.js +145 -0
- package/dist/content/learnings.js +25 -5
- package/dist/content/meta-skill.js +12 -0
- package/dist/content/next-command.js +8 -0
- package/dist/content/observe.js +18 -0
- package/dist/content/session-hooks.js +1 -1
- package/dist/content/stage-schema.js +12 -2
- package/dist/content/status-command.d.ts +9 -0
- package/dist/content/status-command.js +132 -0
- package/dist/content/templates.js +14 -0
- package/dist/content/utility-skills.d.ts +6 -2
- package/dist/content/utility-skills.js +431 -3
- package/dist/flow-state.d.ts +16 -4
- package/dist/flow-state.js +50 -11
- package/dist/harness-adapters.js +1 -0
- package/dist/install.d.ts +2 -1
- package/dist/install.js +107 -6
- package/dist/runs.js +24 -3
- package/dist/types.d.ts +13 -0
- package/dist/types.js +13 -0
- package/package.json +1 -1
package/dist/flow-state.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { COMMAND_FILE_ORDER } from "./constants.js";
|
|
2
2
|
import { buildTransitionRules, orderedStageSchemas, stageGateIds } from "./content/stage-schema.js";
|
|
3
|
+
import { FLOW_STAGES, FLOW_TRACKS, TRACK_STAGES } from "./types.js";
|
|
3
4
|
export const TRANSITION_RULES = buildTransitionRules();
|
|
4
|
-
export function
|
|
5
|
+
export function isFlowTrack(value) {
|
|
6
|
+
return typeof value === "string" && FLOW_TRACKS.includes(value);
|
|
7
|
+
}
|
|
8
|
+
export function trackStages(track) {
|
|
9
|
+
return [...TRACK_STAGES[track]];
|
|
10
|
+
}
|
|
11
|
+
export function skippedStagesForTrack(track) {
|
|
12
|
+
const inTrack = new Set(TRACK_STAGES[track]);
|
|
13
|
+
return FLOW_STAGES.filter((stage) => !inTrack.has(stage));
|
|
14
|
+
}
|
|
15
|
+
export function firstStageForTrack(track) {
|
|
16
|
+
const stages = TRACK_STAGES[track];
|
|
17
|
+
return stages[0] ?? "brainstorm";
|
|
18
|
+
}
|
|
19
|
+
export function createInitialFlowState(activeRunIdOrOptions = "active", maybeTrack) {
|
|
20
|
+
const options = typeof activeRunIdOrOptions === "string"
|
|
21
|
+
? { activeRunId: activeRunIdOrOptions, track: maybeTrack }
|
|
22
|
+
: activeRunIdOrOptions;
|
|
23
|
+
const activeRunId = options.activeRunId ?? "active";
|
|
24
|
+
const track = options.track ?? "standard";
|
|
25
|
+
const skippedStages = skippedStagesForTrack(track);
|
|
5
26
|
const stageGateCatalog = {};
|
|
6
27
|
for (const schema of orderedStageSchemas()) {
|
|
7
28
|
stageGateCatalog[schema.stage] = {
|
|
@@ -12,10 +33,12 @@ export function createInitialFlowState(activeRunId = "active") {
|
|
|
12
33
|
}
|
|
13
34
|
return {
|
|
14
35
|
activeRunId,
|
|
15
|
-
currentStage:
|
|
36
|
+
currentStage: firstStageForTrack(track),
|
|
16
37
|
completedStages: [],
|
|
17
38
|
guardEvidence: {},
|
|
18
|
-
stageGateCatalog
|
|
39
|
+
stageGateCatalog,
|
|
40
|
+
track,
|
|
41
|
+
skippedStages
|
|
19
42
|
};
|
|
20
43
|
}
|
|
21
44
|
export function canTransition(from, to) {
|
|
@@ -25,17 +48,33 @@ export function getTransitionGuards(from, to) {
|
|
|
25
48
|
const match = TRANSITION_RULES.find((rule) => rule.from === from && rule.to === to);
|
|
26
49
|
return match ? [...match.guards] : [];
|
|
27
50
|
}
|
|
28
|
-
export function nextStage(stage) {
|
|
29
|
-
const
|
|
30
|
-
|
|
51
|
+
export function nextStage(stage, track = "standard") {
|
|
52
|
+
const ordered = TRACK_STAGES[track];
|
|
53
|
+
const index = ordered.indexOf(stage);
|
|
54
|
+
if (index < 0) {
|
|
55
|
+
const fallback = COMMAND_FILE_ORDER.indexOf(stage);
|
|
56
|
+
if (fallback < 0 || fallback === COMMAND_FILE_ORDER.length - 1) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return COMMAND_FILE_ORDER[fallback + 1];
|
|
60
|
+
}
|
|
61
|
+
if (index === ordered.length - 1) {
|
|
31
62
|
return null;
|
|
32
63
|
}
|
|
33
|
-
return
|
|
64
|
+
return ordered[index + 1];
|
|
34
65
|
}
|
|
35
|
-
export function previousStage(stage) {
|
|
36
|
-
const
|
|
37
|
-
|
|
66
|
+
export function previousStage(stage, track = "standard") {
|
|
67
|
+
const ordered = TRACK_STAGES[track];
|
|
68
|
+
const index = ordered.indexOf(stage);
|
|
69
|
+
if (index === 0) {
|
|
38
70
|
return null;
|
|
39
71
|
}
|
|
40
|
-
|
|
72
|
+
if (index < 0) {
|
|
73
|
+
const fallback = COMMAND_FILE_ORDER.indexOf(stage);
|
|
74
|
+
if (fallback <= 0) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return COMMAND_FILE_ORDER[fallback - 1];
|
|
78
|
+
}
|
|
79
|
+
return ordered[index - 1];
|
|
41
80
|
}
|
package/dist/harness-adapters.js
CHANGED
|
@@ -124,6 +124,7 @@ export async function syncHarnessShims(projectRoot, harnesses) {
|
|
|
124
124
|
await writeFileSafe(path.join(commandDir, "cc.md"), utilityShimContent(harness, "cc", "flow-start", "start.md"));
|
|
125
125
|
await writeFileSafe(path.join(commandDir, "cc-next.md"), utilityShimContent(harness, "next", "flow-next-step", "next.md"));
|
|
126
126
|
await writeFileSafe(path.join(commandDir, "cc-learn.md"), utilityShimContent(harness, "learn", "learnings", "learn.md"));
|
|
127
|
+
await writeFileSafe(path.join(commandDir, "cc-status.md"), utilityShimContent(harness, "status", "flow-status", "status.md"));
|
|
127
128
|
}
|
|
128
129
|
await syncAgentFiles(projectRoot);
|
|
129
130
|
await syncAgentsMd(projectRoot);
|
package/dist/install.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { HarnessId } from "./types.js";
|
|
1
|
+
import type { FlowTrack, HarnessId } from "./types.js";
|
|
2
2
|
export interface InitOptions {
|
|
3
3
|
projectRoot: string;
|
|
4
4
|
harnesses?: HarnessId[];
|
|
5
|
+
track?: FlowTrack;
|
|
5
6
|
}
|
|
6
7
|
export declare function initCclaw(options: InitOptions): Promise<void>;
|
|
7
8
|
export declare function syncCclaw(projectRoot: string): Promise<void>;
|
package/dist/install.js
CHANGED
|
@@ -9,9 +9,10 @@ import { contextModeFiles, createInitialContextModeState } from "./content/conte
|
|
|
9
9
|
import { learnSkillMarkdown, learnCommandContract } from "./content/learnings.js";
|
|
10
10
|
import { nextCommandContract, nextCommandSkillMarkdown } from "./content/next-command.js";
|
|
11
11
|
import { startCommandContract, startCommandSkillMarkdown } from "./content/start-command.js";
|
|
12
|
+
import { statusCommandContract, statusCommandSkillMarkdown } from "./content/status-command.js";
|
|
12
13
|
import { subagentDrivenDevSkill, parallelAgentsSkill } from "./content/subagents.js";
|
|
13
14
|
import { sessionHooksSkillMarkdown } from "./content/session-hooks.js";
|
|
14
|
-
import { sessionStartScript, stopCheckpointScript, opencodePluginJs, claudeHooksJson, cursorHooksJson, codexHooksJson } from "./content/hooks.js";
|
|
15
|
+
import { sessionStartScript, stopCheckpointScript, preCompactScript, opencodePluginJs, claudeHooksJson, cursorHooksJson, codexHooksJson } from "./content/hooks.js";
|
|
15
16
|
import { contextMonitorScript, promptGuardScript, workflowGuardScript } from "./content/observe.js";
|
|
16
17
|
import { META_SKILL_NAME, usingCclawSkillMarkdown } from "./content/meta-skill.js";
|
|
17
18
|
import { ARTIFACT_TEMPLATES, CURSOR_WORKFLOW_RULE_MDC, RULEBOOK_MARKDOWN, buildRulesJson } from "./content/templates.js";
|
|
@@ -173,6 +174,7 @@ async function writeSkills(projectRoot) {
|
|
|
173
174
|
await writeFileSafe(runtimePath(projectRoot, "skills", "learnings", "SKILL.md"), learnSkillMarkdown());
|
|
174
175
|
await writeFileSafe(runtimePath(projectRoot, "skills", "flow-next-step", "SKILL.md"), nextCommandSkillMarkdown());
|
|
175
176
|
await writeFileSafe(runtimePath(projectRoot, "skills", "flow-start", "SKILL.md"), startCommandSkillMarkdown());
|
|
177
|
+
await writeFileSafe(runtimePath(projectRoot, "skills", "flow-status", "SKILL.md"), statusCommandSkillMarkdown());
|
|
176
178
|
await writeFileSafe(runtimePath(projectRoot, "skills", "subagent-dev", "SKILL.md"), subagentDrivenDevSkill());
|
|
177
179
|
await writeFileSafe(runtimePath(projectRoot, "skills", "parallel-dispatch", "SKILL.md"), parallelAgentsSkill());
|
|
178
180
|
await writeFileSafe(runtimePath(projectRoot, "skills", "session", "SKILL.md"), sessionHooksSkillMarkdown());
|
|
@@ -186,6 +188,7 @@ async function writeUtilityCommands(projectRoot) {
|
|
|
186
188
|
await writeFileSafe(runtimePath(projectRoot, "commands", "learn.md"), learnCommandContract());
|
|
187
189
|
await writeFileSafe(runtimePath(projectRoot, "commands", "next.md"), nextCommandContract());
|
|
188
190
|
await writeFileSafe(runtimePath(projectRoot, "commands", "start.md"), startCommandContract());
|
|
191
|
+
await writeFileSafe(runtimePath(projectRoot, "commands", "status.md"), statusCommandContract());
|
|
189
192
|
}
|
|
190
193
|
function toObject(value) {
|
|
191
194
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -482,6 +485,7 @@ async function writeHooks(projectRoot, config) {
|
|
|
482
485
|
await ensureDir(hooksDir);
|
|
483
486
|
await writeFileSafe(path.join(hooksDir, "session-start.sh"), sessionStartScript());
|
|
484
487
|
await writeFileSafe(path.join(hooksDir, "stop-checkpoint.sh"), stopCheckpointScript());
|
|
488
|
+
await writeFileSafe(path.join(hooksDir, "pre-compact.sh"), preCompactScript());
|
|
485
489
|
await writeFileSafe(path.join(hooksDir, "prompt-guard.sh"), promptGuardScript({
|
|
486
490
|
strictMode: config.promptGuardMode === "strict"
|
|
487
491
|
}));
|
|
@@ -493,6 +497,7 @@ async function writeHooks(projectRoot, config) {
|
|
|
493
497
|
for (const script of [
|
|
494
498
|
"session-start.sh",
|
|
495
499
|
"stop-checkpoint.sh",
|
|
500
|
+
"pre-compact.sh",
|
|
496
501
|
"prompt-guard.sh",
|
|
497
502
|
"workflow-guard.sh",
|
|
498
503
|
"context-monitor.sh",
|
|
@@ -542,6 +547,101 @@ async function ensureKnowledgeStore(projectRoot) {
|
|
|
542
547
|
await writeFileSafe(storePath, "# Project Knowledge\n\n");
|
|
543
548
|
}
|
|
544
549
|
}
|
|
550
|
+
async function ensureCustomSkillsScaffold(projectRoot) {
|
|
551
|
+
const customDir = runtimePath(projectRoot, "custom-skills");
|
|
552
|
+
await ensureDir(customDir);
|
|
553
|
+
const readmePath = path.join(customDir, "README.md");
|
|
554
|
+
if (!(await exists(readmePath))) {
|
|
555
|
+
await writeFileSafe(readmePath, CUSTOM_SKILLS_README);
|
|
556
|
+
}
|
|
557
|
+
const examplePath = path.join(customDir, "example", "SKILL.md");
|
|
558
|
+
if (!(await exists(examplePath))) {
|
|
559
|
+
await writeFileSafe(examplePath, CUSTOM_SKILLS_EXAMPLE);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
const CUSTOM_SKILLS_README = `# Custom Skills (sync-safe)
|
|
563
|
+
|
|
564
|
+
This directory is **never overwritten** by \`cclaw sync\` or \`cclaw upgrade\`. Use it
|
|
565
|
+
to add project-specific skills that complement the managed skills under
|
|
566
|
+
\`.cclaw/skills/\`.
|
|
567
|
+
|
|
568
|
+
## When to add a custom skill
|
|
569
|
+
|
|
570
|
+
- A repeatable lens specific to **this project** (e.g. "billing-domain", "kafka-message-contracts").
|
|
571
|
+
- A team convention you want every agent session to load.
|
|
572
|
+
- A domain checklist that does not generalize to other projects.
|
|
573
|
+
|
|
574
|
+
If the skill is general (security, performance, accessibility, etc.) prefer
|
|
575
|
+
contributing it upstream instead — the managed skills receive maintenance.
|
|
576
|
+
|
|
577
|
+
## File format
|
|
578
|
+
|
|
579
|
+
Each skill lives at \`.cclaw/custom-skills/<folder>/SKILL.md\` with frontmatter:
|
|
580
|
+
|
|
581
|
+
\`\`\`markdown
|
|
582
|
+
---
|
|
583
|
+
name: <kebab-case-skill-name>
|
|
584
|
+
description: "One sentence describing when this skill applies. Triggers semantic routing."
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
# <Skill title>
|
|
588
|
+
|
|
589
|
+
## When to use
|
|
590
|
+
- ...
|
|
591
|
+
|
|
592
|
+
## HARD-GATE (optional)
|
|
593
|
+
A non-skippable rule, if any. Phrase it as a refusal, not a recommendation.
|
|
594
|
+
|
|
595
|
+
## Algorithm / checklist
|
|
596
|
+
1. ...
|
|
597
|
+
2. ...
|
|
598
|
+
|
|
599
|
+
## Anti-patterns
|
|
600
|
+
- ...
|
|
601
|
+
\`\`\`
|
|
602
|
+
|
|
603
|
+
## Routing
|
|
604
|
+
|
|
605
|
+
Custom skills are surfaced via the \`using-cclaw\` meta-skill at session start.
|
|
606
|
+
Mention the skill name in your prompt or let the agent semantic-route to it
|
|
607
|
+
based on the description.
|
|
608
|
+
|
|
609
|
+
## Removing or replacing
|
|
610
|
+
|
|
611
|
+
Custom skills are user-owned. Delete or edit them at any time — \`cclaw sync\`
|
|
612
|
+
will not touch them.
|
|
613
|
+
`;
|
|
614
|
+
const CUSTOM_SKILLS_EXAMPLE = `---
|
|
615
|
+
name: example-custom-skill
|
|
616
|
+
description: "Replace this with a one-sentence description that triggers when the skill should be used. Delete or rename this folder when you add a real skill."
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
# Example Custom Skill
|
|
620
|
+
|
|
621
|
+
This is a placeholder. Use it as a starting template, then delete or rename
|
|
622
|
+
the \`example/\` folder.
|
|
623
|
+
|
|
624
|
+
## When to use
|
|
625
|
+
|
|
626
|
+
- A real, repeatable situation in **this** project that needs a consistent lens.
|
|
627
|
+
|
|
628
|
+
## HARD-GATE (optional)
|
|
629
|
+
|
|
630
|
+
Drop this section if no hard rule applies. Keep it crisp:
|
|
631
|
+
|
|
632
|
+
> Do not <X> while <Y>.
|
|
633
|
+
|
|
634
|
+
## Algorithm
|
|
635
|
+
|
|
636
|
+
1. Step one — observable, file:line evidence required.
|
|
637
|
+
2. Step two — produce a named artifact, not a vibe.
|
|
638
|
+
3. Step three — escalate / hand off / record knowledge entry.
|
|
639
|
+
|
|
640
|
+
## Anti-patterns
|
|
641
|
+
|
|
642
|
+
- Treating this skill as advisory when the situation matches the trigger.
|
|
643
|
+
- Loading this skill when the situation clearly does not match (context bloat).
|
|
644
|
+
`;
|
|
545
645
|
async function ensureSessionStateFiles(projectRoot) {
|
|
546
646
|
const stateDir = runtimePath(projectRoot, "state");
|
|
547
647
|
await ensureDir(stateDir);
|
|
@@ -623,12 +723,12 @@ async function syncDisabledHarnessArtifacts(projectRoot, harnesses) {
|
|
|
623
723
|
await removeManagedOpenCodePluginConfig(projectRoot, OPENCODE_PLUGIN_REL_PATH);
|
|
624
724
|
}
|
|
625
725
|
}
|
|
626
|
-
async function writeState(projectRoot, forceReset = false) {
|
|
726
|
+
async function writeState(projectRoot, config, forceReset = false) {
|
|
627
727
|
const statePath = runtimePath(projectRoot, "state", "flow-state.json");
|
|
628
728
|
if (!forceReset && (await exists(statePath))) {
|
|
629
729
|
return;
|
|
630
730
|
}
|
|
631
|
-
const state = createInitialFlowState();
|
|
731
|
+
const state = createInitialFlowState("active", config.defaultTrack ?? "standard");
|
|
632
732
|
await writeFileSafe(statePath, `${JSON.stringify(state, null, 2)}\n`);
|
|
633
733
|
}
|
|
634
734
|
async function writeAdapterManifest(projectRoot, harnesses) {
|
|
@@ -740,11 +840,12 @@ async function materializeRuntime(projectRoot, config, forceStateReset) {
|
|
|
740
840
|
await writeContextModes(projectRoot);
|
|
741
841
|
await writeArtifactTemplates(projectRoot);
|
|
742
842
|
await writeRulebook(projectRoot);
|
|
743
|
-
await writeState(projectRoot, forceStateReset);
|
|
843
|
+
await writeState(projectRoot, config, forceStateReset);
|
|
744
844
|
await ensureRunSystem(projectRoot, { createIfMissing: false });
|
|
745
845
|
await ensureSessionStateFiles(projectRoot);
|
|
746
846
|
await writeAdapterManifest(projectRoot, harnesses);
|
|
747
847
|
await ensureKnowledgeStore(projectRoot);
|
|
848
|
+
await ensureCustomSkillsScaffold(projectRoot);
|
|
748
849
|
await writeHooks(projectRoot, config);
|
|
749
850
|
await syncDisabledHarnessArtifacts(projectRoot, harnesses);
|
|
750
851
|
await syncManagedGitHooks(projectRoot, config);
|
|
@@ -753,7 +854,7 @@ async function materializeRuntime(projectRoot, config, forceStateReset) {
|
|
|
753
854
|
await ensureGitignore(projectRoot);
|
|
754
855
|
}
|
|
755
856
|
export async function initCclaw(options) {
|
|
756
|
-
const config = createDefaultConfig(options.harnesses);
|
|
857
|
+
const config = createDefaultConfig(options.harnesses, options.track);
|
|
757
858
|
await writeConfig(options.projectRoot, config);
|
|
758
859
|
await materializeRuntime(options.projectRoot, config, true);
|
|
759
860
|
}
|
|
@@ -828,7 +929,7 @@ function stripManagedHookCommands(value) {
|
|
|
828
929
|
}
|
|
829
930
|
function isManagedRuntimeHookCommand(command) {
|
|
830
931
|
const normalized = command.trim().replace(/\s+/gu, " ");
|
|
831
|
-
return /(^|\s)(?:bash\s+)?(?:\.\/)?\.cclaw\/hooks\/(?:session-start|stop-checkpoint|prompt-guard|workflow-guard|context-monitor)\.sh(?:\s|$)/u.test(normalized);
|
|
932
|
+
return /(^|\s)(?:bash\s+)?(?:\.\/)?\.cclaw\/hooks\/(?:session-start|stop-checkpoint|pre-compact|prompt-guard|workflow-guard|context-monitor)\.sh(?:\s|$)/u.test(normalized);
|
|
832
933
|
}
|
|
833
934
|
async function removeManagedHookEntries(hookFilePath) {
|
|
834
935
|
if (!(await exists(hookFilePath)))
|
package/dist/runs.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { COMMAND_FILE_ORDER, RUNTIME_ROOT } from "./constants.js";
|
|
4
|
-
import { canTransition, createInitialFlowState } from "./flow-state.js";
|
|
4
|
+
import { canTransition, createInitialFlowState, isFlowTrack, skippedStagesForTrack } from "./flow-state.js";
|
|
5
5
|
import { ensureDir, exists, withDirectoryLock, writeFileSafe } from "./fs-utils.js";
|
|
6
6
|
export class InvalidStageTransitionError extends Error {
|
|
7
7
|
from;
|
|
@@ -156,8 +156,27 @@ function sanitizeStageGateCatalog(value, fallback) {
|
|
|
156
156
|
}
|
|
157
157
|
return next;
|
|
158
158
|
}
|
|
159
|
+
function coerceTrack(value) {
|
|
160
|
+
return isFlowTrack(value) ? value : "standard";
|
|
161
|
+
}
|
|
162
|
+
function sanitizeSkippedStages(value, track) {
|
|
163
|
+
const trackDefault = skippedStagesForTrack(track);
|
|
164
|
+
if (!Array.isArray(value)) {
|
|
165
|
+
return trackDefault;
|
|
166
|
+
}
|
|
167
|
+
const seen = new Set();
|
|
168
|
+
const out = [];
|
|
169
|
+
for (const raw of value) {
|
|
170
|
+
if (isFlowStage(raw) && !seen.has(raw)) {
|
|
171
|
+
seen.add(raw);
|
|
172
|
+
out.push(raw);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return out.length > 0 ? out : trackDefault;
|
|
176
|
+
}
|
|
159
177
|
function coerceFlowState(parsed) {
|
|
160
|
-
const
|
|
178
|
+
const track = coerceTrack(parsed.track);
|
|
179
|
+
const next = createInitialFlowState("active", track);
|
|
161
180
|
const activeRunIdRaw = parsed.activeRunId;
|
|
162
181
|
const activeRunId = typeof activeRunIdRaw === "string" && activeRunIdRaw.trim().length > 0
|
|
163
182
|
? activeRunIdRaw.trim()
|
|
@@ -167,7 +186,9 @@ function coerceFlowState(parsed) {
|
|
|
167
186
|
currentStage: isFlowStage(parsed.currentStage) ? parsed.currentStage : next.currentStage,
|
|
168
187
|
completedStages: sanitizeCompletedStages(parsed.completedStages),
|
|
169
188
|
guardEvidence: sanitizeGuardEvidence(parsed.guardEvidence),
|
|
170
|
-
stageGateCatalog: sanitizeStageGateCatalog(parsed.stageGateCatalog, next.stageGateCatalog)
|
|
189
|
+
stageGateCatalog: sanitizeStageGateCatalog(parsed.stageGateCatalog, next.stageGateCatalog),
|
|
190
|
+
track,
|
|
191
|
+
skippedStages: sanitizeSkippedStages(parsed.skippedStages, track)
|
|
171
192
|
};
|
|
172
193
|
}
|
|
173
194
|
function toArchiveDate(date = new Date()) {
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
export declare const FLOW_STAGES: readonly ["brainstorm", "scope", "design", "spec", "plan", "tdd", "review", "ship"];
|
|
2
2
|
export type FlowStage = (typeof FLOW_STAGES)[number];
|
|
3
|
+
export declare const FLOW_TRACKS: readonly ["quick", "standard"];
|
|
4
|
+
export type FlowTrack = (typeof FLOW_TRACKS)[number];
|
|
5
|
+
/**
|
|
6
|
+
* Ordered stages that make up each flow track.
|
|
7
|
+
*
|
|
8
|
+
* - `standard` runs the full 8-stage pipeline (default — same as before tracks existed).
|
|
9
|
+
* - `quick` skips the upstream product stages (brainstorm/scope/design/plan) for
|
|
10
|
+
* small bug fixes or single-purpose changes where the spec is already known.
|
|
11
|
+
* It still keeps the non-negotiable safety gates: spec → tdd → review → ship.
|
|
12
|
+
*/
|
|
13
|
+
export declare const TRACK_STAGES: Record<FlowTrack, readonly FlowStage[]>;
|
|
3
14
|
export declare const HARNESS_IDS: readonly ["claude", "cursor", "opencode", "codex"];
|
|
4
15
|
export type HarnessId = (typeof HARNESS_IDS)[number];
|
|
5
16
|
export interface VibyConfig {
|
|
@@ -12,6 +23,8 @@ export interface VibyConfig {
|
|
|
12
23
|
promptGuardMode?: "advisory" | "strict";
|
|
13
24
|
/** When true, cclaw installs managed git pre-commit/pre-push wrappers. */
|
|
14
25
|
gitHookGuards?: boolean;
|
|
26
|
+
/** Default flow track for new runs (quick = shortened path, standard = full pipeline). */
|
|
27
|
+
defaultTrack?: FlowTrack;
|
|
15
28
|
}
|
|
16
29
|
export interface TransitionRule {
|
|
17
30
|
from: FlowStage;
|
package/dist/types.js
CHANGED
|
@@ -8,4 +8,17 @@ export const FLOW_STAGES = [
|
|
|
8
8
|
"review",
|
|
9
9
|
"ship"
|
|
10
10
|
];
|
|
11
|
+
export const FLOW_TRACKS = ["quick", "standard"];
|
|
12
|
+
/**
|
|
13
|
+
* Ordered stages that make up each flow track.
|
|
14
|
+
*
|
|
15
|
+
* - `standard` runs the full 8-stage pipeline (default — same as before tracks existed).
|
|
16
|
+
* - `quick` skips the upstream product stages (brainstorm/scope/design/plan) for
|
|
17
|
+
* small bug fixes or single-purpose changes where the spec is already known.
|
|
18
|
+
* It still keeps the non-negotiable safety gates: spec → tdd → review → ship.
|
|
19
|
+
*/
|
|
20
|
+
export const TRACK_STAGES = {
|
|
21
|
+
standard: FLOW_STAGES,
|
|
22
|
+
quick: ["spec", "tdd", "review", "ship"]
|
|
23
|
+
};
|
|
11
24
|
export const HARNESS_IDS = ["claude", "cursor", "opencode", "codex"];
|