@ratio-mcp/dev-server 1.0.0 → 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.
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -9
- package/dist/index.js.map +1 -1
- package/dist/orchestrated-index.d.ts +16 -0
- package/dist/orchestrated-index.d.ts.map +1 -0
- package/dist/orchestrated-index.js +41 -0
- package/dist/orchestrated-index.js.map +1 -0
- package/dist/orchestrated-server.d.ts +16 -0
- package/dist/orchestrated-server.d.ts.map +1 -0
- package/dist/orchestrated-server.js +63 -0
- package/dist/orchestrated-server.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +26 -0
- package/dist/server.js.map +1 -1
- package/dist/services/orchestrator.d.ts +63 -0
- package/dist/services/orchestrator.d.ts.map +1 -0
- package/dist/services/orchestrator.js +769 -0
- package/dist/services/orchestrator.js.map +1 -0
- package/dist/services/response-formatter.d.ts +24 -0
- package/dist/services/response-formatter.d.ts.map +1 -0
- package/dist/services/response-formatter.js +311 -0
- package/dist/services/response-formatter.js.map +1 -0
- package/dist/services/session-state.d.ts +51 -0
- package/dist/services/session-state.d.ts.map +1 -0
- package/dist/services/session-state.js +248 -0
- package/dist/services/session-state.js.map +1 -0
- package/dist/services/tool-guard.d.ts +20 -0
- package/dist/services/tool-guard.d.ts.map +1 -0
- package/dist/services/tool-guard.js +164 -0
- package/dist/services/tool-guard.js.map +1 -0
- package/dist/store/requirements-store.d.ts.map +1 -1
- package/dist/store/requirements-store.js +16 -3
- package/dist/store/requirements-store.js.map +1 -1
- package/dist/store/token-store.d.ts.map +1 -1
- package/dist/store/token-store.js +8 -2
- package/dist/store/token-store.js.map +1 -1
- package/dist/templates/backend/.env.example +3 -1
- package/dist/tools/agent-chat.d.ts +9 -0
- package/dist/tools/agent-chat.d.ts.map +1 -0
- package/dist/tools/agent-chat.js +379 -0
- package/dist/tools/agent-chat.js.map +1 -0
- package/dist/tools/app-management.d.ts.map +1 -1
- package/dist/tools/app-management.js +29 -8
- package/dist/tools/app-management.js.map +1 -1
- package/dist/tools/auth.d.ts.map +1 -1
- package/dist/tools/auth.js +45 -8
- package/dist/tools/auth.js.map +1 -1
- package/dist/tools/build.d.ts.map +1 -1
- package/dist/tools/build.js +13 -2
- package/dist/tools/build.js.map +1 -1
- package/dist/tools/codegen.d.ts.map +1 -1
- package/dist/tools/codegen.js +39 -6
- package/dist/tools/codegen.js.map +1 -1
- package/dist/tools/gather-requirements.d.ts +3 -0
- package/dist/tools/gather-requirements.d.ts.map +1 -0
- package/dist/tools/gather-requirements.js +281 -0
- package/dist/tools/gather-requirements.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +7 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lifecycle.d.ts.map +1 -1
- package/dist/tools/lifecycle.js +40 -32
- package/dist/tools/lifecycle.js.map +1 -1
- package/dist/tools/reference-data.d.ts +8 -0
- package/dist/tools/reference-data.d.ts.map +1 -0
- package/dist/tools/reference-data.js +79 -0
- package/dist/tools/reference-data.js.map +1 -0
- package/dist/tools/scaffold.d.ts.map +1 -1
- package/dist/tools/scaffold.js +17 -1
- package/dist/tools/scaffold.js.map +1 -1
- package/dist/tools/submission.d.ts.map +1 -1
- package/dist/tools/submission.js +79 -21
- package/dist/tools/submission.js.map +1 -1
- package/dist/tools/webhooks.d.ts +3 -0
- package/dist/tools/webhooks.d.ts.map +1 -0
- package/dist/tools/webhooks.js +303 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/dist/utils/logger.d.ts +15 -5
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +93 -14
- package/dist/utils/logger.js.map +1 -1
- package/package.json +6 -2
|
@@ -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":"
|
|
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
|
|
12
|
-
redirect_uri: z.string().
|
|
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
|
-
|
|
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('
|
|
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
|
-
|
|
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,
|
|
1
|
+
{"version":3,"file":"app-management.js","sourceRoot":"","sources":["../../src/tools/app-management.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/tools/auth.js
CHANGED
|
@@ -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('
|
|
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
|
-
|
|
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:
|
|
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('
|
|
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,
|