@pikku/inspector 0.12.102 → 0.12.106
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 +61 -0
- package/dist/add/add-cli.js +21 -11
- package/dist/add/add-define-screens.d.ts +8 -0
- package/dist/add/add-define-screens.js +140 -0
- package/dist/add/add-functions.js +8 -8
- package/dist/add/add-virtual-users.d.ts +13 -0
- package/dist/add/{add-personas.js → add-virtual-users.js} +33 -33
- package/dist/add/add-wire-addon.js +39 -2
- package/dist/add/add-workflow.js +14 -10
- package/dist/error-codes.d.ts +9 -3
- package/dist/error-codes.js +9 -3
- package/dist/index.d.ts +1 -1
- package/dist/inspector.js +7 -3
- package/dist/types.d.ts +45 -3
- package/dist/utils/extract-function-name.js +1 -1
- package/dist/utils/get-property-value.js +1 -1
- package/dist/utils/load-addon-functions-meta.d.ts +0 -5
- package/dist/utils/load-addon-functions-meta.js +53 -0
- package/dist/utils/post-process.d.ts +36 -34
- package/dist/utils/post-process.js +227 -169
- package/dist/utils/serialize-inspector-state.d.ts +7 -2
- package/dist/utils/serialize-inspector-state.js +10 -6
- package/dist/utils/single-declaration.d.ts +3 -3
- package/dist/utils/single-declaration.js +3 -3
- package/dist/utils/validate-single-step-workflows.d.ts +3 -0
- package/dist/utils/validate-single-step-workflows.js +32 -0
- package/dist/utils/workflow/dsl/extract-dsl-workflow.js +3 -3
- package/dist/utils/workflow/dsl/patterns.d.ts +3 -3
- package/dist/utils/workflow/dsl/patterns.js +4 -4
- package/dist/utils/workflow/graph/convert-dsl-to-graph.js +6 -6
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +5 -5
- package/dist/visit.js +4 -2
- package/knowledge/decisions/a-channel-with-auth-false-marks-its-connect-and-disconnect-sessionless.md +22 -0
- package/knowledge/decisions/a-declared-scope-id-never-shadows-a-definition.md +20 -0
- package/knowledge/decisions/a-dsl-step-virtual-user-is-the-literal-name-in-its-options.md +27 -0
- package/knowledge/decisions/a-feature-flags-anyof-is-read-from-the-ast-and-an-empty-list-is-refused.md +20 -0
- package/knowledge/decisions/a-non-literal-string-array-reads-as-absent.md +25 -0
- package/knowledge/decisions/a-permission-with-an-underscore-data-parameter-takes-no-data.md +20 -0
- package/knowledge/decisions/a-provider-login-virtual-user-is-never-runnable.md +27 -0
- package/knowledge/decisions/a-remote-addon-bound-credential-or-secret-must-be-wired.md +27 -0
- package/knowledge/decisions/a-route-auth-overrides-its-groups-auth.md +22 -0
- package/knowledge/decisions/a-route-requires-a-session-when-any-auth-signal-says-so.md +29 -0
- package/knowledge/decisions/a-webhook-source-with-verify-gets-a-singleton-secret-credential.md +21 -0
- package/knowledge/decisions/a-wire-with-auth-disabled-cannot-point-at-a-pikkufunc.md +21 -0
- package/knowledge/decisions/addon-contracts-cannot-wire-or-declare-handlers.md +25 -0
- package/knowledge/decisions/addon-declarations-name-the-secrets-and-credentials-the-app-lends-it.md +19 -0
- package/knowledge/decisions/an-inline-wiring-function-is-sessionless-unless-built-with-pikkufunc.md +23 -0
- package/knowledge/decisions/better-auth-admin-plugin-is-refused.md +24 -0
- package/knowledge/decisions/define-screens-scopes-must-be-string-literals.md +18 -0
- package/knowledge/decisions/index.md +38 -0
- package/knowledge/decisions/inspector-records-a-non-literal-global-grant-as-source-text.md +20 -0
- package/knowledge/decisions/only-one-pikku-better-auth-export-per-codebase.md +19 -0
- package/knowledge/decisions/scope-references-and-secret-aliases-are-critical-diagnostics.md +23 -0
- package/knowledge/decisions/scope-segments-may-not-be-wildcards-or-contain-colons.md +23 -0
- package/knowledge/decisions/shorthand-permission-entries-are-extracted.md +22 -0
- package/knowledge/decisions/system-roles-declare-literal-unqualified-scopes.md +28 -0
- package/knowledge/decisions/the-inspector-records-agent-permissions-only-to-aggregate-services.md +14 -0
- package/knowledge/decisions/vault-secrets-reach-no-sink-and-pii-stays-out-of-logs-and-webhooks.md +30 -0
- package/knowledge/decisions/webhook-gateway-wrappers-are-sessionless-and-gateway-auth-runs-inside-the-handler.md +26 -0
- package/knowledge/index.md +14 -0
- package/knowledge/questions/does-a-non-literal-remote-addon-auth-get-checked.md +26 -0
- package/knowledge/questions/index.md +16 -0
- package/knowledge/questions/is-an-incomplete-oauth2-block-dropped-without-a-log.md +23 -0
- package/knowledge/questions/should-app-functions-named-like-scenario-instrumentation-be-refused.md +28 -0
- package/knowledge/questions/should-the-openapi-document-default-every-operation-to-a-bearer-or-api-key.md +22 -0
- package/package.json +3 -3
- package/dist/add/add-personas.d.ts +0 -13
package/dist/add/add-workflow.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
|
+
import { relative } from 'node:path';
|
|
2
3
|
import { extractFunctionName } from '../utils/extract-function-name.js';
|
|
3
4
|
import { extractFunctionNode } from '../utils/extract-function-node.js';
|
|
4
5
|
import { ErrorCode } from '../error-codes.js';
|
|
5
6
|
import { extractStringLiteral, isStringLike, isFunctionLike, extractDescription, extractDuration, } from '../utils/extract-node-value.js';
|
|
6
7
|
import { getCommonWireMetaData, getPropertyValue, } from '../utils/get-property-value.js';
|
|
7
8
|
import { extractDSLWorkflow } from '../utils/workflow/dsl/extract-dsl-workflow.js';
|
|
8
|
-
import { getSourceText,
|
|
9
|
+
import { getSourceText, extractVirtualUserFromOptions, } from '../utils/workflow/dsl/patterns.js';
|
|
9
10
|
/**
|
|
10
11
|
* Extract a workflow step's display name without letting a non-static name
|
|
11
12
|
* (e.g. a function call) abort the scan. The step name is cosmetic, so a
|
|
@@ -141,7 +142,7 @@ function getWorkflowInvocations(node, checker, state, workflowName, steps) {
|
|
|
141
142
|
type: 'rpc',
|
|
142
143
|
stepName,
|
|
143
144
|
rpcName,
|
|
144
|
-
|
|
145
|
+
virtualUser: extractVirtualUserFromOptions(optionsArg),
|
|
145
146
|
});
|
|
146
147
|
state.rpc.invokedFunctions.add(rpcName);
|
|
147
148
|
}
|
|
@@ -164,7 +165,7 @@ function getWorkflowInvocations(node, checker, state, workflowName, steps) {
|
|
|
164
165
|
stepName,
|
|
165
166
|
rpcName,
|
|
166
167
|
expectEventually: true,
|
|
167
|
-
|
|
168
|
+
virtualUser: extractVirtualUserFromOptions(args.length >= 5 ? args[4] : undefined),
|
|
168
169
|
});
|
|
169
170
|
state.rpc.invokedFunctions.add(rpcName);
|
|
170
171
|
}
|
|
@@ -229,7 +230,7 @@ export const addWorkflow = (logger, node, checker, state, options) => {
|
|
|
229
230
|
wrapperType = 'complex';
|
|
230
231
|
}
|
|
231
232
|
else if (expression.text === 'pikkuScenario') {
|
|
232
|
-
// A scenario is a complex workflow whose steps run as
|
|
233
|
+
// A scenario is a complex workflow whose steps run as virtual users over the
|
|
233
234
|
// real transport — same extraction rules as complex, distinct meta.
|
|
234
235
|
wrapperType = 'scenario';
|
|
235
236
|
}
|
|
@@ -243,7 +244,10 @@ export const addWorkflow = (logger, node, checker, state, options) => {
|
|
|
243
244
|
const { pikkuFuncId, name, exportedName } = extractFunctionName(node, checker, state.rootDir);
|
|
244
245
|
const workflowName = exportedName || name;
|
|
245
246
|
if (!workflowName) {
|
|
246
|
-
|
|
247
|
+
const sourceFile = node.getSourceFile();
|
|
248
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
249
|
+
logger.critical(ErrorCode.MISSING_NAME, `Could not determine workflow name from export at ${relative(state.rootDir, sourceFile.fileName)}:${line + 1}. ` +
|
|
250
|
+
`Assign the \`${expression.text}(...)\` call to an exported const; that name is how it is registered.`);
|
|
247
251
|
return;
|
|
248
252
|
}
|
|
249
253
|
// Extract the function node (either direct function or from config.func)
|
|
@@ -358,11 +362,11 @@ export const addWorkflow = (logger, node, checker, state, options) => {
|
|
|
358
362
|
const sink = steps.length > 0 ? [] : steps;
|
|
359
363
|
getWorkflowInvocations(resolvedFunc, checker, state, workflowName, sink);
|
|
360
364
|
}
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
const
|
|
365
|
+
// Virtual user names the flow's steps run as (scenarios) — powers the console
|
|
366
|
+
// virtual users view and the Scenario graph badges.
|
|
367
|
+
const virtualUserNames = [
|
|
364
368
|
...new Set(steps
|
|
365
|
-
.map((s) => ('
|
|
369
|
+
.map((s) => ('virtualUser' in s ? s.virtualUser : undefined))
|
|
366
370
|
.filter((a) => typeof a === 'string')),
|
|
367
371
|
];
|
|
368
372
|
state.workflows.meta[workflowName] = {
|
|
@@ -380,7 +384,7 @@ export const addWorkflow = (logger, node, checker, state, options) => {
|
|
|
380
384
|
skip,
|
|
381
385
|
scenario: wrapperType === 'scenario' ? true : undefined,
|
|
382
386
|
asserts,
|
|
383
|
-
|
|
387
|
+
virtualUsers: virtualUserNames.length > 0 ? virtualUserNames : undefined,
|
|
384
388
|
};
|
|
385
389
|
// The scenario "logger/config only" rule (PKU673) and the implicit
|
|
386
390
|
// workflow platform-service injection both used to live here, reading
|
package/dist/error-codes.d.ts
CHANGED
|
@@ -20,22 +20,28 @@ export declare enum ErrorCode {
|
|
|
20
20
|
CLI_CLIENTSIDE_RENDERER_HAS_SERVICES = "PKU672",
|
|
21
21
|
SCENARIO_HAS_SERVICES = "PKU673",
|
|
22
22
|
EXPECT_EVENTUALLY_SCENARIO_ONLY = "PKU675",
|
|
23
|
-
|
|
23
|
+
SCENARIO_STEP_NEEDS_VIRTUAL_USER = "PKU677",
|
|
24
24
|
SCENARIO_STEP_TARGET_NOT_STATIC = "PKU678",
|
|
25
25
|
SCENARIO_NOT_EXTRACTABLE = "PKU679",
|
|
26
26
|
SCENARIO_HAS_NO_ASSERTION = "PKU680",
|
|
27
|
-
|
|
27
|
+
SCENARIO_STEP_PROSE_NAMES_VIRTUAL_USER = "PKU681",
|
|
28
28
|
SCENARIO_HAS_NO_FEATURE = "PKU682",
|
|
29
29
|
WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED = "PKU600",
|
|
30
30
|
INVALID_DSL_WORKFLOW = "PKU641",
|
|
31
31
|
WORKFLOW_GRAPH_ADDON_NOT_WIRED = "PKU642",
|
|
32
32
|
COMPLEX_WORKFLOW_NOT_ALLOWED = "PKU643",
|
|
33
|
+
SINGLE_STEP_WORKFLOW = "PKU644",
|
|
33
34
|
REMOTE_ADDON_NOT_DEV_DEPENDENCY = "PKU338",
|
|
34
35
|
REMOTE_ADDON_AUTH_UNRESOLVED = "PKU339",
|
|
35
36
|
ADDON_NOT_INSTALLED = "PKU340",
|
|
36
37
|
ADDON_MCP_FUNCTION_NOT_FOUND = "PKU341",
|
|
37
38
|
ADDON_EXPOSE_FUNCTION_NOT_FOUND = "PKU343",
|
|
38
39
|
ADDON_EXPOSE_NOT_STATIC = "PKU344",
|
|
40
|
+
ADDON_SCREENS_NOT_STATIC = "PKU345",
|
|
41
|
+
ADDON_UI_HAS_NO_SCREENS = "PKU346",
|
|
42
|
+
ADDON_USES_NOT_WIRED = "PKU347",
|
|
43
|
+
ADDON_NEEDS_NOT_MAPPED = "PKU348",
|
|
44
|
+
ADDON_CONTENT_GRANT_INVALID = "PKU349",
|
|
39
45
|
DB_COLUMN_NAME_TYPE_CONTRADICTION = "PKU480",
|
|
40
46
|
DB_JSON_COLUMN_UNTYPED = "PKU481",
|
|
41
47
|
DB_FORMAT_ON_NON_STRING = "PKU482",
|
|
@@ -48,7 +54,7 @@ export declare enum ErrorCode {
|
|
|
48
54
|
FUNCTION_METADATA_NOT_FOUND = "PKU559",
|
|
49
55
|
DUPLICATE_AUTH_DEFINITION = "PKU581",
|
|
50
56
|
AUTH_NOT_EXPORTED = "PKU582",
|
|
51
|
-
|
|
57
|
+
DUPLICATE_VIRTUAL_USERS_DEFINITION = "PKU585",
|
|
52
58
|
ROUTE_PARAM_MISMATCH = "PKU571",
|
|
53
59
|
ROUTE_QUERY_MISMATCH = "PKU572",
|
|
54
60
|
AUTH_DISABLED_REQUIRES_SESSIONLESS = "PKU573",
|
package/dist/error-codes.js
CHANGED
|
@@ -22,16 +22,17 @@ export var ErrorCode;
|
|
|
22
22
|
ErrorCode["CLI_CLIENTSIDE_RENDERER_HAS_SERVICES"] = "PKU672";
|
|
23
23
|
ErrorCode["SCENARIO_HAS_SERVICES"] = "PKU673";
|
|
24
24
|
ErrorCode["EXPECT_EVENTUALLY_SCENARIO_ONLY"] = "PKU675";
|
|
25
|
-
ErrorCode["
|
|
25
|
+
ErrorCode["SCENARIO_STEP_NEEDS_VIRTUAL_USER"] = "PKU677";
|
|
26
26
|
ErrorCode["SCENARIO_STEP_TARGET_NOT_STATIC"] = "PKU678";
|
|
27
27
|
ErrorCode["SCENARIO_NOT_EXTRACTABLE"] = "PKU679";
|
|
28
28
|
ErrorCode["SCENARIO_HAS_NO_ASSERTION"] = "PKU680";
|
|
29
|
-
ErrorCode["
|
|
29
|
+
ErrorCode["SCENARIO_STEP_PROSE_NAMES_VIRTUAL_USER"] = "PKU681";
|
|
30
30
|
ErrorCode["SCENARIO_HAS_NO_FEATURE"] = "PKU682";
|
|
31
31
|
ErrorCode["WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED"] = "PKU600";
|
|
32
32
|
ErrorCode["INVALID_DSL_WORKFLOW"] = "PKU641";
|
|
33
33
|
ErrorCode["WORKFLOW_GRAPH_ADDON_NOT_WIRED"] = "PKU642";
|
|
34
34
|
ErrorCode["COMPLEX_WORKFLOW_NOT_ALLOWED"] = "PKU643";
|
|
35
|
+
ErrorCode["SINGLE_STEP_WORKFLOW"] = "PKU644";
|
|
35
36
|
// Remote addon (wireRemoteAddon) validation
|
|
36
37
|
ErrorCode["REMOTE_ADDON_NOT_DEV_DEPENDENCY"] = "PKU338";
|
|
37
38
|
ErrorCode["REMOTE_ADDON_AUTH_UNRESOLVED"] = "PKU339";
|
|
@@ -39,6 +40,11 @@ export var ErrorCode;
|
|
|
39
40
|
ErrorCode["ADDON_MCP_FUNCTION_NOT_FOUND"] = "PKU341";
|
|
40
41
|
ErrorCode["ADDON_EXPOSE_FUNCTION_NOT_FOUND"] = "PKU343";
|
|
41
42
|
ErrorCode["ADDON_EXPOSE_NOT_STATIC"] = "PKU344";
|
|
43
|
+
ErrorCode["ADDON_SCREENS_NOT_STATIC"] = "PKU345";
|
|
44
|
+
ErrorCode["ADDON_UI_HAS_NO_SCREENS"] = "PKU346";
|
|
45
|
+
ErrorCode["ADDON_USES_NOT_WIRED"] = "PKU347";
|
|
46
|
+
ErrorCode["ADDON_NEEDS_NOT_MAPPED"] = "PKU348";
|
|
47
|
+
ErrorCode["ADDON_CONTENT_GRANT_INVALID"] = "PKU349";
|
|
42
48
|
// Database schema codegen warnings
|
|
43
49
|
ErrorCode["DB_COLUMN_NAME_TYPE_CONTRADICTION"] = "PKU480";
|
|
44
50
|
ErrorCode["DB_JSON_COLUMN_UNTYPED"] = "PKU481";
|
|
@@ -60,7 +66,7 @@ export var ErrorCode;
|
|
|
60
66
|
// scopes and roles held this rule until the generated `admin` tree made it
|
|
61
67
|
// unsatisfiable, and get it back once `admin` is a default scope nobody
|
|
62
68
|
// declares. Do not reuse those two numbers for anything else.
|
|
63
|
-
ErrorCode["
|
|
69
|
+
ErrorCode["DUPLICATE_VIRTUAL_USERS_DEFINITION"] = "PKU585";
|
|
64
70
|
// HTTP Route errors
|
|
65
71
|
ErrorCode["ROUTE_PARAM_MISMATCH"] = "PKU571";
|
|
66
72
|
ErrorCode["ROUTE_QUERY_MISMATCH"] = "PKU572";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { inspect, getInitialInspectorState } from './inspector.js';
|
|
2
2
|
export type { TypesMap } from './types-map.js';
|
|
3
|
-
export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
|
|
3
|
+
export type { AddonConfig, AuthDefinition, CredentialOverrideMeta, ScreensManifestMeta, AddonScreenMeta, InspectorDiagnostic, InspectorFilters, InspectorHTTPState, InspectorLogger, InspectorMiddlewareState, InspectorOptions, InspectorPermissionState, InspectorState, MetaInputTypes, MiddlewareGroupMeta, MiddlewareRegistration, SchemaRef, } from './types.js';
|
|
4
4
|
export type { FilesAndMethodsErrors } from './utils/get-files-and-methods.js';
|
|
5
5
|
export { ErrorCode } from './error-codes.js';
|
|
6
6
|
export type { DiagnosticSeverity, CodedDiagnostic } from './error-codes.js';
|
package/dist/inspector.js
CHANGED
|
@@ -9,9 +9,10 @@ import { findCommonAncestor } from './utils/find-root-dir.js';
|
|
|
9
9
|
import { createSourceFileCacheHost } from './source-file-cache.js';
|
|
10
10
|
import { createNestedProjectFilter } from './utils/nested-project-filter.js';
|
|
11
11
|
import { toProgramPath } from './utils/program-path.js';
|
|
12
|
-
import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateAgentScorerReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes,
|
|
12
|
+
import { aggregateRequiredServices, stampAuthHandlerServices, validateAgentModels, validateAgentToolReferences, validateAgentScorerReferences, validateSecretOverrides, validateVariableOverrides, validateCredentialOverrides, validateAddonUses, validateAddonContentGrants, validateRemoteAddonDependencies, validateRemoteAddonAuth, validateScopeReferences, validateSystemRoleScopes, validateVirtualUserRoles, computeResolvedIOTypes, computeMiddlewareGroupsMeta, computePermissionsGroupsMeta, computeRequiredSchemas, validateNoSecretAliasServices, registerDerivedOAuth2AppSecrets, validateSecretUsage, computeDiagnostics, validateSchemaReferences, validateSchemaWiringSeparation, validateScenarioServices, validateScenarioSteps, validateScenarioFeatures, validateWorkflowGraphAddons, } from './utils/post-process.js';
|
|
13
13
|
import { validateExposedFunctionsGated } from './utils/validate-exposed-functions-gated.js';
|
|
14
14
|
import { validateTagsResolveToMiddleware } from './utils/validate-tags-resolve-to-middleware.js';
|
|
15
|
+
import { validateSingleStepWorkflows } from './utils/validate-single-step-workflows.js';
|
|
15
16
|
import { annotateHttpRouteAuth } from './utils/annotate-http-route-auth.js';
|
|
16
17
|
import { generateOpenAPISpec } from './utils/serialize-openapi-json.js';
|
|
17
18
|
import { pikkuState } from '@pikku/core/state';
|
|
@@ -169,7 +170,7 @@ export function getInitialInspectorState(rootDir) {
|
|
|
169
170
|
definitions: [],
|
|
170
171
|
files: new Set(),
|
|
171
172
|
},
|
|
172
|
-
|
|
173
|
+
virtualUsers: {
|
|
173
174
|
definitions: [],
|
|
174
175
|
files: new Set(),
|
|
175
176
|
},
|
|
@@ -408,6 +409,7 @@ export const inspect = async (logger, routeFiles, options = {}) => {
|
|
|
408
409
|
computeDiagnostics(state);
|
|
409
410
|
validateSchemaWiringSeparation(logger, state);
|
|
410
411
|
validateWorkflowGraphAddons(logger, state);
|
|
412
|
+
validateSingleStepWorkflows(logger, state);
|
|
411
413
|
validateScenarioServices(logger, state);
|
|
412
414
|
validateScenarioSteps(logger, state);
|
|
413
415
|
validateScenarioFeatures(logger, state);
|
|
@@ -427,12 +429,14 @@ export const inspect = async (logger, routeFiles, options = {}) => {
|
|
|
427
429
|
validateSecretOverrides(logger, state);
|
|
428
430
|
validateVariableOverrides(logger, state);
|
|
429
431
|
validateCredentialOverrides(logger, state);
|
|
432
|
+
validateAddonUses(logger, state);
|
|
433
|
+
validateAddonContentGrants(logger, state);
|
|
430
434
|
validateRemoteAddonDependencies(logger, state);
|
|
431
435
|
validateRemoteAddonAuth(logger, state);
|
|
432
436
|
applyDeclaredScopes(state);
|
|
433
437
|
validateScopeReferences(logger, state);
|
|
434
438
|
validateSystemRoleScopes(logger, state);
|
|
435
|
-
|
|
439
|
+
validateVirtualUserRoles(logger, state);
|
|
436
440
|
logger.endValidationPass?.();
|
|
437
441
|
}
|
|
438
442
|
const cpu = process.cpuUsage(cpuStart);
|
package/dist/types.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type { CredentialDefinitions } from '@pikku/core/credential';
|
|
|
19
19
|
import type { ScopeDefinitions } from '@pikku/core/scope';
|
|
20
20
|
import type { SystemRoleDefinitions } from '@pikku/core/role';
|
|
21
21
|
import type { FeatureFlagDefinitions } from '@pikku/core/flag';
|
|
22
|
-
import type {
|
|
22
|
+
import type { VirtualUserDefinitions } from '@pikku/core/virtual-user';
|
|
23
23
|
import type { VariableDefinitions } from '@pikku/core/variable';
|
|
24
24
|
import type { TypesMap } from './types-map.js';
|
|
25
25
|
import type { FunctionsMeta } from '@pikku/core/services';
|
|
@@ -491,7 +491,38 @@ export type CredentialOverrideMeta = string | {
|
|
|
491
491
|
name?: string;
|
|
492
492
|
mode?: 'singleton' | 'wire';
|
|
493
493
|
};
|
|
494
|
+
/** A screen of an addon as `defineScreens` declares it, read statically. */
|
|
495
|
+
export type AddonScreenMeta = {
|
|
496
|
+
path: string;
|
|
497
|
+
title: string;
|
|
498
|
+
nav?: boolean;
|
|
499
|
+
scopes?: string[];
|
|
500
|
+
} & ({
|
|
501
|
+
component: string;
|
|
502
|
+
app?: undefined;
|
|
503
|
+
} | {
|
|
504
|
+
app: string;
|
|
505
|
+
component?: undefined;
|
|
506
|
+
});
|
|
507
|
+
export type ScreensManifestMeta = {
|
|
508
|
+
title: string;
|
|
509
|
+
icon?: string;
|
|
510
|
+
/** The source file whose `defineScreens` call declared this manifest. */
|
|
511
|
+
file: string;
|
|
512
|
+
screens: AddonScreenMeta[];
|
|
513
|
+
/**
|
|
514
|
+
* The addon's role: every scope its own functions require, derived by
|
|
515
|
+
* `pikku all` and never declared. Absent from the raw `defineScreens` read.
|
|
516
|
+
* On a wired instance it also carries the host's `wireAddon` scopes, which
|
|
517
|
+
* the runner demands of every function in the package.
|
|
518
|
+
*/
|
|
519
|
+
scopes?: string[];
|
|
520
|
+
};
|
|
494
521
|
export interface InspectorState {
|
|
522
|
+
/** Set when this package calls `defineScreens`: the screens it ships. */
|
|
523
|
+
screensManifest?: ScreensManifestMeta;
|
|
524
|
+
/** The screens of the addons this project wires with `ui: true`, by namespace. */
|
|
525
|
+
addonScreens?: Record<string, ScreensManifestMeta>;
|
|
495
526
|
rootDir: string;
|
|
496
527
|
singletonServicesTypeImportMap: PathToNameAndType;
|
|
497
528
|
wireServicesTypeImportMap: PathToNameAndType;
|
|
@@ -605,7 +636,11 @@ export interface InspectorState {
|
|
|
605
636
|
package: string;
|
|
606
637
|
/** The app source file whose `wireAddon` call declared this instance. */
|
|
607
638
|
file?: string;
|
|
639
|
+
/** Declared with `ui: true`: the package must ship screens, and the host mounts them. */
|
|
640
|
+
ui?: boolean;
|
|
608
641
|
rpcEndpoint?: string;
|
|
642
|
+
/** The other addons this instance may call: package -> the name it is wired under. */
|
|
643
|
+
uses?: Record<string, string>;
|
|
609
644
|
/**
|
|
610
645
|
* `true` offers every function the addon declared `mcp: true`; a list
|
|
611
646
|
* names the functions to offer, whatever the addon declared. Absent
|
|
@@ -660,6 +695,13 @@ export interface InspectorState {
|
|
|
660
695
|
* `CredentialService` instead of one scoped to its declared credentials.
|
|
661
696
|
*/
|
|
662
697
|
globalCredentials?: string;
|
|
698
|
+
contentBucket?: string;
|
|
699
|
+
contentGrants?: Record<string, string>;
|
|
700
|
+
/**
|
|
701
|
+
* The app's stated reason for handing this instance the whole
|
|
702
|
+
* `ContentService` instead of one scoped to its own folder.
|
|
703
|
+
*/
|
|
704
|
+
globalContent?: string;
|
|
663
705
|
}>;
|
|
664
706
|
wireAddonFiles: Set<string>;
|
|
665
707
|
};
|
|
@@ -742,8 +784,8 @@ export interface InspectorState {
|
|
|
742
784
|
definitions: FeatureFlagDefinitions;
|
|
743
785
|
files: Set<string>;
|
|
744
786
|
};
|
|
745
|
-
|
|
746
|
-
definitions:
|
|
787
|
+
virtualUsers: {
|
|
788
|
+
definitions: VirtualUserDefinitions;
|
|
747
789
|
files: Set<string>;
|
|
748
790
|
};
|
|
749
791
|
variables: {
|
|
@@ -30,7 +30,7 @@ export function funcIdToTypeName(id) {
|
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
32
|
* The step wrappers, whichever kind of subject acts in them. A scenario calls a
|
|
33
|
-
* platform or addon step by name exactly as it calls a
|
|
33
|
+
* platform or addon step by name exactly as it calls a virtual user one.
|
|
34
34
|
*/
|
|
35
35
|
const SCENARIO_STEP_WRAPPERS = new Set([
|
|
36
36
|
'pikkuScenarioStep',
|
|
@@ -102,7 +102,7 @@ export const assertStringLiteralProperty = (obj, propertyName, wiringType, logge
|
|
|
102
102
|
* that anything written as an expression comes through raw: a `description`
|
|
103
103
|
* split across lines as `'Fetch the thing ' + 'from upstream'` reaches
|
|
104
104
|
* `infra.json` with the quotes and the `+` still in it, and is rendered that
|
|
105
|
-
* way in the
|
|
105
|
+
* way in the cloud console.
|
|
106
106
|
*
|
|
107
107
|
* Deliberately checker-free, unlike `extractStringLiteral`. Every value this
|
|
108
108
|
* resolves is a literal in the same expression, so no symbol resolution is
|
|
@@ -8,11 +8,6 @@ export declare const describeMissingAddonMeta: (namespace: string, packageName:
|
|
|
8
8
|
* Every source starts off: the app turns one on at runtime.
|
|
9
9
|
*/
|
|
10
10
|
export declare const namespaceAddonWebhookSources: (sources: WebhookSourcesMeta, namespace: string) => WebhookSourcesMeta;
|
|
11
|
-
/**
|
|
12
|
-
* After the setup sweep discovers wireAddon() declarations, load each addon
|
|
13
|
-
* package's function metadata so that wiring handlers (channels, HTTP routes,
|
|
14
|
-
* schedules, etc.) can look up addon function types during the routes sweep.
|
|
15
|
-
*/
|
|
16
11
|
export declare function loadAddonFunctionsMeta(logger: InspectorLogger, state: InspectorState): Promise<void>;
|
|
17
12
|
/**
|
|
18
13
|
* Load addon schemas into state.schemas. Called after generateAllSchemas
|
|
@@ -45,6 +45,7 @@ const applyPackageToCLICommands = (commands, packageName, namespace) => {
|
|
|
45
45
|
}
|
|
46
46
|
if (namespace &&
|
|
47
47
|
typeof command.pikkuFuncId === 'string' &&
|
|
48
|
+
command.pikkuFuncId !== '' &&
|
|
48
49
|
!command.pikkuFuncId.includes(':')) {
|
|
49
50
|
command.pikkuFuncId = `${namespace}:${command.pikkuFuncId}`;
|
|
50
51
|
}
|
|
@@ -181,6 +182,27 @@ export const namespaceAddonWebhookSources = (sources, namespace) => {
|
|
|
181
182
|
* package's function metadata so that wiring handlers (channels, HTTP routes,
|
|
182
183
|
* schedules, etc.) can look up addon function types during the routes sweep.
|
|
183
184
|
*/
|
|
185
|
+
const loadScreensManifest = async (require, packageName) => {
|
|
186
|
+
const path = resolveAddonMeta(require, packageName, 'screens/pikku-screens-meta');
|
|
187
|
+
if (!path)
|
|
188
|
+
return null;
|
|
189
|
+
return JSON.parse(await readFile(path, 'utf-8'));
|
|
190
|
+
};
|
|
191
|
+
const readAddonNeeds = async (dirs, packageName) => {
|
|
192
|
+
const dir = findInstalledPackageDir(dirs, packageName);
|
|
193
|
+
if (!dir)
|
|
194
|
+
return [];
|
|
195
|
+
try {
|
|
196
|
+
const pkg = JSON.parse(await readFile(join(dir, 'package.json'), 'utf-8'));
|
|
197
|
+
const uses = pkg?.pikku?.uses;
|
|
198
|
+
return Array.isArray(uses)
|
|
199
|
+
? uses.filter((u) => typeof u === 'string')
|
|
200
|
+
: [];
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
return [];
|
|
204
|
+
}
|
|
205
|
+
};
|
|
184
206
|
export async function loadAddonFunctionsMeta(logger, state) {
|
|
185
207
|
const { wireAddonDeclarations } = state.rpc;
|
|
186
208
|
if (wireAddonDeclarations.size === 0)
|
|
@@ -194,6 +216,37 @@ export async function loadAddonFunctionsMeta(logger, state) {
|
|
|
194
216
|
const dirs = addonResolutionDirs(state.rootDir, decl.file);
|
|
195
217
|
const require = createAddonResolver(dirs);
|
|
196
218
|
try {
|
|
219
|
+
for (const needed of await readAddonNeeds(dirs, decl.package)) {
|
|
220
|
+
if (!decl.uses?.[needed]) {
|
|
221
|
+
logger.critical(ErrorCode.ADDON_NEEDS_NOT_MAPPED, `${decl.package} needs ${needed}, but wireAddon('${namespace}') does not map it. Wire ${needed} and add uses: { '${needed}': '<name>' } to this wireAddon.`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (decl.ui) {
|
|
225
|
+
let manifest;
|
|
226
|
+
let unreadable = false;
|
|
227
|
+
try {
|
|
228
|
+
manifest = await loadScreensManifest(require, decl.package);
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
logger.critical(ErrorCode.ADDON_UI_HAS_NO_SCREENS, `wireAddon('${namespace}') sets ui: true, but the screens manifest of ${decl.package} could not be read: ${e instanceof Error ? e.message : e}`);
|
|
232
|
+
unreadable = true;
|
|
233
|
+
}
|
|
234
|
+
if (unreadable) {
|
|
235
|
+
// reported above; the addon's functions and scopes still load
|
|
236
|
+
}
|
|
237
|
+
else if (!manifest || manifest.screens.length === 0) {
|
|
238
|
+
logger.critical(ErrorCode.ADDON_UI_HAS_NO_SCREENS, `wireAddon('${namespace}') sets ui: true, but ${decl.package} declares no screens. Add a defineScreens call to the package, or drop ui.`);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
;
|
|
242
|
+
(state.addonScreens ??= {})[namespace] = {
|
|
243
|
+
...manifest,
|
|
244
|
+
scopes: [
|
|
245
|
+
...new Set([...(manifest.scopes ?? []), ...(decl.scopes ?? [])]),
|
|
246
|
+
].sort(),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
}
|
|
197
250
|
// Verbose first. `description` is one of the fields stripped from the
|
|
198
251
|
// minimal copy, and it is what an addon's function is offered to a model
|
|
199
252
|
// under — both as an MCP tool below and as an agent tool. Read the minimal
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { InspectorState, InspectorLogger, InspectorOptions } from
|
|
2
|
-
import type { PermissionMetadata } from
|
|
3
|
-
import type { MiddlewareMetadata } from
|
|
4
|
-
import type ts from
|
|
1
|
+
import type { InspectorState, InspectorLogger, InspectorOptions } from '../types.js';
|
|
2
|
+
import type { PermissionMetadata } from '@pikku/core/function';
|
|
3
|
+
import type { MiddlewareMetadata } from '@pikku/core/middleware';
|
|
4
|
+
import type ts from 'typescript';
|
|
5
5
|
/**
|
|
6
6
|
* Stamp the inspected authorize/callbacks service set onto the generated auth
|
|
7
7
|
* handler's function meta.
|
|
@@ -15,7 +15,7 @@ import type ts from "typescript";
|
|
|
15
15
|
* onto the handler meta. Re-derived every inspect and ordered BEFORE
|
|
16
16
|
* `aggregateRequiredServices` so it flows into `requiredServices`.
|
|
17
17
|
*/
|
|
18
|
-
export declare function stampAuthHandlerServices(state: InspectorState | Omit<InspectorState,
|
|
18
|
+
export declare function stampAuthHandlerServices(state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
19
19
|
/**
|
|
20
20
|
* Helper to extract wire-level middleware/permission names from metadata.
|
|
21
21
|
* Only extracts type:'wire' variants (individual middleware/permissions).
|
|
@@ -29,10 +29,12 @@ export declare function extractWireNames(list?: Array<MiddlewareMetadata | Permi
|
|
|
29
29
|
* Note: usedFunctions, usedMiddleware, and usedPermissions are tracked directly
|
|
30
30
|
* in the add-* methods during AST traversal for efficiency.
|
|
31
31
|
*/
|
|
32
|
-
export declare function aggregateRequiredServices(state: InspectorState | Omit<InspectorState,
|
|
33
|
-
export declare function validateSecretOverrides(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
34
|
-
export declare function
|
|
35
|
-
export declare function
|
|
32
|
+
export declare function aggregateRequiredServices(state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
33
|
+
export declare function validateSecretOverrides(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
34
|
+
export declare function validateAddonUses(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
35
|
+
export declare function validateAddonContentGrants(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
36
|
+
export declare function validateCredentialOverrides(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
37
|
+
export declare function validateVariableOverrides(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
36
38
|
/**
|
|
37
39
|
* Every wired addon must be installed, in the bucket matching how it is used.
|
|
38
40
|
*
|
|
@@ -56,14 +58,14 @@ export declare function validateVariableOverrides(logger: InspectorLogger, state
|
|
|
56
58
|
* up in `dependencies`. Asking the resolver is the only question that matches
|
|
57
59
|
* what the loader will actually do.
|
|
58
60
|
*/
|
|
59
|
-
export declare function validateRemoteAddonDependencies(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
61
|
+
export declare function validateRemoteAddonDependencies(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
60
62
|
/**
|
|
61
63
|
* The auth a `wireRemoteAddon` consumer binds must reference a slot the consumer
|
|
62
64
|
* actually declares: a `credentialId` must be a wired credential, a `secretId`
|
|
63
65
|
* a wired secret. A custom `resolve()` and a public (omitted) surface are not
|
|
64
66
|
* statically checkable and are left to runtime.
|
|
65
67
|
*/
|
|
66
|
-
export declare function validateRemoteAddonAuth(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
68
|
+
export declare function validateRemoteAddonAuth(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
67
69
|
export declare function computeResolvedIOTypes(state: InspectorState): void;
|
|
68
70
|
export declare function computeMiddlewareGroupsMeta(state: InspectorState): void;
|
|
69
71
|
export declare function computePermissionsGroupsMeta(state: InspectorState): void;
|
|
@@ -88,11 +90,11 @@ export declare function validateSchemaReferences(logger: InspectorLogger, state:
|
|
|
88
90
|
* A model is either concrete (`provider/model`) or an alias, which must appear
|
|
89
91
|
* in the `models` table from pikku.config.json.
|
|
90
92
|
*/
|
|
91
|
-
export declare function validateAgentModels(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
93
|
+
export declare function validateAgentModels(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>, modelAliases?: Record<string, string>): void;
|
|
92
94
|
/**
|
|
93
95
|
* Scenarios are pure stories of remote RPCs (same rule as client-side CLI
|
|
94
96
|
* renderers): the func may only destructure logger/config — everything else
|
|
95
|
-
* must go through
|
|
97
|
+
* must go through virtual user steps so the flow runs against the TARGET
|
|
96
98
|
* environment, never local services.
|
|
97
99
|
*
|
|
98
100
|
* This runs in post-processing rather than in `addWorkflow` because
|
|
@@ -100,17 +102,17 @@ export declare function validateAgentModels(logger: InspectorLogger, state: Insp
|
|
|
100
102
|
* `addFunctions` (`visitFunctions`) has populated `state.functions.meta` — so
|
|
101
103
|
* the check read `undefined` there and never fired.
|
|
102
104
|
*/
|
|
103
|
-
export declare function validateScenarioServices(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
105
|
+
export declare function validateScenarioServices(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
104
106
|
/**
|
|
105
|
-
* Does this step's prose open by naming the
|
|
107
|
+
* Does this step's prose open by naming the virtual user who is already its subject?
|
|
106
108
|
*
|
|
107
|
-
* `composeStepProse` renders the
|
|
109
|
+
* `composeStepProse` renders the virtual user as the sentence's subject, so a step
|
|
108
110
|
* authored as `'sam' creates the client` reads "Given sam 'sam' creates the
|
|
109
|
-
* client". Only the subject position counts: a
|
|
111
|
+
* client". Only the subject position counts: a virtual user keyed after a role noun
|
|
110
112
|
* ("admin") must still be able to say "creates the admin client", and naming
|
|
111
113
|
* someone mid-sentence — "sends sam an invite" — is ordinary prose.
|
|
112
114
|
*/
|
|
113
|
-
export declare const
|
|
115
|
+
export declare const proseOpensWithVirtualUser: (prose: string, virtualUser: string) => boolean;
|
|
114
116
|
/**
|
|
115
117
|
* Walk every scenario step, wherever it is nested, and validate the two things
|
|
116
118
|
* that can only be known once both the workflow meta and the function meta
|
|
@@ -118,9 +120,9 @@ export declare const proseOpensWithActor: (prose: string, actor: string) => bool
|
|
|
118
120
|
*
|
|
119
121
|
* - the step target must be a static string literal (PKU678) — otherwise it
|
|
120
122
|
* can't be bundled, typed or drawn;
|
|
121
|
-
* - a step that runs as a
|
|
122
|
-
* `
|
|
123
|
-
* signs in as that
|
|
123
|
+
* - a step that runs as a virtual user must be given one (PKU677) — declared by
|
|
124
|
+
* `virtualUser: true`, or implied by a `browser` binding, since the browser context
|
|
125
|
+
* signs in as that virtual user. It is checked statically even though a browser
|
|
124
126
|
* binding only runs on a browser run: a step that can never be driven by a
|
|
125
127
|
* human is a latent failure, not a passing default run.
|
|
126
128
|
* - a scenario written as a step ladder must assert something (PKU680).
|
|
@@ -128,7 +130,7 @@ export declare const proseOpensWithActor: (prose: string, actor: string) => bool
|
|
|
128
130
|
* It also marks the step's function as used, so `scenario run` boots the
|
|
129
131
|
* singletons the step actually needs.
|
|
130
132
|
*/
|
|
131
|
-
export declare function validateScenarioSteps(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
133
|
+
export declare function validateScenarioSteps(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
132
134
|
/**
|
|
133
135
|
* Reports scenarios that no `pikkuFeature` lists.
|
|
134
136
|
*
|
|
@@ -153,7 +155,7 @@ export declare function validateScenarioSteps(logger: InspectorLogger, state: In
|
|
|
153
155
|
* the check reports it then and downgrades to a warn naming both sides, rather
|
|
154
156
|
* than accusing a scenario that may well be in that array.
|
|
155
157
|
*/
|
|
156
|
-
export declare function validateScenarioFeatures(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
158
|
+
export declare function validateScenarioFeatures(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
157
159
|
/**
|
|
158
160
|
* A `pikkuWorkflowGraph` node that references the `graph:` namespace (e.g.
|
|
159
161
|
* `graph:editFields`) needs @pikku/addon-graph wired — otherwise the RPC never
|
|
@@ -178,7 +180,7 @@ export declare function validateSchemaWiringSeparation(logger: InspectorLogger,
|
|
|
178
180
|
* a name the omit does not cover. A name-based rule misses this; the type does
|
|
179
181
|
* not.
|
|
180
182
|
*/
|
|
181
|
-
export declare function validateNoSecretAliasServices(logger: InspectorLogger, checker: ts.TypeChecker, state: InspectorState | Omit<InspectorState,
|
|
183
|
+
export declare function validateNoSecretAliasServices(logger: InspectorLogger, checker: ts.TypeChecker, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
182
184
|
/**
|
|
183
185
|
* Reports secret reads the catalogue does not account for.
|
|
184
186
|
*
|
|
@@ -191,8 +193,8 @@ export declare function validateNoSecretAliasServices(logger: InspectorLogger, c
|
|
|
191
193
|
* deployment is asked for the client id and secret every connect flow needs
|
|
192
194
|
* without an author restating a shape the runtime already fixes.
|
|
193
195
|
*/
|
|
194
|
-
export declare function registerDerivedOAuth2AppSecrets(state: InspectorState | Omit<InspectorState,
|
|
195
|
-
export declare function validateSecretUsage(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
196
|
+
export declare function registerDerivedOAuth2AppSecrets(state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
197
|
+
export declare function validateSecretUsage(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
196
198
|
export declare function computeDiagnostics(state: InspectorState): void;
|
|
197
199
|
/**
|
|
198
200
|
* Validates that every scope referenced by a function is declared via
|
|
@@ -201,7 +203,7 @@ export declare function computeDiagnostics(state: InspectorState): void;
|
|
|
201
203
|
* A `*` suffix is a wildcard requirement: `admin:*` requires the `admin` scope
|
|
202
204
|
* to be declared, and grants its whole subtree.
|
|
203
205
|
*/
|
|
204
|
-
export declare function validateScopeReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
206
|
+
export declare function validateScopeReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
205
207
|
/**
|
|
206
208
|
* Resolves every `tools:` entry on every agent and reports the ones that do not
|
|
207
209
|
* land on a real function, or that land on one with nothing to tell the model.
|
|
@@ -218,7 +220,7 @@ export declare function validateScopeReferences(logger: InspectorLogger, state:
|
|
|
218
220
|
* quality loss rather than a failure. A title deliberately does not satisfy it —
|
|
219
221
|
* a title labels a tool in a UI, it does not tell a model when to reach for it.
|
|
220
222
|
*/
|
|
221
|
-
export declare function validateAgentToolReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
223
|
+
export declare function validateAgentToolReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>, options?: InspectorOptions): void;
|
|
222
224
|
/**
|
|
223
225
|
* Validates that every scorer an agent asks to be graded by exists.
|
|
224
226
|
*
|
|
@@ -226,7 +228,7 @@ export declare function validateAgentToolReferences(logger: InspectorLogger, sta
|
|
|
226
228
|
* that has already answered the user — which means a typo would otherwise cost
|
|
227
229
|
* nothing visible and simply grade nothing, forever.
|
|
228
230
|
*/
|
|
229
|
-
export declare function validateAgentScorerReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
231
|
+
export declare function validateAgentScorerReferences(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
230
232
|
/**
|
|
231
233
|
* Validates that every scope granted by a system role is declared via
|
|
232
234
|
* `defineScope`. Runs after all visitors, so declaration order does not matter.
|
|
@@ -234,21 +236,21 @@ export declare function validateAgentScorerReferences(logger: InspectorLogger, s
|
|
|
234
236
|
* The same rule functions get, for a sharper reason: a role granting an
|
|
235
237
|
* undeclared scope is not merely useless, it is *invisibly* useless. No
|
|
236
238
|
* function checks the scope, so the role appears to work — every call a
|
|
237
|
-
*
|
|
239
|
+
* virtual user holding it makes succeeds or fails for unrelated reasons, and the
|
|
238
240
|
* authorization boundary it was written to describe is never exercised.
|
|
239
241
|
*
|
|
240
242
|
* A `*` suffix grants a subtree; the node it hangs off must exist.
|
|
241
243
|
*/
|
|
242
|
-
export declare function validateSystemRoleScopes(logger: InspectorLogger, state: InspectorState | Omit<InspectorState,
|
|
244
|
+
export declare function validateSystemRoleScopes(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|
|
243
245
|
/**
|
|
244
|
-
* Validates that every role a
|
|
246
|
+
* Validates that every role a virtual user names is declared with
|
|
245
247
|
* `defineSystemRole`. Runs after all visitors, so declaration order does not
|
|
246
248
|
* matter.
|
|
247
249
|
*
|
|
248
250
|
* Custom roles are refused rather than tolerated. A role composed in the
|
|
249
251
|
* console does not exist at build time and can be deleted after it, so a
|
|
250
|
-
*
|
|
252
|
+
* virtual user pinned to one silently stops testing what it claims to — and the
|
|
251
253
|
* symptom is a scatter of 403s that read like authorization findings rather
|
|
252
254
|
* than like a deleted role.
|
|
253
255
|
*/
|
|
254
|
-
export declare function
|
|
256
|
+
export declare function validateVirtualUserRoles(logger: InspectorLogger, state: InspectorState | Omit<InspectorState, 'typesLookup'>): void;
|