@pikku/inspector 0.12.11 → 0.12.12
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/CHANGELOG.md +13 -0
- package/dist/add/add-cli.js +10 -3
- package/dist/add/add-credential.js +2 -1
- package/dist/add/add-functions.js +28 -1
- package/dist/add/add-http-route.js +24 -5
- package/dist/add/add-keyed-wiring.js +3 -1
- package/dist/add/add-middleware.js +33 -4
- package/dist/add/add-permission.js +7 -7
- package/dist/add/add-workflow-graph.js +20 -1
- package/dist/error-codes.d.ts +1 -0
- package/dist/error-codes.js +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/inspector.js +2 -5
- package/dist/types.d.ts +10 -19
- package/dist/utils/extract-function-name.js +6 -0
- package/dist/utils/filter-inspector-state.js +187 -59
- package/dist/utils/filter-utils.js +13 -5
- package/dist/utils/get-property-value.d.ts +10 -0
- package/dist/utils/get-property-value.js +30 -0
- package/dist/utils/post-process.d.ts +2 -3
- package/dist/utils/post-process.js +3 -23
- package/dist/utils/resolve-addon-package.d.ts +4 -5
- package/dist/utils/resolve-addon-package.js +64 -16
- package/dist/utils/resolve-deploy-target.d.ts +28 -0
- package/dist/utils/resolve-deploy-target.js +56 -0
- package/dist/utils/resolve-versions.js +79 -0
- package/dist/utils/schema-generator.js +31 -12
- package/package.json +2 -2
- package/src/add/add-cli.ts +10 -3
- package/src/add/add-credential.ts +3 -0
- package/src/add/add-functions.test.ts +149 -0
- package/src/add/add-functions.ts +37 -1
- package/src/add/add-gateway.ts +5 -1
- package/src/add/add-http-route.ts +26 -6
- package/src/add/add-keyed-wiring.ts +7 -1
- package/src/add/add-mcp-prompt.ts +5 -1
- package/src/add/add-mcp-resource.ts +5 -1
- package/src/add/add-middleware.ts +42 -4
- package/src/add/add-permission.ts +7 -7
- package/src/add/add-schedule.ts +5 -1
- package/src/add/add-workflow-graph.ts +19 -1
- package/src/add/wire-name-literal.test.ts +114 -0
- package/src/error-codes.ts +1 -0
- package/src/index.ts +1 -0
- package/src/inspector.ts +1 -5
- package/src/types.ts +19 -15
- package/src/utils/extract-function-name.ts +8 -0
- package/src/utils/filter-inspector-state.test.ts +168 -64
- package/src/utils/filter-inspector-state.ts +290 -64
- package/src/utils/filter-utils.test.ts +30 -15
- package/src/utils/filter-utils.ts +14 -5
- package/src/utils/get-property-value.ts +40 -0
- package/src/utils/post-process.ts +3 -38
- package/src/utils/resolve-addon-package.ts +65 -14
- package/src/utils/resolve-deploy-target.test.ts +105 -0
- package/src/utils/resolve-deploy-target.ts +63 -0
- package/src/utils/resolve-versions.test.ts +108 -0
- package/src/utils/resolve-versions.ts +86 -0
- package/src/utils/schema-generator.ts +37 -13
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 0.12.12
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- 9060165: Agents now declare their model directly as `<provider>/<model>` (e.g. `openai/gpt-4o`). The `models`, `agentDefaults`, and `agentOverrides` config blocks have been removed.
|
|
6
|
+
|
|
7
|
+
**Migration:** replace any bare `model: 'alias'` values with the full provider-qualified form and remove those blocks from `pikku.config.json`.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [9060165]
|
|
10
|
+
- Updated dependencies [9060165]
|
|
11
|
+
- Updated dependencies [9060165]
|
|
12
|
+
- @pikku/core@0.12.21
|
|
13
|
+
|
|
1
14
|
## 0.12.11
|
|
2
15
|
|
|
3
16
|
### Patch Changes
|
package/dist/add/add-cli.js
CHANGED
|
@@ -295,10 +295,16 @@ function processCommand(logger, inspectorState, options, name, node, sourceFile,
|
|
|
295
295
|
meta.options = processOptions(logger, optionsNode, typeChecker, inspectorState, options, pikkuFuncId);
|
|
296
296
|
}
|
|
297
297
|
break;
|
|
298
|
-
case 'subcommands':
|
|
299
|
-
|
|
298
|
+
case 'subcommands': {
|
|
299
|
+
let subcommandsNode = prop.initializer;
|
|
300
|
+
if (ts.isIdentifier(prop.initializer)) {
|
|
301
|
+
subcommandsNode = resolveIdentifier(prop.initializer, typeChecker, [
|
|
302
|
+
'defineCLICommands',
|
|
303
|
+
]);
|
|
304
|
+
}
|
|
305
|
+
if (subcommandsNode && ts.isObjectLiteralExpression(subcommandsNode)) {
|
|
300
306
|
meta.subcommands = {};
|
|
301
|
-
for (const subProp of
|
|
307
|
+
for (const subProp of subcommandsNode.properties) {
|
|
302
308
|
if (!ts.isPropertyAssignment(subProp))
|
|
303
309
|
continue;
|
|
304
310
|
const subName = getPropertyName(subProp);
|
|
@@ -311,6 +317,7 @@ function processCommand(logger, inspectorState, options, name, node, sourceFile,
|
|
|
311
317
|
}
|
|
312
318
|
}
|
|
313
319
|
break;
|
|
320
|
+
}
|
|
314
321
|
case 'isDefault':
|
|
315
322
|
if (prop.initializer.kind === ts.SyntaxKind.TrueKeyword ||
|
|
316
323
|
prop.initializer.kind === ts.SyntaxKind.FalseKeyword) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { getPropertyValue, getArrayPropertyValue, } from '../utils/get-property-value.js';
|
|
2
|
+
import { getPropertyValue, getArrayPropertyValue, assertStringLiteralProperty, } from '../utils/get-property-value.js';
|
|
3
3
|
import { ErrorCode } from '../error-codes.js';
|
|
4
4
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js';
|
|
5
5
|
export const addCredential = (logger, node, checker, state, _options) => {
|
|
@@ -17,6 +17,7 @@ export const addCredential = (logger, node, checker, state, _options) => {
|
|
|
17
17
|
}
|
|
18
18
|
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
19
19
|
const obj = firstArg;
|
|
20
|
+
assertStringLiteralProperty(obj, 'name', 'Credential', logger);
|
|
20
21
|
const nameValue = getPropertyValue(obj, 'name');
|
|
21
22
|
const displayNameValue = getPropertyValue(obj, 'displayName');
|
|
22
23
|
const descriptionValue = getPropertyValue(obj, 'description');
|
|
@@ -5,6 +5,7 @@ import { extractFunctionNode } from '../utils/extract-function-node.js';
|
|
|
5
5
|
import { extractUsedWires } from '../utils/extract-services.js';
|
|
6
6
|
import { formatVersionedId, parseVersionedId } from '@pikku/core';
|
|
7
7
|
import { getPropertyValue, getCommonWireMetaData, } from '../utils/get-property-value.js';
|
|
8
|
+
import { canonicalJSON, hashString } from '../utils/hash.js';
|
|
8
9
|
import { resolveMiddleware } from '../utils/middleware.js';
|
|
9
10
|
import { resolvePermissions } from '../utils/permissions.js';
|
|
10
11
|
import { extractWireNames } from '../utils/post-process.js';
|
|
@@ -222,6 +223,20 @@ const areCompatibleFunctionIds = (existingId, incomingId) => {
|
|
|
222
223
|
const incomingParsed = parseVersionedId(incomingId);
|
|
223
224
|
return existingParsed.baseName === incomingParsed.baseName;
|
|
224
225
|
};
|
|
226
|
+
function printNode(node) {
|
|
227
|
+
return ts
|
|
228
|
+
.createPrinter({ removeComments: true })
|
|
229
|
+
.printNode(ts.EmitHint.Unspecified, node, node.getSourceFile());
|
|
230
|
+
}
|
|
231
|
+
function computeImplementationHash(args) {
|
|
232
|
+
const { wrapper, handler, objectNode, isDirectFunction } = args;
|
|
233
|
+
return hashString(canonicalJSON({
|
|
234
|
+
wrapper,
|
|
235
|
+
isDirectFunction,
|
|
236
|
+
handler: printNode(handler),
|
|
237
|
+
config: objectNode ? printNode(objectNode) : null,
|
|
238
|
+
}));
|
|
239
|
+
}
|
|
225
240
|
/**
|
|
226
241
|
* Inspect pikkuFunc calls, extract input/output and first-arg destructuring,
|
|
227
242
|
* then push into state.functions.meta.
|
|
@@ -409,7 +424,12 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
409
424
|
}
|
|
410
425
|
}
|
|
411
426
|
if (version !== undefined) {
|
|
412
|
-
|
|
427
|
+
let baseName = explicitName || exportedName || pikkuFuncId;
|
|
428
|
+
// Strip trailing VN suffix if it matches the version (e.g. getDataV1 + version:1 → getData@v1)
|
|
429
|
+
const vSuffix = `V${version}`;
|
|
430
|
+
if (baseName.endsWith(vSuffix) && baseName.length > vSuffix.length) {
|
|
431
|
+
baseName = baseName.slice(0, -vSuffix.length);
|
|
432
|
+
}
|
|
413
433
|
pikkuFuncId = formatVersionedId(baseName, version);
|
|
414
434
|
}
|
|
415
435
|
const isMCPToolFunc = expression.text === 'pikkuMCPToolFunc';
|
|
@@ -636,6 +656,12 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
636
656
|
}
|
|
637
657
|
}
|
|
638
658
|
const sessionless = expression.text !== 'pikkuFunc';
|
|
659
|
+
const implementationHash = computeImplementationHash({
|
|
660
|
+
wrapper: expression.text,
|
|
661
|
+
handler,
|
|
662
|
+
objectNode,
|
|
663
|
+
isDirectFunction,
|
|
664
|
+
});
|
|
639
665
|
state.functions.meta[pikkuFuncId] = {
|
|
640
666
|
pikkuFuncId,
|
|
641
667
|
functionType: 'user',
|
|
@@ -655,6 +681,7 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
655
681
|
deploy: deploy || undefined,
|
|
656
682
|
approvalRequired: approvalRequired || undefined,
|
|
657
683
|
approvalDescription: approvalDescription || undefined,
|
|
684
|
+
implementationHash,
|
|
658
685
|
version,
|
|
659
686
|
title,
|
|
660
687
|
tags: tags || undefined,
|
|
@@ -146,17 +146,36 @@ export function registerHTTPRoute({ obj, state, checker, logger, sourceFile, bas
|
|
|
146
146
|
return;
|
|
147
147
|
}
|
|
148
148
|
const input = fnMeta.inputs?.[0] || null;
|
|
149
|
+
const getRouteInputKeys = () => {
|
|
150
|
+
const targetFuncName = refAddonTarget ?? funcName;
|
|
151
|
+
const inputTypes = state.typesLookup.get(targetFuncName);
|
|
152
|
+
if (inputTypes && inputTypes.length > 0) {
|
|
153
|
+
return extractTypeKeys(inputTypes[0]);
|
|
154
|
+
}
|
|
155
|
+
const targetMeta = resolveFunctionMeta(state, targetFuncName);
|
|
156
|
+
if (targetMeta?.inputSchemaName) {
|
|
157
|
+
const schema = state.schemas[targetMeta.inputSchemaName];
|
|
158
|
+
const properties = schema?.properties;
|
|
159
|
+
if (properties && typeof properties === 'object') {
|
|
160
|
+
return Object.keys(properties);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
};
|
|
149
165
|
// Validate that route params and query params exist in function input type
|
|
150
166
|
if (params.length > 0 || query.length > 0) {
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
153
|
-
|
|
167
|
+
const inputKeys = getRouteInputKeys();
|
|
168
|
+
if (!inputKeys) {
|
|
169
|
+
// Input shape isn't inspectable at this phase (e.g. addon ref or opaque handler).
|
|
170
|
+
// Skip param/query validation rather than emitting a false positive.
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
154
173
|
// Check path params
|
|
155
174
|
if (params.length > 0) {
|
|
156
175
|
const missingParams = params.filter((p) => !inputKeys.includes(p));
|
|
157
176
|
if (missingParams.length > 0) {
|
|
158
177
|
logger.critical(ErrorCode.ROUTE_PARAM_MISMATCH, `Route '${fullRoute}' has path parameter(s) [${missingParams.join(', ')}] ` +
|
|
159
|
-
`not found in function '${funcName}' input type. ` +
|
|
178
|
+
`not found in function '${refAddonTarget ?? funcName}' input type. ` +
|
|
160
179
|
`Input type has: [${inputKeys.join(', ')}]`);
|
|
161
180
|
return;
|
|
162
181
|
}
|
|
@@ -166,7 +185,7 @@ export function registerHTTPRoute({ obj, state, checker, logger, sourceFile, bas
|
|
|
166
185
|
const missingQuery = query.filter((q) => !inputKeys.includes(q));
|
|
167
186
|
if (missingQuery.length > 0) {
|
|
168
187
|
logger.critical(ErrorCode.ROUTE_QUERY_MISMATCH, `Route '${fullRoute}' has query parameter(s) [${missingQuery.join(', ')}] ` +
|
|
169
|
-
`not found in function '${funcName}' input type. ` +
|
|
188
|
+
`not found in function '${refAddonTarget ?? funcName}' input type. ` +
|
|
170
189
|
`Input type has: [${inputKeys.join(', ')}]`);
|
|
171
190
|
return;
|
|
172
191
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
-
import { getPropertyValue } from '../utils/get-property-value.js';
|
|
2
|
+
import { getPropertyValue, assertStringLiteralProperty, } from '../utils/get-property-value.js';
|
|
3
3
|
import { ErrorCode } from '../error-codes.js';
|
|
4
4
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js';
|
|
5
5
|
export const createAddKeyedWiring = (config) => {
|
|
@@ -19,6 +19,8 @@ export const createAddKeyedWiring = (config) => {
|
|
|
19
19
|
}
|
|
20
20
|
if (ts.isObjectLiteralExpression(firstArg)) {
|
|
21
21
|
const obj = firstArg;
|
|
22
|
+
assertStringLiteralProperty(obj, 'name', config.label, logger);
|
|
23
|
+
assertStringLiteralProperty(obj, config.idField, config.label, logger);
|
|
22
24
|
const nameValue = getPropertyValue(obj, 'name');
|
|
23
25
|
const displayNameValue = getPropertyValue(obj, 'displayName');
|
|
24
26
|
const descriptionValue = getPropertyValue(obj, 'description');
|
|
@@ -171,7 +171,7 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
171
171
|
logger.debug(`• Found middleware factory with services: ${services.services.join(', ')}${name ? ` (name: ${name})` : ''}${description ? ` (description: ${description})` : ''}`);
|
|
172
172
|
return;
|
|
173
173
|
}
|
|
174
|
-
if (expression.text === '
|
|
174
|
+
if (expression.text === 'addTagMiddleware') {
|
|
175
175
|
const tagArg = args[0];
|
|
176
176
|
const middlewareArrayArg = args[1];
|
|
177
177
|
if (!tagArg || !middlewareArrayArg)
|
|
@@ -181,11 +181,11 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
181
181
|
tag = tagArg.text;
|
|
182
182
|
}
|
|
183
183
|
if (!tag) {
|
|
184
|
-
logger.warn(`•
|
|
184
|
+
logger.warn(`• addTagMiddleware call without valid tag string`);
|
|
185
185
|
return;
|
|
186
186
|
}
|
|
187
187
|
if (!ts.isArrayLiteralExpression(middlewareArrayArg)) {
|
|
188
|
-
logger.error(`•
|
|
188
|
+
logger.error(`• addTagMiddleware('${tag}', ...) must have a literal array as second argument`);
|
|
189
189
|
return;
|
|
190
190
|
}
|
|
191
191
|
const refs = extractMiddlewareRefs(middlewareArrayArg, checker, state.rootDir);
|
|
@@ -236,7 +236,7 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
236
236
|
}
|
|
237
237
|
if (!isFactory && exportedName) {
|
|
238
238
|
logger.warn(`• Middleware group '${exportedName}' for tag '${tag}' is not wrapped in a factory function. ` +
|
|
239
|
-
`For tree-shaking, use: export const ${exportedName} = () =>
|
|
239
|
+
`For tree-shaking, use: export const ${exportedName} = () => addTagMiddleware('${tag}', [...])`);
|
|
240
240
|
}
|
|
241
241
|
state.middleware.tagMiddleware.set(tag, {
|
|
242
242
|
exportName: exportedName,
|
|
@@ -253,6 +253,34 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
253
253
|
logger.debug(`• Found tag middleware group: ${tag} -> [${instanceIds.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
254
254
|
return;
|
|
255
255
|
}
|
|
256
|
+
if (expression.text === 'addGlobalMiddleware') {
|
|
257
|
+
const middlewareArrayArg = args[0];
|
|
258
|
+
if (!middlewareArrayArg ||
|
|
259
|
+
!ts.isArrayLiteralExpression(middlewareArrayArg)) {
|
|
260
|
+
logger.error(`• addGlobalMiddleware(...) must have a literal array as its only argument`);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const refs = extractMiddlewareRefs(middlewareArrayArg, checker, state.rootDir);
|
|
264
|
+
const definitionIds = refs.map((r) => r.definitionId);
|
|
265
|
+
if (definitionIds.length > 0) {
|
|
266
|
+
renameTempDefinitions(state, definitionIds, 'global', 'middleware');
|
|
267
|
+
}
|
|
268
|
+
const sourceFile = node.getSourceFile().fileName;
|
|
269
|
+
for (let i = 0; i < refs.length; i++) {
|
|
270
|
+
const instanceId = makeContextBasedId('global', 'middleware', String(i));
|
|
271
|
+
state.middleware.instances[instanceId] = {
|
|
272
|
+
definitionId: definitionIds[i],
|
|
273
|
+
sourceFile,
|
|
274
|
+
position: node.getStart(),
|
|
275
|
+
isFactoryCall: refs[i].isFactoryCall,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// Without this, bootstrap codegen's "import every file with a wire-call"
|
|
279
|
+
// pass skips middleware-only files and the registration never runs.
|
|
280
|
+
state.http.files.add(sourceFile);
|
|
281
|
+
logger.debug(`• Found global middleware group with ${refs.length} entries`);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
256
284
|
if (expression.text === 'addHTTPMiddleware') {
|
|
257
285
|
const patternArg = args[0];
|
|
258
286
|
const middlewareArrayArg = args[1];
|
|
@@ -332,6 +360,7 @@ export const addMiddleware = (logger, node, checker, state) => {
|
|
|
332
360
|
instanceIds,
|
|
333
361
|
isFactory,
|
|
334
362
|
});
|
|
363
|
+
state.http.files.add(sourceFile);
|
|
335
364
|
logger.debug(`• Found HTTP route middleware group: ${pattern} -> [${instanceIds.join(', ')}] (${isFactory ? 'factory' : 'direct'})`);
|
|
336
365
|
return;
|
|
337
366
|
}
|
|
@@ -27,7 +27,7 @@ function isInsidePermissionContainer(node) {
|
|
|
27
27
|
if (ts.isCallExpression(current) &&
|
|
28
28
|
ts.isIdentifier(current.expression) &&
|
|
29
29
|
(current.expression.text === 'pikkuPermissionFactory' ||
|
|
30
|
-
current.expression.text === '
|
|
30
|
+
current.expression.text === 'addTagPermission' ||
|
|
31
31
|
current.expression.text === 'addHTTPPermission')) {
|
|
32
32
|
return true;
|
|
33
33
|
}
|
|
@@ -247,9 +247,9 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
247
247
|
}
|
|
248
248
|
// Handle addPermission('tag', [permission1, permission2])
|
|
249
249
|
// Supports two patterns:
|
|
250
|
-
// 1. export const x = () =>
|
|
251
|
-
// 2. export const x =
|
|
252
|
-
if (expression.text === '
|
|
250
|
+
// 1. export const x = () => addTagPermission('tag', [...]) (factory - tree-shakeable)
|
|
251
|
+
// 2. export const x = addTagPermission('tag', [...]) (direct - no tree-shaking)
|
|
252
|
+
if (expression.text === 'addTagPermission') {
|
|
253
253
|
const tagArg = args[0];
|
|
254
254
|
const permissionsArrayArg = args[1];
|
|
255
255
|
if (!tagArg || !permissionsArrayArg)
|
|
@@ -260,13 +260,13 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
260
260
|
tag = tagArg.text;
|
|
261
261
|
}
|
|
262
262
|
if (!tag) {
|
|
263
|
-
logger.warn(`•
|
|
263
|
+
logger.warn(`• addTagPermission call without valid tag string`);
|
|
264
264
|
return;
|
|
265
265
|
}
|
|
266
266
|
// Check if permissions is a literal array or object
|
|
267
267
|
if (!ts.isArrayLiteralExpression(permissionsArrayArg) &&
|
|
268
268
|
!ts.isObjectLiteralExpression(permissionsArrayArg)) {
|
|
269
|
-
logger.error(`•
|
|
269
|
+
logger.error(`• addTagPermission('${tag}', ...) must have a literal array or object as second argument`);
|
|
270
270
|
return;
|
|
271
271
|
}
|
|
272
272
|
// Extract permission pikkuFuncIds from array
|
|
@@ -305,7 +305,7 @@ export const addPermission = (logger, node, checker, state) => {
|
|
|
305
305
|
}
|
|
306
306
|
if (!isFactory && exportedName) {
|
|
307
307
|
logger.warn(`• Permission group '${exportedName}' for tag '${tag}' is not wrapped in a factory function. ` +
|
|
308
|
-
`For tree-shaking, use: export const ${exportedName} = () =>
|
|
308
|
+
`For tree-shaking, use: export const ${exportedName} = () => addTagPermission('${tag}', [...])`);
|
|
309
309
|
}
|
|
310
310
|
state.permissions.tagPermissions.set(tag, {
|
|
311
311
|
exportName: exportedName,
|
|
@@ -281,6 +281,8 @@ function extractGraphFromNewFormat(nodesNode, configNode, checker, state) {
|
|
|
281
281
|
input: {},
|
|
282
282
|
next: undefined,
|
|
283
283
|
onError: undefined,
|
|
284
|
+
retries: undefined,
|
|
285
|
+
retryDelay: undefined,
|
|
284
286
|
};
|
|
285
287
|
}
|
|
286
288
|
// Extract config for each node from 'config' property
|
|
@@ -301,6 +303,8 @@ function extractGraphFromNewFormat(nodesNode, configNode, checker, state) {
|
|
|
301
303
|
nodes[nodeId].next = nodeConfig.next;
|
|
302
304
|
nodes[nodeId].onError = nodeConfig.onError;
|
|
303
305
|
nodes[nodeId].input = nodeConfig.input;
|
|
306
|
+
nodes[nodeId].retries = nodeConfig.retries;
|
|
307
|
+
nodes[nodeId].retryDelay = nodeConfig.retryDelay;
|
|
304
308
|
}
|
|
305
309
|
}
|
|
306
310
|
}
|
|
@@ -314,6 +318,8 @@ function extractNodeConfigFromObject(obj, checker) {
|
|
|
314
318
|
let next = undefined;
|
|
315
319
|
let onError = undefined;
|
|
316
320
|
let input = {};
|
|
321
|
+
let retries = undefined;
|
|
322
|
+
let retryDelay = undefined;
|
|
317
323
|
for (const prop of obj.properties) {
|
|
318
324
|
if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name))
|
|
319
325
|
continue;
|
|
@@ -327,8 +333,21 @@ function extractNodeConfigFromObject(obj, checker) {
|
|
|
327
333
|
else if (propName === 'input') {
|
|
328
334
|
input = extractInputMapping(prop.initializer, checker);
|
|
329
335
|
}
|
|
336
|
+
else if (propName === 'retries') {
|
|
337
|
+
if (ts.isNumericLiteral(prop.initializer)) {
|
|
338
|
+
retries = Number(prop.initializer.text);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (propName === 'retryDelay') {
|
|
342
|
+
if (ts.isNumericLiteral(prop.initializer)) {
|
|
343
|
+
retryDelay = Number(prop.initializer.text);
|
|
344
|
+
}
|
|
345
|
+
else if (ts.isStringLiteral(prop.initializer)) {
|
|
346
|
+
retryDelay = prop.initializer.text;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
330
349
|
}
|
|
331
|
-
return { next, onError, input };
|
|
350
|
+
return { next, onError, input, retries, retryDelay };
|
|
332
351
|
}
|
|
333
352
|
/**
|
|
334
353
|
* Inspector for pikkuWorkflowGraph() calls
|
package/dist/error-codes.d.ts
CHANGED
package/dist/error-codes.js
CHANGED
|
@@ -10,6 +10,7 @@ export var ErrorCode;
|
|
|
10
10
|
(function (ErrorCode) {
|
|
11
11
|
// Validation errors
|
|
12
12
|
ErrorCode["MISSING_NAME"] = "PKU111";
|
|
13
|
+
ErrorCode["NON_LITERAL_WIRE_NAME"] = "PKU118";
|
|
13
14
|
ErrorCode["MISSING_DESCRIPTION"] = "PKU123";
|
|
14
15
|
ErrorCode["INVALID_VALUE"] = "PKU124";
|
|
15
16
|
ErrorCode["MISSING_URI"] = "PKU220";
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { ErrorCode } from './error-codes.js';
|
|
|
6
6
|
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
7
7
|
export type { SerializableInspectorState } from './utils/serialize-inspector-state.js';
|
|
8
8
|
export { filterInspectorState } from './utils/filter-inspector-state.js';
|
|
9
|
+
export { resolveDeployTarget } from './utils/resolve-deploy-target.js';
|
|
9
10
|
export { generateCustomTypes, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
10
11
|
export { createEmptyManifest, serializeManifest, } from './utils/contract-hashes.js';
|
|
11
12
|
export type { ContractEntry, VersionHashEntry, VersionValidateError, VersionManifest, VersionManifestEntry, } from './utils/contract-hashes.js';
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ export { inspect, getInitialInspectorState } from './inspector.js';
|
|
|
2
2
|
export { ErrorCode } from './error-codes.js';
|
|
3
3
|
export { serializeInspectorState, deserializeInspectorState, } from './utils/serialize-inspector-state.js';
|
|
4
4
|
export { filterInspectorState } from './utils/filter-inspector-state.js';
|
|
5
|
+
export { resolveDeployTarget } from './utils/resolve-deploy-target.js';
|
|
5
6
|
export { generateCustomTypes, sanitizeTypeName, } from './utils/custom-types-generator.js';
|
|
6
7
|
export { createEmptyManifest, serializeManifest, } from './utils/contract-hashes.js';
|
|
7
8
|
export { serializeMCPJson } from './utils/serialize-mcp-json.js';
|
package/dist/inspector.js
CHANGED
|
@@ -4,7 +4,7 @@ import { visitSetup, visitRoutes } from './visit.js';
|
|
|
4
4
|
import { TypesMap } from './types-map.js';
|
|
5
5
|
import { getFilesAndMethods } from './utils/get-files-and-methods.js';
|
|
6
6
|
import { findCommonAncestor } from './utils/find-root-dir.js';
|
|
7
|
-
import { aggregateRequiredServices, validateAgentModels,
|
|
7
|
+
import { aggregateRequiredServices, validateAgentModels, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, computeDiagnostics, validateSchemaWiringSeparation, } from './utils/post-process.js';
|
|
8
8
|
import { generateOpenAPISpec } from './utils/serialize-openapi-json.js';
|
|
9
9
|
import { pikkuState } from '@pikku/core/internal';
|
|
10
10
|
import { resolveLatestVersions } from './utils/resolve-versions.js';
|
|
@@ -203,8 +203,6 @@ export const inspect = async (logger, routeFiles, options = {}) => {
|
|
|
203
203
|
// Use provided rootDir or infer from source files
|
|
204
204
|
const rootDir = options.rootDir || findCommonAncestor(routeFiles);
|
|
205
205
|
const startSourceFiles = performance.now();
|
|
206
|
-
// Filter source files to only include files within the project rootDir
|
|
207
|
-
// This prevents picking up types from external packages (including workspace symlinks)
|
|
208
206
|
const sourceFiles = program
|
|
209
207
|
.getSourceFiles()
|
|
210
208
|
.filter((sf) => sf.fileName.startsWith(rootDir));
|
|
@@ -262,8 +260,7 @@ export const inspect = async (logger, routeFiles, options = {}) => {
|
|
|
262
260
|
if (options.openAPI) {
|
|
263
261
|
state.openAPISpec = await generateOpenAPISpec(logger, state.functions.meta, state.http.meta, state.schemas, options.openAPI.additionalInfo, pikkuState(null, 'misc', 'errors'));
|
|
264
262
|
}
|
|
265
|
-
validateAgentModels(logger, state
|
|
266
|
-
validateAgentOverrides(logger, state, options.modelConfig);
|
|
263
|
+
validateAgentModels(logger, state);
|
|
267
264
|
validateSecretOverrides(logger, state);
|
|
268
265
|
validateVariableOverrides(logger, state);
|
|
269
266
|
validateCredentialOverrides(logger, state);
|
package/dist/types.d.ts
CHANGED
|
@@ -143,10 +143,19 @@ export interface InspectorPermissionState {
|
|
|
143
143
|
export type InspectorFilters = {
|
|
144
144
|
names?: string[];
|
|
145
145
|
tags?: string[];
|
|
146
|
-
|
|
146
|
+
wires?: string[];
|
|
147
147
|
directories?: string[];
|
|
148
148
|
httpRoutes?: string[];
|
|
149
149
|
httpMethods?: string[];
|
|
150
|
+
excludeNames?: string[];
|
|
151
|
+
excludeTags?: string[];
|
|
152
|
+
excludeWires?: string[];
|
|
153
|
+
excludeDirectories?: string[];
|
|
154
|
+
excludeHttpRoutes?: string[];
|
|
155
|
+
excludeHttpMethods?: string[];
|
|
156
|
+
target?: Array<'serverless' | 'server'>;
|
|
157
|
+
excludeTarget?: Array<'serverless' | 'server'>;
|
|
158
|
+
serverlessIncompatible?: string[];
|
|
150
159
|
};
|
|
151
160
|
export type AddonConfig = {
|
|
152
161
|
package: string;
|
|
@@ -154,23 +163,6 @@ export type AddonConfig = {
|
|
|
154
163
|
secretOverrides?: Record<string, string>;
|
|
155
164
|
forceInclude?: boolean;
|
|
156
165
|
};
|
|
157
|
-
export type ModelConfigEntry = string | {
|
|
158
|
-
model: string;
|
|
159
|
-
temperature?: number;
|
|
160
|
-
maxSteps?: number;
|
|
161
|
-
};
|
|
162
|
-
export type InspectorModelConfig = {
|
|
163
|
-
models?: Record<string, ModelConfigEntry>;
|
|
164
|
-
agentDefaults?: {
|
|
165
|
-
temperature?: number;
|
|
166
|
-
maxSteps?: number;
|
|
167
|
-
};
|
|
168
|
-
agentOverrides?: Record<string, {
|
|
169
|
-
model?: string;
|
|
170
|
-
temperature?: number;
|
|
171
|
-
maxSteps?: number;
|
|
172
|
-
}>;
|
|
173
|
-
};
|
|
174
166
|
export type InspectorOptions = Partial<{
|
|
175
167
|
setupOnly: boolean;
|
|
176
168
|
rootDir: string;
|
|
@@ -193,7 +185,6 @@ export type InspectorOptions = Partial<{
|
|
|
193
185
|
};
|
|
194
186
|
tags: string[];
|
|
195
187
|
manifest: VersionManifest;
|
|
196
|
-
modelConfig: InspectorModelConfig;
|
|
197
188
|
oldProgram: ts.Program | undefined;
|
|
198
189
|
}>;
|
|
199
190
|
export interface InspectorLogger {
|
|
@@ -338,6 +338,12 @@ export function extractFunctionName(callExpr, checker, rootDir) {
|
|
|
338
338
|
result.pikkuFuncId = `__temp_${randomUUID()}`;
|
|
339
339
|
}
|
|
340
340
|
if (result.version !== null) {
|
|
341
|
+
// Strip trailing VN suffix if it matches the version (e.g. createCardV1 + version:1 → createCard@v1)
|
|
342
|
+
const vSuffix = `V${result.version}`;
|
|
343
|
+
if (result.pikkuFuncId.endsWith(vSuffix) &&
|
|
344
|
+
result.pikkuFuncId.length > vSuffix.length) {
|
|
345
|
+
result.pikkuFuncId = result.pikkuFuncId.slice(0, -vSuffix.length);
|
|
346
|
+
}
|
|
341
347
|
result.pikkuFuncId = formatVersionedId(result.pikkuFuncId, result.version);
|
|
342
348
|
}
|
|
343
349
|
return result;
|