@grimoire-cc/cli 0.7.2 → 0.7.4
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/bin.js +14 -2
- package/dist/bin.js.map +1 -1
- package/dist/commands/remove.d.ts +11 -0
- package/dist/commands/remove.d.ts.map +1 -1
- package/dist/commands/remove.js +24 -2
- package/dist/commands/remove.js.map +1 -1
- package/dist/remove.d.ts +13 -2
- package/dist/remove.d.ts.map +1 -1
- package/dist/remove.js +57 -8
- package/dist/remove.js.map +1 -1
- package/package.json +1 -1
- package/packs/dev-pack/grimoire.json +19 -0
- package/packs/dev-pack/skills/gr.conventional-commit/SKILL.md +149 -0
- package/packs/docs-pack/skills/gr.business-logic-docs/SKILL.md +44 -1
package/dist/bin.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { defineCommand, runMain } from 'citty';
|
|
4
4
|
import { runAdd } from './commands/add.js';
|
|
5
|
-
import { runRemove } from './commands/remove.js';
|
|
5
|
+
import { runRemove, runRemovePack } from './commands/remove.js';
|
|
6
6
|
import { runLogs } from './commands/logs.js';
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
8
|
const { version } = require('../package.json');
|
|
@@ -30,9 +30,21 @@ const removeCommand = defineCommand({
|
|
|
30
30
|
type: 'string',
|
|
31
31
|
description: 'Interactive selection of items to remove',
|
|
32
32
|
},
|
|
33
|
+
pack: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description: 'Remove all items from a pack',
|
|
36
|
+
},
|
|
33
37
|
},
|
|
34
38
|
async run({ args }) {
|
|
35
|
-
|
|
39
|
+
if (args.pack && args.name) {
|
|
40
|
+
throw new Error('Cannot use --pack with a positional item name');
|
|
41
|
+
}
|
|
42
|
+
if (args.pack) {
|
|
43
|
+
await runRemovePack(args.pack, process.cwd());
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
await runRemove(args.name, args.pick, process.cwd());
|
|
47
|
+
}
|
|
36
48
|
},
|
|
37
49
|
});
|
|
38
50
|
const logsCommand = defineCommand({
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,4 +9,15 @@ import type { RemoveSummary } from '../types.js';
|
|
|
9
9
|
* @returns The remove summary
|
|
10
10
|
*/
|
|
11
11
|
export declare function runRemove(itemName: string | undefined, pick: string | undefined, cwd?: string | undefined): Promise<RemoveSummary>;
|
|
12
|
+
/**
|
|
13
|
+
* Removes all items from a pack and cleans up the manifest.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runRemovePack(packName: string, cwd?: string | undefined): Promise<RemoveSummary>;
|
|
16
|
+
export declare function printRemoveSummary(results: readonly {
|
|
17
|
+
item: {
|
|
18
|
+
type: string;
|
|
19
|
+
name: string;
|
|
20
|
+
};
|
|
21
|
+
removed: boolean;
|
|
22
|
+
}[]): void;
|
|
12
23
|
//# sourceMappingURL=remove.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAAC,aAAa,CAAC,CA2BxB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAAC,aAAa,CAAC,CAsBxB;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS;IAAE,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,GAC7E,IAAI,CAWN"}
|
package/dist/commands/remove.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { scanInstalled, removeItems, cleanManifest } from '../remove.js';
|
|
1
|
+
import { scanInstalled, removeItems, cleanManifest, resolvePackItems } from '../remove.js';
|
|
2
|
+
import { resolvePackDir } from '../resolve.js';
|
|
3
|
+
import { loadManifest } from '../manifest.js';
|
|
2
4
|
/**
|
|
3
5
|
* Runs the `remove` command: scans installed items, selects the target,
|
|
4
6
|
* removes files, and cleans up the manifest.
|
|
@@ -28,7 +30,27 @@ export async function runRemove(itemName, pick, cwd) {
|
|
|
28
30
|
printRemoveSummary(results.filter((r) => r.removed));
|
|
29
31
|
return { results };
|
|
30
32
|
}
|
|
31
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Removes all items from a pack and cleans up the manifest.
|
|
35
|
+
*/
|
|
36
|
+
export async function runRemovePack(packName, cwd) {
|
|
37
|
+
const projectDir = cwd ?? process.cwd();
|
|
38
|
+
const packDir = resolvePackDir(packName);
|
|
39
|
+
const packManifest = loadManifest(packDir);
|
|
40
|
+
const packItems = resolvePackItems(packManifest);
|
|
41
|
+
// Only remove items that are actually installed
|
|
42
|
+
const installed = scanInstalled(projectDir);
|
|
43
|
+
const installedNames = new Set(installed.map((i) => i.name));
|
|
44
|
+
const toRemove = packItems.filter((i) => installedNames.has(i.name));
|
|
45
|
+
const results = removeItems(toRemove, projectDir);
|
|
46
|
+
// Collect pack manifest names for proper manifest cleanup
|
|
47
|
+
const agentNames = packManifest.agents.map((a) => a.name);
|
|
48
|
+
const skillNames = packManifest.skills.map((s) => s.name);
|
|
49
|
+
cleanManifest(toRemove, projectDir, { agentNames, skillNames });
|
|
50
|
+
printRemoveSummary(results.filter((r) => r.removed));
|
|
51
|
+
return { results };
|
|
52
|
+
}
|
|
53
|
+
export function printRemoveSummary(results) {
|
|
32
54
|
if (results.length === 0) {
|
|
33
55
|
console.log('Nothing to remove.');
|
|
34
56
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
|
package/dist/remove.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InstallItem, RemoveResult } from './types.js';
|
|
1
|
+
import type { InstallItem, PackManifest, RemoveResult } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Scans the project's .claude/ directory for installed agents and skills.
|
|
4
4
|
*/
|
|
@@ -7,9 +7,20 @@ export declare function scanInstalled(projectDir: string): readonly InstallItem[
|
|
|
7
7
|
* Removes agent files and skill directories from the project.
|
|
8
8
|
*/
|
|
9
9
|
export declare function removeItems(items: readonly InstallItem[], projectDir: string): readonly RemoveResult[];
|
|
10
|
+
/**
|
|
11
|
+
* Converts a PackManifest into InstallItem[] using filesystem-derived names.
|
|
12
|
+
*/
|
|
13
|
+
export declare function resolvePackItems(packManifest: PackManifest): readonly InstallItem[];
|
|
10
14
|
/**
|
|
11
15
|
* Removes entries for the given items from skills-manifest.json.
|
|
12
16
|
* Removes skill entries, agent entries, and agent references from other agents.
|
|
17
|
+
*
|
|
18
|
+
* Skills are matched by path (`.claude/skills/{dirName}`) to handle namespaced names.
|
|
19
|
+
* An optional `manifestNames` parameter provides additional agent/skill names
|
|
20
|
+
* to match (for pack removal where manifest names differ from filesystem names).
|
|
13
21
|
*/
|
|
14
|
-
export declare function cleanManifest(items: readonly InstallItem[], projectDir: string
|
|
22
|
+
export declare function cleanManifest(items: readonly InstallItem[], projectDir: string, manifestNames?: {
|
|
23
|
+
readonly agentNames?: readonly string[];
|
|
24
|
+
readonly skillNames?: readonly string[];
|
|
25
|
+
}): void;
|
|
15
26
|
//# sourceMappingURL=remove.d.ts.map
|
package/dist/remove.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1E;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,WAAW,EAAE,CAiCxE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,UAAU,EAAE,MAAM,GACjB,SAAS,YAAY,EAAE,CAczB;AAoBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,YAAY,GAAG,SAAS,WAAW,EAAE,CAsBnF;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE;IACd,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC,GACA,IAAI,CA2DN"}
|
package/dist/remove.js
CHANGED
|
@@ -49,30 +49,79 @@ export function removeItems(items, projectDir) {
|
|
|
49
49
|
return { item, removed: true };
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Converts a PackManifest into InstallItem[] using filesystem-derived names.
|
|
54
|
+
*/
|
|
55
|
+
export function resolvePackItems(packManifest) {
|
|
56
|
+
const items = [];
|
|
57
|
+
for (const agent of packManifest.agents) {
|
|
58
|
+
items.push({
|
|
59
|
+
type: 'agent',
|
|
60
|
+
name: basename(agent.path, '.md'),
|
|
61
|
+
sourcePath: '',
|
|
62
|
+
description: agent.description,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
for (const skill of packManifest.skills) {
|
|
66
|
+
items.push({
|
|
67
|
+
type: 'skill',
|
|
68
|
+
name: basename(skill.path),
|
|
69
|
+
sourcePath: '',
|
|
70
|
+
description: skill.description,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return items;
|
|
74
|
+
}
|
|
52
75
|
/**
|
|
53
76
|
* Removes entries for the given items from skills-manifest.json.
|
|
54
77
|
* Removes skill entries, agent entries, and agent references from other agents.
|
|
78
|
+
*
|
|
79
|
+
* Skills are matched by path (`.claude/skills/{dirName}`) to handle namespaced names.
|
|
80
|
+
* An optional `manifestNames` parameter provides additional agent/skill names
|
|
81
|
+
* to match (for pack removal where manifest names differ from filesystem names).
|
|
55
82
|
*/
|
|
56
|
-
export function cleanManifest(items, projectDir) {
|
|
83
|
+
export function cleanManifest(items, projectDir, manifestNames) {
|
|
57
84
|
const manifestPath = join(projectDir, '.claude', 'skills-manifest.json');
|
|
58
85
|
if (!existsSync(manifestPath))
|
|
59
86
|
return;
|
|
60
87
|
const manifest = JSON.parse(readFileSync(manifestPath, 'utf-8'));
|
|
61
|
-
|
|
88
|
+
// Build path-based removal set for skills
|
|
89
|
+
const removedSkillPaths = new Set(items.filter((i) => i.type === 'skill').map((i) => `.claude/skills/${i.name}`));
|
|
90
|
+
// Build agent removal set from both filesystem names and manifest names
|
|
62
91
|
const removedAgentNames = new Set(items.filter((i) => i.type === 'agent').map((i) => i.name));
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
92
|
+
if (manifestNames?.agentNames) {
|
|
93
|
+
for (const name of manifestNames.agentNames) {
|
|
94
|
+
removedAgentNames.add(name);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Remove skill entries by path, collecting their manifest names for reference cleanup
|
|
98
|
+
const removedSkillManifestNames = new Set();
|
|
99
|
+
if (manifestNames?.skillNames) {
|
|
100
|
+
for (const name of manifestNames.skillNames) {
|
|
101
|
+
removedSkillManifestNames.add(name);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (removedSkillPaths.size > 0) {
|
|
105
|
+
const kept = [];
|
|
106
|
+
for (const s of manifest.skills) {
|
|
107
|
+
if (removedSkillPaths.has(s.path)) {
|
|
108
|
+
removedSkillManifestNames.add(s.name);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
kept.push(s);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
manifest.skills = kept;
|
|
66
115
|
}
|
|
67
116
|
// Remove agent entries
|
|
68
117
|
for (const name of removedAgentNames) {
|
|
69
118
|
delete manifest.agents[name];
|
|
70
119
|
}
|
|
71
120
|
// Remove skill references from remaining agents
|
|
72
|
-
if (
|
|
121
|
+
if (removedSkillManifestNames.size > 0) {
|
|
73
122
|
for (const agentConfig of Object.values(manifest.agents)) {
|
|
74
|
-
agentConfig.always_skills = agentConfig.always_skills.filter((s) => !
|
|
75
|
-
agentConfig.compatible_skills = agentConfig.compatible_skills.filter((s) => !
|
|
123
|
+
agentConfig.always_skills = agentConfig.always_skills.filter((s) => !removedSkillManifestNames.has(s));
|
|
124
|
+
agentConfig.compatible_skills = agentConfig.compatible_skills.filter((s) => !removedSkillManifestNames.has(s));
|
|
76
125
|
}
|
|
77
126
|
}
|
|
78
127
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
package/dist/remove.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACvG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAGtC;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB;IAC9C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;oBAC3B,UAAU,EAAE,EAAE;oBACd,WAAW,EAAE,EAAE;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACxC,IAAI,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC;oBACT,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,KAAK;oBACX,UAAU,EAAE,EAAE;oBACd,WAAW,EAAE,EAAE;iBAChB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,KAA6B,EAC7B,UAAkB;IAElB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACxB,MAAM,UAAU,GACd,IAAI,CAAC,IAAI,KAAK,OAAO;YACnB,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,IAAI,KAAK,CAAC;YAC1D,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAEvD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAClC,CAAC;QAED,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACjC,CAAC,CAAC,CAAC;AACL,CAAC;AAoBD
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../src/remove.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -50,6 +50,25 @@
|
|
|
50
50
|
"**/*.spec.*"
|
|
51
51
|
]
|
|
52
52
|
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"name": "grimoire:conventional-commit",
|
|
56
|
+
"path": "skills/gr.conventional-commit",
|
|
57
|
+
"description": "Generate git commits following Conventional Commits 1.0.0. Use for /conventional-commit, git commit, or when committing changes.",
|
|
58
|
+
"triggers": {
|
|
59
|
+
"keywords": [
|
|
60
|
+
"conventional-commit",
|
|
61
|
+
"git-commit"
|
|
62
|
+
],
|
|
63
|
+
"file_extensions": [],
|
|
64
|
+
"patterns": [
|
|
65
|
+
"commit.*change",
|
|
66
|
+
"create.*commit",
|
|
67
|
+
"make.*commit",
|
|
68
|
+
"conventional.*commit"
|
|
69
|
+
],
|
|
70
|
+
"file_paths": []
|
|
71
|
+
}
|
|
53
72
|
}
|
|
54
73
|
]
|
|
55
74
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grimoire:conventional-commit
|
|
3
|
+
description: "Generate git commits following Conventional Commits 1.0.0. Use for /conventional-commit, git commit, or when committing changes."
|
|
4
|
+
user_invocable: true
|
|
5
|
+
disable-model-invocation: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Git Commit Generator
|
|
9
|
+
|
|
10
|
+
Generate git commit messages following the [Conventional Commits 1.0.0](https://www.conventionalcommits.org/en/v1.0.0/) specification.
|
|
11
|
+
|
|
12
|
+
## Commit Message Format
|
|
13
|
+
|
|
14
|
+
```plain
|
|
15
|
+
<type>[optional scope]: <description>
|
|
16
|
+
|
|
17
|
+
[optional body]
|
|
18
|
+
|
|
19
|
+
[optional footer(s)]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Types
|
|
23
|
+
|
|
24
|
+
| Type | Description |
|
|
25
|
+
| ------ | ------------- |
|
|
26
|
+
| `feat` | New feature (correlates with MINOR in SemVer) |
|
|
27
|
+
| `fix` | Bug fix (correlates with PATCH in SemVer) |
|
|
28
|
+
| `docs` | Documentation only changes |
|
|
29
|
+
| `style` | Code style (formatting, semicolons, etc.) - no logic change |
|
|
30
|
+
| `refactor` | Code change that neither fixes a bug nor adds a feature |
|
|
31
|
+
| `perf` | Performance improvement |
|
|
32
|
+
| `test` | Adding or correcting tests |
|
|
33
|
+
| `build` | Build system or external dependencies |
|
|
34
|
+
| `ci` | CI configuration files and scripts |
|
|
35
|
+
| `chore` | Other changes that don't modify src or test files |
|
|
36
|
+
|
|
37
|
+
## Breaking Changes
|
|
38
|
+
|
|
39
|
+
For breaking changes, either:
|
|
40
|
+
|
|
41
|
+
- Add `BREAKING CHANGE:` footer in body
|
|
42
|
+
|
|
43
|
+
Breaking changes correlate with MAJOR in SemVer.
|
|
44
|
+
|
|
45
|
+
## Workflow
|
|
46
|
+
|
|
47
|
+
When user invokes /commit:
|
|
48
|
+
|
|
49
|
+
1. **Check staged changes**:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
git status
|
|
53
|
+
git diff --cached
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
2. **Check recent commits** for style consistency:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
git log --oneline -10
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
3. **Analyze changes** and determine:
|
|
63
|
+
- Filter out trivial changes (see below)
|
|
64
|
+
- Primary type (feat, fix, docs, etc.)
|
|
65
|
+
- Scope if applicable (component, module, or file area)
|
|
66
|
+
- Concise description (imperative mood, no period)
|
|
67
|
+
- Whether body is needed for complex changes
|
|
68
|
+
|
|
69
|
+
4. **Generate commit** using HEREDOC for proper formatting:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
git commit -m "$(cat <<'EOF'
|
|
73
|
+
type(scope): description
|
|
74
|
+
|
|
75
|
+
Optional body explaining what and why.
|
|
76
|
+
EOF
|
|
77
|
+
)"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
5. **Verify** the commit was created:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
git log -1
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Filtering Trivial Changes
|
|
87
|
+
|
|
88
|
+
Ignore changes that don't affect functionality or user experience:
|
|
89
|
+
|
|
90
|
+
- Whitespace adjustments (indentation, line breaks, trailing newlines)
|
|
91
|
+
- Code formatting/style changes (line wrapping, bracket positioning)
|
|
92
|
+
- Comment formatting
|
|
93
|
+
- Import reordering without additions/removals
|
|
94
|
+
|
|
95
|
+
Only document changes with semantic meaning or technical impact. For pure formatting commits, use simple descriptions like "format code" or "apply linting fixes".
|
|
96
|
+
|
|
97
|
+
## Rules
|
|
98
|
+
|
|
99
|
+
- Focus on primary purpose and impact, not implementation details
|
|
100
|
+
- Description must be lowercase, imperative mood ("add feature" not "added feature")
|
|
101
|
+
- No period at end of description
|
|
102
|
+
- Keep description under 72 characters
|
|
103
|
+
- Scope is optional but recommended for larger codebases
|
|
104
|
+
- Body should explain "what" and "why", not "how"
|
|
105
|
+
- Be concise—avoid redundant or verbose language
|
|
106
|
+
- **Never** use `--no-verify` unless explicitly requested
|
|
107
|
+
- **Never** amend commits that have been pushed to remote
|
|
108
|
+
- **Never** include Co-Authored-By footers in commit messages
|
|
109
|
+
|
|
110
|
+
## Examples
|
|
111
|
+
|
|
112
|
+
**Simple feature:**
|
|
113
|
+
|
|
114
|
+
```plain
|
|
115
|
+
feat: add health check endpoint
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Feature with scope:**
|
|
119
|
+
|
|
120
|
+
```plain
|
|
121
|
+
feat(api): add CSV enrichment endpoint
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Fix with body:**
|
|
125
|
+
|
|
126
|
+
```plain
|
|
127
|
+
fix(validation): handle empty date fields
|
|
128
|
+
|
|
129
|
+
Previously empty dates caused NullReferenceException.
|
|
130
|
+
Now validates and rejects rows with empty required fields.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Breaking change:**
|
|
134
|
+
|
|
135
|
+
```plain
|
|
136
|
+
feat(api)!: change enrichment response format
|
|
137
|
+
|
|
138
|
+
BREAKING CHANGE: Response now returns JSON wrapper with metadata
|
|
139
|
+
instead of raw CSV. Clients must update parsing logic.
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Documentation:**
|
|
143
|
+
|
|
144
|
+
```plain
|
|
145
|
+
docs: update README with API examples
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Multiple changes (pick primary):**
|
|
149
|
+
When changes span multiple types, use the most significant one and mention others in body.
|
|
@@ -57,6 +57,34 @@ Add a reference to the knowledge base in the project's `CLAUDE.md` (create one i
|
|
|
57
57
|
|
|
58
58
|
Use this when business logic changes. Updates are driven by text input — user stories, change requests, discussion transcripts/summaries — not by code analysis.
|
|
59
59
|
|
|
60
|
+
### Step 0: Triage the Input
|
|
61
|
+
|
|
62
|
+
When the input is unstructured (meeting notes, transcripts, raw discussions), classify each item before proceeding:
|
|
63
|
+
|
|
64
|
+
- **Business rule/constraint** — what the system MUST or MUST NOT allow → document these
|
|
65
|
+
- **UX/presentation decision** — how something is displayed or interacted with → skip. Document only if the UX element is the mechanism that enforces a business constraint (e.g., a button is disabled because the system MUST NOT allow editing after dispatch). The constraint itself is the business rule; the UI mechanism is just implementation detail noted in "Enforced in."
|
|
66
|
+
- **Feature request / planned capability** — something that doesn't exist yet → skip, not documentation material
|
|
67
|
+
- **Scope / phase decision** — what's included in or deferred from a release phase → skip, this is project management, not a business rule
|
|
68
|
+
- **Action item / tangent** — not documentation material → skip
|
|
69
|
+
|
|
70
|
+
**Litmus test:** Would violating this item cause incorrect data, broken invariants, security holes, or compliance violations? If the only consequence is a suboptimal user experience, it's a UX decision, not a business rule.
|
|
71
|
+
|
|
72
|
+
Examples:
|
|
73
|
+
- "Users must not edit shipments after dispatch" → Business rule (data integrity)
|
|
74
|
+
- "Items should not be pre-selected by default" → UX decision (no data/integrity consequence)
|
|
75
|
+
- "Use 'Next' instead of 'Save' on wizard buttons" → UX decision (label preference)
|
|
76
|
+
- "Save as Draft is deferred to phase 2" → Scope decision (skip)
|
|
77
|
+
- "One shipment = one dock in MQS" → Business rule (hard system mapping)
|
|
78
|
+
- "Create Shipment from Orders List needed" → Feature request (skip)
|
|
79
|
+
|
|
80
|
+
Present the classification as a table for the user to confirm before proceeding:
|
|
81
|
+
|
|
82
|
+
| Item | Classification | Reason | Action |
|
|
83
|
+
|------|---------------|--------|--------|
|
|
84
|
+
| ... | Business rule / UX / Feature / Scope / Tangent | Why this classification | Document / Skip |
|
|
85
|
+
|
|
86
|
+
For well-structured input (user stories with clear acceptance criteria, formal change requests), this step can be brief or skipped.
|
|
87
|
+
|
|
60
88
|
### Step 1: Understand the Change
|
|
61
89
|
|
|
62
90
|
Read the provided input (user story, change request, discussion transcript/summary). Extract:
|
|
@@ -74,6 +102,7 @@ Read the affected Tier 2 file(s). For each change from Step 1, check:
|
|
|
74
102
|
- Does it modify an existing rule or add a new one?
|
|
75
103
|
- Does it affect workflows, entities, or integration points?
|
|
76
104
|
- Does it invalidate any existing constraints, examples, or counterexamples?
|
|
105
|
+
- **Terminology cross-reference**: Does the input use different terms for concepts already documented? Flag mismatches to the user (e.g., "The transcript says 'Dispatched' — does this map to the existing 'InTransit' status in the docs?"). Check the glossary in `_overview.md` and entity names in affected Tier 2 files.
|
|
77
106
|
|
|
78
107
|
Flag any conflicts or ambiguities to the user before making changes.
|
|
79
108
|
|
|
@@ -98,6 +127,10 @@ Only add information you are certain about from the provided input.
|
|
|
98
127
|
- **New domain areas**: Create a new Tier 2 file and add it to the table of contents in `_overview.md`.
|
|
99
128
|
- **"Enforced in" fields**: Leave empty or mark with `<!-- TODO: add code location after implementation -->` — code locations are filled in after implementation, not before.
|
|
100
129
|
- **Diagrams and glossary**: Update as needed to reflect changes.
|
|
130
|
+
- **Feature requests**: MUST NOT be added to business logic docs. If the input contains feature requests or planned capabilities, exclude them and mention to the user what was excluded and why.
|
|
131
|
+
- **UX-only decisions**: Do not document in business logic docs unless they enforce a business constraint (e.g., a disabled button that prevents an invalid state transition is a constraint; a button label rename is not).
|
|
132
|
+
- **Scope/phase annotations**: Do not add "deferred to phase 2" or "planned for future release" annotations. Business logic docs describe what IS true now, not what's planned. If a capability doesn't exist yet, there's nothing to document.
|
|
133
|
+
- **Template compliance**: Do NOT invent new template sections. Only use sections defined in [references/tier2-template.md](references/tier2-template.md). If information doesn't fit an existing section, it likely doesn't belong in business logic docs.
|
|
101
134
|
|
|
102
135
|
### Step 5: Validate and Present
|
|
103
136
|
|
|
@@ -193,6 +226,14 @@ Each entry follows:
|
|
|
193
226
|
**Affected areas:** Which Tier 2 files are impacted.
|
|
194
227
|
```
|
|
195
228
|
|
|
229
|
+
**Threshold for a decision log entry** — only add an entry when:
|
|
230
|
+
|
|
231
|
+
- The decision involves a non-obvious tradeoff where rejected alternatives had real consequences
|
|
232
|
+
- Future developers might question or accidentally reverse the decision
|
|
233
|
+
- The "why" is not self-evident from the rule itself
|
|
234
|
+
|
|
235
|
+
Do NOT add decision log entries for: UI label changes, default value tweaks, deferred features without evaluated alternatives, or any decision where there was no meaningful alternative considered.
|
|
236
|
+
|
|
196
237
|
## Writing Principles
|
|
197
238
|
|
|
198
239
|
Follow these when writing or updating business logic docs:
|
|
@@ -217,7 +258,7 @@ Follow these when writing or updating business logic docs:
|
|
|
217
258
|
|
|
218
259
|
10. **Use decision trees for complex conditional logic.** Any logic with 3+ branches MUST use sequential if-then format. Mark mutually exclusive paths explicitly. No prose-only descriptions for multi-branch logic.
|
|
219
260
|
|
|
220
|
-
11. **Mark information sources.** Tag rules with their origin: `[SOURCE: user-story]`, `[SOURCE: discussion]
|
|
261
|
+
11. **Mark information sources.** Tag rules with their origin using the format `[SOURCE: type — YYYY-MM-DD]` when a date is available: e.g., `[SOURCE: user-story — 2025-01-15]`, `[SOURCE: discussion — 2025-02-10]`. The date is optional — omit the suffix when no date is explicitly provided (e.g., `[SOURCE: change-request]` is fine). During audits (Workflow 3 only), rules surfaced from code analysis get `[SOURCE: code-audit — unconfirmed]` and MUST be confirmed with the user before being treated as business rules. Incorrect docs are worse than missing docs.
|
|
221
262
|
|
|
222
263
|
12. **State machines over prose for workflows.** Any process with 3+ states MUST use a mermaid stateDiagram plus a transition table. No prose-only workflow descriptions for stateful processes.
|
|
223
264
|
|
|
@@ -253,6 +294,8 @@ Docs describe the current state, not history:
|
|
|
253
294
|
- NEVER use "previously was" / "changed from X to Y" / history annotations — docs describe current state, git tracks history
|
|
254
295
|
- NEVER leave diagrams contradicting documented transitions
|
|
255
296
|
- NEVER duplicate rules across files — reference the canonical location instead
|
|
297
|
+
- NEVER add feature requests, roadmap items, or planned capabilities to business logic docs — these are not current-state business rules
|
|
298
|
+
- NEVER invent template sections not defined in `tier2-template.md`
|
|
256
299
|
|
|
257
300
|
## CLAUDE.md Integration
|
|
258
301
|
|