@adityaaria/spark 6.0.6 → 6.0.8

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.
@@ -2,7 +2,7 @@
2
2
  "name": "spark-dev",
3
3
  "description": "Development marketplace for SPARK core skills library",
4
4
  "owner": {
5
- "name": "Jesse Vincent",
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": "Jesse Vincent",
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": "Jesse Vincent",
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": "Jesse Vincent",
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": "Jesse Vincent",
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": "Jesse Vincent",
7
+ "name": "Aditya Aria",
8
8
  "email": "jesse@fsck.com"
9
9
  },
10
10
  "homepage": "https://github.com/adityaaria/SPARK",
@@ -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": "Jesse Vincent",
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": "Jesse Vincent",
30
+ "developerName": "Aditya Aria",
31
31
  "capabilities": [
32
32
  "Interactive",
33
33
  "Read",
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Jesse Vincent
3
+ Copyright (c) 2025 Aditya Aria
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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 [Jesse Vincent](https://blog.fsck.com) and contributors.
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adityaaria/spark",
3
- "version": "6.0.6",
3
+ "version": "6.0.8",
4
4
  "description": "SPARK skills and runtime bootstrap for coding agents",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -139,12 +139,14 @@ function interpolatePlanText(text, metadata) {
139
139
  function buildReadyLines(adapter, plan, metadata) {
140
140
  const lines = [];
141
141
 
142
- if (metadata.relativeTargetRoot) {
142
+ if (metadata.relativeTargetRoot && adapter.id === 'vscode') {
143
+ lines.push(bullet(`Local VS Code bundle prepared at ${pathText(metadata.relativeTargetRoot)}.`));
144
+ } else if (metadata.relativeTargetRoot) {
143
145
  lines.push(bullet(`Plugin bundle staged at ${pathText(metadata.relativeTargetRoot)}.`));
144
146
  }
145
147
 
146
148
  if (metadata.relativeMarketplaceRoot) {
147
- lines.push(bullet(`Local Codex marketplace staged at ${pathText(metadata.relativeMarketplaceRoot)}.`));
149
+ lines.push(bullet(`Local marketplace staged at ${pathText(metadata.relativeMarketplaceRoot)}.`));
148
150
  }
149
151
 
150
152
  if (adapter.id === 'codex') {
@@ -152,6 +154,14 @@ function buildReadyLines(adapter, plan, metadata) {
152
154
  return lines;
153
155
  }
154
156
 
157
+ if (adapter.id === 'vscode') {
158
+ if (metadata.relativeSettingsPath) {
159
+ lines.push(bullet(`VS Code plugin registration was written to ${pathText(metadata.relativeSettingsPath)}.`));
160
+ }
161
+ lines.push(bullet('Open a fresh VS Code agent session to confirm using-spark loads before coding.'));
162
+ return lines;
163
+ }
164
+
155
165
  lines.push(bullet('Start a fresh session in the selected harness to confirm using-spark loads before coding.'));
156
166
  return lines;
157
167
  }
package/src/cli/output.js CHANGED
@@ -24,7 +24,7 @@ export function printHelp() {
24
24
  printLine('');
25
25
  printMuted('Without --harness, the installer will ask which AI assistance to target.');
26
26
  printLine('');
27
- printLine(labelValue('Supported', 'Codex, Cursor, Antigravity, Copilot, OpenCode, Gemini, Pi'));
27
+ printLine(labelValue('Supported', 'Claude Code, Codex CLI, VS Code, Cursor, Copilot CLI, OpenCode, Gemini CLI, Pi, Antigravity'));
28
28
  }
29
29
 
30
30
  export function printCommandHeader(title) {
@@ -101,9 +101,15 @@ export function formatPromptPrefix() {
101
101
  return `${styled('◆', 'spark')} ${styled('Select', 'pink', true)} ${styled('›', 'dimGray')} `;
102
102
  }
103
103
 
104
- export function promptOption(index, label, id, hint = null) {
104
+ export function promptOption(index, label, id, hint = null, detail = null) {
105
105
  const base = `${styled(`${index}.`, 'spark', true)} ${styled(label, 'white', true)} ${styled(`(${id})`, 'dimGray')}`;
106
- return hint ? `${base} ${styled(hint, 'warning')}` : base;
106
+ const header = hint ? `${base} ${styled(hint, 'warning')}` : base;
107
+
108
+ if (!detail) {
109
+ return header;
110
+ }
111
+
112
+ return `${header}\n ${styled(detail, 'dimGray')}`;
107
113
  }
108
114
 
109
115
  function styled(text, tone, bold = false) {
@@ -2,6 +2,7 @@ import { createAdapter } from './common.js';
2
2
  import { stageClaudePlugin } from './claude-staging.js';
3
3
  import { stageCodexPlugin } from './codex-staging.js';
4
4
  import { installCursorPlugin } from './cursor-staging.js';
5
+ import { installVsCodePlugin } from './vscode-staging.js';
5
6
  import { dirname, resolve } from 'node:path';
6
7
  import { fileURLToPath } from 'node:url';
7
8
 
@@ -42,14 +43,14 @@ export function createClaudeCodeAdapter() {
42
43
  export function createCodexAdapter() {
43
44
  return createAdapter({
44
45
  id: 'codex',
45
- label: 'Codex',
46
+ label: 'Codex CLI',
46
47
  kind: 'shell-hook',
47
48
  envKeys: ['CLAUDE_PLUGIN_ROOT'],
48
49
  binaryNames: ['codex'],
49
50
  bootstrap: 'shell hook -> hooks/session-start-codex -> using-spark',
50
51
  installHint: '.codex-plugin/plugin.json + hooks/hooks-codex.json + hooks/session-start-codex',
51
52
  verifyHint: 'Run a fresh Codex session and confirm using-spark loads before coding.',
52
- successMessage: 'Installed SPARK for Codex.',
53
+ successMessage: 'Installed SPARK for Codex CLI.',
53
54
  commands: [
54
55
  {
55
56
  file: 'codex',
@@ -71,6 +72,26 @@ export function createCodexAdapter() {
71
72
  });
72
73
  }
73
74
 
75
+ export function createVsCodeAdapter() {
76
+ return createAdapter({
77
+ id: 'vscode',
78
+ label: 'VS Code',
79
+ kind: 'shell-hook',
80
+ bootstrap: 'workspace plugin bundle -> VS Code chat.pluginLocations -> hooks/session-start -> using-spark',
81
+ installHint: 'A standard plugin bundle is staged locally and registered through .vscode/settings.json chat.pluginLocations.',
82
+ verifyHint: 'Open a fresh VS Code agent session and confirm using-spark loads before coding.',
83
+ successMessage: 'SPARK is ready in VS Code.',
84
+ automatedSteps: [
85
+ 'Prepare a local VS Code plugin bundle at .spark/vscode-plugin.',
86
+ 'Register that bundle in .vscode/settings.json via chat.pluginLocations.',
87
+ 'Start a fresh VS Code agent session so using-spark loads before coding.',
88
+ ],
89
+ customInstall({ cwd, dryRun }) {
90
+ return installVsCodePlugin({ cwd, packageRoot, dryRun });
91
+ },
92
+ });
93
+ }
94
+
74
95
  export function createCursorAdapter() {
75
96
  return createAdapter({
76
97
  id: 'cursor',
@@ -0,0 +1,75 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ const VSCODE_PLUGIN_DIR = path.join('.spark', 'vscode-plugin');
5
+ const SETTINGS_PATH = path.join('.vscode', 'settings.json');
6
+ const COPY_PATHS = [
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
+ ];
14
+
15
+ export function installVsCodePlugin({ cwd = process.cwd(), packageRoot, dryRun = false }) {
16
+ const targetRoot = path.join(cwd, VSCODE_PLUGIN_DIR);
17
+ const settingsPath = path.join(cwd, SETTINGS_PATH);
18
+
19
+ if (!dryRun) {
20
+ fs.mkdirSync(targetRoot, { recursive: true });
21
+
22
+ for (const mapping of COPY_PATHS) {
23
+ const sourcePath = path.join(packageRoot, mapping.src);
24
+ const targetPath = path.join(targetRoot, mapping.dest);
25
+ const stat = fs.statSync(sourcePath);
26
+
27
+ if (stat.isDirectory()) {
28
+ fs.cpSync(sourcePath, targetPath, { recursive: true });
29
+ continue;
30
+ }
31
+
32
+ fs.mkdirSync(path.dirname(targetPath), { recursive: true });
33
+ fs.copyFileSync(sourcePath, targetPath);
34
+ fs.chmodSync(targetPath, stat.mode);
35
+ }
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
+
44
+ writeVsCodeSettings(settingsPath, targetRoot);
45
+ }
46
+
47
+ return {
48
+ targetRoot,
49
+ relativeTargetRoot: VSCODE_PLUGIN_DIR,
50
+ settingsPath,
51
+ relativeSettingsPath: SETTINGS_PATH,
52
+ };
53
+ }
54
+
55
+ function writeVsCodeSettings(settingsPath, targetRoot) {
56
+ fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
57
+
58
+ let settings = {};
59
+ if (fs.existsSync(settingsPath)) {
60
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
61
+ }
62
+
63
+ const pluginLocations = isPlainObject(settings['chat.pluginLocations'])
64
+ ? { ...settings['chat.pluginLocations'] }
65
+ : {};
66
+
67
+ pluginLocations[targetRoot] = true;
68
+ settings['chat.pluginLocations'] = pluginLocations;
69
+
70
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
71
+ }
72
+
73
+ function isPlainObject(value) {
74
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
75
+ }
@@ -164,7 +164,15 @@ function renderPrompt(candidates, validationMessage = null) {
164
164
 
165
165
  for (const [index, candidate] of candidates.entries()) {
166
166
  const hint = recommendedIds.has(candidate.id) ? 'recommended' : null;
167
- lines.push(promptOption(index + 1, candidate.label, candidate.id, hint));
167
+ lines.push(
168
+ promptOption(
169
+ index + 1,
170
+ candidate.label,
171
+ candidate.id,
172
+ hint,
173
+ describeHarness(candidate.id)
174
+ )
175
+ );
168
176
  }
169
177
 
170
178
  return formatPromptBlock(
@@ -189,6 +197,42 @@ function resolvePromptAnswer(answer, candidates) {
189
197
  return getAdapterById(exact.id);
190
198
  }
191
199
 
200
+ function describeHarness(id) {
201
+ const descriptions = {
202
+ claude: 'Best for Claude Code sessions and project-local plugin workflows.',
203
+ codex: 'For the Codex CLI plugin marketplace flow in terminal sessions.',
204
+ vscode: 'One install path for VS Code agent sessions across Claude, Copilot, GPT, and other supported models.',
205
+ cursor: 'Native Cursor plugin install for fresh Agent sessions.',
206
+ copilot: 'For GitHub Copilot CLI in terminal-based agent sessions.',
207
+ opencode: 'Registers the OpenCode plugin in your local config directory.',
208
+ gemini: 'Installs the Gemini CLI extension and loads SPARK at startup.',
209
+ pi: 'Installs the Pi extension from the SPARK repository.',
210
+ antigravity: 'Installs the Antigravity plugin and loads SPARK on new sessions.',
211
+ };
212
+
213
+ return descriptions[id] ?? null;
214
+ }
215
+
192
216
  function normalizeHarness(value) {
193
- return String(value ?? '').trim().toLowerCase();
217
+ const normalized = String(value ?? '').trim().toLowerCase();
218
+
219
+ if (!normalized) {
220
+ return '';
221
+ }
222
+
223
+ const aliases = new Map([
224
+ ['codex cli', 'codex'],
225
+ ['codex-cli', 'codex'],
226
+ ['codex vscode', 'vscode'],
227
+ ['codex vs code', 'vscode'],
228
+ ['codex-vs-code', 'vscode'],
229
+ ['codex app', 'vscode'],
230
+ ['copilot vscode', 'vscode'],
231
+ ['copilot vs code', 'vscode'],
232
+ ['copilot-vs-code', 'vscode'],
233
+ ['vscode agent', 'vscode'],
234
+ ['vs code', 'vscode'],
235
+ ]);
236
+
237
+ return aliases.get(normalized) ?? normalized;
194
238
  }
@@ -3,6 +3,7 @@ import {
3
3
  createCodexAdapter,
4
4
  createCopilotAdapter,
5
5
  createCursorAdapter,
6
+ createVsCodeAdapter,
6
7
  } from './adapters/shell-hook.js';
7
8
  import {
8
9
  createAntigravityAdapter,
@@ -14,6 +15,7 @@ import {
14
15
  const ADAPTERS = [
15
16
  createClaudeCodeAdapter(),
16
17
  createCodexAdapter(),
18
+ createVsCodeAdapter(),
17
19
  createCursorAdapter(),
18
20
  createCopilotAdapter(),
19
21
  createOpenCodeAdapter(),