@ace-sdk/core 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 (86) hide show
  1. package/README.md +54 -0
  2. package/dist/cache/index.d.ts +8 -0
  3. package/dist/cache/index.d.ts.map +1 -0
  4. package/dist/cache/index.js +6 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/cache/local-cache.d.ts +72 -0
  7. package/dist/cache/local-cache.d.ts.map +1 -0
  8. package/dist/cache/local-cache.js +227 -0
  9. package/dist/cache/local-cache.js.map +1 -0
  10. package/dist/cache/session-storage.d.ts +76 -0
  11. package/dist/cache/session-storage.d.ts.map +1 -0
  12. package/dist/cache/session-storage.js +237 -0
  13. package/dist/cache/session-storage.js.map +1 -0
  14. package/dist/client/ace-client.d.ts +199 -0
  15. package/dist/client/ace-client.d.ts.map +1 -0
  16. package/dist/client/ace-client.js +454 -0
  17. package/dist/client/ace-client.js.map +1 -0
  18. package/dist/client/index.d.ts +6 -0
  19. package/dist/client/index.d.ts.map +1 -0
  20. package/dist/client/index.js +5 -0
  21. package/dist/client/index.js.map +1 -0
  22. package/dist/config/context.d.ts +48 -0
  23. package/dist/config/context.d.ts.map +1 -0
  24. package/dist/config/context.js +147 -0
  25. package/dist/config/context.js.map +1 -0
  26. package/dist/config/helpers.d.ts +79 -0
  27. package/dist/config/helpers.d.ts.map +1 -0
  28. package/dist/config/helpers.js +173 -0
  29. package/dist/config/helpers.js.map +1 -0
  30. package/dist/config/index.d.ts +10 -0
  31. package/dist/config/index.d.ts.map +1 -0
  32. package/dist/config/index.js +9 -0
  33. package/dist/config/index.js.map +1 -0
  34. package/dist/config/loader.d.ts +58 -0
  35. package/dist/config/loader.d.ts.map +1 -0
  36. package/dist/config/loader.js +275 -0
  37. package/dist/config/loader.js.map +1 -0
  38. package/dist/config/migration.d.ts +29 -0
  39. package/dist/config/migration.d.ts.map +1 -0
  40. package/dist/config/migration.js +137 -0
  41. package/dist/config/migration.js.map +1 -0
  42. package/dist/config/xdg.d.ts +62 -0
  43. package/dist/config/xdg.d.ts.map +1 -0
  44. package/dist/config/xdg.js +168 -0
  45. package/dist/config/xdg.js.map +1 -0
  46. package/dist/index.d.ts +32 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +50 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/logger/index.d.ts +6 -0
  51. package/dist/logger/index.d.ts.map +1 -0
  52. package/dist/logger/index.js +5 -0
  53. package/dist/logger/index.js.map +1 -0
  54. package/dist/logger/interface.d.ts +73 -0
  55. package/dist/logger/interface.d.ts.map +1 -0
  56. package/dist/logger/interface.js +11 -0
  57. package/dist/logger/interface.js.map +1 -0
  58. package/dist/logger/noop.d.ts +32 -0
  59. package/dist/logger/noop.d.ts.map +1 -0
  60. package/dist/logger/noop.js +53 -0
  61. package/dist/logger/noop.js.map +1 -0
  62. package/dist/types/config.d.ts +94 -0
  63. package/dist/types/config.d.ts.map +1 -0
  64. package/dist/types/config.js +26 -0
  65. package/dist/types/config.js.map +1 -0
  66. package/dist/types/index.d.ts +8 -0
  67. package/dist/types/index.d.ts.map +1 -0
  68. package/dist/types/index.js +6 -0
  69. package/dist/types/index.js.map +1 -0
  70. package/dist/types/pattern.d.ts +246 -0
  71. package/dist/types/pattern.d.ts.map +1 -0
  72. package/dist/types/pattern.js +22 -0
  73. package/dist/types/pattern.js.map +1 -0
  74. package/dist/utils/code-extractor.d.ts +34 -0
  75. package/dist/utils/code-extractor.d.ts.map +1 -0
  76. package/dist/utils/code-extractor.js +116 -0
  77. package/dist/utils/code-extractor.js.map +1 -0
  78. package/dist/utils/index.d.ts +8 -0
  79. package/dist/utils/index.d.ts.map +1 -0
  80. package/dist/utils/index.js +6 -0
  81. package/dist/utils/index.js.map +1 -0
  82. package/dist/utils/semver.d.ts +41 -0
  83. package/dist/utils/semver.d.ts.map +1 -0
  84. package/dist/utils/semver.js +90 -0
  85. package/dist/utils/semver.js.map +1 -0
  86. package/package.json +58 -0
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Configuration Loader - Core Logic
3
+ *
4
+ * Loads ACE configuration from multiple sources with priority order:
5
+ * 1. Override options (passed by caller, e.g., from CLI args)
6
+ * 2. Environment variables: ACE_CONFIG_PATH, ACE_PROJECT_ID
7
+ * 3. Config file (autodiscovered or specified)
8
+ * 4. Default values (lowest)
9
+ *
10
+ * XDG Base Directory Specification:
11
+ * - Default: ~/.config/ace/config.json
12
+ * - Legacy: ~/.ace/config.json (auto-migrated with backup)
13
+ *
14
+ * @package @ace-sdk/core
15
+ */
16
+ import { readFileSync, existsSync } from 'fs';
17
+ import { homedir } from 'os';
18
+ import { join } from 'path';
19
+ import { execSync } from 'child_process';
20
+ import { autoMigrateConfig, expandPath } from './xdg.js';
21
+ /**
22
+ * Validate orgs configuration structure (v3.8.1)
23
+ */
24
+ function validateOrgsConfig(config, logger) {
25
+ if (!config.orgs)
26
+ return;
27
+ for (const [orgId, orgConfig] of Object.entries(config.orgs)) {
28
+ if (!orgConfig.apiToken) {
29
+ throw new Error(`Organization ${orgId} missing required field: apiToken`);
30
+ }
31
+ if (!orgConfig.orgName) {
32
+ logger?.warn(`Organization ${orgId} missing orgName (not critical, but recommended)`);
33
+ }
34
+ if (!Array.isArray(orgConfig.projects)) {
35
+ throw new Error(`Organization ${orgId}: projects must be an array`);
36
+ }
37
+ }
38
+ }
39
+ /**
40
+ * Resolve organization-specific API token (v3.8.1)
41
+ * Priority:
42
+ * 1. Explicit orgId override (from CLI --org-id or ENV ACE_ORG_ID)
43
+ * 2. Auto-resolve: find org containing projectId
44
+ * 3. Fallback: root-level apiToken
45
+ */
46
+ function resolveOrgToken(config, projectId, orgIdOverride) {
47
+ // No multi-org config? Use root token
48
+ if (!config.orgs) {
49
+ return { token: config.apiToken };
50
+ }
51
+ // Priority 1: Explicit org-id override
52
+ if (orgIdOverride && config.orgs[orgIdOverride]) {
53
+ const orgConfig = config.orgs[orgIdOverride];
54
+ return {
55
+ token: orgConfig.apiToken,
56
+ orgId: orgIdOverride,
57
+ orgName: orgConfig.orgName
58
+ };
59
+ }
60
+ // Priority 2: Auto-resolve from projectId
61
+ if (projectId) {
62
+ for (const [orgId, orgConfig] of Object.entries(config.orgs)) {
63
+ if (orgConfig.projects.includes(projectId)) {
64
+ return {
65
+ token: orgConfig.apiToken,
66
+ orgId: orgId,
67
+ orgName: orgConfig.orgName
68
+ };
69
+ }
70
+ }
71
+ }
72
+ // Priority 3: Fallback to root token
73
+ return { token: config.apiToken };
74
+ }
75
+ /**
76
+ * Load configuration with priority:
77
+ * 1. Override options (from caller)
78
+ * 2. Environment variables: ACE_CONFIG_PATH, ACE_PROJECT_ID
79
+ * 3. Config file (autodiscovered via XDG or specified)
80
+ * 4. Default values (lowest)
81
+ *
82
+ * @param overrides - Optional configuration overrides (typically from CLI args)
83
+ * @param logger - Optional logger for output
84
+ * @returns Loaded configuration
85
+ */
86
+ export function loadConfig(overrides = {}, logger) {
87
+ // Determine config file path with precedence
88
+ let configPath;
89
+ if (overrides.configPath) {
90
+ // Priority 1: Explicit config path from overrides
91
+ const rawPath = overrides.configPath;
92
+ configPath = expandPath(rawPath);
93
+ logger?.info(`Using config path from override: ${rawPath}`);
94
+ if (rawPath !== configPath) {
95
+ logger?.debug(`Expanded to: ${configPath}`);
96
+ }
97
+ }
98
+ else if (process.env.ACE_CONFIG_PATH) {
99
+ // Priority 2: ACE_CONFIG_PATH environment variable
100
+ const rawPath = process.env.ACE_CONFIG_PATH;
101
+ configPath = expandPath(rawPath);
102
+ logger?.info(`Using config path from environment: ACE_CONFIG_PATH=${rawPath}`);
103
+ if (rawPath !== configPath) {
104
+ logger?.debug(`Expanded to: ${configPath}`);
105
+ }
106
+ }
107
+ else {
108
+ // Priority 3: Autodiscover with XDG migration
109
+ configPath = autoMigrateConfig(logger);
110
+ }
111
+ // Initialize config with defaults
112
+ const config = {
113
+ serverUrl: '',
114
+ apiToken: '',
115
+ projectId: '',
116
+ cacheTtlMinutes: 120 // Default: 2 hours
117
+ };
118
+ // Load config file if it exists
119
+ if (existsSync(configPath)) {
120
+ try {
121
+ const fileConfig = JSON.parse(readFileSync(configPath, 'utf8'));
122
+ if (fileConfig.serverUrl)
123
+ config.serverUrl = fileConfig.serverUrl;
124
+ if (fileConfig.apiToken)
125
+ config.apiToken = fileConfig.apiToken;
126
+ if (fileConfig.cacheTtlMinutes && !isNaN(parseInt(fileConfig.cacheTtlMinutes))) {
127
+ config.cacheTtlMinutes = parseInt(fileConfig.cacheTtlMinutes);
128
+ }
129
+ // v3.8.1: Load orgs section if present
130
+ if (fileConfig.orgs) {
131
+ config.orgs = fileConfig.orgs;
132
+ }
133
+ logger?.info(`Loaded config from: ${configPath}`);
134
+ // v3.8.1: Show multi-org status
135
+ if (config.orgs) {
136
+ const orgCount = Object.keys(config.orgs).length;
137
+ logger?.debug(`Multi-org: ${orgCount} organization(s) configured`);
138
+ }
139
+ }
140
+ catch (error) {
141
+ logger?.warn(`Failed to load config from: ${configPath}`);
142
+ logger?.error('Error:', error instanceof Error ? error : String(error));
143
+ }
144
+ }
145
+ else {
146
+ logger?.info(`Config file not found: ${configPath}`);
147
+ logger?.debug('Config file should contain serverUrl and apiToken');
148
+ }
149
+ // BACKWARD COMPATIBILITY: Check for deprecated project-local config
150
+ let projectRoot;
151
+ try {
152
+ projectRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
153
+ }
154
+ catch (error) {
155
+ projectRoot = process.cwd();
156
+ }
157
+ const projectConfigPath = join(projectRoot, '.ace', 'config.json');
158
+ if (existsSync(projectConfigPath)) {
159
+ try {
160
+ logger?.warn(`DEPRECATED: Found project-local config at: ${projectConfigPath}`);
161
+ logger?.info('This config format is deprecated. Please migrate to:');
162
+ logger?.info(' - Global config: ~/.config/ace/config.json (credentials with multi-org support)');
163
+ logger?.info(' - ENV variables: ACE_ORG_ID and ACE_PROJECT_ID');
164
+ logger?.info('Loading deprecated config for backward compatibility...');
165
+ const projectConfig = JSON.parse(readFileSync(projectConfigPath, 'utf8'));
166
+ // Override global config with project-local config (maintaining old behavior)
167
+ if (projectConfig.serverUrl)
168
+ config.serverUrl = projectConfig.serverUrl;
169
+ if (projectConfig.apiToken)
170
+ config.apiToken = projectConfig.apiToken;
171
+ if (projectConfig.projectId)
172
+ config.projectId = projectConfig.projectId;
173
+ if (projectConfig.cacheTtlMinutes && !isNaN(parseInt(projectConfig.cacheTtlMinutes))) {
174
+ config.cacheTtlMinutes = parseInt(projectConfig.cacheTtlMinutes);
175
+ }
176
+ logger?.info(`Loaded project-local config (deprecated): ${projectConfigPath}`);
177
+ }
178
+ catch (error) {
179
+ logger?.warn(`Failed to load project-local config: ${projectConfigPath}`);
180
+ logger?.error('Error:', error instanceof Error ? error : String(error));
181
+ }
182
+ }
183
+ // Override with environment variables
184
+ if (process.env.ACE_SERVER_URL) {
185
+ config.serverUrl = process.env.ACE_SERVER_URL;
186
+ }
187
+ if (process.env.ACE_API_TOKEN) {
188
+ config.apiToken = process.env.ACE_API_TOKEN;
189
+ }
190
+ if (process.env.ACE_PROJECT_ID) {
191
+ config.projectId = process.env.ACE_PROJECT_ID;
192
+ }
193
+ if (process.env.ACE_CACHE_TTL_MINUTES) {
194
+ const ttl = parseInt(process.env.ACE_CACHE_TTL_MINUTES, 10);
195
+ if (!isNaN(ttl) && ttl > 0) {
196
+ config.cacheTtlMinutes = ttl;
197
+ }
198
+ }
199
+ // v3.8.1: Organization ID environment variable
200
+ let envOrgId;
201
+ if (process.env.ACE_ORG_ID) {
202
+ envOrgId = process.env.ACE_ORG_ID;
203
+ }
204
+ // Override with explicit overrides (highest priority)
205
+ if (overrides.serverUrl) {
206
+ config.serverUrl = overrides.serverUrl;
207
+ logger?.debug('Using serverUrl from override');
208
+ }
209
+ if (overrides.apiToken) {
210
+ config.apiToken = overrides.apiToken;
211
+ logger?.debug('Using apiToken from override');
212
+ }
213
+ if (overrides.projectId) {
214
+ config.projectId = overrides.projectId;
215
+ logger?.debug('Using projectId from override');
216
+ }
217
+ if (overrides.cacheTtlMinutes !== undefined) {
218
+ config.cacheTtlMinutes = overrides.cacheTtlMinutes;
219
+ logger?.debug('Using cacheTtlMinutes from override');
220
+ }
221
+ // v3.8.1: CLI orgId has highest priority
222
+ const finalOrgId = overrides.orgId || envOrgId;
223
+ if (overrides.orgId) {
224
+ logger?.debug('Using orgId from override');
225
+ }
226
+ // Defaults for missing values
227
+ if (!config.serverUrl) {
228
+ config.serverUrl = 'http://localhost:9000';
229
+ logger?.info('Using default server URL: http://localhost:9000');
230
+ }
231
+ // v3.8.1: Validate orgs configuration if present
232
+ try {
233
+ validateOrgsConfig(config, logger);
234
+ }
235
+ catch (error) {
236
+ logger?.error('Invalid orgs configuration!', error instanceof Error ? error : String(error));
237
+ throw error;
238
+ }
239
+ // v3.8.1: Resolve organization-specific token
240
+ // Note: Skip resolution if explicit apiToken was provided (highest priority)
241
+ if (!overrides.apiToken && !process.env.ACE_API_TOKEN && config.orgs) {
242
+ const resolution = resolveOrgToken(config, config.projectId, finalOrgId);
243
+ config.apiToken = resolution.token;
244
+ if (resolution.orgId) {
245
+ logger?.info(`Using token from organization: ${resolution.orgName} (${resolution.orgId})`);
246
+ }
247
+ else if (config.orgs) {
248
+ logger?.info('Project not found in any org, using fallback token');
249
+ }
250
+ }
251
+ // DEBUG: Log final configuration
252
+ logger?.debug('Final Configuration:');
253
+ logger?.debug(` serverUrl: ${config.serverUrl}`);
254
+ logger?.debug(` apiToken: ${config.apiToken ? config.apiToken.substring(0, 20) + '...' : 'MISSING'}`);
255
+ logger?.debug(` projectId: ${config.projectId || 'MISSING'}`);
256
+ logger?.debug(` cacheTtlMinutes: ${config.cacheTtlMinutes}`);
257
+ if (config.orgs) {
258
+ logger?.debug(` multiOrg: ${Object.keys(config.orgs).length} organization(s) configured`);
259
+ }
260
+ return config;
261
+ }
262
+ /**
263
+ * Get config file path
264
+ */
265
+ export function getConfigPath() {
266
+ return join(homedir(), '.ace', 'config.json');
267
+ }
268
+ /**
269
+ * Check if configuration is complete
270
+ */
271
+ export function isConfigured(overrides = {}, logger) {
272
+ const config = loadConfig(overrides, logger);
273
+ return !!(config.apiToken && config.projectId);
274
+ }
275
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Configuration Migration System
3
+ * Auto-migrates from old single-config to new dual-config system
4
+ *
5
+ * Old format (v3.6.2 and earlier):
6
+ * ./.ace/config.json - All settings in project directory
7
+ *
8
+ * New format (v3.7.0+):
9
+ * ~/.ace/config.json - Global settings (serverUrl, apiToken, cacheTtlMinutes)
10
+ * ./.ace/config.json - Project settings (projectId only)
11
+ *
12
+ * @package @ace-sdk/core
13
+ */
14
+ import { ILogger } from '../logger/index.js';
15
+ /**
16
+ * Perform migration from old to new config format
17
+ * v3.3.1 → v3.7.0: Single config → Dual config (global + project args)
18
+ */
19
+ export declare function migrateConfig(logger?: ILogger): boolean;
20
+ /**
21
+ * Check and perform migration if needed
22
+ * Called during configuration loading
23
+ */
24
+ export declare function checkAndMigrate(logger?: ILogger): void;
25
+ /**
26
+ * Auto-migrate if needed (silent, non-blocking)
27
+ */
28
+ export declare function autoMigrate(logger?: ILogger): void;
29
+ //# sourceMappingURL=migration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AA2C7C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAiEvD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAQtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI,CAoBlD"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Configuration Migration System
3
+ * Auto-migrates from old single-config to new dual-config system
4
+ *
5
+ * Old format (v3.6.2 and earlier):
6
+ * ./.ace/config.json - All settings in project directory
7
+ *
8
+ * New format (v3.7.0+):
9
+ * ~/.ace/config.json - Global settings (serverUrl, apiToken, cacheTtlMinutes)
10
+ * ./.ace/config.json - Project settings (projectId only)
11
+ *
12
+ * @package @ace-sdk/core
13
+ */
14
+ import { readFileSync, writeFileSync, existsSync, renameSync, mkdirSync } from 'fs';
15
+ import { homedir } from 'os';
16
+ import { join } from 'path';
17
+ import { execSync } from 'child_process';
18
+ /**
19
+ * Detect if old config format exists
20
+ */
21
+ function hasOldConfig() {
22
+ // Try to find project root
23
+ let projectRoot;
24
+ try {
25
+ projectRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
26
+ }
27
+ catch {
28
+ projectRoot = process.cwd();
29
+ }
30
+ const oldConfigPath = join(projectRoot, '.ace', 'config.json');
31
+ return {
32
+ exists: existsSync(oldConfigPath),
33
+ path: oldConfigPath
34
+ };
35
+ }
36
+ /**
37
+ * Check if global config already exists
38
+ */
39
+ function hasGlobalConfig() {
40
+ const globalConfigPath = join(homedir(), '.ace', 'config.json');
41
+ return existsSync(globalConfigPath);
42
+ }
43
+ /**
44
+ * Perform migration from old to new config format
45
+ * v3.3.1 → v3.7.0: Single config → Dual config (global + project args)
46
+ */
47
+ export function migrateConfig(logger) {
48
+ const oldConfigInfo = hasOldConfig();
49
+ // No old config to migrate
50
+ if (!oldConfigInfo.exists) {
51
+ return false;
52
+ }
53
+ logger?.info('Detected v3.3.1 config - migrating to v3.7.0 dual-config...');
54
+ try {
55
+ // Read old config
56
+ const oldConfig = JSON.parse(readFileSync(oldConfigInfo.path, 'utf8'));
57
+ // Skip migration if config is already in new format (no server settings)
58
+ const hasOnlyProjectId = oldConfig.projectId &&
59
+ !oldConfig.serverUrl &&
60
+ !oldConfig.apiToken &&
61
+ !oldConfig.cacheTtlMinutes;
62
+ if (hasOnlyProjectId) {
63
+ logger?.info('Config already in new format - skipping migration');
64
+ return false;
65
+ }
66
+ // Create global config if it doesn't exist
67
+ if (!hasGlobalConfig() && (oldConfig.serverUrl || oldConfig.apiToken)) {
68
+ const globalConfigPath = join(homedir(), '.ace', 'config.json');
69
+ const globalConfigDir = join(homedir(), '.ace');
70
+ // Ensure global config directory exists
71
+ if (!existsSync(globalConfigDir)) {
72
+ mkdirSync(globalConfigDir, { recursive: true });
73
+ }
74
+ const globalConfig = {
75
+ serverUrl: oldConfig.serverUrl || 'http://localhost:9000',
76
+ apiToken: oldConfig.apiToken || '',
77
+ cacheTtlMinutes: oldConfig.cacheTtlMinutes || 120
78
+ };
79
+ writeFileSync(globalConfigPath, JSON.stringify(globalConfig, null, 2), 'utf8');
80
+ logger?.success(`Created global config: ${globalConfigPath}`);
81
+ }
82
+ else {
83
+ logger?.info('Global config already exists - skipping global config creation');
84
+ }
85
+ // Backup old config (DO NOT create new ./.ace/config.json)
86
+ const backupPath = `${oldConfigInfo.path}.v3.3.1.backup`;
87
+ renameSync(oldConfigInfo.path, backupPath);
88
+ logger?.success(`Backed up old config: ${backupPath}`);
89
+ logger?.success('Migration complete!');
90
+ logger?.info('New configuration:');
91
+ logger?.info(' Global: ~/.ace/config.json (serverUrl, apiToken, cacheTtlMinutes)');
92
+ logger?.info(' Project: .claude/settings.local.json (managed by plugin)');
93
+ logger?.info('To complete migration, run: ce-ace config');
94
+ return true;
95
+ }
96
+ catch (error) {
97
+ logger?.error('Migration failed:', error instanceof Error ? error : String(error));
98
+ logger?.info('Your old config has been preserved');
99
+ return false;
100
+ }
101
+ }
102
+ /**
103
+ * Check and perform migration if needed
104
+ * Called during configuration loading
105
+ */
106
+ export function checkAndMigrate(logger) {
107
+ const oldConfigInfo = hasOldConfig();
108
+ if (oldConfigInfo.exists && !hasGlobalConfig()) {
109
+ logger?.info('Old config format detected. Migration recommended.');
110
+ logger?.info('Run: ce-ace config');
111
+ logger?.info('Or migration will happen automatically on next startup');
112
+ }
113
+ }
114
+ /**
115
+ * Auto-migrate if needed (silent, non-blocking)
116
+ */
117
+ export function autoMigrate(logger) {
118
+ const oldConfigInfo = hasOldConfig();
119
+ // Only auto-migrate if:
120
+ // 1. Old config exists
121
+ // 2. Global config doesn't exist
122
+ // 3. Old config has server settings (not already migrated)
123
+ if (oldConfigInfo.exists && !hasGlobalConfig()) {
124
+ try {
125
+ const oldConfig = JSON.parse(readFileSync(oldConfigInfo.path, 'utf8'));
126
+ // Check if old config has server settings (needs migration)
127
+ if (oldConfig.serverUrl || oldConfig.apiToken) {
128
+ migrateConfig(logger);
129
+ }
130
+ }
131
+ catch (error) {
132
+ // Silent failure - don't block startup
133
+ logger?.warn(`Auto-migration failed (non-critical): ${error instanceof Error ? error.message : String(error)}`);
134
+ }
135
+ }
136
+ }
137
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/config/migration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * XDG Base Directory Specification support for ACE config files
3
+ *
4
+ * New default path: ~/.config/ace/config.json (XDG standard)
5
+ * Legacy fallback: ~/.ace/config.json (backward compatibility)
6
+ *
7
+ * @package @ace-sdk/core
8
+ */
9
+ import { ILogger } from '../logger/index.js';
10
+ /**
11
+ * Expand shell variables in a path string
12
+ *
13
+ * Supports:
14
+ * - Tilde expansion: ~/path → /home/user/path
15
+ * - Simple variables: $HOME → /home/user
16
+ * - Braced variables: ${HOME} → /home/user
17
+ * - Default values: ${VAR:-default} → default (if VAR not set)
18
+ * - Nested defaults: ${XDG_CONFIG_HOME:-${HOME}/.config}
19
+ *
20
+ * @param pathString Path with potential shell variables
21
+ * @returns Expanded absolute path
22
+ */
23
+ export declare function expandPath(pathString: string): string;
24
+ /**
25
+ * Autodiscover config file path following XDG Base Directory specification
26
+ *
27
+ * Priority:
28
+ * 1. XDG path: ~/.config/ace/config.json (or $XDG_CONFIG_HOME/ace/config.json)
29
+ * 2. Legacy path: ~/.ace/config.json (backward compatibility with warning)
30
+ * 3. Default: XDG path (even if doesn't exist yet)
31
+ */
32
+ export declare function autodiscoverConfigPath(logger?: ILogger): string;
33
+ /**
34
+ * Get the legacy config path for migration purposes
35
+ */
36
+ export declare function getLegacyConfigPath(): string;
37
+ /**
38
+ * Get the XDG config path
39
+ */
40
+ export declare function getXdgConfigPath(): string;
41
+ /**
42
+ * Auto-migrate config from legacy path to XDG path
43
+ *
44
+ * Migration strategy:
45
+ * - Only migrate if legacy exists and XDG doesn't
46
+ * - Create XDG directory with secure permissions (0700)
47
+ * - Copy config to XDG path with secure permissions (0600)
48
+ * - Rename legacy config to .bak (don't delete)
49
+ * - Print clear migration messages
50
+ *
51
+ * @returns The config path to use (XDG path after migration)
52
+ */
53
+ export declare function autoMigrateConfig(logger?: ILogger): string;
54
+ /**
55
+ * Ensure config directory exists with secure permissions
56
+ */
57
+ export declare function ensureConfigDirectory(configPath: string): void;
58
+ /**
59
+ * Set secure permissions on config file
60
+ */
61
+ export declare function setSecurePermissions(configPath: string): void;
62
+ //# sourceMappingURL=xdg.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xdg.d.ts","sourceRoot":"","sources":["../../src/config/xdg.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAwCrD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAmB/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAgD1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAM9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAI7D"}