@ratio-mcp/dev-server 1.0.1 → 1.1.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 (83) hide show
  1. package/dist/index.d.ts +9 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +41 -9
  4. package/dist/index.js.map +1 -1
  5. package/dist/orchestrated-index.d.ts +16 -0
  6. package/dist/orchestrated-index.d.ts.map +1 -0
  7. package/dist/orchestrated-index.js +41 -0
  8. package/dist/orchestrated-index.js.map +1 -0
  9. package/dist/orchestrated-server.d.ts +16 -0
  10. package/dist/orchestrated-server.d.ts.map +1 -0
  11. package/dist/orchestrated-server.js +63 -0
  12. package/dist/orchestrated-server.js.map +1 -0
  13. package/dist/server.d.ts.map +1 -1
  14. package/dist/server.js +26 -0
  15. package/dist/server.js.map +1 -1
  16. package/dist/services/orchestrator.d.ts +63 -0
  17. package/dist/services/orchestrator.d.ts.map +1 -0
  18. package/dist/services/orchestrator.js +769 -0
  19. package/dist/services/orchestrator.js.map +1 -0
  20. package/dist/services/response-formatter.d.ts +24 -0
  21. package/dist/services/response-formatter.d.ts.map +1 -0
  22. package/dist/services/response-formatter.js +311 -0
  23. package/dist/services/response-formatter.js.map +1 -0
  24. package/dist/services/session-state.d.ts +51 -0
  25. package/dist/services/session-state.d.ts.map +1 -0
  26. package/dist/services/session-state.js +248 -0
  27. package/dist/services/session-state.js.map +1 -0
  28. package/dist/services/tool-guard.d.ts +20 -0
  29. package/dist/services/tool-guard.d.ts.map +1 -0
  30. package/dist/services/tool-guard.js +164 -0
  31. package/dist/services/tool-guard.js.map +1 -0
  32. package/dist/store/requirements-store.d.ts.map +1 -1
  33. package/dist/store/requirements-store.js +16 -3
  34. package/dist/store/requirements-store.js.map +1 -1
  35. package/dist/store/token-store.d.ts.map +1 -1
  36. package/dist/store/token-store.js +8 -2
  37. package/dist/store/token-store.js.map +1 -1
  38. package/dist/templates/backend/.env.example +3 -1
  39. package/dist/tools/agent-chat.d.ts +9 -0
  40. package/dist/tools/agent-chat.d.ts.map +1 -0
  41. package/dist/tools/agent-chat.js +379 -0
  42. package/dist/tools/agent-chat.js.map +1 -0
  43. package/dist/tools/app-management.d.ts.map +1 -1
  44. package/dist/tools/app-management.js +29 -8
  45. package/dist/tools/app-management.js.map +1 -1
  46. package/dist/tools/auth.d.ts.map +1 -1
  47. package/dist/tools/auth.js +45 -8
  48. package/dist/tools/auth.js.map +1 -1
  49. package/dist/tools/build.d.ts.map +1 -1
  50. package/dist/tools/build.js +13 -2
  51. package/dist/tools/build.js.map +1 -1
  52. package/dist/tools/codegen.d.ts.map +1 -1
  53. package/dist/tools/codegen.js +39 -6
  54. package/dist/tools/codegen.js.map +1 -1
  55. package/dist/tools/gather-requirements.d.ts +3 -0
  56. package/dist/tools/gather-requirements.d.ts.map +1 -0
  57. package/dist/tools/gather-requirements.js +281 -0
  58. package/dist/tools/gather-requirements.js.map +1 -0
  59. package/dist/tools/index.d.ts.map +1 -1
  60. package/dist/tools/index.js +7 -1
  61. package/dist/tools/index.js.map +1 -1
  62. package/dist/tools/lifecycle.d.ts.map +1 -1
  63. package/dist/tools/lifecycle.js +40 -32
  64. package/dist/tools/lifecycle.js.map +1 -1
  65. package/dist/tools/reference-data.d.ts +8 -0
  66. package/dist/tools/reference-data.d.ts.map +1 -0
  67. package/dist/tools/reference-data.js +79 -0
  68. package/dist/tools/reference-data.js.map +1 -0
  69. package/dist/tools/scaffold.d.ts.map +1 -1
  70. package/dist/tools/scaffold.js +17 -1
  71. package/dist/tools/scaffold.js.map +1 -1
  72. package/dist/tools/submission.d.ts.map +1 -1
  73. package/dist/tools/submission.js +79 -21
  74. package/dist/tools/submission.js.map +1 -1
  75. package/dist/tools/webhooks.d.ts +3 -0
  76. package/dist/tools/webhooks.d.ts.map +1 -0
  77. package/dist/tools/webhooks.js +303 -0
  78. package/dist/tools/webhooks.js.map +1 -0
  79. package/dist/utils/logger.d.ts +15 -5
  80. package/dist/utils/logger.d.ts.map +1 -1
  81. package/dist/utils/logger.js +93 -14
  82. package/dist/utils/logger.js.map +1 -1
  83. package/package.json +18 -15
@@ -0,0 +1,379 @@
1
+ import { z } from 'zod';
2
+ import { allDevTools } from './index.js';
3
+ import { getNextStep, getCurrentPhase, canSkipPhase, } from '../services/orchestrator.js';
4
+ import { getSession, recordToolSuccess, resetSession, } from '../services/session-state.js';
5
+ import { formatSuccess, formatInputNeeded, formatError, formatComplete, } from '../services/response-formatter.js';
6
+ import { logger } from '../utils/logger.js';
7
+ /**
8
+ * Input schema for the agent-chat tool.
9
+ * This is the single unified tool that replaces all 24+ individual tools.
10
+ */
11
+ const agentChatSchema = z.object({
12
+ message: z.string().describe('The user message or intent. Can be natural language like "I want to build an order management app" ' +
13
+ 'OR structured input like providing app details. For the very first message, just say what you want to build.'),
14
+ input_data: z
15
+ .record(z.unknown())
16
+ .optional()
17
+ .describe('Structured input data when the orchestrator requests specific fields. ' +
18
+ 'For example: { "email": "dev@example.com", "password": "pass123" } for login, ' +
19
+ 'or { "name": "My App", "description": "..." } for app creation. ' +
20
+ 'The previous response will tell you exactly which fields are needed.'),
21
+ action: z
22
+ .enum(['next', 'skip', 'status', 'reset'])
23
+ .default('next')
24
+ .describe('Action to take: "next" = proceed with flow (default), ' +
25
+ '"skip" = skip current optional phase (only webhooks), ' +
26
+ '"status" = show current progress without advancing, ' +
27
+ '"reset" = start over from scratch'),
28
+ });
29
+ /**
30
+ * Normalize input field names so each tool always receives its canonical fields.
31
+ *
32
+ * The LLM can send reasonable variants like "categories" or "categoryIds"
33
+ * instead of the exact "category_ids" the Zod schema expects. Instead of
34
+ * scattering fallback logic in every tool handler, we fix it once here — the
35
+ * same way the backend DTO enforces a single canonical field via class-validator.
36
+ *
37
+ * Rules per tool are explicit and easy to audit.
38
+ */
39
+ function normalizeToolInput(toolName, args) {
40
+ const normalized = { ...args };
41
+ if (toolName === 'create_app' || toolName === 'update_app') {
42
+ // Canonical field: category_ids (array of slugs)
43
+ // LLM may send: categories, categoryIds, category_slugs
44
+ if (!normalized.category_ids) {
45
+ const value = normalized.categories ??
46
+ normalized.categoryIds ??
47
+ normalized.category_slugs;
48
+ if (value) {
49
+ normalized.category_ids = value;
50
+ delete normalized.categories;
51
+ delete normalized.categoryIds;
52
+ delete normalized.category_slugs;
53
+ logger.info(`[normalizeToolInput] Mapped variant field to category_ids for ${toolName}`);
54
+ }
55
+ }
56
+ }
57
+ if (toolName === 'build_frontend') {
58
+ // If project_path doesn't contain a package.json but has a /frontend
59
+ // sub-directory, the scaffold tool returned the parent path — adjust
60
+ // to point at the actual frontend dir. This mirrors the backend's
61
+ // approach of resolving paths at the controller layer.
62
+ // (Handled at runtime in the tool itself — see build.ts fix.)
63
+ }
64
+ return normalized;
65
+ }
66
+ /**
67
+ * Handler for the unified agent-chat tool.
68
+ * Orchestrates the entire Ratio app development lifecycle through a single interface.
69
+ */
70
+ async function handleAgentChat(input) {
71
+ try {
72
+ const { message, input_data, action } = input;
73
+ const inputData = input_data;
74
+ const actionType = action || 'next';
75
+ logger.info(`agent-chat: action=${actionType}, hasInputData=${!!inputData}, messageLen=${String(message).length}`);
76
+ // ─────────────────────────────────────────────────────────────────────
77
+ // Capture app description from early messages for later use
78
+ // (e.g., "I want to build an order management app")
79
+ // ─────────────────────────────────────────────────────────────────────
80
+ const session = getSession();
81
+ const msgStr = String(message || '').trim();
82
+ if (msgStr.length > 10 && !session.context.appDescription) {
83
+ // Store the developer's initial description — used by gather_requirements
84
+ session.context.appDescription = msgStr;
85
+ logger.info(`Captured app description: "${msgStr.substring(0, 80)}..."`);
86
+ }
87
+ // Also capture from input_data.description if provided during app creation
88
+ if (inputData?.description && !session.context.appDescription) {
89
+ session.context.appDescription = String(inputData.description);
90
+ }
91
+ // ─────────────────────────────────────────────────────────────────────
92
+ // Action: reset
93
+ // ─────────────────────────────────────────────────────────────────────
94
+ if (actionType === 'reset') {
95
+ resetSession();
96
+ logger.info('Session reset by user');
97
+ return {
98
+ message: 'Session reset. Starting fresh! Tell me about the app you want to build.',
99
+ phase: 'auth',
100
+ progress: { current: 0, total: 15, percentage: 0 },
101
+ needsInput: true,
102
+ inputPrompt: 'What kind of app would you like to build? (e.g., "order management app", "inventory tracking system")',
103
+ inputFields: ['message'],
104
+ };
105
+ }
106
+ // ─────────────────────────────────────────────────────────────────────
107
+ // Action: status
108
+ // ─────────────────────────────────────────────────────────────────────
109
+ if (actionType === 'status') {
110
+ const currentPhase = getCurrentPhase();
111
+ const orchestratorResult = getNextStep(inputData);
112
+ return {
113
+ message: `Current phase: ${orchestratorResult.phase_description}. ${orchestratorResult.message}`,
114
+ phase: currentPhase,
115
+ progress: orchestratorResult.progress,
116
+ needsInput: orchestratorResult.needsInput,
117
+ inputPrompt: orchestratorResult.inputPrompt,
118
+ inputFields: orchestratorResult.inputFields,
119
+ };
120
+ }
121
+ // ─────────────────────────────────────────────────────────────────────
122
+ // Action: skip
123
+ // ─────────────────────────────────────────────────────────────────────
124
+ if (actionType === 'skip') {
125
+ const currentPhase = getCurrentPhase();
126
+ // Check if this phase can be skipped
127
+ if (!canSkipPhase(currentPhase)) {
128
+ return {
129
+ message: `Cannot skip "${currentPhase}" phase. This phase is required.`,
130
+ phase: currentPhase,
131
+ progress: { current: 0, total: 15, percentage: 0 },
132
+ needsInput: false,
133
+ error: `Phase "${currentPhase}" is mandatory and cannot be skipped.`,
134
+ };
135
+ }
136
+ // Mark phase as complete and advance
137
+ const session = getSession();
138
+ if (currentPhase === 'webhooks') {
139
+ session.context.webhooksConfigured = true;
140
+ recordToolSuccess('skip_webhooks', { skipped: true });
141
+ logger.info('Webhooks phase skipped');
142
+ }
143
+ // Get the next step after skipping
144
+ const nextOrchestrationResult = getNextStep();
145
+ if (nextOrchestrationResult.phase === 'complete') {
146
+ return formatComplete();
147
+ }
148
+ return formatInputNeeded(nextOrchestrationResult);
149
+ }
150
+ // ─────────────────────────────────────────────────────────────────────
151
+ // Action: next (main flow)
152
+ // ─────────────────────────────────────────────────────────────────────
153
+ if (actionType === 'next') {
154
+ // Step 1: Get orchestrator guidance
155
+ const orchestratorResult = getNextStep(inputData);
156
+ logger.info(`Orchestrator returned phase=${orchestratorResult.phase}, tool=${orchestratorResult.toolToCall}, needsInput=${orchestratorResult.needsInput}`);
157
+ // Step 2: Check if we're done
158
+ if (orchestratorResult.phase === 'complete') {
159
+ logger.info('Application development complete');
160
+ return formatComplete();
161
+ }
162
+ // Step 3: Check if user input is required
163
+ if (orchestratorResult.needsInput && !inputData) {
164
+ logger.info(`Input needed for ${orchestratorResult.toolToCall}: fields=${orchestratorResult.inputFields}`);
165
+ return formatInputNeeded(orchestratorResult);
166
+ }
167
+ // Step 4: Execute the tool
168
+ const toolName = orchestratorResult.toolToCall;
169
+ let toolArgs = { ...orchestratorResult.toolArgs };
170
+ logger.info(`[agent-chat] ── TOOL EXECUTION ──`);
171
+ logger.info(`[agent-chat] Tool: ${toolName}`);
172
+ logger.info(`[agent-chat] Orchestrator args: ${JSON.stringify(orchestratorResult.toolArgs)}`);
173
+ // If user provided input, merge it with orchestrator-provided args
174
+ if (inputData) {
175
+ logger.info(`[agent-chat] User inputData: ${JSON.stringify(inputData)}`);
176
+ toolArgs = { ...toolArgs, ...inputData };
177
+ logger.info(`[agent-chat] Merged args: ${JSON.stringify(toolArgs)}`);
178
+ }
179
+ // ── Normalize input field names ──────────────────────────────────
180
+ toolArgs = normalizeToolInput(toolName, toolArgs);
181
+ logger.info(`[agent-chat] Normalized args: ${JSON.stringify(toolArgs)}`);
182
+ // Find the tool from the registry
183
+ const tool = allDevTools.find((t) => t.name === toolName);
184
+ if (!tool) {
185
+ logger.error(`Tool not found: ${toolName}`);
186
+ return formatError(orchestratorResult, new Error(`Tool "${toolName}" not found in registry`), toolName);
187
+ }
188
+ // Validate & apply Zod defaults before executing.
189
+ // Direct MCP tool calls go through Zod automatically, but agent_chat
190
+ // bypasses that — so we parse here to ensure .default() values,
191
+ // type coercions, and validations all apply consistently.
192
+ let validatedArgs = toolArgs;
193
+ try {
194
+ validatedArgs = tool.inputSchema.parse(toolArgs);
195
+ logger.info(`[agent-chat] Zod validation passed for ${toolName}`);
196
+ }
197
+ catch (zodError) {
198
+ // If Zod rejects the input, log it but still try with raw args
199
+ // (some tools handle loose input gracefully)
200
+ logger.warn(`[agent-chat] Zod validation failed for ${toolName}, using raw args: ${zodError instanceof Error ? zodError.message : String(zodError)}`);
201
+ }
202
+ // Execute the tool
203
+ let toolResult;
204
+ const startTime = Date.now();
205
+ try {
206
+ toolResult = await tool.handler(validatedArgs);
207
+ const duration = Date.now() - startTime;
208
+ logger.info(`[agent-chat] Tool ${toolName} succeeded in ${duration}ms`);
209
+ logger.info(`[agent-chat] Tool ${toolName} result keys: ${toolResult ? JSON.stringify(Object.keys(toolResult)) : 'null'}`);
210
+ logger.debug(`[agent-chat] Tool ${toolName} full result: ${JSON.stringify(toolResult)?.slice(0, 3000)}`);
211
+ }
212
+ catch (error) {
213
+ const duration = Date.now() - startTime;
214
+ logger.error(`[agent-chat] Tool ${toolName} FAILED in ${duration}ms: ${error instanceof Error ? error.message : String(error)}`);
215
+ if (error instanceof Error && error.stack) {
216
+ logger.error(`[agent-chat] Stack: ${error.stack}`);
217
+ }
218
+ return formatError(orchestratorResult, error instanceof Error ? error : new Error(String(error)), toolName);
219
+ }
220
+ // Step 5: Check if the tool returned a soft error (error: true in result)
221
+ const resultObj = toolResult;
222
+ if (resultObj && resultObj.error === true) {
223
+ logger.error(`[agent-chat] Tool ${toolName} returned soft error: ${resultObj.message || 'Unknown error'}`);
224
+ return formatError(orchestratorResult, new Error(String(resultObj.message || `Tool "${toolName}" returned an error`)), toolName);
225
+ }
226
+ // Step 6: Record success and get next step
227
+ logger.info(`[agent-chat] Recording success for ${toolName} and getting next step...`);
228
+ recordToolSuccess(toolName, toolResult);
229
+ const nextOrchestrationResult = getNextStep();
230
+ logger.info(`[agent-chat] Next step after ${toolName}: phase=${nextOrchestrationResult.phase}, tool=${nextOrchestrationResult.toolToCall}`);
231
+ // Step 6: Check if we're now complete
232
+ if (nextOrchestrationResult.phase === 'complete') {
233
+ logger.info('Application development complete after tool execution');
234
+ return formatComplete();
235
+ }
236
+ // Step 7: Return success with what's next
237
+ const successResponse = formatSuccess(nextOrchestrationResult, toolResult, toolName);
238
+ logger.info(`Returning success response. Next phase: ${nextOrchestrationResult.phase}`);
239
+ return successResponse;
240
+ }
241
+ // Default fallback (should not reach here with valid action enum)
242
+ return {
243
+ message: 'Invalid action. Please use "next", "skip", "status", or "reset".',
244
+ phase: getCurrentPhase(),
245
+ progress: { current: 0, total: 15, percentage: 0 },
246
+ needsInput: false,
247
+ error: `Unknown action: ${actionType}`,
248
+ };
249
+ }
250
+ catch (error) {
251
+ logger.error(`Unexpected error in agent-chat: ${error instanceof Error ? error.message : String(error)}`);
252
+ return {
253
+ message: 'An unexpected error occurred. Please try again or reset the session.',
254
+ phase: getCurrentPhase(),
255
+ progress: { current: 0, total: 15, percentage: 0 },
256
+ needsInput: false,
257
+ error: error instanceof Error ? error.message : String(error),
258
+ };
259
+ }
260
+ }
261
+ /**
262
+ * The unified agent-chat tool definition.
263
+ * This single tool replaces all 24+ individual dev tools by orchestrating them intelligently.
264
+ */
265
+ export const agentChatTool = {
266
+ name: 'agent_chat',
267
+ description: `Unified interface for the entire Ratio app development lifecycle.
268
+
269
+ This is the SINGLE tool for building Ratio apps from start to finish. Instead of juggling 24+ individual tools, use this one conversational interface.
270
+
271
+ ## The Workflow (9 Phases)
272
+ 1. **Authentication** - Log in with your Ratio developer account
273
+ 2. **App Setup** - Create your application and select categories
274
+ 3. **Requirements** - Define your app's OAuth scopes and API access
275
+ 4. **Webhooks** (optional) - Configure webhook subscriptions for real-time events
276
+ 5. **Frontend Build** - Scaffold, build, and submit your React frontend
277
+ 6. **Review Wait** - Your app goes under admin review
278
+ 7. **Publish & OAuth** - Publish your approved app and complete the OAuth flow
279
+ 8. **Backend Codegen** - Auto-generate NestJS backend from your scopes
280
+ 9. **Complete** - You're done! Your app is live
281
+
282
+ ## How to Use This Tool
283
+
284
+ ### First Message
285
+ Just tell me what you want to build:
286
+ \`\`\`
287
+ {
288
+ "message": "I want to build an order management app",
289
+ "action": "next"
290
+ }
291
+ \`\`\`
292
+
293
+ ### When Input is Requested
294
+ I'll ask for specific information. Provide it like this:
295
+ \`\`\`
296
+ {
297
+ "message": "Your email and password",
298
+ "input_data": {
299
+ "email": "dev@example.com",
300
+ "password": "yourpassword"
301
+ },
302
+ "action": "next"
303
+ }
304
+ \`\`\`
305
+
306
+ ### Special Actions
307
+ - **"next"** (default): Proceed with the current step and advance to the next one
308
+ - **"skip"**: Skip the current phase (only webhooks can be skipped; it's optional)
309
+ - **"status"**: Check where you are without advancing
310
+ - **"reset"**: Start completely over from scratch
311
+
312
+ ## Examples
313
+
314
+ ### Start a new app
315
+ \`\`\`
316
+ {
317
+ "message": "Build a product inventory system",
318
+ "action": "next"
319
+ }
320
+ \`\`\`
321
+
322
+ ### Provide credentials when asked
323
+ \`\`\`
324
+ {
325
+ "message": "Logging in",
326
+ "input_data": {
327
+ "email": "john@company.com",
328
+ "password": "mypassword"
329
+ },
330
+ "action": "next"
331
+ }
332
+ \`\`\`
333
+
334
+ ### Skip optional webhooks phase
335
+ \`\`\`
336
+ {
337
+ "message": "Skip webhooks for now",
338
+ "action": "skip"
339
+ }
340
+ \`\`\`
341
+
342
+ ### Check current progress
343
+ \`\`\`
344
+ {
345
+ "message": "Where are we?",
346
+ "action": "status"
347
+ }
348
+ \`\`\`
349
+
350
+ ### Start over
351
+ \`\`\`
352
+ {
353
+ "message": "Start fresh",
354
+ "action": "reset"
355
+ }
356
+ \`\`\`
357
+
358
+ ## Response Format
359
+ You'll get back a response with:
360
+ - \`message\` - Status/result description
361
+ - \`phase\` - Your current phase
362
+ - \`progress\` - Percentage of overall completion
363
+ - \`needsInput\` - Whether you need to provide data
364
+ - \`inputPrompt\` - What information is needed (if asking)
365
+ - \`inputFields\` - Which fields to fill
366
+ - \`data\` - Extracted results from the last tool (masked for security)
367
+
368
+ ## Tips
369
+ - Follow the orchestrator's guidance on what's needed next
370
+ - Input fields are always listed in the response
371
+ - Sensitive data (tokens, secrets) is automatically masked in responses
372
+ - If you make a mistake, just provide the correct data on the next call
373
+ - Webhooks are optional; you can configure them later in the dashboard`,
374
+ inputSchema: agentChatSchema,
375
+ handler: handleAgentChat,
376
+ };
377
+ // Re-export allDevTools for any code that needs access to the underlying tools
378
+ export { allDevTools };
379
+ //# sourceMappingURL=agent-chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-chat.js","sourceRoot":"","sources":["../../src/tools/agent-chat.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"app-management.d.ts","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,kBAAkB,EAAE,cAAc,EA2H9C,CAAC"}
1
+ {"version":3,"file":"app-management.d.ts","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,kBAAkB,EAAE,cAAc,EAsJ9C,CAAC"}
@@ -1,15 +1,20 @@
1
1
  import { z } from 'zod';
2
2
  import { developerApiRequest } from '../api/developer.js';
3
+ import { resolveCategoryIdsToUUIDs } from './reference-data.js';
3
4
  import { logger } from '../utils/logger.js';
4
5
  export const appManagementTools = [
5
6
  {
6
7
  name: 'create_app',
7
- description: 'Create a new application in the Ratio Developer Dashboard. Returns app_id, client_id, and client_secret.',
8
+ description: 'Create a new application in the Ratio Developer Dashboard. Returns app_id, client_id, and client_secret. ' +
9
+ 'PREREQUISITES before calling this tool:\n' +
10
+ '1. Call get_categories and let the developer pick categories\n' +
11
+ '2. Ask the developer: "Do you have a callback URL for OAuth, or should I use localhost?"\n' +
12
+ 'Only call create_app after both are answered.',
8
13
  inputSchema: z.object({
9
14
  name: z.string().min(1).max(100).describe('Application name (required)'),
10
15
  description: z.string().max(2000).optional().describe('Application description'),
11
- category_ids: z.array(z.string()).min(1).describe('Category strings (e.g. ["analytics", "marketing"])'),
12
- redirect_uri: z.string().optional().describe('OAuth callback URL'),
16
+ category_ids: z.array(z.string()).min(1).describe('Category slugs from get_categories (e.g. ["analytics", "marketing"]). MUST call get_categories first to get valid slugs.'),
17
+ redirect_uri: z.string().default('http://localhost:3000/callback').describe('OAuth callback URL. MUST ask the developer before defaulting. Use http://localhost:3000/callback only if the developer has no preference.'),
13
18
  contact_email: z.string().optional().describe('Contact email'),
14
19
  tags: z.array(z.string()).optional().describe('Application tags'),
15
20
  icon: z.string().optional().describe('Icon URL'),
@@ -17,7 +22,21 @@ export const appManagementTools = [
17
22
  handler: async (input) => {
18
23
  const inp = input;
19
24
  logger.info(`Creating application: ${inp.name}`);
20
- const appData = { name: inp.name, categoryIds: inp.category_ids };
25
+ // Accept category_ids OR common variants (LLM may send different field names).
26
+ // Primary normalization happens in agent_chat's normalizeToolInput(), but this
27
+ // fallback covers direct tool calls outside the agent_chat flow.
28
+ const rawCategories = (inp.category_ids ?? inp.categories ?? inp.category_slugs ?? inp.categoryIds);
29
+ if (!rawCategories || !Array.isArray(rawCategories) || rawCategories.length === 0) {
30
+ throw new Error('category_ids is required and must be a non-empty array of category slugs. ' +
31
+ 'Call get_categories first to see valid slugs, then provide them as category_ids: ["slug1", "slug2"].');
32
+ }
33
+ // Resolve category slugs/names to UUIDs (same as update_app)
34
+ const resolvedCategories = await resolveCategoryIdsToUUIDs(rawCategories);
35
+ if (resolvedCategories.length === 0) {
36
+ throw new Error(`None of the provided categories could be resolved: [${rawCategories.join(', ')}]. ` +
37
+ 'Call get_categories first to see valid category slugs.');
38
+ }
39
+ const appData = { name: inp.name, categoryIds: resolvedCategories };
21
40
  if (inp.description)
22
41
  appData['description'] = inp.description;
23
42
  if (inp.redirect_uri)
@@ -65,12 +84,12 @@ export const appManagementTools = [
65
84
  },
66
85
  {
67
86
  name: 'update_app',
68
- description: 'Update an existing application. Only provided fields will be updated.',
87
+ description: 'Update an existing application. Only provided fields will be updated. Category slugs are auto-resolved to UUIDs.',
69
88
  inputSchema: z.object({
70
89
  app_id: z.string().min(1).describe('Application ID to update'),
71
90
  name: z.string().optional().describe('New name'),
72
91
  description: z.string().optional().describe('New description'),
73
- category_ids: z.array(z.string()).optional().describe('New categories'),
92
+ category_ids: z.array(z.string()).optional().describe('Category slugs or UUIDs. Slugs are auto-resolved.'),
74
93
  redirect_uri: z.string().optional().describe('New redirect URI'),
75
94
  contact_email: z.string().optional().describe('New contact email'),
76
95
  tags: z.array(z.string()).optional().describe('New tags'),
@@ -83,8 +102,10 @@ export const appManagementTools = [
83
102
  updateData['name'] = inp.name;
84
103
  if (inp.description !== undefined)
85
104
  updateData['description'] = inp.description;
86
- if (inp.category_ids !== undefined)
87
- updateData['categoryIds'] = inp.category_ids;
105
+ if (inp.category_ids !== undefined) {
106
+ const resolved = await resolveCategoryIdsToUUIDs(inp.category_ids);
107
+ updateData['categoryIds'] = resolved;
108
+ }
88
109
  if (inp.redirect_uri !== undefined)
89
110
  updateData['redirectUri'] = inp.redirect_uri;
90
111
  if (inp.contact_email !== undefined)
@@ -1 +1 @@
1
- {"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAG5C,MAAM,CAAC,MAAM,kBAAkB,GAAqB;IAClD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EACT,0GAA0G;QAC5G,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACxE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yBAAyB,CAAC;YAChF,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;YACvG,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YAClE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YAC9D,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YACjE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;SACjD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,GAAG,GAAG,KAAgC,CAAC;YAC7C,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YAEjD,MAAM,OAAO,GAA4B,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC;YAC3F,IAAI,GAAG,CAAC,WAAW;gBAAE,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;YAC9D,IAAI,GAAG,CAAC,YAAY;gBAAE,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;YAChE,IAAI,GAAG,CAAC,aAAa;gBAAE,OAAO,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC;YACnE,IAAI,GAAG,CAAC,IAAI;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YACzC,IAAI,GAAG,CAAC,IAAI;gBAAE,OAAO,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YAEzC,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAEvC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;YAErC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,kCAAkC;gBAC3C,WAAW,EAAE;oBACX,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,SAAS,EAAE,GAAG,CAAC,QAAQ;oBACvB,aAAa,EAAE,GAAG,CAAC,YAAY;oBAC/B,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB;gBACD,UAAU,EAAE;oBACV,8CAA8C;oBAC9C,6CAA6C;oBAC7C,0DAA0D;oBAC1D,8CAA8C;oBAC9C,yEAAyE;iBAC1E;aACF,CAAC;QACJ,CAAC;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,4EAA4E;QACzF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACjE,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,EAAE,MAAM,EAAE,GAAG,KAA2B,CAAC;YAC/C,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAA0B,KAAK,EAAE,iBAAiB,MAAM,EAAE,CAAC,CAAC;YACtG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;QAClD,CAAC;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,uEAAuE;QACpF,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC9D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YAChD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YAC9D,YAAY,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACvE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;YAChE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAClE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC;YACzD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;SACrD,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,GAAG,GAAG,KAAgC,CAAC;YAC7C,MAAM,UAAU,GAA4B,EAAE,CAAC;YAC/C,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1D,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS;gBAAE,UAAU,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;YAC/E,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;gBAAE,UAAU,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;YACjF,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS;gBAAE,UAAU,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;YACjF,IAAI,GAAG,CAAC,aAAa,KAAK,SAAS;gBAAE,UAAU,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC;YACpF,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1D,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS;gBAAE,UAAU,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC;YAE1D,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAA0B,OAAO,EAAE,iBAAiB,GAAG,CAAC,MAAM,EAAE,EAAE,UAAU,CAAC,CAAC;YACxH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;QAClF,CAAC;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YAC9D,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;SACjE,CAAC;QACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACvB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAA6C,CAAC;YAC1E,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,4CAA4C,EAAE,CAAC;YAC/F,MAAM,mBAAmB,CAAO,QAAQ,EAAE,iBAAiB,MAAM,EAAE,CAAC,CAAC;YACrE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,MAAM,UAAU,EAAE,CAAC;QACrE,CAAC;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,iDAAiD;QAC9D,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAEvC,KAAK,EAAE,eAAe,CAAC,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK;gBAC1B,YAAY,EAAE,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBACrD,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI;oBAC1C,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW;iBAC1E,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;KACF;CACF,CAAC"}
1
+ {"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,eAAO,MAAM,SAAS,EAAE,cAAc,EAgLrC,CAAC"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAOjD,eAAO,MAAM,SAAS,EAAE,cAAc,EAiNrC,CAAC"}
@@ -1,18 +1,28 @@
1
1
  import { z } from 'zod';
2
+ import fs from 'fs';
3
+ import os from 'os';
4
+ import path from 'path';
2
5
  import { requestAuthorization, exchangeCodeForToken, refreshToken } from '../api/oauth.js';
3
6
  import { saveToken, getToken, isTokenExpired, writeTokenToScaffoldEnv } from '../store/token-store.js';
4
7
  import { getRequirements, getRequirementsByClientId } from '../store/requirements-store.js';
5
8
  import { logger } from '../utils/logger.js';
9
+ const DEBUG_LOG = path.join(os.homedir(), 'Desktop', 'ratio-debug.log');
10
+ function debugLog(msg) {
11
+ fs.appendFileSync(DEBUG_LOG, `[${new Date().toISOString()}] ${msg}\n`);
12
+ }
6
13
  export const authTools = [
7
14
  {
8
15
  name: 'request_auth_code',
9
16
  description: 'Request an authorization code for app installation (OAuth Step 1). App must be PUBLISHED first. ' +
10
- 'Auto-fills scopes from saved requirements if app_id is provided.',
17
+ 'Auto-fills scopes from saved requirements if app_id is provided. ' +
18
+ 'IMPORTANT: Ask the developer if they have a callback URL for OAuth. If they do, use it. ' +
19
+ 'If not, default to http://localhost:3000/callback. The redirect_uri here MUST match ' +
20
+ 'the one used in get_access_token, and should match the redirect_uri set during create_app.',
11
21
  inputSchema: z.object({
12
22
  app_id: z.string().optional().describe('App ID to auto-fill scopes from requirements'),
13
23
  client_id: z.string().min(1).describe('Application Client ID'),
14
24
  merchant_id: z.string().min(1).describe('Merchant ID of the store installing the app'),
15
- redirect_uri: z.string().describe('Registered redirect URI'),
25
+ redirect_uri: z.string().default('http://localhost:3000/callback').describe('OAuth callback URL. Ask the developer if they have one, otherwise defaults to http://localhost:3000/callback'),
16
26
  scopes: z.array(z.string()).optional().describe('Scopes to request. Auto-filled from requirements if omitted.'),
17
27
  }),
18
28
  handler: async (input) => {
@@ -33,30 +43,49 @@ export const authTools = [
33
43
  }
34
44
  }
35
45
  const response = await requestAuthorization({ clientId: client_id, merchantId: merchant_id, redirectUri: redirect_uri, scopes });
36
- const { code, redirectUri, expiresAt } = response.data;
46
+ debugLog(`FULL RESPONSE: ${JSON.stringify(response, null, 2)}`);
47
+ debugLog(`Raw response keys: ${JSON.stringify(Object.keys(response))}`);
48
+ debugLog(`response.data type: ${typeof response.data}, value: ${JSON.stringify(response.data)?.slice(0, 500)}`);
49
+ // The API might return data nested differently — try multiple paths
50
+ const responseData = response.data || response;
51
+ const code = responseData.code ?? responseData.authorizationCode ?? responseData.authorization_code ?? response.code;
52
+ const resolvedRedirectUri = responseData.redirectUri ?? responseData.redirect_uri ?? redirect_uri;
53
+ const expiresAt = responseData.expiresAt ?? responseData.expires_at;
54
+ debugLog(`Extracted code: ${code ? String(code).substring(0, 12) + '...' : 'UNDEFINED'}`);
55
+ debugLog(`Extracted redirectUri: ${resolvedRedirectUri}`);
37
56
  return {
38
57
  success: true,
39
- message: response.message,
58
+ message: response.message || 'Authorization code obtained',
40
59
  auth_code: code,
41
- redirect_uri: redirectUri,
60
+ redirect_uri: resolvedRedirectUri,
42
61
  expires_at: expiresAt,
43
62
  warning: 'Auth code expires quickly! Call get_access_token immediately.',
63
+ _debug: {
64
+ responseKeys: Object.keys(response),
65
+ hasData: response.data !== undefined,
66
+ dataKeys: response.data ? Object.keys(response.data) : [],
67
+ rawResponse: JSON.stringify(response).slice(0, 500),
68
+ },
44
69
  };
45
70
  },
46
71
  },
47
72
  {
48
73
  name: 'get_access_token',
49
74
  description: 'Exchange authorization code for access and refresh tokens (OAuth Step 2). ' +
50
- 'Saves tokens persistently and auto-injects into backend .env if project is scaffolded.',
75
+ 'Saves tokens persistently and auto-injects into backend .env if project is scaffolded. ' +
76
+ 'IMPORTANT: redirect_uri MUST exactly match the one used in request_auth_code.',
51
77
  inputSchema: z.object({
52
78
  auth_code: z.string().min(1).describe('Authorization code from request_auth_code'),
53
79
  client_id: z.string().min(1).describe('Application Client ID'),
54
80
  client_secret: z.string().min(1).describe('Application Client Secret'),
55
- redirect_uri: z.string().describe('Redirect URI (must match request_auth_code)'),
81
+ redirect_uri: z.string().default('http://localhost:3000/callback').describe('Must match the redirect_uri used in request_auth_code'),
56
82
  }),
57
83
  handler: async (input) => {
58
84
  const { auth_code, client_id, client_secret, redirect_uri } = input;
85
+ logger.info(`[get_access_token] ══ START ══`);
86
+ logger.info(`[get_access_token] input: client_id=${client_id}, has_client_secret=${!!client_secret}, redirect_uri=${redirect_uri}, auth_code=${auth_code?.substring(0, 12)}...`);
59
87
  const tokenData = await exchangeCodeForToken({ code: auth_code, clientId: client_id, clientSecret: client_secret, redirectUri: redirect_uri });
88
+ logger.info(`[get_access_token] exchangeCodeForToken returned: token_type=${tokenData.token_type}, expires_in=${tokenData.expires_in}, merchant_id=${tokenData.merchant_id}, scope=${tokenData.scope}, has_access_token=${!!tokenData.access_token}, has_refresh_token=${!!tokenData.refresh_token}`);
60
89
  const expiresAt = new Date(Date.now() + tokenData.expires_in * 1000);
61
90
  const storedToken = {
62
91
  access_token: tokenData.access_token,
@@ -67,15 +96,23 @@ export const authTools = [
67
96
  created_at: new Date().toISOString(),
68
97
  client_id, client_secret, redirect_uri,
69
98
  };
99
+ logger.info(`[get_access_token] Saving token to store with key=${client_id}, scopes=${storedToken.scopes.join(',')}, merchant_id=${storedToken.merchant_id}`);
70
100
  saveToken(client_id, storedToken);
101
+ logger.info(`[get_access_token] Token saved successfully`);
71
102
  // Auto-inject into backend .env
72
103
  let tokenInjected = false;
104
+ logger.info(`[get_access_token] Looking up requirements by client_id=${client_id}`);
73
105
  const requirements = getRequirementsByClientId(client_id);
106
+ logger.info(`[get_access_token] requirements found=${!!requirements}, project_path=${requirements?.project_path}`);
74
107
  if (requirements?.project_path) {
75
108
  const backendEnvPath = `${requirements.project_path}/backend/.env`;
109
+ logger.info(`[get_access_token] Auto-injecting token into ${backendEnvPath}`);
76
110
  writeTokenToScaffoldEnv(backendEnvPath, storedToken);
77
111
  tokenInjected = true;
78
- logger.info(`Token injected into: ${backendEnvPath}`);
112
+ logger.info(`[get_access_token] Token injected into: ${backendEnvPath}`);
113
+ }
114
+ else {
115
+ logger.info(`[get_access_token] No project_path in requirements — token NOT auto-injected into backend .env (will be injected when scaffold_backend runs)`);
79
116
  }
80
117
  return {
81
118
  success: true,