@khanhcan148/mk 0.1.8 → 0.1.10

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 CHANGED
@@ -2,12 +2,20 @@
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/@khanhcan148/mk)](https://www.npmjs.com/package/@khanhcan148/mk)
4
4
 
5
- **Built by** TRAN Le Khanh — developer and AI tooling author.
5
+ **Built by** TRAN Le Khanh (khanhcan148@gmail.com) — developer and AI tooling author.
6
6
 
7
7
  Modular packages that extend Claude Code with specialized knowledge, workflows, and tool integrations.
8
8
 
9
9
  **Quick Navigation:** [Quick Reference](docs/QUICK-REFERENCE.md) | [Common Workflows](docs/COMMON-WORKFLOWS.md) | [Skill Index](docs/SKILL-INDEX.md)
10
10
 
11
+ ## 🔒 Access Notice
12
+
13
+ **This package has limited access.** To get access to the npm package and repository:
14
+
15
+ 📧 **Email:** khanhcan148@gmail.com
16
+
17
+ Include your use case and I'll send you an invitation.
18
+
11
19
  ## Quick Start
12
20
 
13
21
  ### CLI Installation (Recommended)
@@ -26,7 +34,7 @@ mk init --global
26
34
  mk init --dry-run
27
35
  ```
28
36
 
29
- **Note**: The source repository is private. Use the published npm package for installation.
37
+ **Note**: This package has limited access. Email khanhcan148@gmail.com for an invitation to access the npm package and repository.
30
38
 
31
39
  ### CLI Commands
32
40
 
@@ -65,17 +73,20 @@ cp -r .claude ~/.claude/
65
73
 
66
74
  ```bash
67
75
  # Use a workflow command
68
- /mk-init # Bootstrap new project
69
- /mk-brainstorm # Explore options, debate trade-offs
70
- /mk-plan # Create implementation plan
71
- /mk-implement # End-to-end feature delivery
72
- /mk-test # Run tests and validate
73
- /mk-review # Code quality review
74
- /mk-debug # Debug issues
75
- /mk-security # Security scan and audit
76
- /mk-db # Database operations
77
- /mk-docs # Generate documentation
78
- /mk-git # Git operations
76
+ /mk-init # Bootstrap new project
77
+ /mk-brainstorm # Explore options, debate trade-offs
78
+ /mk-plan # Create implementation plan
79
+ /mk-implement # End-to-end feature delivery
80
+ /mk-test # Run tests and validate
81
+ /mk-review # Code quality review
82
+ /mk-debug # Debug issues
83
+ /mk-security # Security scan and audit
84
+ /mk-db # Database operations
85
+ /mk-docs # Generate documentation
86
+ /mk-git # Git operations
87
+ /mk-audit # Code archaeology chain: orientation, testing, heatmap, breaking-change analysis, technical debt, domain extraction
88
+ /mk-skill-creator # Create and scaffold new Claude Code skills with automated validation
89
+ /mk-selftest # Self-validation checks on kit agents, skills, docs, workflows
79
90
  ```
80
91
 
81
92
  ## Structure
@@ -83,8 +94,8 @@ cp -r .claude ~/.claude/
83
94
  ```
84
95
  ├── .claude/
85
96
  │ ├── agents/ # 29 agents (5 primary + 24 utility: implementers, quality, docs, specialized, concerns)
86
- │ ├── skills/ # 53 skill packages (SKILL.md + scripts/references/assets)
87
- │ │ ├── mk-*/ # 14 workflow commands (/mk-brainstorm, /mk-selftest, etc.)
97
+ │ ├── skills/ # 58 skill packages (SKILL.md + scripts/references/assets)
98
+ │ │ ├── mk-*/ # 16 workflow commands (/mk-audit, /mk-brainstorm, /mk-skill-creator, /mk-selftest, etc.)
88
99
  │ │ └── ... # Domain skills (frontend, backend, testing, etc.)
89
100
  │ └── workflows/ # Development protocols
90
101
  ├── bin/ # CLI entry point (mk command)
@@ -116,8 +127,8 @@ User → /mk-* command (skill) → spawns utility agents → agents use knowledg
116
127
  | Command | Purpose |
117
128
  |---------|---------|
118
129
  | `/mk-init` | Full project bootstrap from conception to deployment; includes brownfield detection (Phase 0 gate) and adoption workflow (B1-B4.5 stages) |
119
- | `/mk-brainstorm` | Ideation, requirements exploration, structured debate (analyzer opus agent); use `--domain` flag to extract and document domain knowledge |
120
- | `/mk-research` | Deep multi-source research on technical topics |
130
+ | `/mk-brainstorm` | Ideation, requirements exploration, structured debate (analyzer opus agent) |
131
+ | `/mk-audit` | Code archaeology chain: orientation report, characterization testing, topology heatmap, breaking-change analysis, technical debt dashboard, domain extraction |
121
132
  | `/mk-plan` | Create implementation plans with phases and tasks (opus) |
122
133
  | `/mk-design` | UI/UX wireframes, design systems, mockups |
123
134
  | `/mk-implement` | End-to-end feature delivery (sonnet) |
@@ -128,6 +139,8 @@ User → /mk-* command (skill) → spawns utility agents → agents use knowledg
128
139
  | `/mk-db` | Database operations: diagnose, optimize, design, migrate |
129
140
  | `/mk-docs` | Generate and update project documentation |
130
141
  | `/mk-git` | Git operations: branch, commit, push, PR, merge |
142
+ | `/mk-research` | Deep multi-source research on technical topics |
143
+ | `/mk-skill-creator` | Create and scaffold new Claude Code skills with automated SKILL.md, scripts, references, and agent |
131
144
  | `/mk-selftest` | Run self-validation checks on kit agents, skills, docs, and workflows |
132
145
 
133
146
  ## Primary Agents
@@ -203,11 +216,12 @@ Each skill contains:
203
216
  - `assets/` (optional) - Templates, images
204
217
 
205
218
  ```bash
206
- # Initialize new skill
207
- .claude/skills/skill-creator/scripts/init_skill.py <skill-name> --path <output-directory>
219
+ # Create new skill (recommended)
220
+ /mk-skill-creator
208
221
 
209
- # Package for distribution
210
- .claude/skills/skill-creator/scripts/package_skill.py <path/to/skill-folder>
222
+ # Or use scripts directly
223
+ .claude/skills/mk-skill-creator/scripts/init_skill.py <skill-name> --path <output-directory>
224
+ .claude/skills/mk-skill-creator/scripts/package_skill.py <path/to/skill-folder>
211
225
  ```
212
226
 
213
227
  ## Documentation
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanhcan148/mk",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "CLI to install and manage MyClaudeKit (.claude/) in your projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,11 +1,11 @@
1
1
  import chalk from 'chalk';
2
2
  import { createInterface } from 'node:readline';
3
- import { existsSync, unlinkSync, copyFileSync, mkdirSync, readFileSync } from 'node:fs';
4
- import { join, dirname, resolve } from 'node:path';
3
+ import { existsSync, unlinkSync, copyFileSync, mkdirSync, readFileSync, rmdirSync, readdirSync } from 'node:fs';
4
+ import { join, dirname, resolve, sep } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { readManifest, updateManifest, diffManifest } from '../lib/manifest.js';
7
7
  import { computeChecksum } from '../lib/checksum.js';
8
- import { copyKitFiles } from '../lib/copy.js';
8
+ import { copyKitFiles, collectDiskFiles } from '../lib/copy.js';
9
9
  import { resolveTargetDir, resolveManifestPath, deriveProjectRoot, assertSafePath } from '../lib/paths.js';
10
10
  import { resolveTokenOrLogin } from '../lib/auth.js';
11
11
  import { writeToken, readStoredToken } from '../lib/config.js';
@@ -167,6 +167,58 @@ export async function runUpdate(params = {}) {
167
167
  delete newFiles[relPath];
168
168
  }
169
169
 
170
+ // Orphan cleanup: files on disk (in kit subdirs) that are not in the new source
171
+ const diskFiles = collectDiskFiles(targetDir);
172
+ const orphans = [];
173
+ const orphanParentDirs = new Set();
174
+ for (const relPath of diskFiles) {
175
+ if (relPath in sourceFiles) continue; // present in new source — keep
176
+ const absPath = join(projectRoot, relPath);
177
+ try {
178
+ assertSafePath(absPath, claudeRoot, `orphan "${relPath}"`);
179
+ } catch (err) {
180
+ process.stderr.write(`Warning: Skipping unsafe orphan path: ${err.message}\n`);
181
+ continue;
182
+ }
183
+ try {
184
+ unlinkSync(absPath);
185
+ orphans.push(relPath);
186
+ orphanParentDirs.add(dirname(absPath));
187
+ } catch {
188
+ // Already missing — skip
189
+ }
190
+ }
191
+
192
+ // Clean up empty directories bottom-up after orphan deletion
193
+ const resolvedTarget = resolve(targetDir);
194
+ const sortedOrphanDirs = [...orphanParentDirs].sort((a, b) => {
195
+ return b.split(/[/\\]/).length - a.split(/[/\\]/).length;
196
+ });
197
+ for (const dir of sortedOrphanDirs) {
198
+ if (isEmptyDir(dir)) {
199
+ try {
200
+ rmdirSync(dir);
201
+ let current = dirname(dir);
202
+ let prev = dir;
203
+ while (current !== prev && isEmptyDir(current)) {
204
+ const resolvedCurrent = resolve(current);
205
+ if (resolvedCurrent === resolvedTarget || !resolvedCurrent.startsWith(resolvedTarget + sep)) {
206
+ break;
207
+ }
208
+ try {
209
+ rmdirSync(current);
210
+ } catch {
211
+ break;
212
+ }
213
+ prev = current;
214
+ current = dirname(current);
215
+ }
216
+ } catch {
217
+ // Non-empty or permission error — skip
218
+ }
219
+ }
220
+ }
221
+
170
222
  // Update manifest with new file map.
171
223
  // Use explicitVersion when provided (e.g. release.version from updateAction);
172
224
  // fall back to pkg.version for direct runUpdate calls or main-branch fallback downloads.
@@ -178,10 +230,24 @@ export async function runUpdate(params = {}) {
178
230
  removed: diff.removed,
179
231
  conflicts: skippedConflicts,
180
232
  unchanged: diff.unchanged,
233
+ orphans,
181
234
  upToDate: false
182
235
  };
183
236
  }
184
237
 
238
+ /**
239
+ * Check if a directory is empty.
240
+ * @param {string} dir
241
+ * @returns {boolean}
242
+ */
243
+ function isEmptyDir(dir) {
244
+ try {
245
+ return readdirSync(dir).length === 0;
246
+ } catch {
247
+ return false;
248
+ }
249
+ }
250
+
185
251
  /**
186
252
  * CLI action handler for 'mk update'.
187
253
  * Checks GitHub Releases for a newer version, prompts the user, then downloads
@@ -305,6 +371,15 @@ export async function updateAction(options = {}, deps = {}) {
305
371
  }
306
372
  if (result.removed.length > 0) {
307
373
  process.stdout.write(chalk.yellow(`Removed: ${result.removed.length} files\n`));
374
+ for (const f of result.removed) {
375
+ process.stdout.write(` Removed: ${f}\n`);
376
+ }
377
+ }
378
+ if (result.orphans && result.orphans.length > 0) {
379
+ process.stdout.write(chalk.yellow(`Cleaned: ${result.orphans.length} orphan files\n`));
380
+ for (const f of result.orphans) {
381
+ process.stdout.write(` Cleaned: ${f}\n`);
382
+ }
308
383
  }
309
384
  if (result.conflicts.length > 0) {
310
385
  process.stdout.write(
@@ -13,6 +13,7 @@ export const MANIFEST_FILENAME = '.mk-manifest.json';
13
13
  */
14
14
  export const COPY_FILTER_PATTERNS = [
15
15
  '__pycache__',
16
+ '.pytest_cache',
16
17
  '.pyc',
17
18
  '.pyo',
18
19
  'node_modules',
package/src/lib/copy.js CHANGED
@@ -52,6 +52,31 @@ function collectFiles(dir) {
52
52
  return results;
53
53
  }
54
54
 
55
+ /**
56
+ * Collect all kit-managed files currently on disk under targetDir (.claude/).
57
+ * Only walks KIT_SUBDIRS (agents/, skills/, workflows/).
58
+ * Returns relative paths in the form `.claude/agents/foo.md`.
59
+ * Applies shouldFilter to exclude filtered patterns.
60
+ *
61
+ * @param {string} targetDir - Absolute path to target .claude/
62
+ * @returns {string[]} relative paths (relative to project root, e.g. `.claude/agents/foo.md`)
63
+ */
64
+ export function collectDiskFiles(targetDir) {
65
+ const results = [];
66
+ for (const subdir of KIT_SUBDIRS) {
67
+ const subdirAbs = join(targetDir, subdir);
68
+ if (!existsSync(subdirAbs)) continue;
69
+ const files = collectFiles(subdirAbs);
70
+ for (const absPath of files) {
71
+ if (shouldFilter(absPath)) continue;
72
+ const relFromSubdir = relative(subdirAbs, absPath);
73
+ const relPath = join('.claude', subdir, relFromSubdir).replace(/\\/g, '/');
74
+ results.push(relPath);
75
+ }
76
+ }
77
+ return results;
78
+ }
79
+
55
80
  /**
56
81
  * Copy kit files from sourceDir (.claude/) to targetDir (.claude/).
57
82
  * Only copies KIT_SUBDIRS (agents/, skills/, workflows/).