@lkangd/cc-settings-preset 1.0.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 (124) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +304 -0
  3. package/README.zh-hans.md +304 -0
  4. package/dist/cli.d.ts +19 -0
  5. package/dist/cli.js +547 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/args.d.ts +5 -0
  8. package/dist/core/args.js +20 -0
  9. package/dist/core/args.js.map +1 -0
  10. package/dist/core/errors.d.ts +4 -0
  11. package/dist/core/errors.js +9 -0
  12. package/dist/core/errors.js.map +1 -0
  13. package/dist/core/json.d.ts +3 -0
  14. package/dist/core/json.js +46 -0
  15. package/dist/core/json.js.map +1 -0
  16. package/dist/core/name.d.ts +15 -0
  17. package/dist/core/name.js +58 -0
  18. package/dist/core/name.js.map +1 -0
  19. package/dist/core/paths.d.ts +26 -0
  20. package/dist/core/paths.js +79 -0
  21. package/dist/core/paths.js.map +1 -0
  22. package/dist/core/schema.d.ts +137 -0
  23. package/dist/core/schema.js +70 -0
  24. package/dist/core/schema.js.map +1 -0
  25. package/dist/core/spawn.d.ts +1 -0
  26. package/dist/core/spawn.js +32 -0
  27. package/dist/core/spawn.js.map +1 -0
  28. package/dist/core/terminal.d.ts +2 -0
  29. package/dist/core/terminal.js +5 -0
  30. package/dist/core/terminal.js.map +1 -0
  31. package/dist/flows/create-flow.d.ts +14 -0
  32. package/dist/flows/create-flow.js +13 -0
  33. package/dist/flows/create-flow.js.map +1 -0
  34. package/dist/flows/manage-flow.d.ts +9 -0
  35. package/dist/flows/manage-flow.js +8 -0
  36. package/dist/flows/manage-flow.js.map +1 -0
  37. package/dist/flows/project-launch-flow.d.ts +79 -0
  38. package/dist/flows/project-launch-flow.js +217 -0
  39. package/dist/flows/project-launch-flow.js.map +1 -0
  40. package/dist/flows/run-flow.d.ts +52 -0
  41. package/dist/flows/run-flow.js +167 -0
  42. package/dist/flows/run-flow.js.map +1 -0
  43. package/dist/flows/settings-select-flow.d.ts +21 -0
  44. package/dist/flows/settings-select-flow.js +20 -0
  45. package/dist/flows/settings-select-flow.js.map +1 -0
  46. package/dist/ink/components/global-shortcut-handler.d.ts +10 -0
  47. package/dist/ink/components/global-shortcut-handler.js +9 -0
  48. package/dist/ink/components/global-shortcut-handler.js.map +1 -0
  49. package/dist/ink/components/json-tree-view.d.ts +3 -0
  50. package/dist/ink/components/json-tree-view.js +52 -0
  51. package/dist/ink/components/json-tree-view.js.map +1 -0
  52. package/dist/ink/components/resize-context.d.ts +8 -0
  53. package/dist/ink/components/resize-context.js +10 -0
  54. package/dist/ink/components/resize-context.js.map +1 -0
  55. package/dist/ink/components/text-input-editing.d.ts +23 -0
  56. package/dist/ink/components/text-input-editing.js +42 -0
  57. package/dist/ink/components/text-input-editing.js.map +1 -0
  58. package/dist/ink/components/text-input-field.d.ts +15 -0
  59. package/dist/ink/components/text-input-field.js +127 -0
  60. package/dist/ink/components/text-input-field.js.map +1 -0
  61. package/dist/ink/components/text-input.d.ts +10 -0
  62. package/dist/ink/components/text-input.js +22 -0
  63. package/dist/ink/components/text-input.js.map +1 -0
  64. package/dist/ink/components/toggle-column.d.ts +8 -0
  65. package/dist/ink/components/toggle-column.js +30 -0
  66. package/dist/ink/components/toggle-column.js.map +1 -0
  67. package/dist/ink/components/truncate-text.d.ts +3 -0
  68. package/dist/ink/components/truncate-text.js +6 -0
  69. package/dist/ink/components/truncate-text.js.map +1 -0
  70. package/dist/ink/components/two-column-settings-view.d.ts +9 -0
  71. package/dist/ink/components/two-column-settings-view.js +16 -0
  72. package/dist/ink/components/two-column-settings-view.js.map +1 -0
  73. package/dist/ink/components/use-text-input-state.d.ts +45 -0
  74. package/dist/ink/components/use-text-input-state.js +100 -0
  75. package/dist/ink/components/use-text-input-state.js.map +1 -0
  76. package/dist/ink/components/use-text-input.d.ts +8 -0
  77. package/dist/ink/components/use-text-input.js +87 -0
  78. package/dist/ink/components/use-text-input.js.map +1 -0
  79. package/dist/ink/create-app.d.ts +11 -0
  80. package/dist/ink/create-app.js +49 -0
  81. package/dist/ink/create-app.js.map +1 -0
  82. package/dist/ink/manage-app.d.ts +25 -0
  83. package/dist/ink/manage-app.js +92 -0
  84. package/dist/ink/manage-app.js.map +1 -0
  85. package/dist/ink/project-launch-app.d.ts +22 -0
  86. package/dist/ink/project-launch-app.js +144 -0
  87. package/dist/ink/project-launch-app.js.map +1 -0
  88. package/dist/ink/project-manage-app.d.ts +28 -0
  89. package/dist/ink/project-manage-app.js +239 -0
  90. package/dist/ink/project-manage-app.js.map +1 -0
  91. package/dist/ink/settings-select-app.d.ts +9 -0
  92. package/dist/ink/settings-select-app.js +31 -0
  93. package/dist/ink/settings-select-app.js.map +1 -0
  94. package/dist/services/global-last-settings-service.d.ts +4 -0
  95. package/dist/services/global-last-settings-service.js +25 -0
  96. package/dist/services/global-last-settings-service.js.map +1 -0
  97. package/dist/services/launch-preset-service.d.ts +13 -0
  98. package/dist/services/launch-preset-service.js +186 -0
  99. package/dist/services/launch-preset-service.js.map +1 -0
  100. package/dist/services/mcp-service.d.ts +18 -0
  101. package/dist/services/mcp-service.js +106 -0
  102. package/dist/services/mcp-service.js.map +1 -0
  103. package/dist/services/plugin-service.d.ts +16 -0
  104. package/dist/services/plugin-service.js +58 -0
  105. package/dist/services/plugin-service.js.map +1 -0
  106. package/dist/services/preset-service.d.ts +13 -0
  107. package/dist/services/preset-service.js +152 -0
  108. package/dist/services/preset-service.js.map +1 -0
  109. package/dist/services/project-store-service.d.ts +6 -0
  110. package/dist/services/project-store-service.js +16 -0
  111. package/dist/services/project-store-service.js.map +1 -0
  112. package/dist/services/reveal-service.d.ts +2 -0
  113. package/dist/services/reveal-service.js +7 -0
  114. package/dist/services/reveal-service.js.map +1 -0
  115. package/dist/services/settings-finalizer-service.d.ts +2 -0
  116. package/dist/services/settings-finalizer-service.js +21 -0
  117. package/dist/services/settings-finalizer-service.js.map +1 -0
  118. package/dist/services/settings-source-service.d.ts +11 -0
  119. package/dist/services/settings-source-service.js +26 -0
  120. package/dist/services/settings-source-service.js.map +1 -0
  121. package/dist/services/skill-service.d.ts +24 -0
  122. package/dist/services/skill-service.js +193 -0
  123. package/dist/services/skill-service.js.map +1 -0
  124. package/package.json +67 -0
@@ -0,0 +1,106 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { basename, join } from 'node:path';
3
+ import { pathExists, readJsonFile } from '../core/json.js';
4
+ import { resolveClaudePluginCacheDir, resolveProjectMcpPath, resolveUserClaudeJsonPath } from '../core/paths.js';
5
+ async function readDirSafe(dirPath) {
6
+ try {
7
+ return await fs.readdir(dirPath, { withFileTypes: true });
8
+ }
9
+ catch (error) {
10
+ if (error.code === 'ENOENT')
11
+ return [];
12
+ throw error;
13
+ }
14
+ }
15
+ function readMcpServers(value) {
16
+ if (!value || typeof value !== 'object')
17
+ return {};
18
+ const servers = value.mcpServers;
19
+ if (!servers || typeof servers !== 'object' || Array.isArray(servers))
20
+ return {};
21
+ return servers;
22
+ }
23
+ function sortMcpStates(states) {
24
+ return [...states].sort((a, b) => a.name.localeCompare(b.name));
25
+ }
26
+ async function discoverPluginMcpServers(homeDir) {
27
+ const cacheDir = resolveClaudePluginCacheDir(homeDir);
28
+ const servers = [];
29
+ async function scan(dirPath) {
30
+ const entries = await readDirSafe(dirPath);
31
+ for (const entry of entries) {
32
+ if (!entry.isDirectory())
33
+ continue;
34
+ const fullPath = join(dirPath, entry.name);
35
+ const manifestPath = join(fullPath, 'plugin.json');
36
+ if (await pathExists(manifestPath)) {
37
+ const manifest = await readJsonFile(manifestPath);
38
+ const pluginName = typeof manifest.name === 'string'
39
+ ? manifest.name
40
+ : basename(fullPath);
41
+ for (const [name, config] of Object.entries(readMcpServers(manifest))) {
42
+ servers.push({ name, config: { pluginName, ...asRecord(config) } });
43
+ }
44
+ continue;
45
+ }
46
+ await scan(fullPath);
47
+ }
48
+ }
49
+ await scan(cacheDir);
50
+ return servers;
51
+ }
52
+ function asRecord(value) {
53
+ if (!value || typeof value !== 'object' || Array.isArray(value))
54
+ return {};
55
+ return value;
56
+ }
57
+ export async function discoverMcpStates(input) {
58
+ const resolved = new Map();
59
+ const userClaudePath = resolveUserClaudeJsonPath(input.homeDir);
60
+ const userClaudeJson = await pathExists(userClaudePath) ? await readJsonFile(userClaudePath) : {};
61
+ const projectMcpPath = resolveProjectMcpPath(input.cwd);
62
+ const projectMcpJson = await pathExists(projectMcpPath) ? await readJsonFile(projectMcpPath) : {};
63
+ for (const { name, config } of await discoverPluginMcpServers(input.homeDir)) {
64
+ resolved.set(name, { name, enabled: true, source: 'plugin', config });
65
+ }
66
+ for (const [name, config] of Object.entries(readMcpServers(userClaudeJson))) {
67
+ resolved.set(name, { name, enabled: true, source: 'user', config });
68
+ }
69
+ for (const [name, config] of Object.entries(readMcpServers(projectMcpJson))) {
70
+ resolved.set(name, { name, enabled: true, source: 'project', config });
71
+ }
72
+ const projectEntry = userClaudeJson.projects?.[input.cwd];
73
+ for (const [name, config] of Object.entries(readMcpServers(projectEntry))) {
74
+ resolved.set(name, { name, enabled: true, source: 'local', config });
75
+ }
76
+ return sortMcpStates(Array.from(resolved.values()));
77
+ }
78
+ export function resolveDeniedMcpServers(sources) {
79
+ const seenServerNames = new Set();
80
+ const denied = [];
81
+ for (const source of sources) {
82
+ for (const entry of source.settings.deniedMcpServers ?? []) {
83
+ if ('serverName' in entry) {
84
+ if (seenServerNames.has(entry.serverName))
85
+ continue;
86
+ seenServerNames.add(entry.serverName);
87
+ denied.push(entry);
88
+ continue;
89
+ }
90
+ denied.push(entry);
91
+ }
92
+ }
93
+ return denied;
94
+ }
95
+ export function applyDeniedMcpServers(states, denied = []) {
96
+ const deniedNames = new Set(denied.flatMap(entry => 'serverName' in entry ? [entry.serverName] : []));
97
+ if (deniedNames.size === 0)
98
+ return sortMcpStates(states);
99
+ return sortMcpStates(states.map(state => (deniedNames.has(state.name) ? { ...state, enabled: false } : state)));
100
+ }
101
+ export function mcpStatesToDeniedServers(states) {
102
+ return states
103
+ .filter(state => !state.enabled)
104
+ .map(state => ({ serverName: state.name }));
105
+ }
106
+ //# sourceMappingURL=mcp-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-service.js","sourceRoot":"","sources":["../../src/services/mcp-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Settings } from '../core/schema.js';
2
+ import type { SettingsSourceScope } from './settings-source-service.js';
3
+ export type PluginState = {
4
+ name: string;
5
+ enabled: boolean;
6
+ source: SettingsSourceScope | 'preset';
7
+ };
8
+ export type PluginSettingsSource = {
9
+ scope: SettingsSourceScope | 'preset';
10
+ filePath: string;
11
+ settings: Settings;
12
+ };
13
+ export declare function sortPluginStates(states: PluginState[]): PluginState[];
14
+ export declare function resolvePluginStates(sources: PluginSettingsSource[]): PluginState[];
15
+ export declare function applyPluginOverrides(states: PluginState[], overrides?: Record<string, boolean>): PluginState[];
16
+ export declare function pluginStatesToEnabledPlugins(states: PluginState[]): Record<string, boolean>;
@@ -0,0 +1,58 @@
1
+ export function sortPluginStates(states) {
2
+ return [...states].sort((a, b) => {
3
+ if (a.enabled !== b.enabled)
4
+ return a.enabled ? -1 : 1;
5
+ return a.name.localeCompare(b.name);
6
+ });
7
+ }
8
+ export function resolvePluginStates(sources) {
9
+ const ownershipPrecedence = {
10
+ user: 0,
11
+ project: 1,
12
+ 'project-local': 2,
13
+ };
14
+ const resolved = new Map();
15
+ for (const source of sources) {
16
+ const enabledPlugins = source.settings.enabledPlugins ?? {};
17
+ for (const [name, enabled] of Object.entries(enabledPlugins)) {
18
+ const current = resolved.get(name);
19
+ if (source.scope === 'preset') {
20
+ if (current) {
21
+ resolved.set(name, { ...current, enabled });
22
+ }
23
+ else {
24
+ resolved.set(name, { name, enabled, source: 'preset' });
25
+ }
26
+ continue;
27
+ }
28
+ if (!current) {
29
+ resolved.set(name, { name, enabled, source: source.scope });
30
+ continue;
31
+ }
32
+ if (current.source === 'preset') {
33
+ resolved.set(name, { ...current, source: source.scope });
34
+ continue;
35
+ }
36
+ if (ownershipPrecedence[source.scope] >= ownershipPrecedence[current.source]) {
37
+ resolved.set(name, { name, enabled, source: source.scope });
38
+ }
39
+ }
40
+ }
41
+ return sortPluginStates(Array.from(resolved.values()));
42
+ }
43
+ export function applyPluginOverrides(states, overrides = {}) {
44
+ return sortPluginStates(states.map(state => {
45
+ if (!(state.name in overrides))
46
+ return state;
47
+ return { ...state, enabled: overrides[state.name] ?? state.enabled };
48
+ }));
49
+ }
50
+ export function pluginStatesToEnabledPlugins(states) {
51
+ const enabledPlugins = {};
52
+ for (const state of states) {
53
+ if (!state.enabled)
54
+ enabledPlugins[state.name] = false;
55
+ }
56
+ return enabledPlugins;
57
+ }
58
+ //# sourceMappingURL=plugin-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-service.js","sourceRoot":"","sources":["../../src/services/plugin-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { type BasePresetMeta, type PresetIndex, type PresetMeta, type Settings } from '../core/schema.js';
2
+ export declare function createPresetService(globalRoot: string): {
3
+ getPresetPath(name: string): Promise<string>;
4
+ readIndex(): Promise<PresetIndex>;
5
+ listPresets(): Promise<PresetMeta[]>;
6
+ readPresetSettings(name: string): Promise<Settings>;
7
+ createBasePreset(nameInput: string, settingsInput: unknown): Promise<BasePresetMeta>;
8
+ writeBasePreset(nameInput: string, settingsInput: unknown): Promise<BasePresetMeta>;
9
+ writePresetSettingsByName(nameInput: string, settingsInput: unknown): Promise<PresetMeta>;
10
+ renamePreset(nameInput: string, newNameInput: string): Promise<PresetMeta>;
11
+ deletePreset(nameInput: string): Promise<void>;
12
+ importExistingSettingsFile(filePath: string, nameInput?: string): Promise<BasePresetMeta>;
13
+ };
@@ -0,0 +1,152 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { CliError } from '../core/errors.js';
3
+ import { pathExists, readJsonFile, writeJsonFile } from '../core/json.js';
4
+ import { buildSettingsFileName, derivePresetNameFromSettingsPath, normalizePresetName, resolvePresetIndexKey } from '../core/name.js';
5
+ import { resolveIndexPath, resolvePresetPath } from '../core/paths.js';
6
+ import { createEmptyIndex, indexSchema, parseSettings, } from '../core/schema.js';
7
+ function nowIso() {
8
+ return new Date().toISOString();
9
+ }
10
+ export function createPresetService(globalRoot) {
11
+ const indexPath = resolveIndexPath(globalRoot);
12
+ async function readIndex() {
13
+ if (!(await pathExists(indexPath)))
14
+ return createEmptyIndex();
15
+ return indexSchema.parse(await readJsonFile(indexPath));
16
+ }
17
+ async function writeIndex(index) {
18
+ await writeJsonFile(indexPath, indexSchema.parse(index));
19
+ }
20
+ function getPresetPath(meta) {
21
+ return resolvePresetPath(globalRoot, meta.fileName);
22
+ }
23
+ async function readPresetSettings(name) {
24
+ const index = await readIndex();
25
+ const meta = index.presets[name];
26
+ if (!meta)
27
+ throw new CliError(`Preset not found: ${name}`);
28
+ return parseSettings(await readJsonFile(getPresetPath(meta)));
29
+ }
30
+ async function writePresetSettings(meta, settings) {
31
+ await writeJsonFile(getPresetPath(meta), parseSettings(settings));
32
+ }
33
+ const service = {
34
+ async getPresetPath(name) {
35
+ const index = await readIndex();
36
+ const meta = index.presets[name];
37
+ if (!meta)
38
+ throw new CliError(`Preset not found: ${name}`);
39
+ return getPresetPath(meta);
40
+ },
41
+ async readIndex() {
42
+ return readIndex();
43
+ },
44
+ async listPresets() {
45
+ const index = await readIndex();
46
+ return Object.values(index.presets)
47
+ .filter((preset) => preset.type === 'base')
48
+ .sort((a, b) => a.name.localeCompare(b.name));
49
+ },
50
+ async readPresetSettings(name) {
51
+ return readPresetSettings(name);
52
+ },
53
+ async createBasePreset(nameInput, settingsInput) {
54
+ const settings = parseSettings(settingsInput);
55
+ const name = normalizePresetName(nameInput);
56
+ const index = await readIndex();
57
+ if (index.presets[name])
58
+ throw new CliError(`Preset already exists: ${name}`);
59
+ const timestamp = nowIso();
60
+ const meta = {
61
+ type: 'base',
62
+ name,
63
+ fileName: buildSettingsFileName(name),
64
+ createdAt: timestamp,
65
+ updatedAt: timestamp,
66
+ };
67
+ index.presets[name] = meta;
68
+ await writePresetSettings(meta, settings);
69
+ await writeIndex(index);
70
+ return meta;
71
+ },
72
+ async writeBasePreset(nameInput, settingsInput) {
73
+ const settings = parseSettings(settingsInput);
74
+ const index = await readIndex();
75
+ const name = resolvePresetIndexKey(index.presets, nameInput);
76
+ if (!name)
77
+ throw new CliError(`Base preset not found: ${nameInput}`);
78
+ const existing = index.presets[name];
79
+ if (!existing || existing.type !== 'base')
80
+ throw new CliError(`Base preset not found: ${nameInput}`);
81
+ const updated = { ...existing, updatedAt: nowIso() };
82
+ index.presets[name] = updated;
83
+ await writePresetSettings(updated, settings);
84
+ await writeIndex(index);
85
+ return updated;
86
+ },
87
+ async writePresetSettingsByName(nameInput, settingsInput) {
88
+ const settings = parseSettings(settingsInput);
89
+ const index = await readIndex();
90
+ const name = resolvePresetIndexKey(index.presets, nameInput);
91
+ if (!name)
92
+ throw new CliError(`Preset not found: ${nameInput}`);
93
+ const existing = index.presets[name];
94
+ if (!existing)
95
+ throw new CliError(`Preset not found: ${nameInput}`);
96
+ const updated = { ...existing, updatedAt: nowIso() };
97
+ index.presets[name] = updated;
98
+ await writePresetSettings(updated, settings);
99
+ await writeIndex(index);
100
+ return updated;
101
+ },
102
+ async renamePreset(nameInput, newNameInput) {
103
+ const requestedName = normalizePresetName(newNameInput, { preserveCase: true });
104
+ const index = await readIndex();
105
+ const name = resolvePresetIndexKey(index.presets, nameInput);
106
+ if (!name)
107
+ throw new CliError(`Preset not found: ${nameInput}`);
108
+ const meta = index.presets[name];
109
+ if (!meta)
110
+ throw new CliError(`Preset not found: ${nameInput}`);
111
+ if (meta.type !== 'base')
112
+ throw new CliError(`Base preset not found: ${nameInput}`);
113
+ const newName = requestedName;
114
+ if (newName === name) {
115
+ return { ...meta, updatedAt: nowIso() };
116
+ }
117
+ if (index.presets[newName])
118
+ throw new CliError(`Preset already exists: ${newName}`);
119
+ const updated = { ...meta, name: newName, fileName: buildSettingsFileName(newName, { preserveCase: true }), updatedAt: nowIso() };
120
+ await fs.rename(getPresetPath(meta), resolvePresetPath(globalRoot, updated.fileName));
121
+ delete index.presets[name];
122
+ index.presets[newName] = updated;
123
+ await writeIndex(index);
124
+ return updated;
125
+ },
126
+ async deletePreset(nameInput) {
127
+ const index = await readIndex();
128
+ const name = resolvePresetIndexKey(index.presets, nameInput);
129
+ if (!name)
130
+ return;
131
+ const meta = index.presets[name];
132
+ if (!meta)
133
+ return;
134
+ try {
135
+ await fs.unlink(getPresetPath(meta));
136
+ }
137
+ catch (error) {
138
+ if (error.code !== 'ENOENT')
139
+ throw error;
140
+ }
141
+ delete index.presets[name];
142
+ await writeIndex(index);
143
+ },
144
+ async importExistingSettingsFile(filePath, nameInput) {
145
+ const settings = parseSettings(await readJsonFile(filePath));
146
+ const baseName = nameInput ?? derivePresetNameFromSettingsPath(filePath);
147
+ return service.createBasePreset(baseName, settings);
148
+ },
149
+ };
150
+ return service;
151
+ }
152
+ //# sourceMappingURL=preset-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset-service.js","sourceRoot":"","sources":["../../src/services/preset-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export type ProjectCcspStore = {
2
+ rootDir: string;
3
+ launchPresetDir: string;
4
+ tempSettingsDir: string;
5
+ };
6
+ export declare function ensureProjectCcspStore(cwd: string): Promise<ProjectCcspStore>;
@@ -0,0 +1,16 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { resolveProjectCcspRoot, resolveProjectLaunchPresetDir, resolveProjectTempSettingsDir, } from '../core/paths.js';
4
+ async function ensureStoreGitignore(rootDir) {
5
+ await fs.writeFile(join(rootDir, '.gitignore'), '*\n', 'utf8');
6
+ }
7
+ export async function ensureProjectCcspStore(cwd) {
8
+ const rootDir = resolveProjectCcspRoot(cwd);
9
+ const launchPresetDir = resolveProjectLaunchPresetDir(cwd);
10
+ const tempSettingsDir = resolveProjectTempSettingsDir(cwd);
11
+ await fs.mkdir(launchPresetDir, { recursive: true });
12
+ await fs.mkdir(tempSettingsDir, { recursive: true });
13
+ await ensureStoreGitignore(rootDir);
14
+ return { rootDir, launchPresetDir, tempSettingsDir };
15
+ }
16
+ //# sourceMappingURL=project-store-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-store-service.js","sourceRoot":"","sources":["../../src/services/project-store-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,kBAAkB,CAAA;AAQzB,KAAK,UAAU,oBAAoB,CAAC,OAAe;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,GAAW;IACtD,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAA;IAC3C,MAAM,eAAe,GAAG,6BAA6B,CAAC,GAAG,CAAC,CAAA;IAC1D,MAAM,eAAe,GAAG,6BAA6B,CAAC,GAAG,CAAC,CAAA;IAE1D,MAAM,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpD,MAAM,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACpD,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAEnC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA;AACtD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { spawn } from 'node:child_process';
2
+ export declare function revealInFinder(filePath: string, spawnProcess?: typeof spawn): void;
@@ -0,0 +1,7 @@
1
+ import { spawn } from 'node:child_process';
2
+ export function revealInFinder(filePath, spawnProcess = spawn) {
3
+ if (!filePath)
4
+ return;
5
+ spawnProcess('open', ['-R', filePath], { stdio: 'ignore' });
6
+ }
7
+ //# sourceMappingURL=reveal-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reveal-service.js","sourceRoot":"","sources":["../../src/services/reveal-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAE1C,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,eAA6B,KAAK;IACjF,IAAI,CAAC,QAAQ;QAAE,OAAM;IACrB,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;AAC7D,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type Settings } from '../core/schema.js';
2
+ export declare function finalizeSettings(baseInput: unknown, launchInput: unknown): Settings;
@@ -0,0 +1,21 @@
1
+ import { parseLaunchPresetSettings, parseSettings, } from '../core/schema.js';
2
+ function hasEntries(value) {
3
+ return Boolean(value && Object.keys(value).length > 0);
4
+ }
5
+ export function finalizeSettings(baseInput, launchInput) {
6
+ const base = parseSettings(baseInput);
7
+ const launch = parseLaunchPresetSettings(launchInput);
8
+ const finalized = { ...base };
9
+ delete finalized.enabledPlugins;
10
+ delete finalized.skillOverrides;
11
+ delete finalized.deniedMcpServers;
12
+ if (hasEntries(launch.enabledPlugins))
13
+ finalized.enabledPlugins = launch.enabledPlugins;
14
+ if (hasEntries(launch.skillOverrides))
15
+ finalized.skillOverrides = launch.skillOverrides;
16
+ if (launch.deniedMcpServers && launch.deniedMcpServers.length > 0) {
17
+ finalized.deniedMcpServers = launch.deniedMcpServers;
18
+ }
19
+ return parseSettings(finalized);
20
+ }
21
+ //# sourceMappingURL=settings-finalizer-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-finalizer-service.js","sourceRoot":"","sources":["../../src/services/settings-finalizer-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,aAAa,GAGd,MAAM,mBAAmB,CAAA;AAE1B,SAAS,UAAU,CAAC,KAA0C;IAC5D,OAAO,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,SAAkB,EAAE,WAAoB;IACvE,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,CAAC,CAAA;IACrC,MAAM,MAAM,GAAG,yBAAyB,CAAC,WAAW,CAAyB,CAAA;IAC7E,MAAM,SAAS,GAAa,EAAE,GAAG,IAAI,EAAE,CAAA;IAEvC,OAAO,SAAS,CAAC,cAAc,CAAA;IAC/B,OAAO,SAAS,CAAC,cAAc,CAAA;IAC/B,OAAO,SAAS,CAAC,gBAAgB,CAAA;IAEjC,IAAI,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC;QAAE,SAAS,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAA;IACvF,IAAI,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC;QAAE,SAAS,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAA;IACvF,IAAI,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClE,SAAS,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAA;IACtD,CAAC;IAED,OAAO,aAAa,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type PathContext } from '../core/paths.js';
2
+ import { type Settings } from '../core/schema.js';
3
+ export type SettingsSourceScope = 'project-local' | 'project' | 'user';
4
+ export type SettingsSource = {
5
+ scope: SettingsSourceScope;
6
+ filePath: string;
7
+ settings: Settings;
8
+ };
9
+ export declare function createSettingsSourceService(context: PathContext): {
10
+ discoverSettingsSources(): Promise<SettingsSource[]>;
11
+ };
@@ -0,0 +1,26 @@
1
+ import { pathExists, readJsonFile } from '../core/json.js';
2
+ import { resolveProjectClaudeLocalSettingsPath, resolveProjectClaudeSettingsPath, resolveUserClaudeSettingsPath, } from '../core/paths.js';
3
+ import { parseSettings } from '../core/schema.js';
4
+ export function createSettingsSourceService(context) {
5
+ const candidates = [
6
+ { scope: 'project-local', filePath: resolveProjectClaudeLocalSettingsPath(context.cwd) },
7
+ { scope: 'project', filePath: resolveProjectClaudeSettingsPath(context.cwd) },
8
+ { scope: 'user', filePath: resolveUserClaudeSettingsPath(context.homeDir) },
9
+ ];
10
+ return {
11
+ async discoverSettingsSources() {
12
+ const sources = [];
13
+ for (const candidate of candidates) {
14
+ if (!(await pathExists(candidate.filePath)))
15
+ continue;
16
+ sources.push({
17
+ scope: candidate.scope,
18
+ filePath: candidate.filePath,
19
+ settings: parseSettings(await readJsonFile(candidate.filePath)),
20
+ });
21
+ }
22
+ return sources;
23
+ },
24
+ };
25
+ }
26
+ //# sourceMappingURL=settings-source-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-source-service.js","sourceRoot":"","sources":["../../src/services/settings-source-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EACL,qCAAqC,EACrC,gCAAgC,EAChC,6BAA6B,GAE9B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,aAAa,EAAiB,MAAM,mBAAmB,CAAA;AAUhE,MAAM,UAAU,2BAA2B,CAAC,OAAoB;IAC9D,MAAM,UAAU,GAA4D;QAC1E,EAAE,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,qCAAqC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACxF,EAAE,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,gCAAgC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QAC7E,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,6BAA6B,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;KAC5E,CAAA;IAED,OAAO;QACL,KAAK,CAAC,uBAAuB;YAC3B,MAAM,OAAO,GAAqB,EAAE,CAAA;YAEpC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gBACnC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;oBAAE,SAAQ;gBACrD,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK,EAAE,SAAS,CAAC,KAAK;oBACtB,QAAQ,EAAE,SAAS,CAAC,QAAQ;oBAC5B,QAAQ,EAAE,aAAa,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;iBAChE,CAAC,CAAA;YACJ,CAAC;YAED,OAAO,OAAO,CAAA;QAChB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { Settings, SkillOverrideValue } from '../core/schema.js';
2
+ import type { SettingsSourceScope } from './settings-source-service.js';
3
+ export type SkillState = {
4
+ name: string;
5
+ enabled: boolean;
6
+ source: 'user' | 'project' | 'command' | 'plugin';
7
+ toggleable: boolean;
8
+ controlledByPlugin?: string;
9
+ };
10
+ export type SkillDiscoveryInput = {
11
+ homeDir: string;
12
+ cwd: string;
13
+ enabledPlugins: Record<string, boolean>;
14
+ skillOverrides?: Record<string, SkillOverrideValue>;
15
+ };
16
+ export declare function sortSkillStatesByStatus(states: SkillState[]): SkillState[];
17
+ export type SkillSettingsSource = {
18
+ scope: SettingsSourceScope | 'preset';
19
+ settings: Settings;
20
+ };
21
+ export declare function resolveSkillOverrides(sources: SkillSettingsSource[]): Record<string, SkillOverrideValue>;
22
+ export declare function applySkillOverrides(states: SkillState[], overrides?: Record<string, SkillOverrideValue>): SkillState[];
23
+ export declare function discoverSkillStates(input: SkillDiscoveryInput): Promise<SkillState[]>;
24
+ export declare function skillStatesToOverrides(states: SkillState[]): Record<string, SkillOverrideValue>;