harness-everything 0.2.1 → 0.2.2

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.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/build-multi-agent-system/SKILL.md +68 -68
  3. package/create-agent-launcher/SKILL.md +48 -48
  4. package/docs/architecture.md +2 -2
  5. package/docs/workflows/build-multi-agent-system.md +62 -62
  6. package/docs/workflows/create-agent-launcher.md +62 -62
  7. package/docs/workflows/environment-detection.md +63 -63
  8. package/docs/workflows/eval-harness.md +57 -57
  9. package/docs/workflows/fable-discipline.md +59 -59
  10. package/docs/workflows/fable-mode.md +32 -32
  11. package/docs/workflows/git-commit.md +62 -62
  12. package/docs/workflows/grill-me.md +62 -62
  13. package/docs/workflows/grill-with-docs.md +62 -62
  14. package/docs/workflows/improve-codebase-architecture.md +60 -60
  15. package/docs/workflows/repo-docs.md +59 -59
  16. package/docs/workflows/rewrite-commits.md +60 -60
  17. package/docs/workflows/security-review.md +58 -58
  18. package/docs/workflows/self-evolve.md +59 -59
  19. package/docs/workflows/tdd.md +39 -39
  20. package/docs/workflows/todo-driven-workflow.md +36 -36
  21. package/docs/workflows/using-git-worktrees.md +63 -63
  22. package/docs/workflows/verification-loop.md +69 -69
  23. package/docs/workflows/verify-before-claim.md +60 -60
  24. package/docs/workflows/zoom-out.md +62 -62
  25. package/environment-detection/SKILL.md +77 -77
  26. package/eval-framework/behavioral-test.js +105 -105
  27. package/eval-framework/mechanism-test.js +251 -251
  28. package/eval-harness/SKILL.md +59 -59
  29. package/fable-discipline/SKILL.md +38 -38
  30. package/fable-mode/SKILL.md +51 -51
  31. package/git-commit/SKILL.md +55 -55
  32. package/grill-me/SKILL.md +36 -36
  33. package/grill-with-docs/SKILL.md +99 -99
  34. package/harness-everything/SKILL.md +141 -141
  35. package/harness-everything/examples/README.md +9 -9
  36. package/harness-everything/examples/todo-workflow.md +22 -22
  37. package/harness-everything/scripts/todo-cli.js +157 -157
  38. package/harness-everything/scripts/verify-gate.js +31 -31
  39. package/hooks/scripts/atomic-commit-check.js +68 -68
  40. package/hooks/scripts/context-compact.js +114 -114
  41. package/hooks/scripts/lib/platforms/claude.js +132 -42
  42. package/hooks/scripts/lib/platforms/codex.js +96 -46
  43. package/hooks/scripts/lib/platforms/continue.js +73 -41
  44. package/hooks/scripts/lib/platforms/copilot.js +91 -41
  45. package/hooks/scripts/lib/platforms/cursor.js +71 -41
  46. package/hooks/scripts/lib/platforms/hermes.js +25 -0
  47. package/hooks/scripts/rule-of-3.js +176 -176
  48. package/improve-codebase-architecture/SKILL.md +44 -44
  49. package/install-cognitive-os/SKILL.md +95 -95
  50. package/package.json +1 -1
  51. package/repo-docs/SKILL.md +45 -45
  52. package/rewrite-commits/SKILL.md +32 -32
  53. package/scripts/installer.js +57 -200
  54. package/scripts/lib/advisory-text.js +163 -163
  55. package/scripts/lib/claude-hooks.js +71 -71
  56. package/scripts/lib/manifest.js +82 -82
  57. package/scripts/lib/prompts.js +241 -241
  58. package/scripts/lib/skills.js +174 -172
  59. package/scripts/lib/workspace.js +28 -28
  60. package/security-review/SKILL.md +510 -510
  61. package/self-evolve/SKILL.md +54 -54
  62. package/skill-creator/SKILL.md +91 -91
  63. package/skill-creator/references/testing-workflow.md +32 -32
  64. package/skill-style/SKILL.md +48 -48
  65. package/tdd/SKILL.md +53 -53
  66. package/todo-driven-workflow/SKILL.md +54 -54
  67. package/using-git-worktrees/SKILL.md +161 -161
  68. package/verification-loop/SKILL.md +138 -138
  69. package/verify-before-claim/SKILL.md +86 -86
  70. package/zoom-out/SKILL.md +90 -90
@@ -1,172 +1,174 @@
1
- // Skill discovery, copy, and manifest-aware install/uninstall bookkeeping.
2
- const fs = require('fs');
3
- const path = require('path');
4
- const manifest = require('./manifest');
5
-
6
- function copyDir(src, dest) {
7
- fs.mkdirSync(dest, { recursive: true });
8
- const entries = fs.readdirSync(src, { withFileTypes: true });
9
- for (const entry of entries) {
10
- const srcPath = path.join(src, entry.name);
11
- const destPath = path.join(dest, entry.name);
12
- if (entry.isDirectory()) {
13
- copyDir(srcPath, destPath);
14
- } else {
15
- fs.copyFileSync(srcPath, destPath);
16
- }
17
- }
18
- }
19
-
20
- function getAvailableSkills(harnessSourceDir) {
21
- const dirs = fs.readdirSync(harnessSourceDir, { withFileTypes: true });
22
- const skills = [];
23
- for (const dir of dirs) {
24
- if (dir.isDirectory() && !dir.name.startsWith('.') && !['bin', 'docs', 'hooks', 'scripts', 'node_modules'].includes(dir.name)) {
25
- const skillPath = path.join(harnessSourceDir, dir.name, 'SKILL.md');
26
- if (fs.existsSync(skillPath)) {
27
- skills.push(dir.name);
28
- }
29
- }
30
- }
31
- return skills.sort();
32
- }
33
-
34
- function parseFrontmatter(skillMdPath) {
35
- if (!fs.existsSync(skillMdPath)) return null;
36
- try {
37
- const content = fs.readFileSync(skillMdPath, 'utf8');
38
- const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
39
- if (!match) return null;
40
- const yaml = match[1];
41
- const get = (key) => {
42
- const m = yaml.match(new RegExp(`^${key}:\\s*(.*)$`, 'm'));
43
- return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
44
- };
45
- return { name: get('name'), description: get('description'), author: get('author'), version: get('version') };
46
- } catch (e) {
47
- return null;
48
- }
49
- }
50
-
51
- function getSkillInfo(harnessSourceDir, skillDirName) {
52
- const fm = parseFrontmatter(path.join(harnessSourceDir, skillDirName, 'SKILL.md'));
53
- if (!fm) return null;
54
- return { id: skillDirName, name: fm.name || skillDirName, description: fm.description || '' };
55
- }
56
-
57
- // The one signal that lets uninstall tell "a skill this package shipped"
58
- // apart from anything else living in the same shared skills folder (Cursor/
59
- // Copilot/Codex/Continue skills keep their platform-native location, so it's
60
- // still a shared folder) - including a user's own manually-installed skills
61
- // and self-evolve's locally-generated `skills/generated/*` skills, neither
62
- // of which carry this author string.
63
- function isHarnessSkillDir(dirPath) {
64
- const fm = parseFrontmatter(path.join(dirPath, 'SKILL.md'));
65
- return !!fm && fm.author === manifest.HARNESS_AUTHOR;
66
- }
67
-
68
- // targetDirs entries: { path, label, manifestPath } - manifestPath is that
69
- // target's own <platform-home>/harness-everything/manifest.json.
70
- function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion }) {
71
- for (const target of targetDirs) {
72
- fs.mkdirSync(target.path, { recursive: true });
73
- for (const skillName of chosenSkills) {
74
- const src = path.join(harnessSourceDir, skillName);
75
- const dest = path.join(target.path, skillName);
76
- if (fs.existsSync(dest)) {
77
- fs.rmSync(dest, { recursive: true, force: true });
78
- }
79
- copyDir(src, dest);
80
- manifest.recordSkillInstall(target.manifestPath, packageVersion, skillName, dest);
81
- console.log(` ✅ Installed skill: ${target.label}${skillName}/`);
82
- }
83
- }
84
- }
85
-
86
- function manifestTrackedSkills(manifestPath, scopeLabel) {
87
- const data = manifest.readManifest(manifestPath);
88
- const results = [];
89
- for (const entry of data.skills || []) {
90
- if (fs.existsSync(entry.dirPath) && isHarnessSkillDir(entry.dirPath)) {
91
- results.push({ id: entry.id, scope: scopeLabel, dirPath: entry.dirPath, parentPath: path.dirname(entry.dirPath), manifestPath });
92
- }
93
- }
94
- return results;
95
- }
96
-
97
- // Returns every skill this package can currently account for, scoped local +
98
- // global. Never lists a directory just because it happens to live under a
99
- // known skills folder - only manifest-recorded installs (or, as a fallback
100
- // for pre-manifest / pre-reorg installs, directories that still self-identify
101
- // via the author marker) qualify. This is what keeps "uninstall skills" from
102
- // ever touching a skill this package didn't put there.
103
- function getInstalledSkills(workspaceRoot, userHome) {
104
- const results = [];
105
- const globalAgentsDir = path.join(userHome, '.agents');
106
-
107
- const manifestHomes = [
108
- { home: path.join(workspaceRoot, '.claude'), scope: 'local (Claude)' },
109
- { home: path.join(workspaceRoot, '.cursor'), scope: 'local (Cursor)' },
110
- { home: path.join(workspaceRoot, '.github'), scope: 'local (Copilot)' },
111
- { home: path.join(workspaceRoot, '.codex'), scope: 'local (Codex)' },
112
- { home: path.join(workspaceRoot, '.continue'), scope: 'local (Continue)' },
113
- { home: globalAgentsDir, scope: 'global' },
114
- ];
115
- for (const { home, scope } of manifestHomes) {
116
- results.push(...manifestTrackedSkills(manifest.getManifestPath(home), scope));
117
- }
118
-
119
- // Legacy fallback for installs that predate per-platform manifests (or the
120
- // old self-invented .harness/ local root, or - for Codex specifically - an
121
- // earlier version's mistaken `.agents/skills` target; Codex's real project
122
- // skills directory is `.codex/skills/`): scan the raw directories
123
- // directly, but only ever list an entry that still self-identifies via the
124
- // author marker - never a blind directory listing.
125
- const legacyDirs = [
126
- { path: path.join(workspaceRoot, '.harness', 'skills'), scope: 'local (legacy .harness)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
127
- { path: path.join(workspaceRoot, '.cursor', 'skills'), scope: 'local (Cursor)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.cursor')) },
128
- { path: path.join(workspaceRoot, '.github', 'skills'), scope: 'local (Copilot)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.github')) },
129
- { path: path.join(workspaceRoot, '.codex', 'skills'), scope: 'local (Codex)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
130
- { path: path.join(workspaceRoot, '.agents', 'skills'), scope: 'local (Codex, legacy .agents path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
131
- { path: path.join(workspaceRoot, '.continue', 'skills'), scope: 'local (Continue)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.continue')) },
132
- { path: path.join(globalAgentsDir, 'skills'), scope: 'global', manifestPath: manifest.getManifestPath(globalAgentsDir) },
133
- ];
134
- const known = new Set(results.map(r => r.dirPath));
135
- for (const item of legacyDirs) {
136
- if (!fs.existsSync(item.path)) continue;
137
- try {
138
- const entries = fs.readdirSync(item.path, { withFileTypes: true });
139
- for (const entry of entries) {
140
- if (!entry.isDirectory()) continue;
141
- const dirPath = path.join(item.path, entry.name);
142
- if (known.has(dirPath)) continue;
143
- if (isHarnessSkillDir(dirPath)) {
144
- results.push({ id: entry.name, scope: item.scope, dirPath, parentPath: item.path, manifestPath: item.manifestPath });
145
- known.add(dirPath);
146
- }
147
- }
148
- } catch (e) {
149
- // ignore unreadable dirs
150
- }
151
- }
152
- return results;
153
- }
154
-
155
- function removeSkill(entry) {
156
- if (fs.existsSync(entry.dirPath)) {
157
- fs.rmSync(entry.dirPath, { recursive: true, force: true });
158
- }
159
- if (entry.manifestPath) {
160
- manifest.removeSkillFromManifest(entry.manifestPath, entry.dirPath);
161
- }
162
- }
163
-
164
- module.exports = {
165
- copyDir,
166
- getAvailableSkills,
167
- getSkillInfo,
168
- isHarnessSkillDir,
169
- installSkillsToTargets,
170
- getInstalledSkills,
171
- removeSkill,
172
- };
1
+ // Skill discovery, copy, and manifest-aware install/uninstall bookkeeping.
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const manifest = require('./manifest');
5
+
6
+ function copyDir(src, dest) {
7
+ fs.mkdirSync(dest, { recursive: true });
8
+ const entries = fs.readdirSync(src, { withFileTypes: true });
9
+ for (const entry of entries) {
10
+ const srcPath = path.join(src, entry.name);
11
+ const destPath = path.join(dest, entry.name);
12
+ if (entry.isDirectory()) {
13
+ copyDir(srcPath, destPath);
14
+ } else {
15
+ fs.copyFileSync(srcPath, destPath);
16
+ }
17
+ }
18
+ }
19
+
20
+ function getAvailableSkills(harnessSourceDir) {
21
+ const dirs = fs.readdirSync(harnessSourceDir, { withFileTypes: true });
22
+ const skills = [];
23
+ for (const dir of dirs) {
24
+ if (dir.isDirectory() && !dir.name.startsWith('.') && !['bin', 'docs', 'hooks', 'scripts', 'node_modules'].includes(dir.name)) {
25
+ const skillPath = path.join(harnessSourceDir, dir.name, 'SKILL.md');
26
+ if (fs.existsSync(skillPath)) {
27
+ skills.push(dir.name);
28
+ }
29
+ }
30
+ }
31
+ return skills.sort();
32
+ }
33
+
34
+ function parseFrontmatter(skillMdPath) {
35
+ if (!fs.existsSync(skillMdPath)) return null;
36
+ try {
37
+ const content = fs.readFileSync(skillMdPath, 'utf8');
38
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
39
+ if (!match) return null;
40
+ const yaml = match[1];
41
+ const get = (key) => {
42
+ const m = yaml.match(new RegExp(`^${key}:\\s*(.*)$`, 'm'));
43
+ return m ? m[1].trim().replace(/^['"]|['"]$/g, '') : '';
44
+ };
45
+ return { name: get('name'), description: get('description'), author: get('author'), version: get('version') };
46
+ } catch (e) {
47
+ return null;
48
+ }
49
+ }
50
+
51
+ function getSkillInfo(harnessSourceDir, skillDirName) {
52
+ const fm = parseFrontmatter(path.join(harnessSourceDir, skillDirName, 'SKILL.md'));
53
+ if (!fm) return null;
54
+ return { id: skillDirName, name: fm.name || skillDirName, description: fm.description || '' };
55
+ }
56
+
57
+ // The one signal that lets uninstall tell "a skill this package shipped"
58
+ // apart from anything else living in the same shared skills folder (Cursor/
59
+ // Copilot/Codex/Continue skills keep their platform-native location, so it's
60
+ // still a shared folder) - including a user's own manually-installed skills
61
+ // and self-evolve's locally-generated `skills/generated/*` skills, neither
62
+ // of which carry this author string.
63
+ function isHarnessSkillDir(dirPath) {
64
+ const fm = parseFrontmatter(path.join(dirPath, 'SKILL.md'));
65
+ return !!fm && fm.author === manifest.HARNESS_AUTHOR;
66
+ }
67
+
68
+ // targetDirs entries: { path, label, manifestPath } - manifestPath is that
69
+ // target's own <platform-home>/harness-everything/manifest.json.
70
+ function installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion }) {
71
+ for (const target of targetDirs) {
72
+ fs.mkdirSync(target.path, { recursive: true });
73
+ for (const skillName of chosenSkills) {
74
+ const src = path.join(harnessSourceDir, skillName);
75
+ const dest = path.join(target.path, skillName);
76
+ if (fs.existsSync(dest)) {
77
+ fs.rmSync(dest, { recursive: true, force: true });
78
+ }
79
+ copyDir(src, dest);
80
+ manifest.recordSkillInstall(target.manifestPath, packageVersion, skillName, dest);
81
+ console.log(` ✅ Installed skill: ${target.label}${skillName}/`);
82
+ }
83
+ }
84
+ }
85
+
86
+ function manifestTrackedSkills(manifestPath, scopeLabel) {
87
+ const data = manifest.readManifest(manifestPath);
88
+ const results = [];
89
+ for (const entry of data.skills || []) {
90
+ if (fs.existsSync(entry.dirPath) && isHarnessSkillDir(entry.dirPath)) {
91
+ results.push({ id: entry.id, scope: scopeLabel, dirPath: entry.dirPath, parentPath: path.dirname(entry.dirPath), manifestPath });
92
+ }
93
+ }
94
+ return results;
95
+ }
96
+
97
+ // Returns every skill this package can currently account for, scoped local +
98
+ // global. Never lists a directory just because it happens to live under a
99
+ // known skills folder - only manifest-recorded installs (or, as a fallback
100
+ // for pre-manifest / pre-reorg installs, directories that still self-identify
101
+ // via the author marker) qualify. This is what keeps "uninstall skills" from
102
+ // ever touching a skill this package didn't put there.
103
+ function getInstalledSkills(workspaceRoot, userHome) {
104
+ const results = [];
105
+ const globalAgentsDir = path.join(userHome, '.agents');
106
+
107
+ const manifestHomes = [
108
+ { home: path.join(workspaceRoot, '.claude'), scope: 'local (Claude)' },
109
+ { home: path.join(workspaceRoot, '.cursor'), scope: 'local (Cursor)' },
110
+ { home: path.join(workspaceRoot, '.github'), scope: 'local (Copilot)' },
111
+ { home: path.join(workspaceRoot, '.codex'), scope: 'local (Codex)' },
112
+ { home: path.join(workspaceRoot, '.continue'), scope: 'local (Continue)' },
113
+ { home: path.join(userHome, '.claude'), scope: 'global (Claude)' },
114
+ { home: globalAgentsDir, scope: 'global' },
115
+ ];
116
+ for (const { home, scope } of manifestHomes) {
117
+ results.push(...manifestTrackedSkills(manifest.getManifestPath(home), scope));
118
+ }
119
+
120
+ // Legacy fallback for installs that predate per-platform manifests (or the
121
+ // old self-invented .harness/ local root, or - for Codex specifically - an
122
+ // earlier version's mistaken `.agents/skills` target; Codex's real project
123
+ // skills directory is `.codex/skills/`): scan the raw directories
124
+ // directly, but only ever list an entry that still self-identifies via the
125
+ // author marker - never a blind directory listing.
126
+ const legacyDirs = [
127
+ { path: path.join(workspaceRoot, '.harness', 'skills'), scope: 'local (legacy .harness)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
128
+ { path: path.join(workspaceRoot, '.claude', 'harness-everything', 'skills'), scope: 'local (Claude legacy erroneous path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.claude')) },
129
+ { path: path.join(workspaceRoot, '.cursor', 'skills'), scope: 'local (Cursor)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.cursor')) },
130
+ { path: path.join(workspaceRoot, '.github', 'skills'), scope: 'local (Copilot)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.github')) },
131
+ { path: path.join(workspaceRoot, '.codex', 'skills'), scope: 'local (Codex)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
132
+ { path: path.join(workspaceRoot, '.agents', 'skills'), scope: 'local (Codex, legacy .agents path)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.codex')) },
133
+ { path: path.join(workspaceRoot, '.continue', 'skills'), scope: 'local (Continue)', manifestPath: manifest.getManifestPath(path.join(workspaceRoot, '.continue')) },
134
+ { path: path.join(globalAgentsDir, 'skills'), scope: 'global', manifestPath: manifest.getManifestPath(globalAgentsDir) },
135
+ ];
136
+ const known = new Set(results.map(r => r.dirPath));
137
+ for (const item of legacyDirs) {
138
+ if (!fs.existsSync(item.path)) continue;
139
+ try {
140
+ const entries = fs.readdirSync(item.path, { withFileTypes: true });
141
+ for (const entry of entries) {
142
+ if (!entry.isDirectory()) continue;
143
+ const dirPath = path.join(item.path, entry.name);
144
+ if (known.has(dirPath)) continue;
145
+ if (isHarnessSkillDir(dirPath)) {
146
+ results.push({ id: entry.name, scope: item.scope, dirPath, parentPath: item.path, manifestPath: item.manifestPath });
147
+ known.add(dirPath);
148
+ }
149
+ }
150
+ } catch (e) {
151
+ // ignore unreadable dirs
152
+ }
153
+ }
154
+ return results;
155
+ }
156
+
157
+ function removeSkill(entry) {
158
+ if (fs.existsSync(entry.dirPath)) {
159
+ fs.rmSync(entry.dirPath, { recursive: true, force: true });
160
+ }
161
+ if (entry.manifestPath) {
162
+ manifest.removeSkillFromManifest(entry.manifestPath, entry.dirPath);
163
+ }
164
+ }
165
+
166
+ module.exports = {
167
+ copyDir,
168
+ getAvailableSkills,
169
+ getSkillInfo,
170
+ isHarnessSkillDir,
171
+ installSkillsToTargets,
172
+ getInstalledSkills,
173
+ removeSkill,
174
+ };
@@ -1,28 +1,28 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const os = require('os');
4
-
5
- function getWorkspaceRoot() {
6
- let dir = path.resolve(process.cwd());
7
- while (dir !== path.parse(dir).root) {
8
- if (fs.existsSync(path.join(dir, '.git'))) return dir;
9
- dir = path.dirname(dir);
10
- }
11
- return process.cwd();
12
- }
13
-
14
- function getUserPromptsDir() {
15
- if (process.env.VSCODE_USER_PROMPTS_FOLDER) {
16
- return process.env.VSCODE_USER_PROMPTS_FOLDER;
17
- }
18
- const home = os.homedir();
19
- if (process.platform === 'win32') {
20
- return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'prompts');
21
- } else if (process.platform === 'darwin') {
22
- return path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts');
23
- } else {
24
- return path.join(home, '.config', 'Code', 'User', 'prompts');
25
- }
26
- }
27
-
28
- module.exports = { getWorkspaceRoot, getUserPromptsDir };
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const os = require('os');
4
+
5
+ function getWorkspaceRoot() {
6
+ let dir = path.resolve(process.cwd());
7
+ while (dir !== path.parse(dir).root) {
8
+ if (fs.existsSync(path.join(dir, '.git'))) return dir;
9
+ dir = path.dirname(dir);
10
+ }
11
+ return process.cwd();
12
+ }
13
+
14
+ function getUserPromptsDir() {
15
+ if (process.env.VSCODE_USER_PROMPTS_FOLDER) {
16
+ return process.env.VSCODE_USER_PROMPTS_FOLDER;
17
+ }
18
+ const home = os.homedir();
19
+ if (process.platform === 'win32') {
20
+ return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'prompts');
21
+ } else if (process.platform === 'darwin') {
22
+ return path.join(home, 'Library', 'Application Support', 'Code', 'User', 'prompts');
23
+ } else {
24
+ return path.join(home, '.config', 'Code', 'User', 'prompts');
25
+ }
26
+ }
27
+
28
+ module.exports = { getWorkspaceRoot, getUserPromptsDir };