@adityaaria/spark 6.0.7 → 6.0.9
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +1 -1
- package/.kimi-plugin/plugin.json +2 -2
- package/LICENSE +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/installer/adapters/common.js +12 -0
- package/src/installer/adapters/shell-hook.js +1 -1
- package/src/installer/adapters/vscode-staging.js +16 -9
- package/src/installer/detect.js +35 -16
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "spark-dev",
|
|
3
3
|
"description": "Development marketplace for SPARK core skills library",
|
|
4
4
|
"owner": {
|
|
5
|
-
"name": "
|
|
5
|
+
"name": "Aditya Aria",
|
|
6
6
|
"email": "jesse@fsck.com"
|
|
7
7
|
},
|
|
8
8
|
"plugins": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"version": "6.0.3",
|
|
13
13
|
"source": "./",
|
|
14
14
|
"author": {
|
|
15
|
-
"name": "
|
|
15
|
+
"name": "Aditya Aria",
|
|
16
16
|
"email": "jesse@fsck.com"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Core skills library for Claude Code: TDD, debugging, collaboration patterns, and proven techniques",
|
|
4
4
|
"version": "6.0.3",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
6
|
+
"name": "Aditya Aria",
|
|
7
7
|
"email": "jesse@fsck.com"
|
|
8
8
|
},
|
|
9
9
|
"homepage": "https://github.com/adityaaria/SPARK",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "6.0.3",
|
|
4
4
|
"description": "An agentic skills framework & software development methodology that works: planning, TDD, debugging, and collaboration workflows.",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
6
|
+
"name": "Aditya Aria",
|
|
7
7
|
"email": "jesse@fsck.com",
|
|
8
8
|
"url": "https://github.com/adityaaria"
|
|
9
9
|
},
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"displayName": "SPARK",
|
|
27
27
|
"shortDescription": "Planning, TDD, debugging, and delivery workflows for coding agents",
|
|
28
28
|
"longDescription": "Use SPARK to guide agent work through brainstorming, implementation planning, test-driven development, systematic debugging, parallel execution, code review, and finish-the-branch workflows.",
|
|
29
|
-
"developerName": "
|
|
29
|
+
"developerName": "Aditya Aria",
|
|
30
30
|
"category": "Coding",
|
|
31
31
|
"capabilities": [
|
|
32
32
|
"Interactive",
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"description": "Core skills library: TDD, debugging, collaboration patterns, and proven techniques",
|
|
5
5
|
"version": "6.0.3",
|
|
6
6
|
"author": {
|
|
7
|
-
"name": "
|
|
7
|
+
"name": "Aditya Aria",
|
|
8
8
|
"email": "jesse@fsck.com"
|
|
9
9
|
},
|
|
10
10
|
"homepage": "https://github.com/adityaaria/SPARK",
|
package/.kimi-plugin/plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"version": "6.0.3",
|
|
4
4
|
"description": "An agentic skills framework and software development methodology.",
|
|
5
5
|
"author": {
|
|
6
|
-
"name": "
|
|
6
|
+
"name": "Aditya Aria",
|
|
7
7
|
"email": "jesse@fsck.com"
|
|
8
8
|
},
|
|
9
9
|
"homepage": "https://github.com/adityaaria/SPARK",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"displayName": "SPARK",
|
|
28
28
|
"shortDescription": "Planning, TDD, debugging, and delivery workflows for coding agents",
|
|
29
29
|
"longDescription": "Use SPARK to guide agent work through brainstorming, implementation planning, test-driven development, systematic debugging, parallel execution, code review, and finish-the-branch workflows.",
|
|
30
|
-
"developerName": "
|
|
30
|
+
"developerName": "Aditya Aria",
|
|
31
31
|
"capabilities": [
|
|
32
32
|
"Interactive",
|
|
33
33
|
"Read",
|
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -276,7 +276,7 @@ MIT License - see LICENSE file for details
|
|
|
276
276
|
|
|
277
277
|
## Community
|
|
278
278
|
|
|
279
|
-
SPARK is built by [
|
|
279
|
+
SPARK is built by [Aditya Aria](https://blog.fsck.com) and contributors.
|
|
280
280
|
|
|
281
281
|
- **Community**: Use the repository issues and discussions for support, questions, and sharing what you're building with SPARK
|
|
282
282
|
- **Issues**: https://github.com/adityaaria/SPARK/issues
|
package/package.json
CHANGED
|
@@ -66,6 +66,18 @@ export function createAdapter({
|
|
|
66
66
|
encoding: 'utf8',
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
+
if (result.error) {
|
|
70
|
+
if (result.error.code === 'ENOENT') {
|
|
71
|
+
throw new InstallerError(
|
|
72
|
+
`\n\u2715 ${label} install failed: Command '${entry.file}' not found.\n` +
|
|
73
|
+
`SPARK requires ${label} to be installed first.\n` +
|
|
74
|
+
`Please install ${label} from its official source (e.g. npm install -g <package-name>)\n` +
|
|
75
|
+
`and ensure '${entry.file}' is in your PATH before retrying.\n`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
throw new InstallerError(`${label} install failed: ${result.error.message}`);
|
|
79
|
+
}
|
|
80
|
+
|
|
69
81
|
if (result.status !== 0) {
|
|
70
82
|
throw new InstallerError(
|
|
71
83
|
`${label} install failed: ${result.stderr || result.stdout || 'unknown error'}`
|
|
@@ -78,7 +78,7 @@ export function createVsCodeAdapter() {
|
|
|
78
78
|
label: 'VS Code',
|
|
79
79
|
kind: 'shell-hook',
|
|
80
80
|
bootstrap: 'workspace plugin bundle -> VS Code chat.pluginLocations -> hooks/session-start -> using-spark',
|
|
81
|
-
installHint: 'A
|
|
81
|
+
installHint: 'A standard plugin bundle is staged locally and registered through .vscode/settings.json chat.pluginLocations.',
|
|
82
82
|
verifyHint: 'Open a fresh VS Code agent session and confirm using-spark loads before coding.',
|
|
83
83
|
successMessage: 'SPARK is ready in VS Code.',
|
|
84
84
|
automatedSteps: [
|
|
@@ -4,12 +4,12 @@ import path from 'node:path';
|
|
|
4
4
|
const VSCODE_PLUGIN_DIR = path.join('.spark', 'vscode-plugin');
|
|
5
5
|
const SETTINGS_PATH = path.join('.vscode', 'settings.json');
|
|
6
6
|
const COPY_PATHS = [
|
|
7
|
-
'.claude-plugin',
|
|
8
|
-
'assets',
|
|
9
|
-
path.join('hooks', 'hooks.json'),
|
|
10
|
-
path.join('hooks', 'run-hook.cmd'),
|
|
11
|
-
path.join('hooks', 'session-start'),
|
|
12
|
-
'skills',
|
|
7
|
+
{ src: '.claude-plugin', dest: '.vscode-plugin' },
|
|
8
|
+
{ src: 'assets', dest: 'assets' },
|
|
9
|
+
{ src: path.join('hooks', 'hooks.json'), dest: path.join('hooks', 'hooks.json') },
|
|
10
|
+
{ src: path.join('hooks', 'run-hook.cmd'), dest: path.join('hooks', 'run-hook.cmd') },
|
|
11
|
+
{ src: path.join('hooks', 'session-start'), dest: path.join('hooks', 'session-start') },
|
|
12
|
+
{ src: 'skills', dest: 'skills' },
|
|
13
13
|
];
|
|
14
14
|
|
|
15
15
|
export function installVsCodePlugin({ cwd = process.cwd(), packageRoot, dryRun = false }) {
|
|
@@ -19,9 +19,9 @@ export function installVsCodePlugin({ cwd = process.cwd(), packageRoot, dryRun =
|
|
|
19
19
|
if (!dryRun) {
|
|
20
20
|
fs.mkdirSync(targetRoot, { recursive: true });
|
|
21
21
|
|
|
22
|
-
for (const
|
|
23
|
-
const sourcePath = path.join(packageRoot,
|
|
24
|
-
const targetPath = path.join(targetRoot,
|
|
22
|
+
for (const mapping of COPY_PATHS) {
|
|
23
|
+
const sourcePath = path.join(packageRoot, mapping.src);
|
|
24
|
+
const targetPath = path.join(targetRoot, mapping.dest);
|
|
25
25
|
const stat = fs.statSync(sourcePath);
|
|
26
26
|
|
|
27
27
|
if (stat.isDirectory()) {
|
|
@@ -34,6 +34,13 @@ export function installVsCodePlugin({ cwd = process.cwd(), packageRoot, dryRun =
|
|
|
34
34
|
fs.chmodSync(targetPath, stat.mode);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
const targetPluginJsonPath = path.join(targetRoot, '.vscode-plugin', 'plugin.json');
|
|
38
|
+
if (fs.existsSync(targetPluginJsonPath)) {
|
|
39
|
+
const pluginData = JSON.parse(fs.readFileSync(targetPluginJsonPath, 'utf8'));
|
|
40
|
+
pluginData.description = "Core skills library for VS Code: TDD, debugging, collaboration patterns, and proven techniques";
|
|
41
|
+
fs.writeFileSync(targetPluginJsonPath, JSON.stringify(pluginData, null, 2) + '\n', 'utf8');
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
writeVsCodeSettings(settingsPath, targetRoot);
|
|
38
45
|
}
|
|
39
46
|
|
package/src/installer/detect.js
CHANGED
|
@@ -33,8 +33,9 @@ export async function chooseHarness({
|
|
|
33
33
|
throw new InstallerError('No harness selected. Re-run with --harness or use an interactive terminal.');
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const homeDir = os.homedir();
|
|
36
37
|
const detectedCandidates = detectHarnessCandidates({ env, fsImpl: fs });
|
|
37
|
-
const candidates = buildPromptCandidates(detectedCandidates);
|
|
38
|
+
const candidates = buildPromptCandidates(detectedCandidates, env, fs, homeDir);
|
|
38
39
|
|
|
39
40
|
let validationMessage = null;
|
|
40
41
|
while (true) {
|
|
@@ -51,6 +52,8 @@ function scoreAdapter(adapter, env, fsImpl, homeDir) {
|
|
|
51
52
|
let score = 0;
|
|
52
53
|
const reasons = [];
|
|
53
54
|
|
|
55
|
+
let missingBinaries = false;
|
|
56
|
+
|
|
54
57
|
for (const key of adapter.envKeys) {
|
|
55
58
|
if (env[key]) {
|
|
56
59
|
score += 100;
|
|
@@ -58,10 +61,15 @@ function scoreAdapter(adapter, env, fsImpl, homeDir) {
|
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
63
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
if (adapter.binaryNames && adapter.binaryNames.length > 0) {
|
|
65
|
+
missingBinaries = true;
|
|
66
|
+
for (const binaryName of adapter.binaryNames) {
|
|
67
|
+
if (commandExists(binaryName, env, fsImpl)) {
|
|
68
|
+
score += 70;
|
|
69
|
+
reasons.push(`path:${binaryName}`);
|
|
70
|
+
missingBinaries = false;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -80,6 +88,7 @@ function scoreAdapter(adapter, env, fsImpl, homeDir) {
|
|
|
80
88
|
label: adapter.label,
|
|
81
89
|
score,
|
|
82
90
|
reasons,
|
|
91
|
+
missingBinaries,
|
|
83
92
|
};
|
|
84
93
|
}
|
|
85
94
|
|
|
@@ -129,7 +138,7 @@ function commandExists(commandName, env, fsImpl) {
|
|
|
129
138
|
return false;
|
|
130
139
|
}
|
|
131
140
|
|
|
132
|
-
function buildPromptCandidates(detectedCandidates) {
|
|
141
|
+
function buildPromptCandidates(detectedCandidates, env, fsImpl, homeDir) {
|
|
133
142
|
const allAdapters = listAdapters();
|
|
134
143
|
const detectedIds = new Set(detectedCandidates.map((candidate) => candidate.id));
|
|
135
144
|
|
|
@@ -137,12 +146,12 @@ function buildPromptCandidates(detectedCandidates) {
|
|
|
137
146
|
...detectedCandidates,
|
|
138
147
|
...allAdapters
|
|
139
148
|
.filter((adapter) => !detectedIds.has(adapter.id))
|
|
140
|
-
.map((adapter) =>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
})
|
|
149
|
+
.map((adapter) => {
|
|
150
|
+
const result = scoreAdapter(adapter, env, fsImpl, homeDir);
|
|
151
|
+
result.score = 0;
|
|
152
|
+
result.reasons = [];
|
|
153
|
+
return result;
|
|
154
|
+
}),
|
|
146
155
|
];
|
|
147
156
|
}
|
|
148
157
|
|
|
@@ -163,14 +172,19 @@ function renderPrompt(candidates, validationMessage = null) {
|
|
|
163
172
|
}
|
|
164
173
|
|
|
165
174
|
for (const [index, candidate] of candidates.entries()) {
|
|
175
|
+
let label = candidate.label;
|
|
176
|
+
if (candidate.missingBinaries) {
|
|
177
|
+
label += ' [Missing CLI]';
|
|
178
|
+
}
|
|
179
|
+
|
|
166
180
|
const hint = recommendedIds.has(candidate.id) ? 'recommended' : null;
|
|
167
181
|
lines.push(
|
|
168
182
|
promptOption(
|
|
169
183
|
index + 1,
|
|
170
|
-
|
|
184
|
+
label,
|
|
171
185
|
candidate.id,
|
|
172
186
|
hint,
|
|
173
|
-
describeHarness(candidate.id)
|
|
187
|
+
describeHarness(candidate.id, candidate.missingBinaries)
|
|
174
188
|
)
|
|
175
189
|
);
|
|
176
190
|
}
|
|
@@ -197,7 +211,7 @@ function resolvePromptAnswer(answer, candidates) {
|
|
|
197
211
|
return getAdapterById(exact.id);
|
|
198
212
|
}
|
|
199
213
|
|
|
200
|
-
function describeHarness(id) {
|
|
214
|
+
function describeHarness(id, missingBinaries = false) {
|
|
201
215
|
const descriptions = {
|
|
202
216
|
claude: 'Best for Claude Code sessions and project-local plugin workflows.',
|
|
203
217
|
codex: 'For the Codex CLI plugin marketplace flow in terminal sessions.',
|
|
@@ -210,7 +224,12 @@ function describeHarness(id) {
|
|
|
210
224
|
antigravity: 'Installs the Antigravity plugin and loads SPARK on new sessions.',
|
|
211
225
|
};
|
|
212
226
|
|
|
213
|
-
|
|
227
|
+
let description = descriptions[id] ?? null;
|
|
228
|
+
if (description && missingBinaries) {
|
|
229
|
+
description += '\n ⚠️ Requires its official CLI to be installed first.';
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return description;
|
|
214
233
|
}
|
|
215
234
|
|
|
216
235
|
function normalizeHarness(value) {
|