@defai.digital/ax-cli 4.1.11 → 4.1.15

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/.ax-cli/settings.json +1 -0
  2. package/README.md +140 -589
  3. package/bin/ax-cli +6 -0
  4. package/dist/agent/dependency-resolver.d.ts +7 -0
  5. package/dist/agent/dependency-resolver.js +46 -18
  6. package/dist/agent/dependency-resolver.js.map +1 -1
  7. package/dist/agent/execution/tool-executor.d.ts +4 -0
  8. package/dist/agent/execution/tool-executor.js +76 -52
  9. package/dist/agent/execution/tool-executor.js.map +1 -1
  10. package/dist/agent/parallel-tools.d.ts +4 -0
  11. package/dist/agent/parallel-tools.js +65 -24
  12. package/dist/agent/parallel-tools.js.map +1 -1
  13. package/dist/agent/planning/plan-executor.d.ts +0 -5
  14. package/dist/agent/planning/plan-executor.js +23 -6
  15. package/dist/agent/planning/plan-executor.js.map +1 -1
  16. package/dist/agent/streaming/stream-handler.js +7 -4
  17. package/dist/agent/streaming/stream-handler.js.map +1 -1
  18. package/dist/agent/subagent-orchestrator.d.ts +35 -2
  19. package/dist/agent/subagent-orchestrator.js +188 -146
  20. package/dist/agent/subagent-orchestrator.js.map +1 -1
  21. package/dist/agent/subagent-types.js +3 -1
  22. package/dist/agent/subagent-types.js.map +1 -1
  23. package/dist/agent/subagent.d.ts +15 -4
  24. package/dist/agent/subagent.js +91 -72
  25. package/dist/agent/subagent.js.map +1 -1
  26. package/dist/design/figma-alias.d.ts +77 -0
  27. package/dist/design/figma-alias.js +246 -0
  28. package/dist/design/figma-alias.js.map +1 -1
  29. package/dist/design/figma-client.d.ts +4 -0
  30. package/dist/design/figma-client.js +24 -4
  31. package/dist/design/figma-client.js.map +1 -1
  32. package/dist/design/figma-map.js +78 -6
  33. package/dist/design/figma-map.js.map +1 -1
  34. package/dist/design/figma-tokens.js +6 -2
  35. package/dist/design/figma-tokens.js.map +1 -1
  36. package/dist/design/index.d.ts +1 -1
  37. package/dist/design/index.js +3 -1
  38. package/dist/design/index.js.map +1 -1
  39. package/dist/design/types.d.ts +9 -0
  40. package/dist/index.js +1 -0
  41. package/dist/index.js.map +1 -1
  42. package/dist/mcp/client-v2.js +4 -0
  43. package/dist/mcp/client-v2.js.map +1 -1
  44. package/dist/mcp/config-detector.js +3 -4
  45. package/dist/mcp/config-detector.js.map +1 -1
  46. package/dist/mcp/debug.d.ts +207 -0
  47. package/dist/mcp/debug.js +398 -0
  48. package/dist/mcp/debug.js.map +1 -0
  49. package/dist/mcp/index.d.ts +1 -0
  50. package/dist/mcp/index.js +4 -0
  51. package/dist/mcp/index.js.map +1 -1
  52. package/dist/mcp/reconnection.js +6 -3
  53. package/dist/mcp/reconnection.js.map +1 -1
  54. package/dist/mcp/validation.js +15 -6
  55. package/dist/mcp/validation.js.map +1 -1
  56. package/dist/memory/index.d.ts +1 -0
  57. package/dist/memory/index.js +2 -0
  58. package/dist/memory/index.js.map +1 -1
  59. package/dist/memory/provider-context-store.d.ts +127 -0
  60. package/dist/memory/provider-context-store.js +385 -0
  61. package/dist/memory/provider-context-store.js.map +1 -0
  62. package/dist/sdk/errors.d.ts +2 -0
  63. package/dist/sdk/errors.js +2 -0
  64. package/dist/sdk/errors.js.map +1 -1
  65. package/dist/sdk/index.d.ts +633 -62
  66. package/dist/sdk/index.js +854 -116
  67. package/dist/sdk/index.js.map +1 -1
  68. package/dist/sdk/testing.d.ts +46 -4
  69. package/dist/sdk/testing.js +58 -6
  70. package/dist/sdk/testing.js.map +1 -1
  71. package/dist/sdk/version.d.ts +13 -9
  72. package/dist/sdk/version.js +13 -9
  73. package/dist/sdk/version.js.map +1 -1
  74. package/dist/utils/file-lock.d.ts +141 -0
  75. package/dist/utils/file-lock.js +559 -0
  76. package/dist/utils/file-lock.js.map +1 -0
  77. package/dist/utils/provider-context.d.ts +243 -0
  78. package/dist/utils/provider-context.js +421 -0
  79. package/dist/utils/provider-context.js.map +1 -0
  80. package/dist/utils/provider-file-cache.d.ts +91 -0
  81. package/dist/utils/provider-file-cache.js +165 -0
  82. package/dist/utils/provider-file-cache.js.map +1 -0
  83. package/dist/utils/provider-settings.d.ts +181 -0
  84. package/dist/utils/provider-settings.js +450 -0
  85. package/dist/utils/provider-settings.js.map +1 -0
  86. package/package.json +4 -3
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Provider Context - Instance-based configuration for multi-provider support
3
+ *
4
+ * This module enables running ax-glm and ax-grok in parallel without conflicts.
5
+ * Each provider gets isolated:
6
+ * - Configuration files (~/.ax-glm/ vs ~/.ax-grok/)
7
+ * - Cache directories
8
+ * - Memory stores
9
+ * - History files
10
+ * - Session data
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // CLI usage (automatic from runCLI)
15
+ * const ctx = ProviderContext.create('glm');
16
+ * ctx.activate(); // Sets as current context
17
+ *
18
+ * // SDK usage (explicit)
19
+ * const agent = await createAgent({
20
+ * provider: 'grok',
21
+ * // ... other options
22
+ * });
23
+ * ```
24
+ */
25
+ /**
26
+ * Supported provider types
27
+ */
28
+ export type ProviderType = 'glm' | 'grok' | 'generic';
29
+ /**
30
+ * Provider-specific configuration
31
+ */
32
+ export interface ProviderConfig {
33
+ /** Provider identifier */
34
+ name: ProviderType;
35
+ /** Display name for UI */
36
+ displayName: string;
37
+ /** CLI command name */
38
+ cliName: string;
39
+ /** npm package name */
40
+ package: string;
41
+ /** Default API base URL */
42
+ defaultBaseURL: string;
43
+ /** Default model */
44
+ defaultModel: string;
45
+ /** Environment variable for API key */
46
+ apiKeyEnvVar: string;
47
+ /** Provider website */
48
+ website: string;
49
+ /** Config directory name (e.g., '.ax-glm') */
50
+ configDirName: string;
51
+ }
52
+ /**
53
+ * Pre-defined provider configurations
54
+ */
55
+ export declare const PROVIDER_CONFIGS: Record<ProviderType, ProviderConfig>;
56
+ /**
57
+ * File names used by the CLI
58
+ */
59
+ export declare const PROVIDER_FILES: {
60
+ readonly CONFIG: "config.json";
61
+ readonly SETTINGS: "settings.json";
62
+ readonly CUSTOM_MD: "CUSTOM.md";
63
+ readonly MEMORY: "memory.json";
64
+ readonly HISTORY: "history.json";
65
+ readonly INDEX: "index.json";
66
+ };
67
+ /**
68
+ * Directory names used by the CLI
69
+ */
70
+ export declare const PROVIDER_DIRS: {
71
+ readonly CACHE: "cache";
72
+ readonly SESSIONS: "sessions";
73
+ readonly PLANS: "plans";
74
+ readonly TEMPLATES: "templates";
75
+ readonly CHECKPOINTS: "checkpoints";
76
+ readonly COMMANDS: "commands";
77
+ readonly BACKUPS: "backups";
78
+ };
79
+ /**
80
+ * Provider Context - Manages provider-specific paths and configuration
81
+ *
82
+ * This class provides instance-based configuration to avoid global state conflicts
83
+ * when running multiple providers in parallel.
84
+ */
85
+ export declare class ProviderContext {
86
+ private static currentContext;
87
+ private static contextStack;
88
+ readonly provider: ProviderType;
89
+ readonly config: ProviderConfig;
90
+ readonly userDir: string;
91
+ readonly projectDir: string;
92
+ private constructor();
93
+ /**
94
+ * Create a new provider context
95
+ */
96
+ static create(provider: ProviderType, projectRoot?: string): ProviderContext;
97
+ /**
98
+ * Get the current active context
99
+ * Falls back to generic if no context is set
100
+ */
101
+ static current(): ProviderContext;
102
+ /**
103
+ * Set this context as the current active context
104
+ */
105
+ activate(): void;
106
+ /**
107
+ * Push this context onto the stack and activate it
108
+ * Useful for temporary context switches
109
+ */
110
+ push(): void;
111
+ /**
112
+ * Pop the current context and restore the previous one
113
+ */
114
+ static pop(): ProviderContext | null;
115
+ /**
116
+ * Reset to no active context (for testing)
117
+ */
118
+ static reset(): void;
119
+ /** User config file path: ~/.ax-{provider}/config.json */
120
+ get userConfigPath(): string;
121
+ /** User history file path: ~/.ax-{provider}/history.json */
122
+ get userHistoryPath(): string;
123
+ /** User custom instructions: ~/.ax-{provider}/CUSTOM.md */
124
+ get userCustomMdPath(): string;
125
+ /** User cache directory: ~/.ax-{provider}/cache/ */
126
+ get userCacheDir(): string;
127
+ /** User sessions directory: ~/.ax-{provider}/sessions/ */
128
+ get userSessionsDir(): string;
129
+ /** User plans directory: ~/.ax-{provider}/plans/ */
130
+ get userPlansDir(): string;
131
+ /** User templates directory: ~/.ax-{provider}/templates/ */
132
+ get userTemplatesDir(): string;
133
+ /** User commands directory: ~/.ax-{provider}/commands/ */
134
+ get userCommandsDir(): string;
135
+ /** Project settings file: .ax-{provider}/settings.json */
136
+ get projectSettingsPath(): string;
137
+ /** Project custom instructions: .ax-{provider}/CUSTOM.md */
138
+ get projectCustomMdPath(): string;
139
+ /** Project memory file: .ax-{provider}/memory.json */
140
+ get projectMemoryPath(): string;
141
+ /** Project index file: .ax-{provider}/index.json */
142
+ get projectIndexPath(): string;
143
+ /** Project cache directory: .ax-{provider}/cache/ */
144
+ get projectCacheDir(): string;
145
+ /** Project checkpoints directory: .ax-{provider}/checkpoints/ */
146
+ get projectCheckpointsDir(): string;
147
+ /** Project commands directory: .ax-{provider}/commands/ */
148
+ get projectCommandsDir(): string;
149
+ /** Project plans directory: .ax-{provider}/plans/ */
150
+ get projectPlansDir(): string;
151
+ /**
152
+ * Ensure user directory exists with proper permissions
153
+ */
154
+ ensureUserDir(): void;
155
+ /**
156
+ * Ensure project directory exists
157
+ */
158
+ ensureProjectDir(): void;
159
+ /**
160
+ * Ensure a subdirectory exists in user dir
161
+ */
162
+ ensureUserSubdir(subdir: string): string;
163
+ /**
164
+ * Ensure a subdirectory exists in project dir
165
+ */
166
+ ensureProjectSubdir(subdir: string): string;
167
+ /**
168
+ * Get a namespaced cache key to avoid conflicts
169
+ */
170
+ getCacheNamespace(baseName: string): string;
171
+ /**
172
+ * Get environment-based API key for this provider
173
+ */
174
+ getEnvApiKey(): string | undefined;
175
+ /**
176
+ * Check if this provider is configured (has config file)
177
+ */
178
+ isConfigured(): boolean;
179
+ /**
180
+ * Get the lock file path for a given file
181
+ */
182
+ getLockPath(filePath: string): string;
183
+ /**
184
+ * Create a context for a specific project root
185
+ */
186
+ withProjectRoot(projectRoot: string): ProviderContext;
187
+ }
188
+ /**
189
+ * Get the current provider context
190
+ * Shorthand for ProviderContext.current()
191
+ */
192
+ export declare function getProviderContext(): ProviderContext;
193
+ /**
194
+ * Create and activate a provider context
195
+ */
196
+ export declare function activateProvider(provider: ProviderType, projectRoot?: string): ProviderContext;
197
+ /**
198
+ * Run a function with a temporary provider context
199
+ */
200
+ export declare function withProvider<T>(provider: ProviderType, fn: (ctx: ProviderContext) => T, projectRoot?: string): T;
201
+ /**
202
+ * Run an async function with a temporary provider context
203
+ *
204
+ * WARNING: This function uses a global stack which is NOT safe for concurrent
205
+ * async operations. If you need to run multiple providers in parallel, use
206
+ * ProviderContext.create() directly and pass the context explicitly.
207
+ *
208
+ * @example Safe usage (sequential):
209
+ * ```typescript
210
+ * await withProviderAsync('glm', async (ctx) => { ... });
211
+ * await withProviderAsync('grok', async (ctx) => { ... });
212
+ * ```
213
+ *
214
+ * @example UNSAFE - DON'T DO THIS:
215
+ * ```typescript
216
+ * await Promise.all([
217
+ * withProviderAsync('glm', async () => { ... }),
218
+ * withProviderAsync('grok', async () => { ... }),
219
+ * ]); // Race condition!
220
+ * ```
221
+ *
222
+ * @example Safe parallel usage:
223
+ * ```typescript
224
+ * const glmCtx = ProviderContext.create('glm');
225
+ * const grokCtx = ProviderContext.create('grok');
226
+ * await Promise.all([
227
+ * doWorkWith(glmCtx),
228
+ * doWorkWith(grokCtx),
229
+ * ]);
230
+ * ```
231
+ *
232
+ * @deprecated For parallel operations, use ProviderContext.create() directly
233
+ */
234
+ export declare function withProviderAsync<T>(provider: ProviderType, fn: (ctx: ProviderContext) => Promise<T>, projectRoot?: string): Promise<T>;
235
+ /**
236
+ * Validate and normalize a provider string
237
+ * Returns the provider type or null if invalid
238
+ */
239
+ export declare function validateProvider(value: string | undefined): ProviderType | null;
240
+ /**
241
+ * Detect provider from environment or fall back to generic
242
+ */
243
+ export declare function detectProvider(): ProviderType;
@@ -0,0 +1,421 @@
1
+ /**
2
+ * Provider Context - Instance-based configuration for multi-provider support
3
+ *
4
+ * This module enables running ax-glm and ax-grok in parallel without conflicts.
5
+ * Each provider gets isolated:
6
+ * - Configuration files (~/.ax-glm/ vs ~/.ax-grok/)
7
+ * - Cache directories
8
+ * - Memory stores
9
+ * - History files
10
+ * - Session data
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // CLI usage (automatic from runCLI)
15
+ * const ctx = ProviderContext.create('glm');
16
+ * ctx.activate(); // Sets as current context
17
+ *
18
+ * // SDK usage (explicit)
19
+ * const agent = await createAgent({
20
+ * provider: 'grok',
21
+ * // ... other options
22
+ * });
23
+ * ```
24
+ */
25
+ import { homedir } from 'os';
26
+ import { join, resolve } from 'path';
27
+ import { existsSync, mkdirSync } from 'fs';
28
+ /**
29
+ * Pre-defined provider configurations
30
+ */
31
+ export const PROVIDER_CONFIGS = {
32
+ glm: {
33
+ name: 'glm',
34
+ displayName: 'GLM (Z.AI)',
35
+ cliName: 'ax-glm',
36
+ package: '@defai.digital/ax-glm',
37
+ defaultBaseURL: 'https://api.z.ai/api/coding/paas/v4',
38
+ defaultModel: 'glm-4.6',
39
+ apiKeyEnvVar: 'ZAI_API_KEY',
40
+ website: 'https://z.ai',
41
+ configDirName: '.ax-glm',
42
+ },
43
+ grok: {
44
+ name: 'grok',
45
+ displayName: 'Grok (xAI)',
46
+ cliName: 'ax-grok',
47
+ package: '@defai.digital/ax-grok',
48
+ defaultBaseURL: 'https://api.x.ai/v1',
49
+ defaultModel: 'grok-3',
50
+ apiKeyEnvVar: 'XAI_API_KEY',
51
+ website: 'https://console.x.ai',
52
+ configDirName: '.ax-grok',
53
+ },
54
+ generic: {
55
+ name: 'generic',
56
+ displayName: 'AX CLI',
57
+ cliName: 'ax-cli',
58
+ package: '@defai.digital/ax-cli',
59
+ defaultBaseURL: '',
60
+ defaultModel: '',
61
+ apiKeyEnvVar: 'AI_API_KEY',
62
+ website: '',
63
+ configDirName: '.ax-cli',
64
+ },
65
+ };
66
+ /**
67
+ * File names used by the CLI
68
+ */
69
+ export const PROVIDER_FILES = {
70
+ CONFIG: 'config.json',
71
+ SETTINGS: 'settings.json',
72
+ CUSTOM_MD: 'CUSTOM.md',
73
+ MEMORY: 'memory.json',
74
+ HISTORY: 'history.json',
75
+ INDEX: 'index.json',
76
+ };
77
+ /**
78
+ * Directory names used by the CLI
79
+ */
80
+ export const PROVIDER_DIRS = {
81
+ CACHE: 'cache',
82
+ SESSIONS: 'sessions',
83
+ PLANS: 'plans',
84
+ TEMPLATES: 'templates',
85
+ CHECKPOINTS: 'checkpoints',
86
+ COMMANDS: 'commands',
87
+ BACKUPS: 'backups',
88
+ };
89
+ /**
90
+ * Provider Context - Manages provider-specific paths and configuration
91
+ *
92
+ * This class provides instance-based configuration to avoid global state conflicts
93
+ * when running multiple providers in parallel.
94
+ */
95
+ export class ProviderContext {
96
+ static currentContext = null;
97
+ static contextStack = [];
98
+ provider;
99
+ config;
100
+ userDir;
101
+ projectDir;
102
+ constructor(provider, projectRoot = process.cwd()) {
103
+ this.provider = provider;
104
+ this.config = PROVIDER_CONFIGS[provider];
105
+ this.userDir = join(homedir(), this.config.configDirName);
106
+ this.projectDir = join(projectRoot, this.config.configDirName);
107
+ }
108
+ /**
109
+ * Create a new provider context
110
+ */
111
+ static create(provider, projectRoot) {
112
+ return new ProviderContext(provider, projectRoot);
113
+ }
114
+ /**
115
+ * Get the current active context
116
+ * Falls back to generic if no context is set
117
+ */
118
+ static current() {
119
+ if (!ProviderContext.currentContext) {
120
+ // Check environment variable for provider hint
121
+ const envProvider = process.env.AX_PROVIDER;
122
+ if (envProvider && PROVIDER_CONFIGS[envProvider]) {
123
+ ProviderContext.currentContext = new ProviderContext(envProvider);
124
+ }
125
+ else {
126
+ // Default to generic
127
+ ProviderContext.currentContext = new ProviderContext('generic');
128
+ }
129
+ }
130
+ return ProviderContext.currentContext;
131
+ }
132
+ /**
133
+ * Set this context as the current active context
134
+ */
135
+ activate() {
136
+ ProviderContext.currentContext = this;
137
+ }
138
+ /**
139
+ * Push this context onto the stack and activate it
140
+ * Useful for temporary context switches
141
+ */
142
+ push() {
143
+ if (ProviderContext.currentContext) {
144
+ ProviderContext.contextStack.push(ProviderContext.currentContext);
145
+ }
146
+ this.activate();
147
+ }
148
+ /**
149
+ * Pop the current context and restore the previous one
150
+ */
151
+ static pop() {
152
+ const previous = ProviderContext.contextStack.pop();
153
+ if (previous) {
154
+ previous.activate();
155
+ }
156
+ return previous || null;
157
+ }
158
+ /**
159
+ * Reset to no active context (for testing)
160
+ */
161
+ static reset() {
162
+ ProviderContext.currentContext = null;
163
+ ProviderContext.contextStack = [];
164
+ }
165
+ // ============================================================================
166
+ // User-Level Paths (Home Directory)
167
+ // ============================================================================
168
+ /** User config file path: ~/.ax-{provider}/config.json */
169
+ get userConfigPath() {
170
+ return join(this.userDir, PROVIDER_FILES.CONFIG);
171
+ }
172
+ /** User history file path: ~/.ax-{provider}/history.json */
173
+ get userHistoryPath() {
174
+ return join(this.userDir, PROVIDER_FILES.HISTORY);
175
+ }
176
+ /** User custom instructions: ~/.ax-{provider}/CUSTOM.md */
177
+ get userCustomMdPath() {
178
+ return join(this.userDir, PROVIDER_FILES.CUSTOM_MD);
179
+ }
180
+ /** User cache directory: ~/.ax-{provider}/cache/ */
181
+ get userCacheDir() {
182
+ return join(this.userDir, PROVIDER_DIRS.CACHE);
183
+ }
184
+ /** User sessions directory: ~/.ax-{provider}/sessions/ */
185
+ get userSessionsDir() {
186
+ return join(this.userDir, PROVIDER_DIRS.SESSIONS);
187
+ }
188
+ /** User plans directory: ~/.ax-{provider}/plans/ */
189
+ get userPlansDir() {
190
+ return join(this.userDir, PROVIDER_DIRS.PLANS);
191
+ }
192
+ /** User templates directory: ~/.ax-{provider}/templates/ */
193
+ get userTemplatesDir() {
194
+ return join(this.userDir, PROVIDER_DIRS.TEMPLATES);
195
+ }
196
+ /** User commands directory: ~/.ax-{provider}/commands/ */
197
+ get userCommandsDir() {
198
+ return join(this.userDir, PROVIDER_DIRS.COMMANDS);
199
+ }
200
+ // ============================================================================
201
+ // Project-Level Paths (Current Working Directory)
202
+ // ============================================================================
203
+ /** Project settings file: .ax-{provider}/settings.json */
204
+ get projectSettingsPath() {
205
+ return join(this.projectDir, PROVIDER_FILES.SETTINGS);
206
+ }
207
+ /** Project custom instructions: .ax-{provider}/CUSTOM.md */
208
+ get projectCustomMdPath() {
209
+ return join(this.projectDir, PROVIDER_FILES.CUSTOM_MD);
210
+ }
211
+ /** Project memory file: .ax-{provider}/memory.json */
212
+ get projectMemoryPath() {
213
+ return join(this.projectDir, PROVIDER_FILES.MEMORY);
214
+ }
215
+ /** Project index file: .ax-{provider}/index.json */
216
+ get projectIndexPath() {
217
+ return join(this.projectDir, PROVIDER_FILES.INDEX);
218
+ }
219
+ /** Project cache directory: .ax-{provider}/cache/ */
220
+ get projectCacheDir() {
221
+ return join(this.projectDir, PROVIDER_DIRS.CACHE);
222
+ }
223
+ /** Project checkpoints directory: .ax-{provider}/checkpoints/ */
224
+ get projectCheckpointsDir() {
225
+ return join(this.projectDir, PROVIDER_DIRS.CHECKPOINTS);
226
+ }
227
+ /** Project commands directory: .ax-{provider}/commands/ */
228
+ get projectCommandsDir() {
229
+ return join(this.projectDir, PROVIDER_DIRS.COMMANDS);
230
+ }
231
+ /** Project plans directory: .ax-{provider}/plans/ */
232
+ get projectPlansDir() {
233
+ return join(this.projectDir, PROVIDER_DIRS.PLANS);
234
+ }
235
+ // ============================================================================
236
+ // Utility Methods
237
+ // ============================================================================
238
+ /**
239
+ * Ensure user directory exists with proper permissions
240
+ */
241
+ ensureUserDir() {
242
+ if (!existsSync(this.userDir)) {
243
+ mkdirSync(this.userDir, { recursive: true, mode: 0o700 });
244
+ }
245
+ }
246
+ /**
247
+ * Ensure project directory exists
248
+ */
249
+ ensureProjectDir() {
250
+ if (!existsSync(this.projectDir)) {
251
+ mkdirSync(this.projectDir, { recursive: true });
252
+ }
253
+ }
254
+ /**
255
+ * Ensure a subdirectory exists in user dir
256
+ */
257
+ ensureUserSubdir(subdir) {
258
+ const fullPath = join(this.userDir, subdir);
259
+ if (!existsSync(fullPath)) {
260
+ mkdirSync(fullPath, { recursive: true, mode: 0o700 });
261
+ }
262
+ return fullPath;
263
+ }
264
+ /**
265
+ * Ensure a subdirectory exists in project dir
266
+ */
267
+ ensureProjectSubdir(subdir) {
268
+ const fullPath = join(this.projectDir, subdir);
269
+ if (!existsSync(fullPath)) {
270
+ mkdirSync(fullPath, { recursive: true });
271
+ }
272
+ return fullPath;
273
+ }
274
+ /**
275
+ * Get a namespaced cache key to avoid conflicts
276
+ */
277
+ getCacheNamespace(baseName) {
278
+ return `${this.provider}_${baseName}`;
279
+ }
280
+ /**
281
+ * Get environment-based API key for this provider
282
+ */
283
+ getEnvApiKey() {
284
+ return process.env[this.config.apiKeyEnvVar];
285
+ }
286
+ /**
287
+ * Check if this provider is configured (has config file)
288
+ */
289
+ isConfigured() {
290
+ return existsSync(this.userConfigPath);
291
+ }
292
+ /**
293
+ * Get the lock file path for a given file
294
+ */
295
+ getLockPath(filePath) {
296
+ return `${filePath}.lock`;
297
+ }
298
+ /**
299
+ * Create a context for a specific project root
300
+ */
301
+ withProjectRoot(projectRoot) {
302
+ return new ProviderContext(this.provider, resolve(projectRoot));
303
+ }
304
+ }
305
+ // ============================================================================
306
+ // Convenience Functions
307
+ // ============================================================================
308
+ /**
309
+ * Get the current provider context
310
+ * Shorthand for ProviderContext.current()
311
+ */
312
+ export function getProviderContext() {
313
+ return ProviderContext.current();
314
+ }
315
+ /**
316
+ * Create and activate a provider context
317
+ */
318
+ export function activateProvider(provider, projectRoot) {
319
+ const ctx = ProviderContext.create(provider, projectRoot);
320
+ ctx.activate();
321
+ return ctx;
322
+ }
323
+ /**
324
+ * Run a function with a temporary provider context
325
+ */
326
+ export function withProvider(provider, fn, projectRoot) {
327
+ const ctx = ProviderContext.create(provider, projectRoot);
328
+ ctx.push();
329
+ try {
330
+ return fn(ctx);
331
+ }
332
+ finally {
333
+ ProviderContext.pop();
334
+ }
335
+ }
336
+ /**
337
+ * Run an async function with a temporary provider context
338
+ *
339
+ * WARNING: This function uses a global stack which is NOT safe for concurrent
340
+ * async operations. If you need to run multiple providers in parallel, use
341
+ * ProviderContext.create() directly and pass the context explicitly.
342
+ *
343
+ * @example Safe usage (sequential):
344
+ * ```typescript
345
+ * await withProviderAsync('glm', async (ctx) => { ... });
346
+ * await withProviderAsync('grok', async (ctx) => { ... });
347
+ * ```
348
+ *
349
+ * @example UNSAFE - DON'T DO THIS:
350
+ * ```typescript
351
+ * await Promise.all([
352
+ * withProviderAsync('glm', async () => { ... }),
353
+ * withProviderAsync('grok', async () => { ... }),
354
+ * ]); // Race condition!
355
+ * ```
356
+ *
357
+ * @example Safe parallel usage:
358
+ * ```typescript
359
+ * const glmCtx = ProviderContext.create('glm');
360
+ * const grokCtx = ProviderContext.create('grok');
361
+ * await Promise.all([
362
+ * doWorkWith(glmCtx),
363
+ * doWorkWith(grokCtx),
364
+ * ]);
365
+ * ```
366
+ *
367
+ * @deprecated For parallel operations, use ProviderContext.create() directly
368
+ */
369
+ export async function withProviderAsync(provider, fn, projectRoot) {
370
+ const ctx = ProviderContext.create(provider, projectRoot);
371
+ ctx.push();
372
+ try {
373
+ return await fn(ctx);
374
+ }
375
+ finally {
376
+ ProviderContext.pop();
377
+ }
378
+ }
379
+ /**
380
+ * Validate and normalize a provider string
381
+ * Returns the provider type or null if invalid
382
+ */
383
+ export function validateProvider(value) {
384
+ if (!value)
385
+ return null;
386
+ const normalized = value.toLowerCase().trim();
387
+ if (PROVIDER_CONFIGS[normalized]) {
388
+ return normalized;
389
+ }
390
+ return null;
391
+ }
392
+ // Track if we've already warned about invalid provider
393
+ let invalidProviderWarned = false;
394
+ /**
395
+ * Detect provider from environment or fall back to generic
396
+ */
397
+ export function detectProvider() {
398
+ // Check explicit environment variable
399
+ const envProvider = process.env.AX_PROVIDER;
400
+ if (envProvider) {
401
+ const validated = validateProvider(envProvider);
402
+ if (validated) {
403
+ return validated;
404
+ }
405
+ // Warn about invalid provider (only once)
406
+ if (process.env.NODE_ENV !== 'test' && !invalidProviderWarned) {
407
+ console.warn(`[ax-cli] Warning: Invalid AX_PROVIDER="${envProvider}". ` +
408
+ `Valid values: glm, grok, generic. Falling back to auto-detection.`);
409
+ invalidProviderWarned = true;
410
+ }
411
+ }
412
+ // Check API key environment variables
413
+ if (process.env.ZAI_API_KEY) {
414
+ return 'glm';
415
+ }
416
+ if (process.env.XAI_API_KEY || process.env.GROK_API_KEY) {
417
+ return 'grok';
418
+ }
419
+ return 'generic';
420
+ }
421
+ //# sourceMappingURL=provider-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider-context.js","sourceRoot":"","sources":["../../src/utils/provider-context.ts"],"names":[],"mappings":"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"}