@pantion/installer 0.2.0

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 (81) hide show
  1. package/dist/adapters/claude-code.d.ts +3 -0
  2. package/dist/adapters/claude-code.d.ts.map +1 -0
  3. package/dist/adapters/claude-code.js +35 -0
  4. package/dist/adapters/claude-code.js.map +1 -0
  5. package/dist/adapters/codex.d.ts +3 -0
  6. package/dist/adapters/codex.d.ts.map +1 -0
  7. package/dist/adapters/codex.js +22 -0
  8. package/dist/adapters/codex.js.map +1 -0
  9. package/dist/adapters/cursor.d.ts +3 -0
  10. package/dist/adapters/cursor.d.ts.map +1 -0
  11. package/dist/adapters/cursor.js +22 -0
  12. package/dist/adapters/cursor.js.map +1 -0
  13. package/dist/adapters/gemini-cli.d.ts +3 -0
  14. package/dist/adapters/gemini-cli.d.ts.map +1 -0
  15. package/dist/adapters/gemini-cli.js +22 -0
  16. package/dist/adapters/gemini-cli.js.map +1 -0
  17. package/dist/adapters/registry.d.ts +5 -0
  18. package/dist/adapters/registry.d.ts.map +1 -0
  19. package/dist/adapters/registry.js +19 -0
  20. package/dist/adapters/registry.js.map +1 -0
  21. package/dist/adapters/types.d.ts +13 -0
  22. package/dist/adapters/types.d.ts.map +1 -0
  23. package/dist/adapters/types.js +2 -0
  24. package/dist/adapters/types.js.map +1 -0
  25. package/dist/adapters/windsurf.d.ts +3 -0
  26. package/dist/adapters/windsurf.d.ts.map +1 -0
  27. package/dist/adapters/windsurf.js +22 -0
  28. package/dist/adapters/windsurf.js.map +1 -0
  29. package/dist/cli.d.ts +24 -0
  30. package/dist/cli.d.ts.map +1 -0
  31. package/dist/cli.js +94 -0
  32. package/dist/cli.js.map +1 -0
  33. package/dist/commands/doctor.d.ts +3 -0
  34. package/dist/commands/doctor.d.ts.map +1 -0
  35. package/dist/commands/doctor.js +56 -0
  36. package/dist/commands/doctor.js.map +1 -0
  37. package/dist/commands/install.d.ts +3 -0
  38. package/dist/commands/install.d.ts.map +1 -0
  39. package/dist/commands/install.js +92 -0
  40. package/dist/commands/install.js.map +1 -0
  41. package/dist/commands/restore.d.ts +9 -0
  42. package/dist/commands/restore.d.ts.map +1 -0
  43. package/dist/commands/restore.js +49 -0
  44. package/dist/commands/restore.js.map +1 -0
  45. package/dist/commands/uninstall.d.ts +3 -0
  46. package/dist/commands/uninstall.d.ts.map +1 -0
  47. package/dist/commands/uninstall.js +91 -0
  48. package/dist/commands/uninstall.js.map +1 -0
  49. package/dist/commands/verify.d.ts +3 -0
  50. package/dist/commands/verify.d.ts.map +1 -0
  51. package/dist/commands/verify.js +66 -0
  52. package/dist/commands/verify.js.map +1 -0
  53. package/dist/index.d.ts +3 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +44 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/types.d.ts +51 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +2 -0
  60. package/dist/types.js.map +1 -0
  61. package/dist/utils/backup.d.ts +2 -0
  62. package/dist/utils/backup.d.ts.map +1 -0
  63. package/dist/utils/backup.js +22 -0
  64. package/dist/utils/backup.js.map +1 -0
  65. package/dist/utils/json-merge.d.ts +7 -0
  66. package/dist/utils/json-merge.d.ts.map +1 -0
  67. package/dist/utils/json-merge.js +58 -0
  68. package/dist/utils/json-merge.js.map +1 -0
  69. package/dist/utils/output.d.ts +7 -0
  70. package/dist/utils/output.d.ts.map +1 -0
  71. package/dist/utils/output.js +20 -0
  72. package/dist/utils/output.js.map +1 -0
  73. package/dist/utils/prereqs.d.ts +5 -0
  74. package/dist/utils/prereqs.d.ts.map +1 -0
  75. package/dist/utils/prereqs.js +27 -0
  76. package/dist/utils/prereqs.js.map +1 -0
  77. package/dist/utils/toml-merge.d.ts +5 -0
  78. package/dist/utils/toml-merge.d.ts.map +1 -0
  79. package/dist/utils/toml-merge.js +54 -0
  80. package/dist/utils/toml-merge.js.map +1 -0
  81. package/package.json +27 -0
@@ -0,0 +1,3 @@
1
+ import type { ClientAdapter } from './types.js';
2
+ export declare const claudeCode: ClientAdapter;
3
+ //# sourceMappingURL=claude-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,eAAO,MAAM,UAAU,EAAE,aA6BxB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import { execSync } from 'node:child_process';
5
+ import * as jsonMerge from '../utils/json-merge.js';
6
+ export const claudeCode = {
7
+ id: 'claude-code',
8
+ displayName: 'Claude Code',
9
+ configPath(homeDir) {
10
+ const home = homeDir ?? os.homedir();
11
+ return path.join(home, '.claude.json');
12
+ },
13
+ isInstalled(homeDir) {
14
+ const configExists = fs.existsSync(this.configPath(homeDir));
15
+ if (configExists)
16
+ return true;
17
+ // Only check binary if no homeDir override (real system check)
18
+ if (!homeDir) {
19
+ try {
20
+ execSync('which claude', { stdio: 'ignore' });
21
+ return true;
22
+ }
23
+ catch {
24
+ // binary not found
25
+ }
26
+ }
27
+ return false;
28
+ },
29
+ hasPantionEntry: jsonMerge.hasPantionEntry,
30
+ isPantionEntryCorrect: jsonMerge.isPantionEntryCorrect,
31
+ mergePantionEntry: jsonMerge.mergePantionEntry,
32
+ removePantionEntry: jsonMerge.removePantionEntry,
33
+ emptyConfig: () => '{}\n',
34
+ };
35
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/adapters/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,UAAU,GAAkB;IACvC,EAAE,EAAE,aAAa;IACjB,WAAW,EAAE,aAAa;IAE1B,UAAU,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IACzC,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,YAAY,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,IAAI,YAAY;YAAE,OAAO,IAAI,CAAC;QAC9B,+DAA+D;QAC/D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,QAAQ,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAC9C,OAAO,IAAI,CAAC;YACd,CAAC;YAAC,MAAM,CAAC;gBACP,mBAAmB;YACrB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;IAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM;CAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ClientAdapter } from './types.js';
2
+ export declare const codex: ClientAdapter;
3
+ //# sourceMappingURL=codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,eAAO,MAAM,KAAK,EAAE,aAmBnB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import * as tomlMerge from '../utils/toml-merge.js';
5
+ export const codex = {
6
+ id: 'codex',
7
+ displayName: 'Codex',
8
+ configPath(homeDir) {
9
+ const home = homeDir ?? os.homedir();
10
+ return path.join(home, '.codex', 'config.toml');
11
+ },
12
+ isInstalled(homeDir) {
13
+ const home = homeDir ?? os.homedir();
14
+ return fs.existsSync(path.join(home, '.codex'));
15
+ },
16
+ hasPantionEntry: tomlMerge.hasPantionEntry,
17
+ isPantionEntryCorrect: tomlMerge.isPantionEntryCorrect,
18
+ mergePantionEntry: tomlMerge.mergePantionEntry,
19
+ removePantionEntry: tomlMerge.removePantionEntry,
20
+ emptyConfig: () => '',
21
+ };
22
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/adapters/codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,KAAK,GAAkB;IAClC,EAAE,EAAE,OAAO;IACX,WAAW,EAAE,OAAO;IAEpB,UAAU,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;IAClD,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;IAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE;CACtB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ClientAdapter } from './types.js';
2
+ export declare const cursor: ClientAdapter;
3
+ //# sourceMappingURL=cursor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.d.ts","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,eAAO,MAAM,MAAM,EAAE,aAmBpB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import * as jsonMerge from '../utils/json-merge.js';
5
+ export const cursor = {
6
+ id: 'cursor',
7
+ displayName: 'Cursor',
8
+ configPath(homeDir) {
9
+ const home = homeDir ?? os.homedir();
10
+ return path.join(home, '.cursor', 'mcp.json');
11
+ },
12
+ isInstalled(homeDir) {
13
+ const home = homeDir ?? os.homedir();
14
+ return fs.existsSync(path.join(home, '.cursor'));
15
+ },
16
+ hasPantionEntry: jsonMerge.hasPantionEntry,
17
+ isPantionEntryCorrect: jsonMerge.isPantionEntryCorrect,
18
+ mergePantionEntry: jsonMerge.mergePantionEntry,
19
+ removePantionEntry: jsonMerge.removePantionEntry,
20
+ emptyConfig: () => '{}\n',
21
+ };
22
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/adapters/cursor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,MAAM,GAAkB;IACnC,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,QAAQ;IAErB,UAAU,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAChD,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;IAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM;CAC1B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ClientAdapter } from './types.js';
2
+ export declare const geminiCli: ClientAdapter;
3
+ //# sourceMappingURL=gemini-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.d.ts","sourceRoot":"","sources":["../../src/adapters/gemini-cli.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,eAAO,MAAM,SAAS,EAAE,aAmBvB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import * as jsonMerge from '../utils/json-merge.js';
5
+ export const geminiCli = {
6
+ id: 'gemini-cli',
7
+ displayName: 'Gemini CLI',
8
+ configPath(homeDir) {
9
+ const home = homeDir ?? os.homedir();
10
+ return path.join(home, '.gemini', 'settings.json');
11
+ },
12
+ isInstalled(homeDir) {
13
+ const home = homeDir ?? os.homedir();
14
+ return fs.existsSync(path.join(home, '.gemini'));
15
+ },
16
+ hasPantionEntry: jsonMerge.hasPantionEntry,
17
+ isPantionEntryCorrect: jsonMerge.isPantionEntryCorrect,
18
+ mergePantionEntry: jsonMerge.mergePantionEntry,
19
+ removePantionEntry: jsonMerge.removePantionEntry,
20
+ emptyConfig: () => '{}\n',
21
+ };
22
+ //# sourceMappingURL=gemini-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini-cli.js","sourceRoot":"","sources":["../../src/adapters/gemini-cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAkB;IACtC,EAAE,EAAE,YAAY;IAChB,WAAW,EAAE,YAAY;IAEzB,UAAU,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACrD,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;IAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM;CAC1B,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { ClientId } from '../types.js';
2
+ import type { ClientAdapter } from './types.js';
3
+ export declare function getAdapter(id: ClientId): ClientAdapter;
4
+ export declare function getAllAdapters(): ClientAdapter[];
5
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAehD,wBAAgB,UAAU,CAAC,EAAE,EAAE,QAAQ,GAAG,aAAa,CAEtD;AAED,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAEhD"}
@@ -0,0 +1,19 @@
1
+ import { claudeCode } from './claude-code.js';
2
+ import { cursor } from './cursor.js';
3
+ import { windsurf } from './windsurf.js';
4
+ import { geminiCli } from './gemini-cli.js';
5
+ import { codex } from './codex.js';
6
+ const adapters = {
7
+ 'claude-code': claudeCode,
8
+ 'cursor': cursor,
9
+ 'windsurf': windsurf,
10
+ 'gemini-cli': geminiCli,
11
+ 'codex': codex,
12
+ };
13
+ export function getAdapter(id) {
14
+ return adapters[id];
15
+ }
16
+ export function getAllAdapters() {
17
+ return Object.values(adapters);
18
+ }
19
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/adapters/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,QAAQ,GAAoC;IAChD,aAAa,EAAE,UAAU;IACzB,QAAQ,EAAE,MAAM;IAChB,UAAU,EAAE,QAAQ;IACpB,YAAY,EAAE,SAAS;IACvB,OAAO,EAAE,KAAK;CACf,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,EAAY;IACrC,OAAO,QAAQ,CAAC,EAAE,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ClientId } from '../types.js';
2
+ export interface ClientAdapter {
3
+ id: ClientId;
4
+ displayName: string;
5
+ configPath(homeDir?: string): string;
6
+ isInstalled(homeDir?: string): boolean;
7
+ hasPantionEntry(content: string): boolean;
8
+ isPantionEntryCorrect(content: string): boolean;
9
+ mergePantionEntry(content: string): string;
10
+ removePantionEntry(content: string): string;
11
+ emptyConfig(): string;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,QAAQ,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACrC,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1C,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAChD,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3C,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5C,WAAW,IAAI,MAAM,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import type { ClientAdapter } from './types.js';
2
+ export declare const windsurf: ClientAdapter;
3
+ //# sourceMappingURL=windsurf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windsurf.d.ts","sourceRoot":"","sources":["../../src/adapters/windsurf.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,eAAO,MAAM,QAAQ,EAAE,aAmBtB,CAAC"}
@@ -0,0 +1,22 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as os from 'node:os';
4
+ import * as jsonMerge from '../utils/json-merge.js';
5
+ export const windsurf = {
6
+ id: 'windsurf',
7
+ displayName: 'Windsurf',
8
+ configPath(homeDir) {
9
+ const home = homeDir ?? os.homedir();
10
+ return path.join(home, '.codeium', 'windsurf', 'mcp_config.json');
11
+ },
12
+ isInstalled(homeDir) {
13
+ const home = homeDir ?? os.homedir();
14
+ return fs.existsSync(path.join(home, '.codeium', 'windsurf'));
15
+ },
16
+ hasPantionEntry: jsonMerge.hasPantionEntry,
17
+ isPantionEntryCorrect: jsonMerge.isPantionEntryCorrect,
18
+ mergePantionEntry: jsonMerge.mergePantionEntry,
19
+ removePantionEntry: jsonMerge.removePantionEntry,
20
+ emptyConfig: () => '{}\n',
21
+ };
22
+ //# sourceMappingURL=windsurf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windsurf.js","sourceRoot":"","sources":["../../src/adapters/windsurf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,KAAK,SAAS,MAAM,wBAAwB,CAAC;AAEpD,MAAM,CAAC,MAAM,QAAQ,GAAkB;IACrC,EAAE,EAAE,UAAU;IACd,WAAW,EAAE,UAAU;IAEvB,UAAU,CAAC,OAAgB;QACzB,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACpE,CAAC;IAED,WAAW,CAAC,OAAgB;QAC1B,MAAM,IAAI,GAAG,OAAO,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,eAAe,EAAE,SAAS,CAAC,eAAe;IAC1C,qBAAqB,EAAE,SAAS,CAAC,qBAAqB;IACtD,iBAAiB,EAAE,SAAS,CAAC,iBAAiB;IAC9C,kBAAkB,EAAE,SAAS,CAAC,kBAAkB;IAChD,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM;CAC1B,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import type { ClientId } from './types.js';
2
+ export type ParsedCommand = {
3
+ command: 'doctor';
4
+ } | {
5
+ command: 'install';
6
+ clients: ClientId[];
7
+ dryRun: boolean;
8
+ } | {
9
+ command: 'verify';
10
+ clients: ClientId[];
11
+ } | {
12
+ command: 'uninstall';
13
+ clients: ClientId[];
14
+ dryRun: boolean;
15
+ } | {
16
+ command: 'restore';
17
+ backupFile: string;
18
+ dryRun: boolean;
19
+ } | {
20
+ command: 'help';
21
+ };
22
+ export declare function parseArgs(argv: string[]): ParsedCommand;
23
+ export declare function printHelp(): void;
24
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,MAAM,aAAa,GACrB;IAAE,OAAO,EAAE,QAAQ,CAAA;CAAE,GACrB;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC5D;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,QAAQ,EAAE,CAAA;CAAE,GAC1C;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,QAAQ,EAAE,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GAC3D;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAyBxB,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,aAAa,CAmDvD;AAED,wBAAgB,SAAS,IAAI,IAAI,CA6BhC"}
package/dist/cli.js ADDED
@@ -0,0 +1,94 @@
1
+ import { ALL_CLIENT_IDS } from './types.js';
2
+ function isValidClientId(value) {
3
+ return ALL_CLIENT_IDS.includes(value);
4
+ }
5
+ function parseClientArg(args) {
6
+ const allIndex = args.indexOf('--all');
7
+ if (allIndex !== -1) {
8
+ return [...ALL_CLIENT_IDS];
9
+ }
10
+ const clientIndex = args.indexOf('--client');
11
+ if (clientIndex === -1 || clientIndex + 1 >= args.length) {
12
+ return null;
13
+ }
14
+ const value = args[clientIndex + 1];
15
+ if (!isValidClientId(value)) {
16
+ return null;
17
+ }
18
+ return [value];
19
+ }
20
+ export function parseArgs(argv) {
21
+ // argv[0] = node, argv[1] = script, rest = user args
22
+ const args = argv.slice(2);
23
+ if (args.length === 0 || args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
24
+ return { command: 'help' };
25
+ }
26
+ const command = args[0];
27
+ const dryRun = args.includes('--dry-run');
28
+ switch (command) {
29
+ case 'doctor':
30
+ return { command: 'doctor' };
31
+ case 'install': {
32
+ const clients = parseClientArg(args);
33
+ if (!clients) {
34
+ return { command: 'help' };
35
+ }
36
+ return { command: 'install', clients, dryRun };
37
+ }
38
+ case 'verify': {
39
+ const clients = parseClientArg(args);
40
+ if (!clients) {
41
+ return { command: 'help' };
42
+ }
43
+ return { command: 'verify', clients };
44
+ }
45
+ case 'uninstall': {
46
+ const clients = parseClientArg(args);
47
+ if (!clients) {
48
+ return { command: 'help' };
49
+ }
50
+ return { command: 'uninstall', clients, dryRun };
51
+ }
52
+ case 'restore': {
53
+ const restoreIndex = args.indexOf('--restore');
54
+ const fileArg = restoreIndex !== -1 ? args[restoreIndex + 1] : args[1];
55
+ if (!fileArg || fileArg.startsWith('--')) {
56
+ return { command: 'help' };
57
+ }
58
+ return { command: 'restore', backupFile: fileArg, dryRun };
59
+ }
60
+ default:
61
+ return { command: 'help' };
62
+ }
63
+ }
64
+ export function printHelp() {
65
+ console.log(`
66
+ @pantion/installer — MCP configuration for coding tools
67
+
68
+ Usage:
69
+ pantion-installer doctor Check prerequisites and detected tools
70
+ pantion-installer install --client <name> Configure Pantion for a coding tool
71
+ pantion-installer install --all Configure Pantion for all detected tools
72
+ pantion-installer verify --client <name> Check if Pantion is correctly configured
73
+ pantion-installer uninstall --client <name> Remove Pantion configuration
74
+ pantion-installer uninstall --all Remove Pantion from all clients
75
+ pantion-installer restore <backup-file> Restore a config from backup
76
+
77
+ Options:
78
+ --client <name> Target client: claude-code, cursor, windsurf, gemini-cli, codex
79
+ --all Target all supported clients
80
+ --dry-run Show what would change without writing files
81
+ --help, -h Show this help message
82
+
83
+ Examples:
84
+ npx @pantion/installer doctor
85
+ npx @pantion/installer install --client claude-code
86
+ npx @pantion/installer install --all --dry-run
87
+ npx @pantion/installer verify --client cursor
88
+ npx @pantion/installer uninstall --client windsurf
89
+ npx @pantion/installer install --client codex
90
+ npx @pantion/installer uninstall --all
91
+ npx @pantion/installer restore ~/.claude.json.bak-20260228-1430
92
+ `);
93
+ }
94
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { DoctorResult } from '../types.js';
2
+ export declare function doctor(homeDir?: string): DoctorResult;
3
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,aAAa,CAAC;AA+B9D,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CA2BrD"}
@@ -0,0 +1,56 @@
1
+ import * as fs from 'node:fs';
2
+ import { checkAllPrereqs } from '../utils/prereqs.js';
3
+ import { getAllAdapters } from '../adapters/registry.js';
4
+ import { heading, ok, fail, warn, info, blank } from '../utils/output.js';
5
+ function getClientStatus(homeDir) {
6
+ return getAllAdapters().map((adapter) => {
7
+ const installed = adapter.isInstalled(homeDir);
8
+ let hasPantion = false;
9
+ if (installed) {
10
+ try {
11
+ const configPath = adapter.configPath(homeDir);
12
+ if (fs.existsSync(configPath)) {
13
+ const content = fs.readFileSync(configPath, 'utf-8');
14
+ hasPantion = adapter.hasPantionEntry(content);
15
+ }
16
+ }
17
+ catch {
18
+ // config unreadable
19
+ }
20
+ }
21
+ return {
22
+ clientId: adapter.id,
23
+ displayName: adapter.displayName,
24
+ installed,
25
+ hasPantionConfig: hasPantion,
26
+ };
27
+ });
28
+ }
29
+ export function doctor(homeDir) {
30
+ const prereqs = checkAllPrereqs();
31
+ const clients = getClientStatus(homeDir);
32
+ heading('Prerequisites');
33
+ for (const p of prereqs) {
34
+ if (p.passed) {
35
+ ok(p.message);
36
+ }
37
+ else {
38
+ fail(p.message);
39
+ }
40
+ }
41
+ heading('Coding Tools');
42
+ for (const c of clients) {
43
+ if (!c.installed) {
44
+ info(`${c.displayName}: not detected`);
45
+ }
46
+ else if (c.hasPantionConfig) {
47
+ ok(`${c.displayName}: Pantion configured`);
48
+ }
49
+ else {
50
+ warn(`${c.displayName}: detected, Pantion not configured`);
51
+ }
52
+ }
53
+ blank();
54
+ return { prereqs, clients };
55
+ }
56
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE1E,SAAS,eAAe,CAAC,OAAgB;IACvC,OAAO,cAAc,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACtC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;oBACrD,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,oBAAoB;YACtB,CAAC;QACH,CAAC;QAED,OAAO;YACL,QAAQ,EAAE,OAAO,CAAC,EAAE;YACpB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,SAAS;YACT,gBAAgB,EAAE,UAAU;SAC7B,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAgB;IACrC,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IAEzC,OAAO,CAAC,eAAe,CAAC,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACb,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,cAAc,CAAC,CAAC;IACxB,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,gBAAgB,CAAC,CAAC;QACzC,CAAC;aAAM,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;YAC9B,EAAE,CAAC,GAAG,CAAC,CAAC,WAAW,sBAAsB,CAAC,CAAC;QAC7C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,oCAAoC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,KAAK,EAAE,CAAC;IAER,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ClientId, InstallResult } from '../types.js';
2
+ export declare function install(clients: ClientId[], dryRun: boolean, homeDir?: string): InstallResult[];
3
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAuE3D,wBAAgB,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE,CA+B/F"}
@@ -0,0 +1,92 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { getAdapter } from '../adapters/registry.js';
4
+ import { createBackup } from '../utils/backup.js';
5
+ import { heading, ok, fail, info, blank } from '../utils/output.js';
6
+ function installOne(clientId, dryRun, homeDir) {
7
+ const adapter = getAdapter(clientId);
8
+ const configPath = adapter.configPath(homeDir);
9
+ // Read existing config or start with empty
10
+ let existing = adapter.emptyConfig();
11
+ const configExists = fs.existsSync(configPath);
12
+ if (configExists) {
13
+ try {
14
+ existing = fs.readFileSync(configPath, 'utf-8');
15
+ }
16
+ catch (err) {
17
+ return {
18
+ clientId,
19
+ success: false,
20
+ action: 'failed',
21
+ configPath,
22
+ error: `Cannot read ${configPath}: ${err instanceof Error ? err.message : String(err)}`,
23
+ };
24
+ }
25
+ // Check if already correctly configured
26
+ if (adapter.hasPantionEntry(existing) && adapter.isPantionEntryCorrect(existing)) {
27
+ return { clientId, success: true, action: 'already-installed', configPath };
28
+ }
29
+ }
30
+ // Merge Pantion entry
31
+ const merged = adapter.mergePantionEntry(existing);
32
+ if (dryRun) {
33
+ info(`Would write to ${configPath}:`);
34
+ console.log(merged);
35
+ return { clientId, success: true, action: 'installed', configPath };
36
+ }
37
+ // Ensure parent directory exists
38
+ const dir = path.dirname(configPath);
39
+ if (!fs.existsSync(dir)) {
40
+ fs.mkdirSync(dir, { recursive: true });
41
+ }
42
+ // Backup existing file
43
+ let backupPath;
44
+ if (configExists) {
45
+ const backup = createBackup(configPath);
46
+ if (backup)
47
+ backupPath = backup;
48
+ }
49
+ // Write merged config
50
+ try {
51
+ fs.writeFileSync(configPath, merged, 'utf-8');
52
+ }
53
+ catch (err) {
54
+ return {
55
+ clientId,
56
+ success: false,
57
+ action: 'failed',
58
+ configPath,
59
+ backupPath,
60
+ error: `Cannot write ${configPath}: ${err instanceof Error ? err.message : String(err)}`,
61
+ };
62
+ }
63
+ return { clientId, success: true, action: 'installed', configPath, backupPath };
64
+ }
65
+ export function install(clients, dryRun, homeDir) {
66
+ const results = [];
67
+ heading(dryRun ? 'Install (dry run)' : 'Install');
68
+ for (const clientId of clients) {
69
+ const adapter = getAdapter(clientId);
70
+ const result = installOne(clientId, dryRun, homeDir);
71
+ results.push(result);
72
+ switch (result.action) {
73
+ case 'installed':
74
+ if (!dryRun) {
75
+ ok(`${adapter.displayName}: configured`);
76
+ if (result.backupPath) {
77
+ info(` Backup: ${result.backupPath}`);
78
+ }
79
+ }
80
+ break;
81
+ case 'already-installed':
82
+ ok(`${adapter.displayName}: already configured`);
83
+ break;
84
+ case 'failed':
85
+ fail(`${adapter.displayName}: ${result.error}`);
86
+ break;
87
+ }
88
+ }
89
+ blank();
90
+ return results;
91
+ }
92
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/commands/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface RestoreResult {
2
+ success: boolean;
3
+ backupFile: string;
4
+ targetFile: string;
5
+ safetyBackupPath?: string;
6
+ error?: string;
7
+ }
8
+ export declare function restore(backupFile: string, dryRun: boolean): RestoreResult;
9
+ //# sourceMappingURL=restore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/commands/restore.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,aAAa,CAmD1E"}
@@ -0,0 +1,49 @@
1
+ import * as fs from 'node:fs';
2
+ import { createBackup } from '../utils/backup.js';
3
+ import { heading, ok, fail, info, blank } from '../utils/output.js';
4
+ export function restore(backupFile, dryRun) {
5
+ heading(dryRun ? 'Restore (dry run)' : 'Restore');
6
+ // Validate backup file exists
7
+ if (!fs.existsSync(backupFile)) {
8
+ fail(`Backup file not found: ${backupFile}`);
9
+ blank();
10
+ return { success: false, backupFile, targetFile: '', error: `Backup file not found: ${backupFile}` };
11
+ }
12
+ // Derive target file path: strip .bak-YYYYMMDD-HHmm suffix
13
+ const bakMatch = backupFile.match(/^(.+)\.bak-\d{8}-\d{4}$/);
14
+ if (!bakMatch) {
15
+ fail(`Not a valid backup file (expected *.bak-YYYYMMDD-HHmm): ${backupFile}`);
16
+ blank();
17
+ return { success: false, backupFile, targetFile: '', error: 'Not a valid backup filename' };
18
+ }
19
+ const targetFile = bakMatch[1];
20
+ if (dryRun) {
21
+ info(`Would restore ${backupFile}`);
22
+ info(` → ${targetFile}`);
23
+ blank();
24
+ return { success: true, backupFile, targetFile };
25
+ }
26
+ // Safety backup of current file before overwriting
27
+ let safetyBackupPath;
28
+ if (fs.existsSync(targetFile)) {
29
+ const safety = createBackup(targetFile);
30
+ if (safety)
31
+ safetyBackupPath = safety;
32
+ }
33
+ try {
34
+ fs.copyFileSync(backupFile, targetFile);
35
+ }
36
+ catch (err) {
37
+ fail(`Cannot restore: ${err instanceof Error ? err.message : String(err)}`);
38
+ blank();
39
+ return { success: false, backupFile, targetFile, safetyBackupPath, error: String(err) };
40
+ }
41
+ ok(`Restored ${targetFile}`);
42
+ info(` From: ${backupFile}`);
43
+ if (safetyBackupPath) {
44
+ info(` Safety backup: ${safetyBackupPath}`);
45
+ }
46
+ blank();
47
+ return { success: true, backupFile, targetFile, safetyBackupPath };
48
+ }
49
+ //# sourceMappingURL=restore.js.map