@pikku/inspector 0.12.96 → 0.12.98

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 CHANGED
@@ -1,3 +1,47 @@
1
+ ## 0.12.98
2
+
3
+ ### Patch Changes
4
+
5
+ - 8ac25a8: An OAuth2 credential can set `scopeSeparator` for a provider that wants scopes joined by something other than a space (Twist wants a comma). A credential with no scopes already sent no `scope` parameter; that is now tested.
6
+ - 6606777: A webhook source can declare how its requests are signed, and the runner checks every request before `receive` runs:
7
+
8
+ ```ts
9
+ wireTriggerWebhookSource({
10
+ name: 'github',
11
+ verify: {
12
+ hmac: {
13
+ header: 'x-hub-signature-256',
14
+ prefix: 'sha256=',
15
+ algorithm: 'sha256',
16
+ encoding: 'hex',
17
+ },
18
+ },
19
+ receive: githubWebhookReceive,
20
+ })
21
+ ```
22
+
23
+ `verify` is an HMAC over the raw body, a shared token or a public-key signature in one header, or a function `(request, secret, services) => boolean` for anything else. A request is refused while the secret is unset or when the signature does not match. A request without a body reaches `receive` unchecked so handshakes still work, but it may only be answered: events from it are refused.
24
+
25
+ Declaring `verify` declares the secret's credential too, so it needs no `defineCredential`. It is a singleton string named `<source>WebhookSecret` in camelCase (`microsoft-outlook` → `microsoftOutlookWebhookSecret`, see `webhookSecretCredentialName`), or whatever `credential` names, described by `credentialDescription`.
26
+
27
+ `@pikku/core/hmac` gains `hmacDigest`, `verifyHmacSignature` and `verifyPublicKeySignature`. `WebhookSigningSecret` is deprecated.
28
+
29
+ - Updated dependencies [d327fa5]
30
+ - Updated dependencies [942ebdd]
31
+ - Updated dependencies [8ac25a8]
32
+ - Updated dependencies [6606777]
33
+ - @pikku/core@0.12.132
34
+
35
+ ## 0.12.97
36
+
37
+ ### Patch Changes
38
+
39
+ - 26dbfc0: A `func` written inline in a `wireCLI` command now registers its function metadata under `cli:<program>:<command path>`, with `sessionless` taken from the helper it was built with. Before, the command pointed at an id nothing had registered. An inline channel `onMessage` still fails the build with the named "No function metadata found" error, and a test now pins that.
40
+ - 2dcc651: The inspector finds a project's source on Windows: its root directory is compared with TypeScript's forward-slash file names, not the backslash path `path.resolve` returns.
41
+ - Updated dependencies [58cccc1]
42
+ - Updated dependencies [a26c60e]
43
+ - @pikku/core@0.12.131
44
+
1
45
  ## 0.12.96
2
46
 
3
47
  ### Patch Changes
@@ -3,6 +3,7 @@ import { extractFunctionName, makeContextBasedId, } from '../utils/extract-funct
3
3
  import { resolveCoreType } from '../utils/resolve-core-type.js';
4
4
  import { resolveMiddleware } from '../utils/middleware.js';
5
5
  import { resolveFunctionMeta } from '../utils/resolve-function-meta.js';
6
+ import { ensureInlineWiringFunction } from '../utils/ensure-function-metadata.js';
6
7
  import { extractWireNames } from '../utils/post-process.js';
7
8
  import { getPropertyValue } from '../utils/get-property-value.js';
8
9
  import { resolveIdentifier } from '../utils/resolve-identifier.js';
@@ -253,9 +254,11 @@ function processCommand(logger, inspectorState, options, name, node, sourceFile,
253
254
  }
254
255
  }
255
256
  else {
256
- pikkuFuncId = extractFunctionName(prop.initializer, typeChecker, inspectorState.rootDir).pikkuFuncId;
257
+ const extracted = extractFunctionName(prop.initializer, typeChecker, inspectorState.rootDir);
258
+ pikkuFuncId = extracted.pikkuFuncId;
257
259
  if (pikkuFuncId.startsWith('__temp_')) {
258
260
  pikkuFuncId = makeContextBasedId('cli', programName, ...fullPath);
261
+ ensureInlineWiringFunction(inspectorState, pikkuFuncId, fullPath.join(' '), prop.initializer, typeChecker, extracted.isHelper);
259
262
  }
260
263
  meta.pikkuFuncId = pikkuFuncId;
261
264
  const cliPackageName = ts.isIdentifier(prop.initializer)
@@ -81,6 +81,7 @@ export const addCredential = (logger, node, checker, state, _options) => {
81
81
  const authorizationUrl = getPropertyValue(oauth2Obj, 'authorizationUrl');
82
82
  const tokenUrl = getPropertyValue(oauth2Obj, 'tokenUrl');
83
83
  const scopes = getArrayPropertyValue(oauth2Obj, 'scopes');
84
+ const scopeSeparator = getPropertyValue(oauth2Obj, 'scopeSeparator');
84
85
  const pkce = getPropertyValue(oauth2Obj, 'pkce');
85
86
  const additionalParams = getRecordPropertyValue(oauth2Obj, 'additionalParams');
86
87
  if (appCredentialSecretId && authorizationUrl && tokenUrl && scopes) {
@@ -90,6 +91,7 @@ export const addCredential = (logger, node, checker, state, _options) => {
90
91
  authorizationUrl,
91
92
  tokenUrl,
92
93
  scopes,
94
+ scopeSeparator: scopeSeparator || undefined,
93
95
  pkce: pkce || undefined,
94
96
  additionalParams: additionalParams || undefined,
95
97
  };
@@ -8,6 +8,7 @@ import { extractWireNames } from '../utils/post-process.js';
8
8
  import { resolveAddonName } from '../utils/resolve-addon-package.js';
9
9
  import { resolveFunctionMeta } from '../utils/resolve-function-meta.js';
10
10
  import { ErrorCode } from '../error-codes.js';
11
+ import { webhookSecretCredentialName } from '@pikku/core/trigger';
11
12
  const WEBHOOK_SOURCE_STEPS = ['receive', 'check', 'setup', 'teardown'];
12
13
  export const addTrigger = (logger, node, checker, state, options) => {
13
14
  if (!ts.isCallExpression(node)) {
@@ -161,6 +162,21 @@ const addWireTriggerWebhookSource = (logger, node, checker, state, firstArg) =>
161
162
  };
162
163
  state.triggers.webhookSourceMeta[name] = meta;
163
164
  state.triggers.files.add(node.getSourceFile().fileName);
165
+ if (!getPropertyAssignmentInitializer(obj, 'verify', false, checker))
166
+ return;
167
+ const sourceFile = node.getSourceFile().fileName;
168
+ const credential = getPropertyValue(obj, 'credential') ??
169
+ webhookSecretCredentialName(name);
170
+ state.credentials.files.add(sourceFile);
171
+ state.credentials.definitions.push({
172
+ name: credential,
173
+ displayName: `${name} webhook secret`,
174
+ description: getPropertyValue(obj, 'credentialDescription') ??
175
+ undefined,
176
+ type: 'singleton',
177
+ schema: { type: 'string' },
178
+ sourceFile,
179
+ });
164
180
  };
165
181
  /**
166
182
  * A trigger named `<source>:<event>` must name an event its webhook source
package/dist/inspector.js CHANGED
@@ -7,6 +7,7 @@ import { getFilesAndMethods } from './utils/get-files-and-methods.js';
7
7
  import { findCommonAncestor } from './utils/find-root-dir.js';
8
8
  import { createSourceFileCacheHost } from './source-file-cache.js';
9
9
  import { createNestedProjectFilter } from './utils/nested-project-filter.js';
10
+ import { toProgramPath } from './utils/program-path.js';
10
11
  import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateAgentScorerReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes, validatePersonaRoles, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, validateNoSecretAliasServices, registerDerivedOAuth2AppSecrets, validateSecretUsage, computeDiagnostics, validateSchemaReferences, validateSchemaWiringSeparation, validateScenarioServices, validateScenarioSteps, validateScenarioFeatures, validateWorkflowGraphAddons, } from './utils/post-process.js';
11
12
  import { validateExposedFunctionsGated } from './utils/validate-exposed-functions-gated.js';
12
13
  import { validateTagsResolveToMiddleware } from './utils/validate-tags-resolve-to-middleware.js';
@@ -293,7 +294,7 @@ export const inspect = async (logger, routeFiles, options = {}) => {
293
294
  const checker = program.getTypeChecker();
294
295
  logger.debug(`Got type checker in ${(performance.now() - startChecker).toFixed(2)}ms`);
295
296
  // Use provided rootDir or infer from source files
296
- const rootDir = options.rootDir || findCommonAncestor(normalizedRouteFiles);
297
+ const rootDir = toProgramPath(options.rootDir || findCommonAncestor(normalizedRouteFiles));
297
298
  const startSourceFiles = performance.now();
298
299
  // node_modules under rootDir (e.g. a locally-installed addon) is a
299
300
  // dependency, not project source — scanning it double-counts the addon's
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A native path in the form a TypeScript program names its files: forward
3
+ * slashes on every platform. `sourceFile.fileName` is `D:/a/app/src/x.ts` on
4
+ * Windows while `path.resolve` gives `D:\a\app`, so comparing the two by
5
+ * prefix rejects every file unless one side is converted.
6
+ */
7
+ export declare const toProgramPath: (nativePath: string, separator?: "/" | "\\") => string;
@@ -0,0 +1,8 @@
1
+ import { sep } from 'path';
2
+ /**
3
+ * A native path in the form a TypeScript program names its files: forward
4
+ * slashes on every platform. `sourceFile.fileName` is `D:/a/app/src/x.ts` on
5
+ * Windows while `path.resolve` gives `D:\a\app`, so comparing the two by
6
+ * prefix rejects every file unless one side is converted.
7
+ */
8
+ export const toProgramPath = (nativePath, separator = sep) => nativePath.split(separator).join('/');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/inspector",
3
- "version": "0.12.96",
3
+ "version": "0.12.98",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/pikkujs/pikku.git",
@@ -54,10 +54,10 @@
54
54
  "zod": "^4.4.3"
55
55
  },
56
56
  "peerDependencies": {
57
- "@pikku/core": "^0.12.130"
57
+ "@pikku/core": "^0.12.132"
58
58
  },
59
59
  "devDependencies": {
60
- "@pikku/core": "^0.12.130",
60
+ "@pikku/core": "^0.12.132",
61
61
  "@types/node": "^24.13.3"
62
62
  },
63
63
  "engines": {