cclaw-cli 7.7.0 → 8.1.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 +210 -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 +90 -508
- 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 -766
- 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 -132
- 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/install.d.ts +27 -15
- package/dist/install.js +230 -1342
- 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 -36
- package/dist/execution-topology.js +0 -73
- 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 -63
- package/dist/internal/wave-status.js +0 -450
- 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/content/idea.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export type IdeaFrameId = "pain-friction" | "assumption-break" | "cross-domain-analogy";
|
|
2
|
-
export interface IdeaFrame {
|
|
3
|
-
id: IdeaFrameId;
|
|
4
|
-
label: string;
|
|
5
|
-
prompt: string;
|
|
6
|
-
examplePatterns: string[];
|
|
7
|
-
}
|
|
8
|
-
export interface IdeaFrameDispatchInput {
|
|
9
|
-
focus: string;
|
|
10
|
-
mode: "repo-grounded" | "elsewhere-software" | "elsewhere-non-software";
|
|
11
|
-
signalSummary: string[];
|
|
12
|
-
}
|
|
13
|
-
export interface IdeaFrameDispatchPlanEntry {
|
|
14
|
-
frameId: IdeaFrameId;
|
|
15
|
-
label: string;
|
|
16
|
-
prompt: string;
|
|
17
|
-
}
|
|
18
|
-
export interface IdeaCandidateDraft {
|
|
19
|
-
title: string;
|
|
20
|
-
evidencePath: string;
|
|
21
|
-
summary: string;
|
|
22
|
-
frameId: IdeaFrameId;
|
|
23
|
-
}
|
|
24
|
-
export interface IdeaCandidateMerged extends Omit<IdeaCandidateDraft, "frameId"> {
|
|
25
|
-
frameIds: IdeaFrameId[];
|
|
26
|
-
}
|
|
27
|
-
export declare const DEFAULT_IDEA_FRAME_IDS: readonly IdeaFrameId[];
|
|
28
|
-
export declare const IDEA_FRAMES: readonly IdeaFrame[];
|
|
29
|
-
export declare function resolveIdeaFrames(frameIds?: readonly IdeaFrameId[]): IdeaFrame[];
|
|
30
|
-
export declare function buildIdeaFrameDispatchPlan(input: IdeaFrameDispatchInput, frameIds?: readonly IdeaFrameId[]): IdeaFrameDispatchPlanEntry[];
|
|
31
|
-
export declare function dedupeIdeaCandidates(drafts: readonly IdeaCandidateDraft[]): IdeaCandidateMerged[];
|
|
32
|
-
export type IdeaImpact = "high" | "medium" | "low";
|
|
33
|
-
export type IdeaEffort = "s" | "m" | "l";
|
|
34
|
-
export type IdeaConfidence = "high" | "medium" | "low";
|
|
35
|
-
export interface IdeaCandidateEvaluationInput {
|
|
36
|
-
id: string;
|
|
37
|
-
title: string;
|
|
38
|
-
impact: IdeaImpact;
|
|
39
|
-
effort: IdeaEffort;
|
|
40
|
-
confidence: IdeaConfidence;
|
|
41
|
-
}
|
|
42
|
-
export interface IdeaCandidateEvaluation extends IdeaCandidateEvaluationInput {
|
|
43
|
-
disposition: "survivor" | "rejected";
|
|
44
|
-
rankingScore: number;
|
|
45
|
-
}
|
|
46
|
-
export interface IdeaRankingResult {
|
|
47
|
-
survivors: IdeaCandidateEvaluation[];
|
|
48
|
-
rejected: IdeaCandidateEvaluation[];
|
|
49
|
-
recommendationId: string | null;
|
|
50
|
-
}
|
|
51
|
-
export declare function scoreIdeaCandidate(impact: IdeaImpact, effort: IdeaEffort, confidence: IdeaConfidence): number;
|
|
52
|
-
export declare function evaluateIdeaCandidate(input: IdeaCandidateEvaluationInput): IdeaCandidateEvaluation;
|
|
53
|
-
export declare function rankIdeaCandidates(inputs: readonly IdeaCandidateEvaluationInput[], maxSurvivors?: number): IdeaRankingResult;
|
|
54
|
-
export interface IdeaCommandOptions {
|
|
55
|
-
frameIds?: readonly IdeaFrameId[];
|
|
56
|
-
mode?: "repo-grounded" | "elsewhere-software" | "elsewhere-non-software" | "narrow";
|
|
57
|
-
}
|
|
58
|
-
export declare function minimumDistinctIdeaFrames(frameCount: number, mode?: IdeaCommandOptions["mode"]): number;
|
|
59
|
-
export declare function ideaCommandContract(options?: IdeaCommandOptions): string;
|
|
60
|
-
export declare function ideaCommandSkillMarkdown(options?: IdeaCommandOptions): string;
|
package/dist/content/idea.js
DELETED
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
import { RUNTIME_ROOT } from "../constants.js";
|
|
2
|
-
import { ideaStructuredAskToolsWithFallback } from "./decision-protocol.js";
|
|
3
|
-
import { conversationLanguagePolicyMarkdown } from "./language-policy.js";
|
|
4
|
-
const FRAME_REGISTRY = {
|
|
5
|
-
"pain-friction": {
|
|
6
|
-
id: "pain-friction",
|
|
7
|
-
label: "pain/friction",
|
|
8
|
-
prompt: "Find repeated friction in the repo workflow. Prioritize changes that eliminate recurring toil, fragile handoffs, or repeated manual recovery.",
|
|
9
|
-
examplePatterns: [
|
|
10
|
-
"Repeated TODO/FIXME hotspots in one subsystem",
|
|
11
|
-
"Flows that require manual retries or ad-hoc scripts",
|
|
12
|
-
"Developer loops slowed by avoidable boilerplate"
|
|
13
|
-
]
|
|
14
|
-
},
|
|
15
|
-
"assumption-break": {
|
|
16
|
-
id: "assumption-break",
|
|
17
|
-
label: "assumption-break",
|
|
18
|
-
prompt: "List the top assumptions behind the current approach and break one: what if that assumption is wrong, incomplete, or expensive to maintain?",
|
|
19
|
-
examplePatterns: [
|
|
20
|
-
"An approval gate currently assumed to be always manual can be automated safely",
|
|
21
|
-
"A broad required section can be optional with measurable trigger conditions",
|
|
22
|
-
"A long checklist step can be replaced by a deterministic verifier"
|
|
23
|
-
]
|
|
24
|
-
},
|
|
25
|
-
"cross-domain-analogy": {
|
|
26
|
-
id: "cross-domain-analogy",
|
|
27
|
-
label: "cross-domain-analogy",
|
|
28
|
-
prompt: "Borrow one proven pattern from an adjacent domain and map it to this repository's constraints.",
|
|
29
|
-
examplePatterns: [
|
|
30
|
-
"Treat post-ship closeout like incident-response runbooks with explicit ownership",
|
|
31
|
-
"Apply API compatibility techniques to artifact schema evolution",
|
|
32
|
-
"Use observability SLO-style thresholds for process-quality gates"
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
export const DEFAULT_IDEA_FRAME_IDS = Object.freeze([
|
|
37
|
-
"pain-friction",
|
|
38
|
-
"assumption-break",
|
|
39
|
-
"cross-domain-analogy"
|
|
40
|
-
]);
|
|
41
|
-
export const IDEA_FRAMES = Object.freeze(DEFAULT_IDEA_FRAME_IDS.map((id) => FRAME_REGISTRY[id]));
|
|
42
|
-
export function resolveIdeaFrames(frameIds) {
|
|
43
|
-
if (!frameIds || frameIds.length === 0) {
|
|
44
|
-
return [...IDEA_FRAMES];
|
|
45
|
-
}
|
|
46
|
-
const seen = new Set();
|
|
47
|
-
const resolved = [];
|
|
48
|
-
for (const rawId of frameIds) {
|
|
49
|
-
if (!DEFAULT_IDEA_FRAME_IDS.includes(rawId)) {
|
|
50
|
-
throw new Error(`Unknown idea frame id: ${rawId}`);
|
|
51
|
-
}
|
|
52
|
-
if (seen.has(rawId))
|
|
53
|
-
continue;
|
|
54
|
-
seen.add(rawId);
|
|
55
|
-
resolved.push(FRAME_REGISTRY[rawId]);
|
|
56
|
-
}
|
|
57
|
-
return resolved;
|
|
58
|
-
}
|
|
59
|
-
export function buildIdeaFrameDispatchPlan(input, frameIds) {
|
|
60
|
-
const signalBlock = input.signalSummary.length > 0
|
|
61
|
-
? input.signalSummary.map((line) => `- ${line}`).join("\n")
|
|
62
|
-
: "- no pre-scan signals captured yet";
|
|
63
|
-
return resolveIdeaFrames(frameIds).map((frame) => ({
|
|
64
|
-
frameId: frame.id,
|
|
65
|
-
label: frame.label,
|
|
66
|
-
prompt: [
|
|
67
|
-
`Frame: ${frame.label} (${frame.id})`,
|
|
68
|
-
`Mode: ${input.mode}`,
|
|
69
|
-
`Focus: ${input.focus || "open-ended scan"}`,
|
|
70
|
-
"",
|
|
71
|
-
"Signal summary:",
|
|
72
|
-
signalBlock,
|
|
73
|
-
"",
|
|
74
|
-
`Frame prompt: ${frame.prompt}`,
|
|
75
|
-
"",
|
|
76
|
-
"Generate 3-5 concrete candidates with repo-grounded evidence."
|
|
77
|
-
].join("\n")
|
|
78
|
-
}));
|
|
79
|
-
}
|
|
80
|
-
function normalizeCandidateKey(title, evidencePath) {
|
|
81
|
-
const normalizedTitle = title.trim().toLowerCase().replace(/[^a-z0-9]+/gu, " ").trim();
|
|
82
|
-
const normalizedEvidence = evidencePath
|
|
83
|
-
.trim()
|
|
84
|
-
.toLowerCase()
|
|
85
|
-
.replace(/\\/gu, "/");
|
|
86
|
-
return `${normalizedTitle}::${normalizedEvidence}`;
|
|
87
|
-
}
|
|
88
|
-
export function dedupeIdeaCandidates(drafts) {
|
|
89
|
-
const merged = new Map();
|
|
90
|
-
for (const draft of drafts) {
|
|
91
|
-
const key = normalizeCandidateKey(draft.title, draft.evidencePath);
|
|
92
|
-
const existing = merged.get(key);
|
|
93
|
-
if (!existing) {
|
|
94
|
-
merged.set(key, {
|
|
95
|
-
title: draft.title,
|
|
96
|
-
evidencePath: draft.evidencePath,
|
|
97
|
-
summary: draft.summary,
|
|
98
|
-
frameIds: [draft.frameId]
|
|
99
|
-
});
|
|
100
|
-
continue;
|
|
101
|
-
}
|
|
102
|
-
if (!existing.frameIds.includes(draft.frameId)) {
|
|
103
|
-
existing.frameIds.push(draft.frameId);
|
|
104
|
-
}
|
|
105
|
-
if (draft.summary.length > existing.summary.length) {
|
|
106
|
-
existing.summary = draft.summary;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return [...merged.values()];
|
|
110
|
-
}
|
|
111
|
-
const IMPACT_PRIORITY = {
|
|
112
|
-
high: 3,
|
|
113
|
-
medium: 2,
|
|
114
|
-
low: 1
|
|
115
|
-
};
|
|
116
|
-
const EFFORT_PRIORITY = {
|
|
117
|
-
s: 0,
|
|
118
|
-
m: 1,
|
|
119
|
-
l: 2
|
|
120
|
-
};
|
|
121
|
-
const CONFIDENCE_PRIORITY = {
|
|
122
|
-
high: 2,
|
|
123
|
-
medium: 1,
|
|
124
|
-
low: 0
|
|
125
|
-
};
|
|
126
|
-
function isRejectedIdea(input) {
|
|
127
|
-
if (input.confidence === "low")
|
|
128
|
-
return true;
|
|
129
|
-
if (input.impact === "low" && input.effort === "l")
|
|
130
|
-
return true;
|
|
131
|
-
return false;
|
|
132
|
-
}
|
|
133
|
-
export function scoreIdeaCandidate(impact, effort, confidence) {
|
|
134
|
-
// Keep the scoring intentionally simple and monotonic.
|
|
135
|
-
return IMPACT_PRIORITY[impact] + CONFIDENCE_PRIORITY[confidence] - EFFORT_PRIORITY[effort];
|
|
136
|
-
}
|
|
137
|
-
export function evaluateIdeaCandidate(input) {
|
|
138
|
-
const disposition = isRejectedIdea(input) ? "rejected" : "survivor";
|
|
139
|
-
return {
|
|
140
|
-
...input,
|
|
141
|
-
disposition,
|
|
142
|
-
rankingScore: scoreIdeaCandidate(input.impact, input.effort, input.confidence)
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
export function rankIdeaCandidates(inputs, maxSurvivors = 10) {
|
|
146
|
-
const evaluated = inputs.map(evaluateIdeaCandidate);
|
|
147
|
-
const survivors = evaluated
|
|
148
|
-
.filter((candidate) => candidate.disposition === "survivor")
|
|
149
|
-
.sort((left, right) => {
|
|
150
|
-
// Deterministic ordering: impact > effort > confidence > id.
|
|
151
|
-
const impactDelta = IMPACT_PRIORITY[right.impact] - IMPACT_PRIORITY[left.impact];
|
|
152
|
-
if (impactDelta !== 0)
|
|
153
|
-
return impactDelta;
|
|
154
|
-
const effortDelta = EFFORT_PRIORITY[left.effort] - EFFORT_PRIORITY[right.effort];
|
|
155
|
-
if (effortDelta !== 0)
|
|
156
|
-
return effortDelta;
|
|
157
|
-
const confidenceDelta = CONFIDENCE_PRIORITY[right.confidence] - CONFIDENCE_PRIORITY[left.confidence];
|
|
158
|
-
if (confidenceDelta !== 0)
|
|
159
|
-
return confidenceDelta;
|
|
160
|
-
return left.id.localeCompare(right.id);
|
|
161
|
-
})
|
|
162
|
-
.slice(0, Math.max(0, maxSurvivors));
|
|
163
|
-
const survivorIds = new Set(survivors.map((candidate) => candidate.id));
|
|
164
|
-
const rejected = evaluated
|
|
165
|
-
.filter((candidate) => candidate.disposition === "rejected" || !survivorIds.has(candidate.id))
|
|
166
|
-
.sort((left, right) => left.id.localeCompare(right.id));
|
|
167
|
-
return {
|
|
168
|
-
survivors,
|
|
169
|
-
rejected,
|
|
170
|
-
recommendationId: survivors[0]?.id ?? null
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
const IDEA_SKILL_FOLDER = "flow-idea";
|
|
174
|
-
const IDEA_SKILL_NAME = "flow-idea";
|
|
175
|
-
const IDEA_ARTIFACT_GLOB = ".cclaw/artifacts/idea-*.md";
|
|
176
|
-
const IDEA_ARTIFACT_PATTERN = ".cclaw/artifacts/idea-<YYYY-MM-DD-slug>.md";
|
|
177
|
-
const IDEA_RESUME_WINDOW_DAYS = 30;
|
|
178
|
-
const STRUCTURED_ASK_TOOLS = ideaStructuredAskToolsWithFallback();
|
|
179
|
-
export function minimumDistinctIdeaFrames(frameCount, mode = "repo-grounded") {
|
|
180
|
-
if (frameCount <= 0)
|
|
181
|
-
return 0;
|
|
182
|
-
const cap = mode === "repo-grounded" ? 3 : 2;
|
|
183
|
-
return Math.min(cap, frameCount);
|
|
184
|
-
}
|
|
185
|
-
function renderFrameBullets(frameIds) {
|
|
186
|
-
return resolveIdeaFrames(frameIds)
|
|
187
|
-
.map((frame) => ` - ${frame.label} (\`${frame.id}\`)`)
|
|
188
|
-
.join("\n");
|
|
189
|
-
}
|
|
190
|
-
function renderFrameNames(frameIds) {
|
|
191
|
-
return resolveIdeaFrames(frameIds)
|
|
192
|
-
.map((frame) => frame.label)
|
|
193
|
-
.join(", ");
|
|
194
|
-
}
|
|
195
|
-
export function ideaCommandContract(options = {}) {
|
|
196
|
-
const frames = resolveIdeaFrames(options.frameIds);
|
|
197
|
-
const frameBullets = renderFrameBullets(options.frameIds);
|
|
198
|
-
const minimumDistinctFrames = minimumDistinctIdeaFrames(frames.length, options.mode);
|
|
199
|
-
return `# /cc-idea
|
|
200
|
-
|
|
201
|
-
## Purpose
|
|
202
|
-
|
|
203
|
-
Repository-improvement idea mode. Generate a ranked backlog of
|
|
204
|
-
high-value improvements, persist it as an artifact on disk, and end with
|
|
205
|
-
an explicit handoff - either launch \`/cc\` on a chosen candidate in the
|
|
206
|
-
same session, or save/discard the backlog.
|
|
207
|
-
|
|
208
|
-
## HARD-GATE
|
|
209
|
-
|
|
210
|
-
${conversationLanguagePolicyMarkdown()}
|
|
211
|
-
- Idea mode only. Never mutate \`.cclaw/state/flow-state.json\`.
|
|
212
|
-
- Every recommendation cites evidence from the current repository
|
|
213
|
-
(file path, command output, or knowledge-store entry id).
|
|
214
|
-
- Whenever you produce ideation output, persist it to
|
|
215
|
-
\`${IDEA_ARTIFACT_PATTERN}\`. Chat-only output is not acceptable.
|
|
216
|
-
The only exception is an explicit user-cancel from the resume prompt -
|
|
217
|
-
in that case, write nothing and exit silently.
|
|
218
|
-
- Always end with a structured handoff prompt, not an open question
|
|
219
|
-
(skipped on explicit cancel).
|
|
220
|
-
|
|
221
|
-
## Algorithm
|
|
222
|
-
|
|
223
|
-
1. **Resume check.** Glob \`${IDEA_ARTIFACT_GLOB}\`. If any artifact
|
|
224
|
-
has been modified within the last ${IDEA_RESUME_WINDOW_DAYS} days,
|
|
225
|
-
offer the user: continue that backlog, start fresh, or cancel.
|
|
226
|
-
2. **Mode classification.** Explicitly classify subject:
|
|
227
|
-
\`repo-grounded\` / \`elsewhere-software\` / \`elsewhere-non-software\` / \`narrow\`.
|
|
228
|
-
3. **Mode-aware grounding (parallel).**
|
|
229
|
-
- Repo-grounded: repo signal scan + \`${RUNTIME_ROOT}/knowledge.jsonl\`
|
|
230
|
-
repetition scan.
|
|
231
|
-
- Elsewhere-software: docs-first grounding (Context7 and official docs).
|
|
232
|
-
- Elsewhere-non-software: constraints and objective grounding.
|
|
233
|
-
4. **Divergent ideation frames (parallel).** Generate candidates with
|
|
234
|
-
configured frames (${frames.length} total):
|
|
235
|
-
${frameBullets}
|
|
236
|
-
Keep at least ${minimumDistinctFrames} distinct frame outputs in this rendered mode.
|
|
237
|
-
Deterministic minimum: repo-grounded = 3, narrow/non-repo = 2, always capped
|
|
238
|
-
by configured frame count.
|
|
239
|
-
5. **Adversarial critique pass.** For each candidate, write the strongest
|
|
240
|
-
counter-argument, kill weak ideas, and keep survivors only.
|
|
241
|
-
6. **Produce 5-10 survivors** with impact (High/Medium/Low),
|
|
242
|
-
effort (S/M/L), confidence (High/Medium/Low), **why now**, expected user impact, risk, and one evidence path per
|
|
243
|
-
survivor.
|
|
244
|
-
7. **Rank by simple triage order**: impact first, then effort, then confidence.
|
|
245
|
-
Reject low-confidence ideas and obvious low-impact/high-effort outliers.
|
|
246
|
-
Recommend the top survivor.
|
|
247
|
-
8. **Write the artifact** at
|
|
248
|
-
\`${IDEA_ARTIFACT_PATTERN}\` using the schema in the skill.
|
|
249
|
-
9. **Present the handoff prompt** with four concrete options - not A/B/C
|
|
250
|
-
letters. Default = "Start /cc on the top recommendation". When the user
|
|
251
|
-
picks the start option, plumb the chosen candidate forward via
|
|
252
|
-
\`start-flow --from-idea-artifact=<path> --from-idea-candidate=I-<n>\`
|
|
253
|
-
so brainstorm reuses the idea's divergent + critique +
|
|
254
|
-
rank work via \`interactionHints.brainstorm.fromIdeaArtifact\`; do NOT
|
|
255
|
-
ask brainstorm to regenerate it.
|
|
256
|
-
|
|
257
|
-
## Headless mode (CI/automation only)
|
|
258
|
-
|
|
259
|
-
Headless envelopes are a machine-mode exception for CI/automation orchestration.
|
|
260
|
-
In normal interactive ideation, respond with natural language plus the artifact path.
|
|
261
|
-
For skill-to-skill invocation, emit exactly one JSON envelope:
|
|
262
|
-
|
|
263
|
-
\`\`\`json
|
|
264
|
-
{"version":"1","kind":"stage-output","stage":"non-flow","payload":{"command":"/cc-idea","artifact":".cclaw/artifacts/idea-<date>-<slug>.md","recommendation":"I-1"},"emittedAt":"<ISO-8601>"}
|
|
265
|
-
\`\`\`
|
|
266
|
-
|
|
267
|
-
Validate envelopes with:
|
|
268
|
-
\`npx cclaw-cli internal envelope-validate --stdin\`
|
|
269
|
-
|
|
270
|
-
## Primary skill
|
|
271
|
-
|
|
272
|
-
**${RUNTIME_ROOT}/skills/${IDEA_SKILL_FOLDER}/SKILL.md**
|
|
273
|
-
`;
|
|
274
|
-
}
|
|
275
|
-
export function ideaCommandSkillMarkdown(options = {}) {
|
|
276
|
-
const frames = resolveIdeaFrames(options.frameIds);
|
|
277
|
-
const frameBullets = renderFrameBullets(options.frameIds);
|
|
278
|
-
const minimumDistinctFrames = minimumDistinctIdeaFrames(frames.length, options.mode);
|
|
279
|
-
const frameNames = renderFrameNames(options.frameIds);
|
|
280
|
-
return `---
|
|
281
|
-
name: ${IDEA_SKILL_NAME}
|
|
282
|
-
description: "Repository idea mode: detect and rank high-leverage improvements, persist a backlog artifact, and hand off to /cc or save/discard."
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
# /cc-idea
|
|
286
|
-
|
|
287
|
-
## Announce at start
|
|
288
|
-
|
|
289
|
-
"Using flow-idea to identify highest-leverage improvements in this
|
|
290
|
-
repository. Will persist a ranked backlog to
|
|
291
|
-
\`${IDEA_ARTIFACT_PATTERN}\` and end with an explicit handoff."
|
|
292
|
-
|
|
293
|
-
## HARD-GATE
|
|
294
|
-
|
|
295
|
-
${conversationLanguagePolicyMarkdown()}
|
|
296
|
-
- Do not start coding in idea mode.
|
|
297
|
-
- Do not mutate \`.cclaw/state/flow-state.json\` - idea mode sits outside
|
|
298
|
-
the critical-path flow.
|
|
299
|
-
- Whenever ideation output is produced, persist the artifact file on disk
|
|
300
|
-
before presenting the handoff. The only exception is an explicit user-cancel
|
|
301
|
-
from the resume prompt - in that case, write nothing and exit silently.
|
|
302
|
-
- Always end with a structured handoff that names the concrete follow-up
|
|
303
|
-
command for each option (skipped on explicit cancel). No A/B/C letters
|
|
304
|
-
without command context.
|
|
305
|
-
|
|
306
|
-
## Protocol
|
|
307
|
-
|
|
308
|
-
### Phase 0 - Resume and classify
|
|
309
|
-
|
|
310
|
-
1. Use the harness's file-glob tool (\`Glob\` pattern
|
|
311
|
-
\`${IDEA_ARTIFACT_GLOB}\` or equivalent \`ls\`).
|
|
312
|
-
2. Filter to files modified within the last ${IDEA_RESUME_WINDOW_DAYS} days.
|
|
313
|
-
3. If one or more match, present **one** structured ask using the
|
|
314
|
-
harness's native tool (${STRUCTURED_ASK_TOOLS}) with options:
|
|
315
|
-
- **Continue the existing backlog**.
|
|
316
|
-
- **Start a fresh scan**.
|
|
317
|
-
- **Cancel**.
|
|
318
|
-
4. If no recent artifact exists, proceed to Phase 1 silently.
|
|
319
|
-
5. Classify the ideation mode before grounding:
|
|
320
|
-
- \`repo-grounded\`
|
|
321
|
-
- \`elsewhere-software\`
|
|
322
|
-
- \`elsewhere-non-software\`
|
|
323
|
-
- \`narrow\`
|
|
324
|
-
6. Record the chosen mode in the artifact.
|
|
325
|
-
|
|
326
|
-
### Phase 1 - Mode-aware grounding
|
|
327
|
-
|
|
328
|
-
Run grounding in parallel where available:
|
|
329
|
-
|
|
330
|
-
- For \`repo-grounded\`:
|
|
331
|
-
- \`rg -n 'TODO|FIXME|XXX|HACK|TBD'\` grouped by file.
|
|
332
|
-
- Test-runner output (\`npm test\`, \`pytest\`, \`go test ./...\`) - note
|
|
333
|
-
failures, timeouts, deprecation warnings.
|
|
334
|
-
- Module size outliers with weak direct test coverage.
|
|
335
|
-
- Docs drift checks for stale references.
|
|
336
|
-
- \`${RUNTIME_ROOT}/knowledge.jsonl\` entries where \`type\` is
|
|
337
|
-
\`rule | pattern | lesson | compound\`, with repeated \`trigger/action\`
|
|
338
|
-
pairs and stable high-confidence patterns.
|
|
339
|
-
- For \`elsewhere-software\`:
|
|
340
|
-
- Gather current framework/library docs first.
|
|
341
|
-
- Add one comparison scan for established solutions.
|
|
342
|
-
- For \`elsewhere-non-software\`:
|
|
343
|
-
- Capture objective, constraints, and measured friction before proposing fixes.
|
|
344
|
-
|
|
345
|
-
Record each finding with exact evidence (path, command, or doc source).
|
|
346
|
-
|
|
347
|
-
### Phase 2 - Divergent ideation
|
|
348
|
-
|
|
349
|
-
Generate candidate ideas by frame, in parallel when possible:
|
|
350
|
-
|
|
351
|
-
${frameBullets}
|
|
352
|
-
|
|
353
|
-
Require at least ${minimumDistinctFrames} distinct frames in this rendered mode. The
|
|
354
|
-
runtime rule is deterministic: repo-grounded scans require 3 distinct frames;
|
|
355
|
-
narrow, elsewhere-software, and elsewhere-non-software runs require 2; all modes
|
|
356
|
-
are capped by the configured frame count.
|
|
357
|
-
|
|
358
|
-
### Phase 3 - Critique all, keep survivors
|
|
359
|
-
|
|
360
|
-
For each raw candidate:
|
|
361
|
-
- Write strongest argument **against** this idea.
|
|
362
|
-
- Identify disqualifiers (duplicate, weak evidence, poor ROI, wrong timing).
|
|
363
|
-
- Mark as \`survivor\` or \`rejected\`.
|
|
364
|
-
|
|
365
|
-
Only survivors advance to ranking.
|
|
366
|
-
|
|
367
|
-
### Phase 4 - Rank and write the artifact
|
|
368
|
-
|
|
369
|
-
1. Keep 5-10 survivors.
|
|
370
|
-
2. For each survivor, include:
|
|
371
|
-
- **ID** - \`I-1\`, \`I-2\`, ...
|
|
372
|
-
- **Title**
|
|
373
|
-
- **Impact** - High / Medium / Low
|
|
374
|
-
- **Effort** - S / M / L
|
|
375
|
-
- **Confidence** - High / Medium / Low
|
|
376
|
-
- **Evidence**
|
|
377
|
-
- **Why now**
|
|
378
|
-
- **Expected impact**
|
|
379
|
-
- **Risk**
|
|
380
|
-
- **Counter-argument**
|
|
381
|
-
- **Next /cc prompt**
|
|
382
|
-
3. Sort survivors by impact, then effort, then confidence.
|
|
383
|
-
4. Write \`.cclaw/artifacts/idea-<date>-<slug>.md\`.
|
|
384
|
-
5. Confirm in chat: "Wrote <path>".
|
|
385
|
-
|
|
386
|
-
### Phase 5 - Handoff prompt
|
|
387
|
-
|
|
388
|
-
Present one structured ask with exactly these options (no bare A/B/C):
|
|
389
|
-
Required options, in this order:
|
|
390
|
-
1. **Start /cc on the top recommendation** (default)
|
|
391
|
-
2. **Pick a different candidate**
|
|
392
|
-
3. **Save and close**
|
|
393
|
-
4. **Discard**
|
|
394
|
-
|
|
395
|
-
### Phase 6 - Execute the choice
|
|
396
|
-
|
|
397
|
-
- Start /cc: load \`${RUNTIME_ROOT}/skills/using-cclaw/SKILL.md\` and run
|
|
398
|
-
\`/cc <phrase>\`. **Handoff carry-forward (mandatory when starting from /cc-idea):**
|
|
399
|
-
the harness shim that turns \`/cc <phrase>\` into a \`start-flow\` invocation
|
|
400
|
-
MUST forward the originating idea artifact and chosen candidate so brainstorm
|
|
401
|
-
reuses divergent + critique + rank work instead of redoing it. Equivalent CLI
|
|
402
|
-
call (used by automation; harness handles this transparently in interactive mode):
|
|
403
|
-
\`npx cclaw-cli internal start-flow --track=<track> --prompt='<phrase>' --from-idea-artifact=${IDEA_ARTIFACT_PATTERN} --from-idea-candidate=I-<n>\`.
|
|
404
|
-
The hint lands in \`flow-state.interactionHints.brainstorm\` and brainstorm's
|
|
405
|
-
\`Idea-evidence carry-forward\` checklist row picks it up.
|
|
406
|
-
- Save and close: reply with artifact path and stop.
|
|
407
|
-
- Discard: delete the artifact and stop.
|
|
408
|
-
|
|
409
|
-
## Do not
|
|
410
|
-
|
|
411
|
-
- Do not write into \`.cclaw/artifacts/0X-*.md\` (stage artifacts).
|
|
412
|
-
- Do not mutate \`.cclaw/state/flow-state.json\`.
|
|
413
|
-
- Do not collapse all ideas into one frame; distribute across:
|
|
414
|
-
${frameNames}.
|
|
415
|
-
`;
|
|
416
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export function conversationLanguagePolicyMarkdown() {
|
|
2
|
-
return `## Conversation Language Policy
|
|
3
|
-
|
|
4
|
-
- Infer the user-facing language from the latest substantive user message.
|
|
5
|
-
- Write user-facing prose, summaries, recommendations, and structured question text/options in that language unless the user asks otherwise.
|
|
6
|
-
- Do not translate stable machine surfaces: commands, file paths, stage ids, gate ids, JSON keys, enum/status values, artifact headings/frontmatter, logs, code identifiers, and quoted source text.
|
|
7
|
-
- If the request mixes languages, use the language of the actual ask sentence for narrative output.
|
|
8
|
-
`;
|
|
9
|
-
}
|
|
10
|
-
export function conversationLanguagePolicyBullets() {
|
|
11
|
-
return `- User-facing narrative follows the latest substantive user message language.
|
|
12
|
-
- Do not translate commands, paths, ids, JSON keys/enums, artifact headings, logs, code identifiers, or quoted source.`;
|
|
13
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canonical required JSONL field order (matches strict validator keys).
|
|
3
|
-
* Optional keys (`source`, `severity`) may be appended after these required fields.
|
|
4
|
-
*/
|
|
5
|
-
export declare const KNOWLEDGE_JSONL_FIELDS: readonly ["type", "trigger", "action", "confidence", "stage", "origin_stage", "frequency", "created", "first_seen_ts", "last_seen_ts", "project"];
|
|
6
|
-
export declare function learnSkillMarkdown(): string;
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Knowledge store content for the learnings skill and stage self-improvement prompts.
|
|
3
|
-
//
|
|
4
|
-
// The knowledge store is a single canonical JSONL file. Each line is one
|
|
5
|
-
// self-contained JSON object matching the strict schema in this module.
|
|
6
|
-
// There is no markdown mirror — cclaw is JSONL-native.
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
const KNOWLEDGE_PATH = ".cclaw/knowledge.jsonl";
|
|
9
|
-
const KNOWLEDGE_ARCHIVE_PATH = ".cclaw/knowledge.archive.jsonl";
|
|
10
|
-
const LEARN_SKILL_NAME = "learnings";
|
|
11
|
-
const LEARN_SKILL_DESCRIPTION = "Project-scoped knowledge store: append and query rule/pattern/lesson/compound entries in the canonical JSONL file at .cclaw/knowledge.jsonl. Strict schema, append-only, machine-queryable.";
|
|
12
|
-
/**
|
|
13
|
-
* Canonical required JSONL field order (matches strict validator keys).
|
|
14
|
-
* Optional keys (`source`, `severity`) may be appended after these required fields.
|
|
15
|
-
*/
|
|
16
|
-
export const KNOWLEDGE_JSONL_FIELDS = [
|
|
17
|
-
"type",
|
|
18
|
-
"trigger",
|
|
19
|
-
"action",
|
|
20
|
-
"confidence",
|
|
21
|
-
"stage",
|
|
22
|
-
"origin_stage",
|
|
23
|
-
"frequency",
|
|
24
|
-
"created",
|
|
25
|
-
"first_seen_ts",
|
|
26
|
-
"last_seen_ts",
|
|
27
|
-
"project"
|
|
28
|
-
];
|
|
29
|
-
export function learnSkillMarkdown() {
|
|
30
|
-
return `---
|
|
31
|
-
name: ${LEARN_SKILL_NAME}
|
|
32
|
-
description: "${LEARN_SKILL_DESCRIPTION}"
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
# ${LEARN_SKILL_NAME}
|
|
36
|
-
|
|
37
|
-
## Overview
|
|
38
|
-
|
|
39
|
-
The project knowledge store is **one canonical JSONL file**: \`${KNOWLEDGE_PATH}\`.
|
|
40
|
-
Each line is one self-contained JSON object. Append-only. Machine-queryable.
|
|
41
|
-
|
|
42
|
-
Use the store to keep durable knowledge that should survive sessions:
|
|
43
|
-
- **rule**: hard constraint to follow every time.
|
|
44
|
-
- **pattern**: repeatable way that works well in this project.
|
|
45
|
-
- **lesson**: non-obvious outcome from a failure or trade-off.
|
|
46
|
-
- **compound**: post-ship insight about how to make the *next* run faster (process accelerator, not domain rule).
|
|
47
|
-
|
|
48
|
-
## Continuous capture (stage closeout path)
|
|
49
|
-
|
|
50
|
-
Knowledge capture is now stage-native:
|
|
51
|
-
- Each stage artifact has a \`## Learnings\` section.
|
|
52
|
-
- Allowed payloads:
|
|
53
|
-
- \`- None this stage.\` (explicit no-op)
|
|
54
|
-
- JSON bullets with required keys \`type\`, \`trigger\`, \`action\`, \`confidence\` (optional keys may mirror the full JSONL schema fields).
|
|
55
|
-
- During \`node .cclaw/hooks/stage-complete.mjs <stage>\`, cclaw:
|
|
56
|
-
1. validates \`## Learnings\`,
|
|
57
|
-
2. appends deduped entries to \`${KNOWLEDGE_PATH}\`,
|
|
58
|
-
3. writes a harvest marker into the artifact.
|
|
59
|
-
|
|
60
|
-
Manual/query operations (search, backfill, curation) use this skill when the
|
|
61
|
-
user asks for knowledge work. If a stage artifact contains JSON learnings but
|
|
62
|
-
\`${KNOWLEDGE_PATH}\` did not change, the missing step is almost always running
|
|
63
|
-
\`node .cclaw/hooks/stage-complete.mjs <stage>\` successfully.
|
|
64
|
-
|
|
65
|
-
## HARD-GATE
|
|
66
|
-
|
|
67
|
-
During manual knowledge operations, only modify \`${KNOWLEDGE_PATH}\`, \`${KNOWLEDGE_ARCHIVE_PATH}\`,
|
|
68
|
-
or an explicitly user-approved summary file. Do not modify application code here.
|
|
69
|
-
Do not invent alternate stores (no markdown mirror, no SQLite, no per-stage files).
|
|
70
|
-
|
|
71
|
-
## Entry format - strict JSONL schema
|
|
72
|
-
|
|
73
|
-
Exactly one JSON object per line. Required fields must appear in the order:
|
|
74
|
-
\`type, trigger, action, confidence, stage, origin_stage, frequency, created, first_seen_ts, last_seen_ts, project\`.
|
|
75
|
-
Optional fields \`source\` and \`severity\` may be appended after \`project\`.
|
|
76
|
-
|
|
77
|
-
\`\`\`json
|
|
78
|
-
{"type":"pattern","trigger":"when reviewing external payloads","action":"parse through zod before touching service layer","confidence":"high","stage":"review","origin_stage":"review","frequency":1,"created":"2026-04-14T12:00:00Z","first_seen_ts":"2026-04-14T12:00:00Z","last_seen_ts":"2026-04-14T12:00:00Z","project":"cclaw"}
|
|
79
|
-
\`\`\`
|
|
80
|
-
|
|
81
|
-
| field | type | required | notes |
|
|
82
|
-
|---|---|---|---|
|
|
83
|
-
| \`type\` | \`"rule" \\| "pattern" \\| "lesson" \\| "compound"\` | yes | Lowercase. |
|
|
84
|
-
| \`trigger\` | string | yes | The concrete situation that must be recognized. Start with a verb or \`when …\`. |
|
|
85
|
-
| \`action\` | string | yes | The concrete move to take when the trigger fires. One sentence. |
|
|
86
|
-
| \`confidence\` | \`"high" \\| "medium" \\| "low"\` | yes | Write \`medium\` when unsure; do not omit. |
|
|
87
|
-
| \`stage\` | \`FlowStage\` \\| null | yes | One of brainstorm / scope / design / spec / plan / tdd / review / ship, or \`null\` when cross-stage. |
|
|
88
|
-
| \`origin_stage\` | \`FlowStage\` \\| null | yes | Stage where this learning was first observed. |
|
|
89
|
-
| \`frequency\` | integer >= 1 | yes | Number of times this same trigger/action pair has been observed. |
|
|
90
|
-
| \`created\` | ISO 8601 UTC string | yes | \`date -u +%Y-%m-%dT%H:%M:%SZ\`. |
|
|
91
|
-
| \`first_seen_ts\` | ISO 8601 UTC string | yes | First observed timestamp (usually equals \`created\`). |
|
|
92
|
-
| \`last_seen_ts\` | ISO 8601 UTC string | yes | Last re-confirmed timestamp. |
|
|
93
|
-
| \`project\` | string \\| null | yes | Repo or scope name. Use \`null\` when the entry crosses projects. |
|
|
94
|
-
| \`source\` | \`"stage" \\| "retro" \\| "compound" \\| "idea" \\| "manual" \\| null\` | no | Origin channel for the entry when known. |
|
|
95
|
-
| \`severity\` | \`"critical" \\| "important" \\| "suggestion"\` | no | Priority signal for compound lifts; \`critical\` enables single-hit override in compound readiness analysis. |
|
|
96
|
-
|
|
97
|
-
Rules:
|
|
98
|
-
- No other fields beyond the table above. Extra keys are forbidden and MUST be rejected by any writer.
|
|
99
|
-
- Append-only: never rewrite or delete a historical line.
|
|
100
|
-
- Keep each entry one line. No pretty-printing. No trailing commas.
|
|
101
|
-
|
|
102
|
-
## Curation policy (target: ≤ 50 active entries)
|
|
103
|
-
|
|
104
|
-
- The file is append-only — entries are never physically deleted.
|
|
105
|
-
- When the canonical file exceeds 50 lines, a curation pass proposes
|
|
106
|
-
soft-archiving: the approved lines are **moved** to \`${KNOWLEDGE_ARCHIVE_PATH}\`
|
|
107
|
-
verbatim (same JSONL shape). The working file stays lean.
|
|
108
|
-
- Use the **Curate** action below for the full read-only audit and
|
|
109
|
-
user-approved soft-archive plan.
|
|
110
|
-
|
|
111
|
-
## Manual Actions
|
|
112
|
-
|
|
113
|
-
### Show recent entries
|
|
114
|
-
- Read \`${KNOWLEDGE_PATH}\`. Stream the last 30 lines; pretty-print each
|
|
115
|
-
line's \`type\` / \`trigger\` / \`action\` for human review.
|
|
116
|
-
- If file is missing or empty, report that clearly and suggest adding a
|
|
117
|
-
manual entry through this skill.
|
|
118
|
-
|
|
119
|
-
### Search \`<query>\`
|
|
120
|
-
- Stream \`${KNOWLEDGE_PATH}\`, JSON.parse each line, filter where any of
|
|
121
|
-
\`trigger\`, \`action\`, \`project\` contains \`<query>\` (case-insensitive).
|
|
122
|
-
- Return the matched lines pretty-printed (do not mutate the file).
|
|
123
|
-
|
|
124
|
-
### Add
|
|
125
|
-
- Ask for required user-facing fields in order: \`type\`, \`trigger\`, \`action\`, \`confidence\`, \`stage\`, \`project\`.
|
|
126
|
-
- \`confidence\` must be one of \`high\`, \`medium\`, \`low\`. Default to \`medium\` if the user declines to set it.
|
|
127
|
-
- \`stage\` and \`project\` may be explicitly \`null\`.
|
|
128
|
-
- Prefer stage-native \`## Learnings\` capture for new flow work; use \`add\` mainly for backfilling historical lessons or ad-hoc entries outside a stage closeout.
|
|
129
|
-
- \`origin_stage\` defaults to \`stage\`.
|
|
130
|
-
- \`frequency\` starts at \`1\`.
|
|
131
|
-
- \`created\`, \`first_seen_ts\`, and \`last_seen_ts\` are set automatically to current UTC ISO timestamp.
|
|
132
|
-
- Append exactly one JSON line to \`${KNOWLEDGE_PATH}\` with the field order from the schema table above.
|
|
133
|
-
- Re-read the file tail to confirm the new line is valid JSON and parses back to the same object.
|
|
134
|
-
|
|
135
|
-
### Curate
|
|
136
|
-
- Produce a read-only audit + soft-archive plan.
|
|
137
|
-
- Never deletes. Soft-archive means **moving** full JSON lines from
|
|
138
|
-
\`${KNOWLEDGE_PATH}\` to \`${KNOWLEDGE_ARCHIVE_PATH}\` as part of a
|
|
139
|
-
user-approved curation pass.
|
|
140
|
-
`;
|
|
141
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type HookHandlerId, type HookManifestHarness } from "./hook-manifest.js";
|
|
2
|
-
export declare function claudeHooksJsonWithObservation(): string;
|
|
3
|
-
export declare function cursorHooksJsonWithObservation(): string;
|
|
4
|
-
export declare function codexHooksJsonWithObservation(): string;
|
|
5
|
-
/**
|
|
6
|
-
* Public accessor so diagnostic CLIs and tests can inspect the
|
|
7
|
-
* manifest without importing the private generator helpers.
|
|
8
|
-
*/
|
|
9
|
-
export declare function hookManifestSnapshot(): Array<{
|
|
10
|
-
harness: HookManifestHarness;
|
|
11
|
-
events: Array<{
|
|
12
|
-
event: string;
|
|
13
|
-
entries: Array<{
|
|
14
|
-
handler: HookHandlerId;
|
|
15
|
-
matcher?: string;
|
|
16
|
-
timeout?: number;
|
|
17
|
-
}>;
|
|
18
|
-
}>;
|
|
19
|
-
}>;
|