thachvd-kit 1.0.35 → 1.0.36

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.
@@ -1,191 +1,192 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { spawnSync } = require('child_process');
4
-
5
- // Source repository for Matt Pocock's promoted skills, installed via the
6
- // upstream `skills` CLI (npx skills@latest add <source>).
7
- const MATT_SKILLS_SOURCE = 'mattpocock/skills';
8
-
9
- // This list mirrors upstream's promoted daily-driver catalog:
10
- // https://github.com/mattpocock/skills -> skills/engineering/ + skills/productivity/
11
- // Do NOT add anything from skills/in-progress, skills/misc, or skills/deprecated —
12
- // those are explicitly not part of the supported set. Update this list by hand
13
- // when upstream promotes a new skill or retires one; there is no reliable
14
- // upstream "promoted only" filter, so this manifest is the source of truth.
15
- const PROMOTED_SKILLS = [
16
- // skills/engineering
17
- 'ask-matt',
18
- 'code-review',
19
- 'codebase-design',
20
- 'diagnosing-bugs',
21
- 'domain-modeling',
22
- 'grill-with-docs',
23
- 'implement',
24
- 'improve-codebase-architecture',
25
- 'prototype',
26
- 'research',
27
- 'resolving-merge-conflicts',
28
- 'setup-matt-pocock-skills',
29
- 'tdd',
30
- 'to-spec',
31
- 'to-tickets',
32
- 'triage',
33
- 'wayfinder',
34
- 'wizard',
35
- // skills/productivity
36
- 'grill-me',
37
- 'grilling',
38
- 'handoff',
39
- 'teach',
40
- 'to-questionnaire',
41
- 'wait-what',
42
- 'writing-for-agents'
43
- ];
44
-
45
- // Agent identifiers as understood by the upstream `skills` CLI (verified
46
- // against its installed agent registry). Both currently resolve to the same
47
- // project-local skills directory below.
48
- const SUPPORTED_AGENTS = ['codex', 'antigravity'];
49
-
50
- // Project-local install target. Skills are intentionally not installed
51
- // globally (see AGENTS.md / .agent/docs/tooling.md for the reasoning).
52
- const SKILLS_RELATIVE_DIR = path.join('.agents', 'skills');
53
-
54
- const SETUP_SKILL_NAME = 'setup-matt-pocock-skills';
55
-
56
- function npxCommand() {
57
- return process.platform === 'win32' ? 'npx.cmd' : 'npx';
58
- }
59
-
60
- function skillsDirFor(targetDir) {
61
- return path.join(targetDir, SKILLS_RELATIVE_DIR);
62
- }
63
-
64
- function isSkillInstalled(targetDir, name) {
65
- return fs.existsSync(path.join(skillsDirFor(targetDir), name, 'SKILL.md'));
66
- }
67
-
68
- // Read-only: never spawns a process. Safe to call from `doctor` and
69
- // `skills check`.
70
- function checkSkills(targetDir) {
71
- const installed = [];
72
- const missing = [];
73
- for (const name of PROMOTED_SKILLS) {
74
- (isSkillInstalled(targetDir, name) ? installed : missing).push(name);
75
- }
76
- return { installed, missing, total: PROMOTED_SKILLS.length };
77
- }
78
-
79
- // Builds the argv for `npx skills@latest add <source> ...`. Always passes
80
- // `--skill <name>` as separate argv entries (never `--skill=<name>`): current
81
- // `skills` CLI versions have a parsing bug where the `--skill=<name>` form is
82
- // silently ignored and installs every skill in the source repository,
83
- // including skills/in-progress, skills/misc, and skills/deprecated.
84
- function buildAddArgs(skillNames) {
85
- return [
86
- '-y', // npx: auto-confirm installing the `skills` package itself
87
- 'skills@latest',
88
- 'add',
89
- MATT_SKILLS_SOURCE,
90
- '--skill', ...skillNames,
91
- '--agent', ...SUPPORTED_AGENTS,
92
- '-y' // skills CLI: skip its own confirmation prompts
93
- ];
94
- }
95
-
96
- function formatCommand(args) {
97
- return `${npxCommand()} ${args.join(' ')}`;
98
- }
99
-
100
- function runNpx(args, options = {}) {
101
- return spawnSync(npxCommand(), args, {
102
- cwd: options.cwd,
103
- encoding: 'utf8',
104
- stdio: options.stdio || 'pipe',
105
- shell: process.platform === 'win32'
106
- });
107
- }
108
-
109
- // Installs the full promoted set in a single `add` call (one clone, one
110
- // filtered install). Never uses `--all`, which would also install
111
- // in-progress/misc/deprecated skills.
112
- function installSkills(targetDir, options = {}) {
113
- const dryRun = options.dryRun === true;
114
- const args = buildAddArgs(PROMOTED_SKILLS);
115
- const command = formatCommand(args);
116
-
117
- if (dryRun) {
118
- return { ok: true, dryRun: true, command, message: `Dry run: would run ${command}` };
119
- }
120
-
121
- const result = runNpx(args, { cwd: targetDir, stdio: 'inherit' });
122
- if (result.error || result.status !== 0) {
123
- return { ok: false, dryRun: false, command, message: `failed to install promoted skills; run manually: ${command}` };
124
- }
125
- return {
126
- ok: true,
127
- dryRun: false,
128
- command,
129
- message: `installed ${PROMOTED_SKILLS.length} promoted Matt Pocock skills to ${SKILLS_RELATIVE_DIR}`
130
- };
131
- }
132
-
133
- // Updates each promoted skill by re-adding it individually and idempotently.
134
- // This is deliberately NOT `npx skills update`: upstream has a known issue
135
- // where updating one project skill can reinstall every skill from the
136
- // source. Re-adding by explicit single-skill name only ever touches that
137
- // skill's directory (verified manually against the upstream CLI).
138
- // Trade-off: this does one network clone of the source repo per promoted
139
- // skill (~PROMOTED_SKILLS.length calls), so it is noticeably slower than
140
- // `installSkills`'s single batched call. That cost is accepted deliberately
141
- // for the safety guarantee above; revisit only if upstream ships a scoped,
142
- // non-destructive `update`.
143
- function updateSkills(targetDir, options = {}) {
144
- const dryRun = options.dryRun === true;
145
- const results = [];
146
-
147
- for (const name of PROMOTED_SKILLS) {
148
- const args = buildAddArgs([name]);
149
- const command = formatCommand(args);
150
-
151
- if (dryRun) {
152
- results.push({ name, ok: true, dryRun: true, command });
153
- continue;
154
- }
155
-
156
- const result = runNpx(args, { cwd: targetDir, stdio: 'pipe' });
157
- const ok = !result.error && result.status === 0;
158
- results.push({
159
- name,
160
- ok,
161
- dryRun: false,
162
- command,
163
- error: ok ? null : (result.stderr || result.stdout || `exit ${result.status}`)
164
- });
165
- }
166
-
167
- const failed = results.filter(r => !r.ok);
168
- const message = dryRun
169
- ? `Dry run: would update ${PROMOTED_SKILLS.length} promoted skills one by one`
170
- : failed.length === 0
171
- ? `updated ${PROMOTED_SKILLS.length} promoted Matt Pocock skills`
172
- : `updated ${results.length - failed.length}/${PROMOTED_SKILLS.length} promoted skills; failed: ${failed.map(f => f.name).join(', ')}`;
173
-
174
- return { ok: failed.length === 0, dryRun, results, message };
175
- }
176
-
177
- module.exports = {
178
- MATT_SKILLS_SOURCE,
179
- PROMOTED_SKILLS,
180
- SUPPORTED_AGENTS,
181
- SKILLS_RELATIVE_DIR,
182
- SETUP_SKILL_NAME,
183
- npxCommand,
184
- skillsDirFor,
185
- isSkillInstalled,
186
- checkSkills,
187
- buildAddArgs,
188
- formatCommand,
189
- installSkills,
190
- updateSkills
191
- };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { spawnSync } = require('child_process');
4
+
5
+ // Source repository for Matt Pocock's promoted skills, installed via the
6
+ // upstream `skills` CLI (npx skills@latest add <source>).
7
+ const MATT_SKILLS_SOURCE = 'mattpocock/skills';
8
+
9
+ // This list mirrors upstream's promoted daily-driver catalog:
10
+ // https://github.com/mattpocock/skills -> skills/engineering/ + skills/productivity/
11
+ // Do NOT add anything from skills/in-progress, skills/misc, or skills/deprecated —
12
+ // those are explicitly not part of the supported set. Update this list by hand
13
+ // when upstream promotes a new skill or retires one; there is no reliable
14
+ // upstream "promoted only" filter, so this manifest is the source of truth.
15
+ const PROMOTED_SKILLS = [
16
+ // skills/engineering
17
+ 'ask-matt',
18
+ 'code-review',
19
+ 'codebase-design',
20
+ 'diagnosing-bugs',
21
+ 'domain-modeling',
22
+ 'grill-with-docs',
23
+ 'implement',
24
+ 'improve-codebase-architecture',
25
+ 'prototype',
26
+ 'research',
27
+ 'resolving-merge-conflicts',
28
+ 'setup-matt-pocock-skills',
29
+ 'tdd',
30
+ 'to-spec',
31
+ 'to-tickets',
32
+ 'triage',
33
+ 'wayfinder',
34
+ 'wizard',
35
+ // skills/productivity
36
+ 'grill-me',
37
+ 'grilling',
38
+ 'handoff',
39
+ 'teach',
40
+ 'to-questionnaire',
41
+ 'wait-what',
42
+ 'writing-for-agents'
43
+ ];
44
+
45
+ // Agent identifiers as understood by the upstream `skills` CLI. Codex and
46
+ // Antigravity share the project-local .agents/skills directory; Claude Code
47
+ // also receives its native .claude/skills integration so skills are exposed
48
+ // as slash commands such as /ask-matt and /implement.
49
+ const SUPPORTED_AGENTS = ['codex', 'antigravity', 'claude-code'];
50
+
51
+ // Project-local install target. Skills are intentionally not installed
52
+ // globally (see AGENTS.md / .agent/docs/tooling.md for the reasoning).
53
+ const SKILLS_RELATIVE_DIR = path.join('.agents', 'skills');
54
+
55
+ const SETUP_SKILL_NAME = 'setup-matt-pocock-skills';
56
+
57
+ function npxCommand() {
58
+ return process.platform === 'win32' ? 'npx.cmd' : 'npx';
59
+ }
60
+
61
+ function skillsDirFor(targetDir) {
62
+ return path.join(targetDir, SKILLS_RELATIVE_DIR);
63
+ }
64
+
65
+ function isSkillInstalled(targetDir, name) {
66
+ return fs.existsSync(path.join(skillsDirFor(targetDir), name, 'SKILL.md'));
67
+ }
68
+
69
+ // Read-only: never spawns a process. Safe to call from `doctor` and
70
+ // `skills check`.
71
+ function checkSkills(targetDir) {
72
+ const installed = [];
73
+ const missing = [];
74
+ for (const name of PROMOTED_SKILLS) {
75
+ (isSkillInstalled(targetDir, name) ? installed : missing).push(name);
76
+ }
77
+ return { installed, missing, total: PROMOTED_SKILLS.length };
78
+ }
79
+
80
+ // Builds the argv for `npx skills@latest add <source> ...`. Always passes
81
+ // `--skill <name>` as separate argv entries (never `--skill=<name>`): current
82
+ // `skills` CLI versions have a parsing bug where the `--skill=<name>` form is
83
+ // silently ignored and installs every skill in the source repository,
84
+ // including skills/in-progress, skills/misc, and skills/deprecated.
85
+ function buildAddArgs(skillNames) {
86
+ return [
87
+ '-y', // npx: auto-confirm installing the `skills` package itself
88
+ 'skills@latest',
89
+ 'add',
90
+ MATT_SKILLS_SOURCE,
91
+ '--skill', ...skillNames,
92
+ '--agent', ...SUPPORTED_AGENTS,
93
+ '-y' // skills CLI: skip its own confirmation prompts
94
+ ];
95
+ }
96
+
97
+ function formatCommand(args) {
98
+ return `${npxCommand()} ${args.join(' ')}`;
99
+ }
100
+
101
+ function runNpx(args, options = {}) {
102
+ return spawnSync(npxCommand(), args, {
103
+ cwd: options.cwd,
104
+ encoding: 'utf8',
105
+ stdio: options.stdio || 'pipe',
106
+ shell: process.platform === 'win32'
107
+ });
108
+ }
109
+
110
+ // Installs the full promoted set in a single `add` call (one clone, one
111
+ // filtered install). Never uses `--all`, which would also install
112
+ // in-progress/misc/deprecated skills.
113
+ function installSkills(targetDir, options = {}) {
114
+ const dryRun = options.dryRun === true;
115
+ const args = buildAddArgs(PROMOTED_SKILLS);
116
+ const command = formatCommand(args);
117
+
118
+ if (dryRun) {
119
+ return { ok: true, dryRun: true, command, message: `Dry run: would run ${command}` };
120
+ }
121
+
122
+ const result = runNpx(args, { cwd: targetDir, stdio: 'inherit' });
123
+ if (result.error || result.status !== 0) {
124
+ return { ok: false, dryRun: false, command, message: `failed to install promoted skills; run manually: ${command}` };
125
+ }
126
+ return {
127
+ ok: true,
128
+ dryRun: false,
129
+ command,
130
+ message: `installed ${PROMOTED_SKILLS.length} promoted Matt Pocock skills to ${SKILLS_RELATIVE_DIR}`
131
+ };
132
+ }
133
+
134
+ // Updates each promoted skill by re-adding it individually and idempotently.
135
+ // This is deliberately NOT `npx skills update`: upstream has a known issue
136
+ // where updating one project skill can reinstall every skill from the
137
+ // source. Re-adding by explicit single-skill name only ever touches that
138
+ // skill's directory (verified manually against the upstream CLI).
139
+ // Trade-off: this does one network clone of the source repo per promoted
140
+ // skill (~PROMOTED_SKILLS.length calls), so it is noticeably slower than
141
+ // `installSkills`'s single batched call. That cost is accepted deliberately
142
+ // for the safety guarantee above; revisit only if upstream ships a scoped,
143
+ // non-destructive `update`.
144
+ function updateSkills(targetDir, options = {}) {
145
+ const dryRun = options.dryRun === true;
146
+ const results = [];
147
+
148
+ for (const name of PROMOTED_SKILLS) {
149
+ const args = buildAddArgs([name]);
150
+ const command = formatCommand(args);
151
+
152
+ if (dryRun) {
153
+ results.push({ name, ok: true, dryRun: true, command });
154
+ continue;
155
+ }
156
+
157
+ const result = runNpx(args, { cwd: targetDir, stdio: 'pipe' });
158
+ const ok = !result.error && result.status === 0;
159
+ results.push({
160
+ name,
161
+ ok,
162
+ dryRun: false,
163
+ command,
164
+ error: ok ? null : (result.stderr || result.stdout || `exit ${result.status}`)
165
+ });
166
+ }
167
+
168
+ const failed = results.filter(r => !r.ok);
169
+ const message = dryRun
170
+ ? `Dry run: would update ${PROMOTED_SKILLS.length} promoted skills one by one`
171
+ : failed.length === 0
172
+ ? `updated ${PROMOTED_SKILLS.length} promoted Matt Pocock skills`
173
+ : `updated ${results.length - failed.length}/${PROMOTED_SKILLS.length} promoted skills; failed: ${failed.map(f => f.name).join(', ')}`;
174
+
175
+ return { ok: failed.length === 0, dryRun, results, message };
176
+ }
177
+
178
+ module.exports = {
179
+ MATT_SKILLS_SOURCE,
180
+ PROMOTED_SKILLS,
181
+ SUPPORTED_AGENTS,
182
+ SKILLS_RELATIVE_DIR,
183
+ SETUP_SKILL_NAME,
184
+ npxCommand,
185
+ skillsDirFor,
186
+ isSkillInstalled,
187
+ checkSkills,
188
+ buildAddArgs,
189
+ formatCommand,
190
+ installSkills,
191
+ updateSkills
192
+ };