skalpel 3.0.4 → 3.0.6

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/INSTALL.md CHANGED
@@ -71,11 +71,11 @@ A user who has rolled back to a previous version (by running `npm install -g ska
71
71
 
72
72
  ## Uninstall
73
73
 
74
- `npm uninstall -g skalpel` removes both binaries. There is no separate uninstall command for `skalpeld`; the package is the unit of removal. Before npm removes the binaries it fires the package's `preuninstall` hook, which invokes `node postinstall/index.js --uninstall`; that pass removes the rc-file managed-block injected on install (so the user's shell stops pointing at the now-defunct local proxy port) and unregisters the per-OS service entry (so `launchctl`, `systemctl --user`, or `schtasks` stops trying to start a daemon whose binary is about to vanish). The shim and registration cleanup happen before the binaries themselves are removed; an interrupted uninstall leaves a coherent intermediate state.
74
+ `skalpel uninstall` is the one-liner for a clean removal. It unregisters the per-OS service entry (launchd / systemd user / Task Scheduler), removes the managed shell-rc block, and deletes `auth.json`, `config.toml`, `skalpeld.lock`, and `logs/` from the per-OS configuration directory. To preserve user data (engine toggles, active org, cached auth), pass `--keep-data`. `--dry-run` previews every action without writing anything. The command does not remove the npm package itself; after running `skalpel uninstall`, finish with `npm uninstall -g skalpel`.
75
75
 
76
- `npx skalpel` users have no global install to uninstall; the npx cache is cleaned by npm on its own schedule. For an `npx`-only user who wants to clean up shell rc-file and service registration without waiting on cache eviction, running `node postinstall/index.js --uninstall` from the package directory performs the same cleanup the `preuninstall` hook would.
76
+ `npm uninstall -g skalpel` on its own removes both binaries. There is no separate uninstall command for `skalpeld`; the package is the unit of removal. Before npm removes the binaries it fires the package's `preuninstall` hook, which invokes `node postinstall/index.js --uninstall`; that pass removes the rc-file managed-block injected on install (so the user's shell stops pointing at the now-defunct local proxy port) and unregisters the per-OS service entry (so `launchctl`, `systemctl --user`, or `schtasks` stops trying to start a daemon whose binary is about to vanish). The shim and registration cleanup happen before the binaries themselves are removed; an interrupted uninstall leaves a coherent intermediate state. The `preuninstall` hook deliberately preserves user data on disk so that `npm uninstall -g skalpel` followed by `npm install -g skalpel` is a non-destructive reinstall; the `skalpel uninstall` one-liner above is the path for users who want a full wipe.
77
77
 
78
- User data is **not** removed by uninstall. The configuration directory (`config.toml` and `auth.json`) persists on disk after the binaries are gone. This is deliberate: a user reinstalling Skalpel on the same machine should find their engine toggles and active organization preserved. To remove user data manually, delete the per-OS configuration directory named in `SPEC.md` §7.
78
+ `npx skalpel` users have no global install to uninstall; the npx cache is cleaned by npm on its own schedule. For an `npx`-only user who wants to clean up shell rc-file and service registration without waiting on cache eviction, `skalpel uninstall` performs the same cleanup the `preuninstall` hook would, plus the user-data wipe.
79
79
 
80
80
  ## Version coupling
81
81
 
@@ -181,11 +181,91 @@ function resolveBinary(name, argv) {
181
181
  return candidate;
182
182
  }
183
183
 
184
+ // runUninstall handles the `skalpel uninstall` subcommand: shells out
185
+ // to postinstall/index.js with --uninstall (+ --cleanup-data by default)
186
+ // and prints a follow-up hint pointing at `npm uninstall -g skalpel` for
187
+ // removing the package itself. The Go binary has no awareness of the
188
+ // postinstall code (which lives in node_modules), so the shim is the
189
+ // only place this command can live.
190
+ function runUninstall(rest) {
191
+ let cleanupData = true;
192
+ let dryRun = false;
193
+ let showHelp = false;
194
+ for (const a of rest) {
195
+ switch (a) {
196
+ case '--keep-data':
197
+ cleanupData = false;
198
+ break;
199
+ case '--dry-run':
200
+ dryRun = true;
201
+ break;
202
+ case '--help':
203
+ case '-h':
204
+ showHelp = true;
205
+ break;
206
+ default:
207
+ break;
208
+ }
209
+ }
210
+ if (showHelp) {
211
+ const colored = process.stdout.isTTY && !process.env.NO_COLOR;
212
+ const head = colored ? theme.bold(theme.lilac('skalpel uninstall')) : 'skalpel uninstall';
213
+ const dim = colored ? theme.dim : (s) => s;
214
+ process.stdout.write(
215
+ `${head} — clean up skalpel state on this machine\n\n` +
216
+ `usage: skalpel uninstall [--keep-data] [--dry-run]\n\n` +
217
+ `By default, removes:\n` +
218
+ ` • per-OS service entry (launchd / systemd user / Task Scheduler)\n` +
219
+ ` • managed shell-rc block injected on install\n` +
220
+ ` • auth.json, config.toml, skalpeld.lock, and logs/ (use --keep-data to preserve)\n\n` +
221
+ `${dim('Does not remove the npm package itself. To finish removal, run:')}\n` +
222
+ ` npm uninstall -g skalpel\n`
223
+ );
224
+ return 0;
225
+ }
226
+
227
+ const postinstall = path.join(__dirname, '..', 'postinstall', 'index.js');
228
+ if (!fs.existsSync(postinstall)) {
229
+ emitError(
230
+ process.stderr,
231
+ 'postinstall script missing',
232
+ `Expected ${postinstall} but it does not exist.`,
233
+ `→ Reinstall: \`npm install -g skalpel\``
234
+ );
235
+ return 1;
236
+ }
237
+ const args = ['--uninstall'];
238
+ if (cleanupData) args.push('--cleanup-data');
239
+ if (dryRun) args.push('--dry-run');
240
+
241
+ const result = spawnSync(process.execPath, [postinstall, ...args], {
242
+ stdio: 'inherit',
243
+ });
244
+ if (result.error) {
245
+ emitError(process.stderr, 'Uninstall failed', result.error.message, '→ Try `npm uninstall -g skalpel`.');
246
+ return 1;
247
+ }
248
+ if (result.status !== 0) {
249
+ return result.status === null ? 1 : result.status;
250
+ }
251
+
252
+ const colored = process.stdout.isTTY && !process.env.NO_COLOR;
253
+ const dim = colored ? theme.dim : (s) => s;
254
+ const ok = colored ? theme.mint('✓') : '✓';
255
+ process.stdout.write(`\n${ok} skalpel state removed from this machine.\n`);
256
+ process.stdout.write(`${dim('To finish removal, also run:')}\n`);
257
+ process.stdout.write(` npm uninstall -g skalpel\n`);
258
+ return 0;
259
+ }
260
+
184
261
  if (require.main === module) {
262
+ const argv = process.argv.slice(2);
263
+ if (argv[0] === 'uninstall') {
264
+ process.exit(runUninstall(argv.slice(1)));
265
+ }
185
266
  if (isFirstRun()) {
186
267
  emitBanner(process.stdout, platformLabel());
187
268
  }
188
- const argv = process.argv.slice(2);
189
269
  const binary = resolveBinary('skalpel', argv);
190
270
  const result = spawnSync(binary, argv, {
191
271
  stdio: 'inherit',
@@ -197,4 +277,4 @@ if (require.main === module) {
197
277
  process.exit(result.status === null ? 1 : result.status);
198
278
  }
199
279
 
200
- module.exports = { resolveBinary, PLATFORM_PACKAGES, renderWelcome, renderError, flagFilePath };
280
+ module.exports = { resolveBinary, runUninstall, PLATFORM_PACKAGES, renderWelcome, renderError, flagFilePath };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skalpel",
3
- "version": "3.0.4",
3
+ "version": "3.0.6",
4
4
  "description": "Skalpel — local proxy and TUI for coding agents (skalpel + skalpeld bundle).",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://skalpel.ai",
@@ -54,10 +54,10 @@
54
54
  "x64"
55
55
  ],
56
56
  "optionalDependencies": {
57
- "@skalpelai/skalpel-darwin-arm64": "3.0.4",
58
- "@skalpelai/skalpel-darwin-x64": "3.0.4",
59
- "@skalpelai/skalpel-linux-arm64": "3.0.4",
60
- "@skalpelai/skalpel-linux-x64": "3.0.4",
61
- "@skalpelai/skalpel-win32-x64": "3.0.4"
57
+ "@skalpelai/skalpel-darwin-arm64": "3.0.6",
58
+ "@skalpelai/skalpel-darwin-x64": "3.0.6",
59
+ "@skalpelai/skalpel-linux-arm64": "3.0.6",
60
+ "@skalpelai/skalpel-linux-x64": "3.0.6",
61
+ "@skalpelai/skalpel-win32-x64": "3.0.6"
62
62
  }
63
63
  }