@khanhcan148/mk 0.1.33 → 0.1.34

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
@@ -6,7 +6,7 @@
6
6
 
7
7
  Modular packages that extend Claude Code with specialized knowledge, workflows, and tool integrations.
8
8
 
9
- **Quick Navigation:** [Quick Reference](docs/quick-reference.md) | [Common Workflows](docs/common-workflows.md) | [Skill Index](docs/skill-index.md)
9
+ **Quick Navigation:** [Usage Guides](docs/guides/index.md) | [Quick Reference](docs/quick-reference.md) | [Common Workflows](docs/common-workflows.md) | [Skill Index](docs/skill-index.md)
10
10
 
11
11
 
12
12
  ## Quick Start
@@ -93,8 +93,8 @@ cp -r .claude ~/.claude/
93
93
 
94
94
  ```
95
95
  ├── .claude/
96
- │ ├── agents/ # 36 agents (5 primary + 31 utility: implementers, quality, docs, specialized, concerns, brainstorm critics)
97
- │ ├── skills/ # 62 skill packages (SKILL.md + scripts/references/assets)
96
+ │ ├── agents/ # 38 agents (5 primary + 33 utility: implementers, quality, docs, specialized, concerns, brainstorm critics)
97
+ │ ├── skills/ # 61 skill packages (SKILL.md + scripts/references/assets)
98
98
  │ │ ├── mk-*/ # 20 workflow commands (/mk-audit, /mk-brainstorm, /mk-log-analysis, /mk-overview, /mk-wiki, etc.)
99
99
  │ │ └── ... # Domain skills (frontend, backend, testing, browser automation, etc.)
100
100
  │ └── workflows/ # Development protocols
@@ -231,6 +231,7 @@ python .claude/skills/skill-creator/scripts/package_skill.py <path/to/skill-fold
231
231
 
232
232
  | Document | Description |
233
233
  |----------|-------------|
234
+ | [mk-* Usage Guides](docs/guides/index.md) | Human how-to guides for all 20 /mk-* commands: when to use, flags, phase flow, pitfalls |
234
235
  | [Skill Index](docs/skill-index.md) | Categorized list of all skills and workflows |
235
236
  | [mk-* Workflows & Agents](docs/mk-workflow-agents.md) | How each /mk-* command works and which agents it uses |
236
237
  | [`mk codex` Command Guide](docs/codex/COMMAND.md) | Convert .claude/ to .codex/ for OpenAI Codex CLI; auto-sync on mk update |
package/bin/mk.js CHANGED
@@ -65,6 +65,7 @@ program.command('env [name]')
65
65
  .description('List or describe MK_* environment variables')
66
66
  .option('--format <fmt>', 'Output format: text (default) or json')
67
67
  .option('--markdown', 'Emit the full env-vars table as markdown (same as .claude/env-vars.md)')
68
+ .option('--all', 'Include internal/testing variables (hidden by default)')
68
69
  .action((name, options) => envAction(name, options));
69
70
 
70
71
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanhcan148/mk",
3
- "version": "0.1.33",
3
+ "version": "0.1.34",
4
4
  "description": "CLI to install and manage MyClaudeKit (.claude/) in your projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -59,8 +59,14 @@ export function renderMarkdown(entries) {
59
59
  return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
60
60
  });
61
61
 
62
+ // User-facing vars are grouped by scope; internal/testing vars (hook *_TEST
63
+ // bypasses, *_MAX_STDIN_BYTES caps) are collected into a single trailing
64
+ // section so the everyday reference stays uncluttered.
65
+ const userFacing = sorted.filter((e) => !e.internal);
66
+ const internal = sorted.filter((e) => e.internal);
67
+
62
68
  const groups = new Map();
63
- for (const entry of sorted) {
69
+ for (const entry of userFacing) {
64
70
  if (!groups.has(entry.scope)) groups.set(entry.scope, []);
65
71
  groups.get(entry.scope).push(entry);
66
72
  }
@@ -78,24 +84,37 @@ export function renderMarkdown(entries) {
78
84
  );
79
85
  lines.push('');
80
86
 
81
- for (const [scope, scopeEntries] of groups) {
82
- lines.push(`## ${scopeLabel(scope)}`);
83
- lines.push('');
87
+ const renderTable = (rows) => {
84
88
  lines.push('| Name | Type | Default | Description |');
85
89
  lines.push('|------|------|---------|-------------|');
86
-
87
- for (const entry of scopeEntries) {
90
+ for (const entry of rows) {
88
91
  const def = entry.default !== undefined ? `\`${entry.default}\`` : '—';
89
92
  const desc = entry.description.replace(/\|/g, '\\|');
90
93
  lines.push(`| \`${entry.name}\` | ${entry.type} | ${def} | ${desc} |`);
91
94
  }
95
+ lines.push('');
96
+ };
92
97
 
98
+ for (const [scope, scopeEntries] of groups) {
99
+ lines.push(`## ${scopeLabel(scope)}`);
100
+ lines.push('');
101
+ renderTable(scopeEntries);
102
+ }
103
+
104
+ if (internal.length > 0) {
105
+ lines.push('## Internal / testing');
106
+ lines.push('');
107
+ lines.push(
108
+ '> These are plumbing knobs a normal user never sets (hook test bypasses and ' +
109
+ 'defensive stdin caps). `mk env` hides them by default — use `mk env --all`.'
110
+ );
93
111
  lines.push('');
112
+ renderTable(internal);
94
113
  }
95
114
 
96
115
  lines.push('---');
97
116
  lines.push('');
98
- lines.push(`_${entries.length} variables documented. Run \`mk env\` for live values._`);
117
+ lines.push(`_${entries.length} variables documented (${internal.length} internal). Run \`mk env\` for live values._`);
99
118
  lines.push('');
100
119
 
101
120
  return lines.join('\n');
@@ -60,16 +60,21 @@ function padRight(str, width) {
60
60
  // List mode — grouped by scope
61
61
  // ---------------------------------------------------------------------------
62
62
 
63
- function listMode(format) {
63
+ function listMode(format, showInternal = false) {
64
+ // By default hide internal/testing vars (hook *_TEST bypasses, *_MAX_STDIN_BYTES
65
+ // caps) — they are plumbing a user never sets. `--all` shows them.
66
+ const visible = showInternal ? [...ENTRIES] : ENTRIES.filter((e) => !e.internal);
67
+ const hiddenCount = ENTRIES.length - visible.length;
68
+
64
69
  // Group entries by scope, preserving insertion order of first occurrence
65
70
  const groups = new Map();
66
- for (const entry of ENTRIES) {
71
+ for (const entry of visible) {
67
72
  if (!groups.has(entry.scope)) groups.set(entry.scope, []);
68
73
  groups.get(entry.scope).push(entry);
69
74
  }
70
75
 
71
76
  if (format === 'json') {
72
- const enriched = ENTRIES.map((e) => ({ ...e, current: currentValue(e) }));
77
+ const enriched = visible.map((e) => ({ ...e, current: currentValue(e) }));
73
78
  process.stdout.write(JSON.stringify({ entries: enriched }, null, 2) + '\n');
74
79
  return;
75
80
  }
@@ -99,7 +104,10 @@ function listMode(format) {
99
104
 
100
105
  const scopeCount = sortedScopes.length;
101
106
  process.stdout.write(`Run \`mk env <NAME>\` for full details on a single variable.\n`);
102
- process.stdout.write(`${ENTRIES.length} variables across ${scopeCount} scope${scopeCount === 1 ? '' : 's'}.\n`);
107
+ process.stdout.write(`${visible.length} variables across ${scopeCount} scope${scopeCount === 1 ? '' : 's'}.\n`);
108
+ if (hiddenCount > 0) {
109
+ process.stdout.write(`${hiddenCount} internal/testing variable${hiddenCount === 1 ? '' : 's'} hidden — run \`mk env --all\` to show.\n`);
110
+ }
103
111
  }
104
112
 
105
113
  // ---------------------------------------------------------------------------
@@ -128,6 +136,9 @@ function detailMode(name) {
128
136
  if (entry.since) {
129
137
  process.stdout.write(` Since: ${entry.since}\n`);
130
138
  }
139
+ if (entry.internal) {
140
+ process.stdout.write(` Internal: yes (testing/tuning plumbing — not a user setting)\n`);
141
+ }
131
142
  process.stdout.write(`\n ${entry.description}\n`);
132
143
  }
133
144
 
@@ -173,6 +184,6 @@ export function envAction(name, options = {}) {
173
184
  detailMode(name);
174
185
  }
175
186
  } else {
176
- listMode(format);
187
+ listMode(format, options.all === true);
177
188
  }
178
189
  }
@@ -80,9 +80,18 @@ export function redactSecrets(message, ctx = {}) {
80
80
  out = out.split(ctx.storedToken).join('[REDACTED-TOKEN]');
81
81
  }
82
82
 
83
- // S3: Redact any GitHub token-shaped substring (belt-and-braces)
83
+ // S3b: Redact any GitHub token-shaped substring (belt-and-braces)
84
84
  out = out.replace(/gh[pousr]_[A-Za-z0-9_]{30,}/g, '[REDACTED-TOKEN]');
85
85
 
86
+ // S5: Redact SQL Server / MSSQL Password= and ODBC Pwd= alias in connection strings
87
+ out = out.replace(/((?:Password|Pwd)\s*=\s*)([^;]+?)(\s*;|\s*$)/gi, '$1[REDACTED-PASSWORD]$3');
88
+
89
+ // S6: Redact PostgreSQL DSN user:pass@ credentials
90
+ out = out.replace(/(postgres(?:ql)?:\/\/)([^:@/]+):([^@/]+)@/gi, '$1[REDACTED-USER]:[REDACTED-PASSWORD]@');
91
+
92
+ // S7: Redact Azure Storage / CosmosDB AccountKey= in connection strings
93
+ out = out.replace(/(AccountKey\s*=\s*)([^;]+?)(\s*;|\s*$)/gi, '$1[REDACTED-KEY]$3');
94
+
86
95
  return out;
87
96
  }
88
97
 
@@ -14,6 +14,12 @@
14
14
  * If a var is secret-like (e.g. MK_*_TOKEN, MK_*_KEY, MK_*_SECRET) it should carry
15
15
  * { secret: true } and `mk env` will redact its current value. None of the current
16
16
  * vars are secret.
17
+ *
18
+ * { internal: true } marks a var as test-only or defensive-tuning plumbing that a
19
+ * normal user never sets (e.g. hook *_TEST bypasses, *_MAX_STDIN_BYTES caps). These
20
+ * stay in the registry so drift detection has a complete catalog, but `mk env` hides
21
+ * them by default (show with `mk env --all`) and the generated doc lists them in a
22
+ * separate "Internal / testing" section. They remain addressable via `mk env <NAME>`.
17
23
  */
18
24
 
19
25
  const _RAW = [
@@ -28,8 +34,96 @@ const _RAW = [
28
34
  applies_to: 'skill',
29
35
  since: '0.1.21',
30
36
  },
37
+ {
38
+ name: 'MK_DAB_AUDIT_DIR',
39
+ scope: 'data-api-builder',
40
+ default: 'docs/dab-audit',
41
+ description:
42
+ 'Override the directory where dab_audit_writer.py appends the data-api-builder ' +
43
+ 'preflight audit log (dab-audit-YYYY-MM-DD.jsonl). Defaults to docs/dab-audit, ' +
44
+ 'relative to invocation cwd. Set to redirect logs to an artefact store in CI. ' +
45
+ 'Mirrors MK_SECURITY_AUDIT_DIR.',
46
+ type: 'path',
47
+ applies_to: 'skill',
48
+ since: '0.1.33',
49
+ },
50
+ {
51
+ name: 'MK_DAB_BASH_GUARD_MAX_STDIN_BYTES',
52
+ internal: true,
53
+ scope: 'data-api-builder',
54
+ default: '1048576',
55
+ description:
56
+ 'Maximum stdin bytes the dab-bash-guard hook (Gate 4) reads before failing open ' +
57
+ '(allowing the command to proceed). Default is 1 048 576 bytes (1 MB).',
58
+ type: 'integer',
59
+ applies_to: 'hook',
60
+ since: '0.1.34',
61
+ },
62
+ {
63
+ name: 'MK_DAB_BASH_GUARD_TEST',
64
+ internal: true,
65
+ scope: 'data-api-builder',
66
+ default: undefined,
67
+ description:
68
+ 'When set to "1", dab-bash-guard.cjs returns early at module load without executing the ' +
69
+ 'stdin pipeline. Used exclusively by hook unit tests; do not set in production.',
70
+ type: 'boolean',
71
+ applies_to: 'hook',
72
+ since: '0.1.34',
73
+ },
74
+ {
75
+ name: 'MK_DAB_BASH_OK',
76
+ scope: 'data-api-builder',
77
+ default: undefined,
78
+ description:
79
+ 'Opt-out override: when set to "1", allows Bash invocations of a DB CLI ' +
80
+ '(sqlcmd/psql/mysql/mssql-cli/mongosh/bcp/cqlsh) with query intent that the dab-bash-guard ' +
81
+ 'hook (Gate 4) otherwise blocks. Set only for deliberate DB administration; prefer the ' +
82
+ 'data-api-builder MCP tools.',
83
+ type: 'boolean',
84
+ applies_to: 'hook',
85
+ since: '0.1.34',
86
+ },
87
+ {
88
+ name: 'MK_DAB_MCP_GUARD_MAX_STDIN_BYTES',
89
+ internal: true,
90
+ scope: 'data-api-builder',
91
+ default: '1048576',
92
+ description:
93
+ 'Maximum stdin bytes the dab-mcp-guard hook (Gate 1) reads before failing open ' +
94
+ '(allowing the call to proceed). Default is 1 048 576 bytes (1 MB).',
95
+ type: 'integer',
96
+ applies_to: 'hook',
97
+ since: '0.1.34',
98
+ },
99
+ {
100
+ name: 'MK_DAB_MCP_GUARD_TEST',
101
+ internal: true,
102
+ scope: 'data-api-builder',
103
+ default: undefined,
104
+ description:
105
+ 'When set to "1", dab-mcp-guard.cjs skips main() at module load. Used exclusively by hook ' +
106
+ 'unit tests; do not set in production.',
107
+ type: 'boolean',
108
+ applies_to: 'hook',
109
+ since: '0.1.34',
110
+ },
111
+ {
112
+ name: 'MK_DAB_WRITES_OK',
113
+ scope: 'data-api-builder',
114
+ default: undefined,
115
+ description:
116
+ 'Opt-out override: when set to "1", allows the four write-capable data-api-builder MCP ' +
117
+ 'calls (create_record/update_record/delete_record/execute_entity) that the dab-mcp-guard ' +
118
+ 'hook (Gate 1) otherwise blocks. Set only for deliberate writes; DAB role config remains ' +
119
+ 'as defence-in-depth.',
120
+ type: 'boolean',
121
+ applies_to: 'hook',
122
+ since: '0.1.34',
123
+ },
31
124
  {
32
125
  name: 'MK_FORCE_NO_TOOL_DIR',
126
+ internal: true,
33
127
  scope: 'codex',
34
128
  default: undefined,
35
129
  description:
@@ -74,6 +168,7 @@ const _RAW = [
74
168
  },
75
169
  {
76
170
  name: 'MK_SQL_GUARD_MAX_STDIN_BYTES',
171
+ internal: true,
77
172
  scope: 'sql-guard',
78
173
  default: '1048576',
79
174
  description:
@@ -85,6 +180,7 @@ const _RAW = [
85
180
  },
86
181
  {
87
182
  name: 'MK_SQL_GUARD_TEST',
183
+ internal: true,
88
184
  scope: 'sql-guard',
89
185
  default: undefined,
90
186
  description: