cclaw-cli 0.7.0 → 0.8.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/content/agents.d.ts +9 -0
- package/dist/content/agents.js +177 -6
- package/dist/content/contracts.js +1 -1
- package/dist/content/examples.d.ts +1 -0
- package/dist/content/examples.js +63 -0
- package/dist/content/hooks.js +6 -6
- package/dist/content/learnings.d.ts +5 -0
- package/dist/content/learnings.js +88 -104
- package/dist/content/meta-skill.js +155 -44
- package/dist/content/session-hooks.js +2 -2
- package/dist/content/skills.js +46 -11
- package/dist/content/stage-schema.js +36 -10
- package/dist/content/start-command.js +63 -17
- package/dist/content/status-command.js +2 -2
- package/dist/content/subagents.js +169 -0
- package/dist/content/templates.js +32 -4
- package/dist/content/utility-skills.d.ts +23 -5
- package/dist/content/utility-skills.js +204 -42
- package/dist/doctor.js +33 -9
- package/dist/harness-adapters.js +55 -16
- package/dist/install.js +21 -7
- package/dist/policy.js +3 -2
- package/dist/runs.d.ts +4 -5
- package/dist/runs.js +19 -11
- package/dist/types.d.ts +4 -4
- package/package.json +1 -1
package/dist/install.js
CHANGED
|
@@ -17,7 +17,7 @@ import { contextMonitorScript, promptGuardScript, workflowGuardScript } from "./
|
|
|
17
17
|
import { META_SKILL_NAME, usingCclawSkillMarkdown } from "./content/meta-skill.js";
|
|
18
18
|
import { ARTIFACT_TEMPLATES, CURSOR_WORKFLOW_RULE_MDC, RULEBOOK_MARKDOWN, buildRulesJson } from "./content/templates.js";
|
|
19
19
|
import { stageSkillFolder, stageSkillMarkdown } from "./content/skills.js";
|
|
20
|
-
import {
|
|
20
|
+
import { LANGUAGE_RULE_PACK_DIR, LANGUAGE_RULE_PACK_FILES, LANGUAGE_RULE_PACK_GENERATORS, LEGACY_LANGUAGE_RULE_PACK_FOLDERS, UTILITY_SKILL_FOLDERS, UTILITY_SKILL_MAP } from "./content/utility-skills.js";
|
|
21
21
|
import { createInitialFlowState } from "./flow-state.js";
|
|
22
22
|
import { ensureDir, exists, writeFileSafe } from "./fs-utils.js";
|
|
23
23
|
import { ensureGitignore, removeGitignorePatterns } from "./gitignore.js";
|
|
@@ -183,13 +183,23 @@ async function writeSkills(projectRoot, config) {
|
|
|
183
183
|
const generator = UTILITY_SKILL_MAP[folder];
|
|
184
184
|
await writeFileSafe(runtimePath(projectRoot, "skills", folder, "SKILL.md"), generator());
|
|
185
185
|
}
|
|
186
|
+
// Language rule packs live under .cclaw/rules/lang/<pack>.md. They are opt-in:
|
|
187
|
+
// only the packs listed in config.languageRulePacks are materialised. Any
|
|
188
|
+
// legacy per-language skill folders from v0.7.0 (.cclaw/skills/language-*)
|
|
189
|
+
// are cleaned up below so the new rules/lang layout is the only truth.
|
|
186
190
|
const enabledPacks = config?.languageRulePacks ?? [];
|
|
187
191
|
for (const pack of enabledPacks) {
|
|
188
|
-
const
|
|
189
|
-
const generator = LANGUAGE_RULE_PACK_GENERATORS[
|
|
190
|
-
if (!
|
|
192
|
+
const fileName = LANGUAGE_RULE_PACK_FILES[pack];
|
|
193
|
+
const generator = LANGUAGE_RULE_PACK_GENERATORS[pack];
|
|
194
|
+
if (!fileName || !generator)
|
|
191
195
|
continue;
|
|
192
|
-
await writeFileSafe(runtimePath(projectRoot,
|
|
196
|
+
await writeFileSafe(runtimePath(projectRoot, ...LANGUAGE_RULE_PACK_DIR, fileName), generator());
|
|
197
|
+
}
|
|
198
|
+
for (const legacyFolder of LEGACY_LANGUAGE_RULE_PACK_FOLDERS) {
|
|
199
|
+
const legacyPath = runtimePath(projectRoot, "skills", legacyFolder);
|
|
200
|
+
if (await exists(legacyPath)) {
|
|
201
|
+
await fs.rm(legacyPath, { recursive: true, force: true });
|
|
202
|
+
}
|
|
193
203
|
}
|
|
194
204
|
}
|
|
195
205
|
async function writeUtilityCommands(projectRoot) {
|
|
@@ -550,9 +560,13 @@ async function writeHooks(projectRoot, config) {
|
|
|
550
560
|
}
|
|
551
561
|
}
|
|
552
562
|
async function ensureKnowledgeStore(projectRoot) {
|
|
553
|
-
const storePath = runtimePath(projectRoot, "knowledge.
|
|
563
|
+
const storePath = runtimePath(projectRoot, "knowledge.jsonl");
|
|
554
564
|
if (!(await exists(storePath))) {
|
|
555
|
-
await writeFileSafe(storePath, "
|
|
565
|
+
await writeFileSafe(storePath, "");
|
|
566
|
+
}
|
|
567
|
+
const legacyMdPath = runtimePath(projectRoot, "knowledge.md");
|
|
568
|
+
if (await exists(legacyMdPath)) {
|
|
569
|
+
await fs.rm(legacyMdPath, { force: true });
|
|
556
570
|
}
|
|
557
571
|
}
|
|
558
572
|
async function ensureCustomSkillsScaffold(projectRoot) {
|
package/dist/policy.js
CHANGED
|
@@ -85,8 +85,9 @@ export async function policyChecks(projectRoot, options = {}) {
|
|
|
85
85
|
// --- utility skill checks ---
|
|
86
86
|
const runtimeFile = (relativePath) => `${RUNTIME_ROOT}/${relativePath}`;
|
|
87
87
|
const utilitySkillChecks = [
|
|
88
|
-
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "
|
|
89
|
-
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "knowledge.jsonl", name: "utility_skill:learnings:
|
|
88
|
+
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "strict JSONL schema", name: "utility_skill:learnings:jsonl_schema" },
|
|
89
|
+
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "knowledge.jsonl", name: "utility_skill:learnings:jsonl_store" },
|
|
90
|
+
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "type, trigger, action, confidence, domain, stage, created, project", name: "utility_skill:learnings:field_order" },
|
|
90
91
|
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "## Subcommands", name: "utility_skill:learnings:subcommands" },
|
|
91
92
|
{ file: runtimeFile("skills/learnings/SKILL.md"), needle: "## HARD-GATE", name: "utility_skill:learnings:hard_gate" },
|
|
92
93
|
{ file: runtimeFile("commands/learn.md"), needle: "## Subcommands", name: "utility_command:learn:subcommands" },
|
package/dist/runs.d.ts
CHANGED
|
@@ -56,11 +56,10 @@ export declare function ensureRunSystem(projectRoot: string, _options?: EnsureRu
|
|
|
56
56
|
export declare function listRuns(projectRoot: string): Promise<CclawRunMeta[]>;
|
|
57
57
|
export declare function archiveRun(projectRoot: string, featureName?: string): Promise<ArchiveRunResult>;
|
|
58
58
|
/**
|
|
59
|
-
* Counts
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* deliberate — the curator reads the file directly to make the soft-archive plan.
|
|
59
|
+
* Counts entries in the canonical JSONL knowledge store. An "active" entry is one
|
|
60
|
+
* non-empty line that parses as JSON with the required `type` field belonging to the
|
|
61
|
+
* allowed set. Malformed lines are ignored (not counted) but do not throw so that a
|
|
62
|
+
* hand-edited file cannot break doctor/archive flows.
|
|
64
63
|
*/
|
|
65
64
|
export declare function countActiveKnowledgeEntries(text: string): number;
|
|
66
65
|
export {};
|
package/dist/runs.js
CHANGED
|
@@ -407,7 +407,7 @@ export async function archiveRun(projectRoot, featureName) {
|
|
|
407
407
|
}
|
|
408
408
|
const KNOWLEDGE_SOFT_THRESHOLD = 50;
|
|
409
409
|
async function readKnowledgeStats(projectRoot) {
|
|
410
|
-
const knowledgePath = path.join(projectRoot, RUNTIME_ROOT, "knowledge.
|
|
410
|
+
const knowledgePath = path.join(projectRoot, RUNTIME_ROOT, "knowledge.jsonl");
|
|
411
411
|
let activeEntryCount = 0;
|
|
412
412
|
if (await exists(knowledgePath)) {
|
|
413
413
|
const text = await fs.readFile(knowledgePath, "utf8");
|
|
@@ -417,22 +417,30 @@ async function readKnowledgeStats(projectRoot) {
|
|
|
417
417
|
activeEntryCount,
|
|
418
418
|
softThreshold: KNOWLEDGE_SOFT_THRESHOLD,
|
|
419
419
|
overThreshold: activeEntryCount > KNOWLEDGE_SOFT_THRESHOLD,
|
|
420
|
-
knowledgePath: `${RUNTIME_ROOT}/knowledge.
|
|
420
|
+
knowledgePath: `${RUNTIME_ROOT}/knowledge.jsonl`
|
|
421
421
|
};
|
|
422
422
|
}
|
|
423
423
|
/**
|
|
424
|
-
* Counts
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
* deliberate — the curator reads the file directly to make the soft-archive plan.
|
|
424
|
+
* Counts entries in the canonical JSONL knowledge store. An "active" entry is one
|
|
425
|
+
* non-empty line that parses as JSON with the required `type` field belonging to the
|
|
426
|
+
* allowed set. Malformed lines are ignored (not counted) but do not throw so that a
|
|
427
|
+
* hand-edited file cannot break doctor/archive flows.
|
|
429
428
|
*/
|
|
430
429
|
export function countActiveKnowledgeEntries(text) {
|
|
431
|
-
const
|
|
430
|
+
const allowed = new Set(["rule", "pattern", "lesson", "compound"]);
|
|
432
431
|
let count = 0;
|
|
433
|
-
for (const
|
|
434
|
-
|
|
435
|
-
|
|
432
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
433
|
+
const line = raw.trim();
|
|
434
|
+
if (line.length === 0)
|
|
435
|
+
continue;
|
|
436
|
+
try {
|
|
437
|
+
const parsed = JSON.parse(line);
|
|
438
|
+
if (typeof parsed.type === "string" && allowed.has(parsed.type)) {
|
|
439
|
+
count += 1;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
// Skip malformed lines silently; curation surfaces them separately.
|
|
436
444
|
}
|
|
437
445
|
}
|
|
438
446
|
return count;
|
package/dist/types.d.ts
CHANGED
|
@@ -48,10 +48,10 @@ export interface VibyConfig {
|
|
|
48
48
|
/** Default flow track for new runs (quick = shortened path, standard = full pipeline). */
|
|
49
49
|
defaultTrack?: FlowTrack;
|
|
50
50
|
/**
|
|
51
|
-
* Opt-in language rule packs. Each enabled pack materializes a matching
|
|
52
|
-
*
|
|
53
|
-
* meta-skill router loads the pack during review/tdd when the diff touches
|
|
54
|
-
* language in question.
|
|
51
|
+
* Opt-in language rule packs. Each enabled pack materializes a matching rule
|
|
52
|
+
* file under `.cclaw/rules/lang/<id>.md` on the next `cclaw sync`. The
|
|
53
|
+
* meta-skill router loads the pack during review/tdd when the diff touches
|
|
54
|
+
* the language in question. Disabled packs have no on-disk footprint.
|
|
55
55
|
*/
|
|
56
56
|
languageRulePacks?: LanguageRulePack[];
|
|
57
57
|
}
|