@pikku/inspector 0.12.59 → 0.12.61
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 +373 -0
- package/OPTIMIZATION-PLAN.md +19 -19
- package/dist/add/add-agent-scorer.d.ts +2 -0
- package/dist/add/{add-ai-scorer.js → add-agent-scorer.js} +4 -4
- package/dist/add/{add-ai-agent.d.ts → add-agent.d.ts} +1 -1
- package/dist/add/{add-ai-agent.js → add-agent.js} +11 -11
- package/dist/add/add-auth.js +1 -1
- package/dist/add/add-cli.js +5 -0
- package/dist/add/add-functions.js +10 -1
- package/dist/add/add-http-route.js +18 -18
- package/dist/add/add-keyed-wiring.d.ts +2 -0
- package/dist/add/add-keyed-wiring.js +3 -1
- package/dist/add/add-middleware.js +5 -5
- package/dist/add/add-personas.js +3 -0
- package/dist/add/add-secret.js +1 -0
- package/dist/add/add-variable.js +1 -0
- package/dist/add/add-wire-remote-addon.js +2 -1
- package/dist/add/add-workflow-graph.js +63 -6
- package/dist/error-codes.d.ts +3 -1
- package/dist/error-codes.js +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -0
- package/dist/inspector.js +13 -3
- package/dist/types.d.ts +10 -5
- package/dist/utils/annotate-http-route-auth.js +2 -1
- package/dist/utils/check-secret-sinks.js +2 -1
- package/dist/utils/compute-required-schemas.d.ts +1 -1
- package/dist/utils/contract-hashes.d.ts +2 -1
- package/dist/utils/contract-hashes.js +1 -1
- package/dist/utils/extract-function-name.js +1 -1
- package/dist/utils/extract-services.d.ts +1 -1
- package/dist/utils/extract-surface-usage.d.ts +29 -0
- package/dist/utils/extract-surface-usage.js +97 -0
- package/dist/utils/filter-inspector-state.js +53 -16
- package/dist/utils/filter-utils.d.ts +1 -1
- package/dist/utils/get-property-value.js +42 -3
- package/dist/utils/load-addon-functions-meta.js +31 -0
- package/dist/utils/middleware.d.ts +2 -2
- package/dist/utils/middleware.js +5 -5
- package/dist/utils/permissions.d.ts +1 -1
- package/dist/utils/post-process.d.ts +28 -8
- package/dist/utils/post-process.js +83 -18
- package/dist/utils/resolve-deploy-target.d.ts +1 -1
- package/dist/utils/resolve-function-meta.d.ts +1 -1
- package/dist/utils/resolve-function-types.d.ts +1 -1
- package/dist/utils/resolve-versions.js +1 -1
- package/dist/utils/schema-generator.d.ts +1 -1
- package/dist/utils/serialize-inspector-state.d.ts +4 -3
- package/dist/utils/serialize-inspector-state.js +6 -4
- package/dist/utils/serialize-openapi-json.d.ts +1 -1
- package/dist/utils/validate-auth-sessionless.js +2 -1
- package/dist/utils/workflow/graph/finalize-workflows.js +1 -1
- package/dist/utils/workflow/graph/serialize-workflow-graph.d.ts +6 -1
- package/dist/utils/workflow/graph/serialize-workflow-graph.js +26 -2
- package/dist/utils/workflow/graph/workflow-graph.types.d.ts +9 -0
- package/dist/visit.js +4 -4
- package/package.json +10 -10
- package/run-tests.sh +0 -0
- package/src/add/{add-ai-scorer.test.ts → add-agent-scorer.test.ts} +11 -11
- package/src/add/{add-ai-scorer.ts → add-agent-scorer.ts} +4 -4
- package/src/add/{add-ai-agent.test.ts → add-agent.test.ts} +1 -1
- package/src/add/{add-ai-agent.ts → add-agent.ts} +13 -21
- package/src/add/add-auth.ts +2 -2
- package/src/add/add-cli.ts +6 -0
- package/src/add/add-credential.ts +3 -6
- package/src/add/add-file-with-factory.ts +2 -6
- package/src/add/add-functions.ts +23 -25
- package/src/add/add-http-route-ref.test.ts +149 -0
- package/src/add/add-http-route.ts +25 -28
- package/src/add/add-keyed-wiring.ts +8 -7
- package/src/add/add-middleware.ts +7 -5
- package/src/add/add-permission.ts +1 -1
- package/src/add/add-personas.test.ts +24 -0
- package/src/add/add-personas.ts +3 -1
- package/src/add/add-scenario-step.test.ts +35 -0
- package/src/add/add-scope.test.ts +4 -4
- package/src/add/add-scope.ts +4 -8
- package/src/add/add-secret.ts +1 -0
- package/src/add/add-system-role.test.ts +8 -8
- package/src/add/add-system-role.ts +2 -4
- package/src/add/add-variable.ts +1 -0
- package/src/add/add-wire-remote-addon.ts +4 -1
- package/src/add/add-workflow-graph-foreach.test.ts +174 -0
- package/src/add/add-workflow-graph.ts +78 -6
- package/src/add/add-workflow-sleep-expression.test.ts +3 -4
- package/src/add/addon-contracts.test.ts +1 -1
- package/src/add/config-value-metadata.test.ts +94 -0
- package/src/add/secret-sink-check.test.ts +4 -1
- package/src/error-codes.ts +3 -1
- package/src/index.ts +3 -4
- package/src/inspector.ts +20 -3
- package/src/types.ts +10 -7
- package/src/utils/annotate-http-route-auth.test.ts +5 -7
- package/src/utils/annotate-http-route-auth.ts +2 -1
- package/src/utils/check-secret-sinks.ts +4 -1
- package/src/utils/compute-required-schemas.ts +1 -1
- package/src/utils/contract-hashes.test.ts +1 -1
- package/src/utils/contract-hashes.ts +3 -2
- package/src/utils/extract-function-name.ts +1 -1
- package/src/utils/extract-services.ts +4 -2
- package/src/utils/extract-surface-usage.test.ts +147 -0
- package/src/utils/extract-surface-usage.ts +121 -0
- package/src/utils/filter-inspector-state.test.ts +138 -12
- package/src/utils/filter-inspector-state.ts +82 -21
- package/src/utils/filter-utils.ts +1 -1
- package/src/utils/get-property-value.ts +43 -5
- package/src/utils/load-addon-functions-meta.ts +40 -0
- package/src/utils/middleware.test.ts +23 -23
- package/src/utils/middleware.ts +6 -6
- package/src/utils/permissions.ts +1 -1
- package/src/utils/post-process.test.ts +68 -11
- package/src/utils/post-process.ts +91 -28
- package/src/utils/resolve-deploy-target.ts +1 -1
- package/src/utils/resolve-function-meta.ts +1 -1
- package/src/utils/resolve-function-types.ts +1 -1
- package/src/utils/resolve-versions.ts +1 -1
- package/src/utils/schema-generator.ts +2 -1
- package/src/utils/serialize-inspector-state.ts +10 -7
- package/src/utils/serialize-mcp-json.ts +1 -1
- package/src/utils/serialize-openapi-json.ts +1 -1
- package/src/utils/validate-auth-sessionless.ts +2 -1
- package/src/utils/validate-tags-resolve-to-middleware.test.ts +4 -1
- package/src/utils/workflow/dsl/extract-approval-policy.test.ts +4 -1
- package/src/utils/workflow/graph/convert-dsl-to-graph-skip.test.ts +1 -1
- package/src/utils/workflow/graph/finalize-workflows.ts +6 -2
- package/src/utils/workflow/graph/serialize-workflow-graph.ts +34 -3
- package/src/utils/workflow/graph/workflow-graph.types.ts +10 -0
- package/src/visit.ts +4 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/add/add-ai-scorer.d.ts +0 -2
- package/dist/utils/secret-brokers.d.ts +0 -2
- package/dist/utils/secret-brokers.js +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,376 @@
|
|
|
1
|
+
## 0.12.61
|
|
2
|
+
|
|
3
|
+
### Patch Changes
|
|
4
|
+
|
|
5
|
+
- ab52d8e: Raise an addon's deploy conflict only where the consuming app wires it. A
|
|
6
|
+
function an addon publishes as `deploy: 'serverless'` while naming one of its
|
|
7
|
+
own services serverless-incompatible previously failed the build of any app
|
|
8
|
+
that merely declared the addon, whether or not that function was used.
|
|
9
|
+
- a281de6: A CLI option's type now drives how it is parsed, and it comes from the command function's input schema rather than a second hand-written declaration.
|
|
10
|
+
|
|
11
|
+
`CLIOption` gains `type?: 'string' | 'number' | 'boolean' | 'string[]'` (replacing the never-honoured `array` flag). Declared, it wins over whatever the schema says; left unset, the parser reads the type off the command function's input schema — the same schema the function is validated against — falling back to `default` and then to `'string'`. A `'string[]'` option consumes one token and splits it on commas; every other non-boolean option consumes the next token verbatim, so values that begin with `-` (base64url tokens, negative numbers, dash-leading name patterns) parse correctly. A boolean option is a flag: it consumes the next token only when that token is an explicit literal (`true`/`false`/`1`/`0`/`yes`/`no`), so `--watch false` still turns a default-on flag off instead of leaving `false` behind as a positional.
|
|
12
|
+
|
|
13
|
+
Because the schema is now what types an option, `pikku serve --console --port 4077` no longer reads `--port` as the value of `--console`, and a numeric option arrives as a number instead of a string. An explicit `type` is mostly needed for options that belong to no function input — the `pikku all` filters, which the config factory reads straight off the CLI data, are declared `string[]`, and the CLI's ad-hoc `parseCommaSeparated` normalisation is gone.
|
|
14
|
+
|
|
15
|
+
An array option takes either one comma list or the flag repeated. It never consumes more than one token, because `--tags alpha beta` cannot be told apart from an option followed by a positional; the stray token is reported as an unexpected argument rather than dropped.
|
|
16
|
+
|
|
17
|
+
- 266e3bc: One door per name: `@pikku/core/ecosystem/*` and the package root are gone
|
|
18
|
+
|
|
19
|
+
`@pikku/core` published every module twice. `ecosystem/http` re-exported
|
|
20
|
+
`./http`, `ecosystem/services` re-exported `./services`, and a name was
|
|
21
|
+
reachable through either — so every addition had to be made in two places, and a
|
|
22
|
+
consumer's import said nothing about what it actually used. The package root was
|
|
23
|
+
the same problem at a larger scale: a single barrel of 206 names that no bundler
|
|
24
|
+
could take apart, and the one specifier that revealed nothing at all.
|
|
25
|
+
|
|
26
|
+
Both are deleted. Every name now lives on the subpath that owns it, and every
|
|
27
|
+
import carries that subpath — `@pikku/core/http`, `@pikku/core/services`,
|
|
28
|
+
`@pikku/core/errors`, `@pikku/core/types`.
|
|
29
|
+
|
|
30
|
+
Deleting the facades meant the raw subpaths had to become a superset of them,
|
|
31
|
+
which they were not: the facade tree had accumulated 25 names with no raw home
|
|
32
|
+
and about 26 more filed under a different area than the module they came from.
|
|
33
|
+
Those names moved to the area that owns them, and three areas were published as
|
|
34
|
+
new entry points rather than left on a root that is going away — `./types` (the
|
|
35
|
+
shared type surface, the largest single destination), `./state` and
|
|
36
|
+
`./classification`.
|
|
37
|
+
|
|
38
|
+
`./classification` is one door onto one subject: what a value is and how it must
|
|
39
|
+
be handled. Its three halves would each have been an entry point — the brands
|
|
40
|
+
and manifest types, the stored-form helpers (`hashToken`, `unsafeAsSealed` and
|
|
41
|
+
friends), and `SecretValue` — split by whether a name happens to be a type or a
|
|
42
|
+
value, which is the same defect as the facades. The duration and versioned-id
|
|
43
|
+
helpers went to `./utils`, which already published, and `PikkuRequest` went to
|
|
44
|
+
`./function`: it is the transport-agnostic request base, not an HTTP one — HTTP
|
|
45
|
+
has `PikkuHTTPAbstractRequest`, and the only thing outside core that extends
|
|
46
|
+
`PikkuRequest` is Azure's timer request.
|
|
47
|
+
|
|
48
|
+
`./types` inherited the root barrel's habit before it inherited its contents, so
|
|
49
|
+
the names with an owner elsewhere were moved off it. The middleware types and the
|
|
50
|
+
five middleware factories — `pikkuMiddleware`, `pikkuMiddlewareFactory`,
|
|
51
|
+
`pikkuChannelMiddleware`, `pikkuChannelMiddlewareFactory` and
|
|
52
|
+
`pikkuAgentMiddleware`, runtime values on a types entry point — are now
|
|
53
|
+
`@pikku/core/middleware`; the function meta types are `@pikku/core/function`;
|
|
54
|
+
`SerializedError` is `@pikku/core/errors`; and the generic TypeScript helpers
|
|
55
|
+
(`MakeRequired`, `PickRequired`, `PickOptional`, `RequireAtLeastOne`,
|
|
56
|
+
`JSONPrimitive`, `JSONValue`) are `@pikku/core/utils`. What is left on `./types`
|
|
57
|
+
is the vocabulary the wirings share, which no single module owns.
|
|
58
|
+
|
|
59
|
+
`pikku` was itself a root barrel — `export * from '@pikku/core'` — and
|
|
60
|
+
now exports only the services it bundles.
|
|
61
|
+
|
|
62
|
+
One module survives at the old specifier, and only for the bootstrap:
|
|
63
|
+
`packages/cli` is generated by the _published_ CLI pinned in its `build.sh`, and
|
|
64
|
+
that CLI still writes a bare `@pikku/core` into the files it generates for the
|
|
65
|
+
CLI itself. `bootstrap-compat/root.ts` carries the eight types it names, a test
|
|
66
|
+
in core fails if that list grows, and it goes when the pin moves to a CLI
|
|
67
|
+
released from this branch. The adapter names the pinned CLI reaches for —
|
|
68
|
+
`pikkuState` and `CreateWireServices` — are rewritten to `@pikku/core/state` and
|
|
69
|
+
`@pikku/core/types` by the same `build.sh` patch pass, so no second shim is
|
|
70
|
+
needed for them.
|
|
71
|
+
|
|
72
|
+
A guard test keeps the root shut: it parses imports and rejects a bare
|
|
73
|
+
`@pikku/core` rather than grepping for it, because several tests hold a user's
|
|
74
|
+
file as a template literal, where `import … from '@pikku/core'` is fixture text
|
|
75
|
+
rather than an import this repo makes.
|
|
76
|
+
|
|
77
|
+
An agent scaffold a project generated under an older CLI is refreshed rather
|
|
78
|
+
than left to fail: `pikku all` already deleted one importing an entry point
|
|
79
|
+
`@pikku/core` no longer publishes, and the `#pikku` hub joins that list.
|
|
80
|
+
Without it a project that scaffolds the agent endpoint but
|
|
81
|
+
declares no agents keeps the old file forever — the generator that would rewrite
|
|
82
|
+
it only runs when agents exist, and the file being present is what stops it
|
|
83
|
+
being regenerated as missing.
|
|
84
|
+
|
|
85
|
+
`pikku new addon` also wrote a tsconfig `paths` map naming only the deleted hub.
|
|
86
|
+
An addon's `imports` map points into `dist`, so `paths` is what resolves
|
|
87
|
+
`#pikku/<leaf>` for the addon's own source build — it now names the two leaf
|
|
88
|
+
patterns, in both the addon and its test harness.
|
|
89
|
+
|
|
90
|
+
- 6eef0a0: Bump every dependency to its latest compatible minor/patch across the monorepo.
|
|
91
|
+
- 20d8a39: Drop better-auth's `admin()` plugin.
|
|
92
|
+
|
|
93
|
+
`admin()` bundles three unrelated things: a `role` column, fifteen HTTP
|
|
94
|
+
endpoints authorized against that column, and the enforcement that stops a
|
|
95
|
+
banned user from getting a session. Pikku only ever wanted the third. The
|
|
96
|
+
endpoints were never reachable directly — each sat behind a pikku function with
|
|
97
|
+
its own `admin:users:*` scope — so all the plugin added was a second gate on a
|
|
98
|
+
column that had to be kept in step with the scopes it duplicated. That sync
|
|
99
|
+
(`syncProjectedAdminRole`, run on every authenticated request) is now gone
|
|
100
|
+
along with the column.
|
|
101
|
+
|
|
102
|
+
User administration is implemented against better-auth's internal adapter
|
|
103
|
+
instead, exported from `@pikku/better-auth` so `@pikku/addon-admin` and the
|
|
104
|
+
`scaffold.userAdmin` generator share one implementation:
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import {
|
|
108
|
+
createAuthUser,
|
|
109
|
+
deleteAuthUser,
|
|
110
|
+
revokeAuthUserSessions,
|
|
111
|
+
setAuthUserBanned,
|
|
112
|
+
setAuthUserPassword,
|
|
113
|
+
} from '@pikku/better-auth'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Ban keeps its schema and its enforcement, in a plugin that does nothing else:
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import { ban } from '@pikku/better-auth'
|
|
120
|
+
|
|
121
|
+
betterAuth({ plugins: [ban()] })
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`ban()` adds `banned`, `banReason` and `banExpires` to `user`, refuses to create
|
|
125
|
+
a session for a banned user, and lapses an expired ban at the sign-in that would
|
|
126
|
+
otherwise be refused. It makes no authorization decision of its own, so it never
|
|
127
|
+
needs to know about scopes.
|
|
128
|
+
|
|
129
|
+
Breaking:
|
|
130
|
+
|
|
131
|
+
- Remove `admin()` from your better-auth `plugins`, and add `ban()` if you ban
|
|
132
|
+
users. `pikku db generate` writes the migration; `user.role` and
|
|
133
|
+
`session.impersonatedBy` are no longer declared by anything.
|
|
134
|
+
- `callAdminApi`, `AdminApiHttpWire`, `syncProjectedAdminRole`,
|
|
135
|
+
`projectedAdminRole` and `ADMIN_ROLE_SCOPES` are removed. `ADMIN_SCOPES`,
|
|
136
|
+
`ADMIN_SCOPE_ROOT` and `ADMIN_SCOPE_TREE` are unchanged.
|
|
137
|
+
- The `scaffold.userAdmin` codegen no longer fails without `admin()`. It now
|
|
138
|
+
fails only when there is no better-auth at all, and warns when `ban()` is
|
|
139
|
+
missing — banning is one capability of six, so the other five still generate.
|
|
140
|
+
- The scope on each function is now the whole authorization decision. Anywhere
|
|
141
|
+
that relied on `user.role` as a backstop no longer has one.
|
|
142
|
+
|
|
143
|
+
- 727671b: Make the public surface an artifact the CLI produces.
|
|
144
|
+
|
|
145
|
+
`@pikku/cli` now ships `surface.json`, computed when the CLI is built by
|
|
146
|
+
generating one application and one addon and reading what each `#pikku/*` leaf
|
|
147
|
+
exports, plus a curated `@pikku/core` entry point for people building on the
|
|
148
|
+
ecosystem. Consumers resolve it as `@pikku/cli/surface.json`.
|
|
149
|
+
|
|
150
|
+
`pikku all` writes the matching per-project overlay to
|
|
151
|
+
`<outDir>/surface-usage.gen.json`: how often each export is imported and which
|
|
152
|
+
source areas it was seen in. The counting happens inside the sweep the inspector
|
|
153
|
+
already makes over every source file, so a prebuild pays no extra pass.
|
|
154
|
+
|
|
155
|
+
- f25f4a2: Fix seven defects found taking one project through `pikku fabric` to deploy
|
|
156
|
+
|
|
157
|
+
**`deploy plan` rewrote the project's own scaffold.** Per-unit codegen re-runs
|
|
158
|
+
`pikku all` with `--outDir` pointed at a unit's `.pikku`, and scaffold imports
|
|
159
|
+
are computed against `config.outDir` — so `console.gen.ts` came back importing
|
|
160
|
+
`../../../../../.deploy/cloudflare/units/<unit>/.pikku/pikku-types.gen.js` and
|
|
161
|
+
the source stopped typechecking until the next ordinary `pikku all`.
|
|
162
|
+
|
|
163
|
+
A guard for this already existed in four generators and had never once fired:
|
|
164
|
+
`LocalVariablesService.get` runs values through `JSON.parse`, so
|
|
165
|
+
`PIKKU_DEPLOY_CODEGEN=1` arrived as the number `1` and every `=== '1'` test
|
|
166
|
+
was false. The comparison is fixed behind a shared `isDeployCodegen`, and the
|
|
167
|
+
real guard now sits in the file writer, which refuses writes _and removals_
|
|
168
|
+
under the scaffold directory for the duration of a per-unit run. Guarding the
|
|
169
|
+
writer rather than each generator matters here: seven further generators had no
|
|
170
|
+
guard at all, several write scaffold source and `.pikku` artifacts in the same
|
|
171
|
+
pass (so an early return would skip too much), and the legacy-scaffold pruners
|
|
172
|
+
delete from the source tree without going through a generator.
|
|
173
|
+
|
|
174
|
+
**`fabric validate` passed on a project that could not deploy.** Deploy clones
|
|
175
|
+
the repository, so a `pikkufabric.config.json` that exists only in the working
|
|
176
|
+
tree is absent exactly when it is needed, and the build container aborts with
|
|
177
|
+
`pikkufabric.config.json not found in repository root`. Validate now reports
|
|
178
|
+
that as an error, and its success line distinguishes "can be linked" from
|
|
179
|
+
"will deploy" instead of reporting unqualified success at a project that is not
|
|
180
|
+
linked yet.
|
|
181
|
+
|
|
182
|
+
**`description` reached `infra.json` as raw source.** `getPropertyValue` fell
|
|
183
|
+
back to `node.getText()`, which is indistinguishable from the value for a lone
|
|
184
|
+
literal — so nobody noticed that a description written as `'a ' + 'b'` arrived
|
|
185
|
+
with the quotes and the `+` still in it, and rendered that way in the console.
|
|
186
|
+
Compile-time constant strings are now folded, checker-free, so a node that
|
|
187
|
+
cannot be resolved statically still takes the old path.
|
|
188
|
+
|
|
189
|
+
**A wired addon that was not installed failed silently.** A missing package
|
|
190
|
+
makes `resolveAddonMeta` return null, which was caught and downgraded to a
|
|
191
|
+
warning; every `ref('<namespace>:…')` then resolved to nothing and the surface
|
|
192
|
+
was dead at runtime with nothing in the build output saying why. The generated
|
|
193
|
+
console is the common case. `wireAddon` now requires its package to be
|
|
194
|
+
installed (`PKU340`), the mirror of the existing `wireRemoteAddon` check whose
|
|
195
|
+
own docs already described this half as if it existed.
|
|
196
|
+
|
|
197
|
+
**The audit-table check demanded an unquoted identifier.** Kysely's schema
|
|
198
|
+
builder always quotes, so `create table "audit"` read as missing on the
|
|
199
|
+
projects most likely to have it. Both this and the better-auth table checks now
|
|
200
|
+
share one matcher that accepts each dialect's quoting — matched pairs only, so
|
|
201
|
+
`"audit'` is not a hit — plus an optional schema qualifier.
|
|
202
|
+
|
|
203
|
+
**Cloudflare bundles kept `pg`.** `getStubModules()` named `postgres` and
|
|
204
|
+
`kysely-postgres-js` but not `pg`, which is the more common driver in
|
|
205
|
+
application code, equally unreachable on a Worker, and additionally pulls at
|
|
206
|
+
`net`/`tls` and `pg-native`, which a Worker build cannot resolve at all.
|
|
207
|
+
|
|
208
|
+
**The deploy plan listed one secret twice.** Two `defineSecret` calls may
|
|
209
|
+
legally share a `secretId` under different local names — the auth scaffold's
|
|
210
|
+
`betterAuthSecret` alongside a hand-written one is the everyday case — and the
|
|
211
|
+
manifest mapped them straight through, so the plan printed two identical
|
|
212
|
+
`create` lines for one resource and `countUnchanged` counted it twice. Secrets
|
|
213
|
+
and variables are now deduplicated in the manifest itself, where variables were
|
|
214
|
+
already being collapsed by accident downstream.
|
|
215
|
+
|
|
216
|
+
- 20d8a39: Generate the schemas a first build used to leave out.
|
|
217
|
+
|
|
218
|
+
A contract type reaches the schema generator only through a file that imports
|
|
219
|
+
it, and for a type exported by nothing but its own function file that file is
|
|
220
|
+
the RPC internal map — which `pikku all` writes _after_ schemas. On a first
|
|
221
|
+
build there is no map to read yet, so those schemas came out missing from a run
|
|
222
|
+
that otherwise succeeded, and the RPC failed with `MissingSchemaError` on its
|
|
223
|
+
first call in a deployment. A second `pikku all` fixed it, which is why this
|
|
224
|
+
only ever bit fresh checkouts and CI.
|
|
225
|
+
|
|
226
|
+
`pikku all` now re-inspects and re-generates schemas when the build that just
|
|
227
|
+
wrote the RPC internal map for the first time left contract references
|
|
228
|
+
unresolved — the condition PKU463 already reports. Confined to that build: a
|
|
229
|
+
project whose references are unresolved for some other reason would otherwise
|
|
230
|
+
pay a second inspection on every run for a re-generation that cannot help it.
|
|
231
|
+
|
|
232
|
+
`@pikku/inspector` exports `unresolvedSchemaReferences(state)`, the check behind
|
|
233
|
+
PKU463, so the decision can be made without re-deriving it.
|
|
234
|
+
|
|
235
|
+
- 3561d67: feat(graph): per-item `forEach` fanout for declarative workflow graphs
|
|
236
|
+
|
|
237
|
+
A graph node can now run once per element of an upstream array:
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
postVideo: {
|
|
241
|
+
forEach: 'getMyVideo', // or (ref) => ref('getMyVideo', 'rows')
|
|
242
|
+
mode: 'sequential', // optional, defaults to 'parallel'
|
|
243
|
+
input: (ref, template, $item) => ({ url: $item('URL VIDEO') }),
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Each element runs as its own step instance (`postVideo[0]`, `postVideo[1]`, …)
|
|
248
|
+
and the node's result is the ordered array of per-item results, so a fanned node
|
|
249
|
+
chains straight into another `forEach`. Downstream nodes wait for every item. A
|
|
250
|
+
non-array source fails the run loudly instead of coercing.
|
|
251
|
+
|
|
252
|
+
The change is additive: `forEach` and `mode` are new optional node fields, and
|
|
253
|
+
`$item` is appended after `template` so existing `input: (ref) => …` and
|
|
254
|
+
`input: (ref, template) => …` nodes are unchanged.
|
|
255
|
+
|
|
256
|
+
- a91c433: HTTP routes wired with `ref('ns:fn')` now record the addon function id as their own `pikkuFuncId`, the same way the CLI and channel wirings already do, instead of minting a per-route wrapper function and linking it back through `refTarget`. The `refTarget` field is gone from `HTTPWiringMeta`, and the runtime resolves a namespaced route function against the addon package's own metadata.
|
|
257
|
+
- 2b57ca8: A persona can name the `app` they sign into, and a browser run takes a url per app (`--app-url <app>=<url>`, or `appUrls` on the environment). Each actor's browser context navigates against its own app's base, so a product that is more than one frontend can be proved in one run — including a scenario that crosses from one app to the other. A run whose personas name an app nobody gave a url for is refused rather than browsing the wrong app's pages.
|
|
258
|
+
- 456c88b: Keep an addon function's contract on a route that reaches it through `ref()`, whether or not `.pikku` already exists.
|
|
259
|
+
|
|
260
|
+
The input and output types were read off the type checker, which can only see them once the consumer's own RPC map already lists the addon's functions — that is, on the second run. A first, cold generation widened the route's input to the whole `FlattenedRPCMap`, so the same sources produced a different http-map on CI than on a developer's machine, and a client compiled against the good one failed to build against the other. The addon's own metadata says what the contract is either way, and its published declaration file is where those names live.
|
|
261
|
+
|
|
262
|
+
- 727671b: `wireAddon` and `wireRemoteAddon` move from `#pikku/function` to `#pikku/addon`.
|
|
263
|
+
|
|
264
|
+
Installing an addon and authoring one are the same concept from opposite ends,
|
|
265
|
+
so they are one import: an application's `#pikku/addon` carries the two install
|
|
266
|
+
functions, an addon package's carries `pikkuAddonConfig`, `pikkuAddonServices`,
|
|
267
|
+
`pikkuAddonWireServices` and `AddonBaseServices`.
|
|
268
|
+
|
|
269
|
+
Two generation fixes came with it:
|
|
270
|
+
|
|
271
|
+
- `CredentialsMap` is generated as a type alias rather than an interface. An
|
|
272
|
+
interface has no implicit index signature, so it was never assignable to the
|
|
273
|
+
`Record<string, unknown>` that `GetCredential` is constrained by, and every
|
|
274
|
+
generated project reported two errors on its own function types.
|
|
275
|
+
- An unresolved `SingletonServices` type is now `PKU724` instead of a services
|
|
276
|
+
map with no entries in it. Written out, the empty map made every service
|
|
277
|
+
optional and the real failure resurfaced as unrelated "possibly undefined"
|
|
278
|
+
errors in files nobody had touched.
|
|
279
|
+
|
|
280
|
+
- Updated dependencies [7722ceb]
|
|
281
|
+
- Updated dependencies [375c1ff]
|
|
282
|
+
- Updated dependencies [02a70cd]
|
|
283
|
+
- Updated dependencies [aeef159]
|
|
284
|
+
- Updated dependencies [a281de6]
|
|
285
|
+
- Updated dependencies [266e3bc]
|
|
286
|
+
- Updated dependencies [02a70cd]
|
|
287
|
+
- Updated dependencies [786dae5]
|
|
288
|
+
- Updated dependencies [6eef0a0]
|
|
289
|
+
- Updated dependencies [3561d67]
|
|
290
|
+
- Updated dependencies [a91c433]
|
|
291
|
+
- Updated dependencies [02a70cd]
|
|
292
|
+
- Updated dependencies [9537f74]
|
|
293
|
+
- Updated dependencies [2b57ca8]
|
|
294
|
+
- Updated dependencies [266e3bc]
|
|
295
|
+
- Updated dependencies [9fce0f1]
|
|
296
|
+
- Updated dependencies [83683a0]
|
|
297
|
+
- Updated dependencies [456c88b]
|
|
298
|
+
- Updated dependencies [456c88b]
|
|
299
|
+
- Updated dependencies [c127273]
|
|
300
|
+
- @pikku/core@0.12.85
|
|
301
|
+
|
|
302
|
+
## 0.12.60
|
|
303
|
+
|
|
304
|
+
### Patch Changes
|
|
305
|
+
|
|
306
|
+
- 7406bfe: Rename the agent runtime from `AI*` to `Agent*` (#596)
|
|
307
|
+
|
|
308
|
+
`AI` described the model provider, not the thing being named. Every symbol that
|
|
309
|
+
belongs to the agent runtime now says `Agent`; the symbols that genuinely wrap a
|
|
310
|
+
model provider — `AIEmbeddingService`, `AIProviderOptions`, `AIEmbedParams`,
|
|
311
|
+
`AITranscriptionParams`, `AIGenerateImageParams` and their siblings, and the
|
|
312
|
+
`@pikku/ai-vercel` / `@pikku/ai-deepinfra` / `@pikku/ai-voice` packages — keep
|
|
313
|
+
their names.
|
|
314
|
+
|
|
315
|
+
**Wiring**
|
|
316
|
+
- `pikkuAIAgent` → `pikkuAgent`, `pikkuAIScorer` → `pikkuAgentScorer`,
|
|
317
|
+
`pikkuAIJudge` → `pikkuAgentJudge`
|
|
318
|
+
- `CoreAIAgent` → `CoreAgent`, `AIAgentInput` → `AgentInput`, `AIAgentStep` →
|
|
319
|
+
`AgentStep`, `AIMessage` → `AgentMessage`, and the rest of the agent types
|
|
320
|
+
- `AIAgentRunnerService` → `AgentRunnerService`, `AIStorageService` →
|
|
321
|
+
`AgentStorageService`, `AIRunStateService` → `AgentRunStateService`
|
|
322
|
+
|
|
323
|
+
**Entry points**
|
|
324
|
+
|
|
325
|
+
`@pikku/core/agent` → `@pikku/core/agent`, `@pikku/core/agent-scorer` →
|
|
326
|
+
`@pikku/core/agent-scorer`.
|
|
327
|
+
|
|
328
|
+
**Queues**
|
|
329
|
+
|
|
330
|
+
The scorer queues are now `agent-score-fast` and `agent-score-slow`. Drain the
|
|
331
|
+
old `ai-score-fast` / `ai-score-slow` queues before deploying — jobs still
|
|
332
|
+
sitting on them when the new workers start will never be picked up.
|
|
333
|
+
|
|
334
|
+
**Scaffolds**
|
|
335
|
+
|
|
336
|
+
The agent scaffold pikku wrote for your project — `<scaffold>/agent/agent.gen.ts`
|
|
337
|
+
and its schemas file — imports `@pikku/core/ai-agent`, which no longer exists. A
|
|
338
|
+
scaffold is normally written once and then left alone, so `pikku all` would find
|
|
339
|
+
it present and leave the broken import in place. It now deletes an agent scaffold
|
|
340
|
+
importing either removed entry point and regenerates it in the same run. Anything
|
|
341
|
+
you added to that file goes with it, so move local edits out first.
|
|
342
|
+
|
|
343
|
+
**Database**
|
|
344
|
+
|
|
345
|
+
The agent tables are renamed: `ai_threads`, `ai_message`, `ai_tool_call`,
|
|
346
|
+
`ai_working_memory`, `ai_run` and `ai_run_score` become `agent_threads`,
|
|
347
|
+
`agent_message`, `agent_tool_call`, `agent_working_memory`, `agent_run` and
|
|
348
|
+
`agent_run_score`, along with their indexes and the `ai_working_memory_pk`
|
|
349
|
+
constraint. The same rename applies to the MongoDB collections.
|
|
350
|
+
|
|
351
|
+
`ensurePikkuSchema` creates tables it cannot find, so an existing database will
|
|
352
|
+
get empty `agent_*` tables and leave the old data stranded in `ai_*`. Rename
|
|
353
|
+
them before the first boot on the new version:
|
|
354
|
+
|
|
355
|
+
```sql
|
|
356
|
+
ALTER TABLE ai_threads RENAME TO agent_threads;
|
|
357
|
+
ALTER TABLE ai_message RENAME TO agent_message;
|
|
358
|
+
ALTER TABLE ai_tool_call RENAME TO agent_tool_call;
|
|
359
|
+
ALTER TABLE ai_working_memory RENAME TO agent_working_memory;
|
|
360
|
+
ALTER TABLE ai_run RENAME TO agent_run;
|
|
361
|
+
ALTER TABLE ai_run_score RENAME TO agent_run_score;
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
- 6794681: Publish the ecosystem surface as per-area sub-barrels under `@pikku/core/ecosystem/*`, and point generated code, the CLI, the inspector and the runtime adapters at them.
|
|
365
|
+
|
|
366
|
+
348 names that only generated code, the toolchain or a runtime adapter ever imports now have a second home on `@pikku/core/ecosystem/<area>` — one sub-barrel per area, matching how core already publishes its entrypoints, so no single barrel grows without bound and a consumer only pulls in the area it uses.
|
|
367
|
+
|
|
368
|
+
This step is additive: every name is still exported from the entrypoint it was published from before, so nothing downstream breaks. Removing them from the app-facing barrels is a later change, and needs a release carrying `./ecosystem/*` first.
|
|
369
|
+
|
|
370
|
+
- Updated dependencies [7406bfe]
|
|
371
|
+
- Updated dependencies [6794681]
|
|
372
|
+
- @pikku/core@0.12.84
|
|
373
|
+
|
|
1
374
|
## 0.12.59
|
|
2
375
|
|
|
3
376
|
### Patch Changes
|
package/OPTIMIZATION-PLAN.md
CHANGED
|
@@ -44,25 +44,25 @@ node --import tsx src/benchmark.ts <target-dir> <iterations>
|
|
|
44
44
|
|
|
45
45
|
**Dispatch map for `visitRoutes`** (all handlers expect CallExpression + Identifier):
|
|
46
46
|
|
|
47
|
-
| Identifier
|
|
48
|
-
|
|
|
49
|
-
| `wireHTTP`
|
|
50
|
-
| `wireHTTPRoutes`
|
|
51
|
-
| `wireScheduler`
|
|
52
|
-
| `wireTrigger`
|
|
53
|
-
| `wireTriggerSource`
|
|
54
|
-
| `wireQueueWorker`
|
|
55
|
-
| `wireChannel`
|
|
56
|
-
| `wireCLI`
|
|
57
|
-
| `pikkuCLIRender`
|
|
58
|
-
| `wireMCPResource`
|
|
59
|
-
| `wireMCPTool`
|
|
60
|
-
| `wireMCPPrompt`
|
|
61
|
-
| `wireWorkflowGraph`
|
|
62
|
-
| `defineSecret`
|
|
63
|
-
| `defineCredential`
|
|
64
|
-
| `defineScope`
|
|
65
|
-
| `defineVariable`
|
|
47
|
+
| Identifier | Handler |
|
|
48
|
+
| ------------------- | ------------------ |
|
|
49
|
+
| `wireHTTP` | `addHTTPRoute` |
|
|
50
|
+
| `wireHTTPRoutes` | `addHTTPRoutes` |
|
|
51
|
+
| `wireScheduler` | `addSchedule` |
|
|
52
|
+
| `wireTrigger` | `addTrigger` |
|
|
53
|
+
| `wireTriggerSource` | `addTrigger` |
|
|
54
|
+
| `wireQueueWorker` | `addQueueWorker` |
|
|
55
|
+
| `wireChannel` | `addChannel` |
|
|
56
|
+
| `wireCLI` | `addCLI` |
|
|
57
|
+
| `pikkuCLIRender` | `addCLIRenderers` |
|
|
58
|
+
| `wireMCPResource` | `addMCPResource` |
|
|
59
|
+
| `wireMCPTool` | `addMCPTool` |
|
|
60
|
+
| `wireMCPPrompt` | `addMCPPrompt` |
|
|
61
|
+
| `wireWorkflowGraph` | `addWorkflowGraph` |
|
|
62
|
+
| `defineSecret` | `addSecret` |
|
|
63
|
+
| `defineCredential` | `addCredential` |
|
|
64
|
+
| `defineScope` | `addScope` |
|
|
65
|
+
| `defineVariable` | `addVariable` |
|
|
66
66
|
|
|
67
67
|
`addAuth` stays outside the map: it matches several identifiers
|
|
68
68
|
(`betterAuthStatelessSession`, `betterAuthSession`) and gates them on
|
|
@@ -3,15 +3,15 @@ import { getPropertyValue } from '../utils/get-property-value.js';
|
|
|
3
3
|
import { extractFunctionName } from '../utils/extract-function-name.js';
|
|
4
4
|
import { ErrorCode } from '../error-codes.js';
|
|
5
5
|
/**
|
|
6
|
-
* `
|
|
6
|
+
* `pikkuAgentScorer` grades in code and `pikkuAgentJudge` grades with a model, which
|
|
7
7
|
* is the whole difference between the two lanes — so the lane is read off which
|
|
8
8
|
* constructor was called rather than from a field an author could contradict.
|
|
9
9
|
*/
|
|
10
10
|
const LANES = {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
pikkuAgentScorer: 'fast',
|
|
12
|
+
pikkuAgentJudge: 'slow',
|
|
13
13
|
};
|
|
14
|
-
export const
|
|
14
|
+
export const addAgentScorer = (logger, node, checker, state) => {
|
|
15
15
|
if (!ts.isCallExpression(node))
|
|
16
16
|
return;
|
|
17
17
|
const expression = node.expression;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
import type { AddWiring, InspectorLogger } from '../types.js';
|
|
3
3
|
export declare function resolveWorkflowReferences(obj: ts.ObjectLiteralExpression, checker: ts.TypeChecker, agentName: string, logger: InspectorLogger): string[] | null;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const addAgent: AddWiring;
|
|
@@ -2,7 +2,7 @@ import * as ts from 'typescript';
|
|
|
2
2
|
import { getPropertyValue, getCommonWireMetaData, } from '../utils/get-property-value.js';
|
|
3
3
|
import { extractWireNames } from '../utils/post-process.js';
|
|
4
4
|
import { extractFunctionName, funcIdToTypeName, } from '../utils/extract-function-name.js';
|
|
5
|
-
import { resolveMiddleware, resolveChannelMiddleware,
|
|
5
|
+
import { resolveMiddleware, resolveChannelMiddleware, resolveAgentMiddleware, } from '../utils/middleware.js';
|
|
6
6
|
import { resolvePermissions } from '../utils/permissions.js';
|
|
7
7
|
import { ErrorCode } from '../error-codes.js';
|
|
8
8
|
import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js';
|
|
@@ -68,7 +68,7 @@ function resolveAgentReferences(obj, checker, agentName, logger) {
|
|
|
68
68
|
for (const element of initializer.elements) {
|
|
69
69
|
if (ts.isStringLiteral(element)) {
|
|
70
70
|
logger.critical(ErrorCode.INVALID_VALUE, `AI agent '${agentName}' agents array contains a string literal '${element.text}'. ` +
|
|
71
|
-
`Use an agent reference instead (e.g., import the
|
|
71
|
+
`Use an agent reference instead (e.g., import the pikkuAgent variable).`);
|
|
72
72
|
continue;
|
|
73
73
|
}
|
|
74
74
|
if (ts.isIdentifier(element)) {
|
|
@@ -78,7 +78,7 @@ function resolveAgentReferences(obj, checker, agentName, logger) {
|
|
|
78
78
|
continue;
|
|
79
79
|
}
|
|
80
80
|
logger.critical(ErrorCode.INVALID_VALUE, `AI agent '${agentName}' agents array contains identifier '${element.text}' ` +
|
|
81
|
-
`that could not be resolved to a
|
|
81
|
+
`that could not be resolved to a pikkuAgent.`);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
84
|
return resolved.length > 0 ? resolved : null;
|
|
@@ -209,7 +209,7 @@ function resolveIdentifierToAgentName(identifier, checker) {
|
|
|
209
209
|
if (ts.isVariableDeclaration(decl) && decl.initializer) {
|
|
210
210
|
if (ts.isCallExpression(decl.initializer) &&
|
|
211
211
|
ts.isIdentifier(decl.initializer.expression) &&
|
|
212
|
-
decl.initializer.expression.text === '
|
|
212
|
+
decl.initializer.expression.text === 'pikkuAgent') {
|
|
213
213
|
if (ts.isIdentifier(decl.name)) {
|
|
214
214
|
return decl.name.text;
|
|
215
215
|
}
|
|
@@ -240,14 +240,14 @@ function resolveScorerNames(obj, agentName, logger) {
|
|
|
240
240
|
}
|
|
241
241
|
return names.length > 0 ? names : null;
|
|
242
242
|
}
|
|
243
|
-
export const
|
|
243
|
+
export const addAgent = (logger, node, checker, state, options) => {
|
|
244
244
|
if (!ts.isCallExpression(node)) {
|
|
245
245
|
return;
|
|
246
246
|
}
|
|
247
247
|
const args = node.arguments;
|
|
248
248
|
const firstArg = args[0];
|
|
249
249
|
const expression = node.expression;
|
|
250
|
-
if (!ts.isIdentifier(expression) || expression.text !== '
|
|
250
|
+
if (!ts.isIdentifier(expression) || expression.text !== 'pikkuAgent') {
|
|
251
251
|
return;
|
|
252
252
|
}
|
|
253
253
|
if (!firstArg) {
|
|
@@ -383,7 +383,7 @@ export const addAIAgent = (logger, node, checker, state, options) => {
|
|
|
383
383
|
}
|
|
384
384
|
const middleware = resolveMiddleware(state, obj, tags, checker);
|
|
385
385
|
const channelMiddleware = resolveChannelMiddleware(state, obj, tags, checker);
|
|
386
|
-
const
|
|
386
|
+
const agentMiddleware = resolveAgentMiddleware(state, obj, checker);
|
|
387
387
|
const permissions = resolvePermissions(state, obj, tags, checker);
|
|
388
388
|
state.serviceAggregation.usedFunctions.add(agentKey);
|
|
389
389
|
extractWireNames(middleware).forEach((name) => state.serviceAggregation.usedMiddleware.add(name));
|
|
@@ -420,7 +420,7 @@ export const addAIAgent = (logger, node, checker, state, options) => {
|
|
|
420
420
|
workingMemorySchema,
|
|
421
421
|
middleware,
|
|
422
422
|
channelMiddleware,
|
|
423
|
-
|
|
423
|
+
agentMiddleware,
|
|
424
424
|
permissions,
|
|
425
425
|
};
|
|
426
426
|
// AI agent functions require platform services that aren't visible
|
|
@@ -428,10 +428,10 @@ export const addAIAgent = (logger, node, checker, state, options) => {
|
|
|
428
428
|
const funcMeta = state.functions.meta[agentKey];
|
|
429
429
|
if (funcMeta?.services) {
|
|
430
430
|
for (const svc of [
|
|
431
|
-
'
|
|
432
|
-
'
|
|
431
|
+
'agentStorage',
|
|
432
|
+
'agentRunState',
|
|
433
433
|
'agentRunService',
|
|
434
|
-
'
|
|
434
|
+
'agentRunner',
|
|
435
435
|
]) {
|
|
436
436
|
if (!funcMeta.services.services.includes(svc)) {
|
|
437
437
|
funcMeta.services.services.push(svc);
|
package/dist/add/add-auth.js
CHANGED
|
@@ -62,7 +62,7 @@ const readArrayProp = (obj, name) => {
|
|
|
62
62
|
};
|
|
63
63
|
/**
|
|
64
64
|
* Read the callee name of a `plugins: [...]` entry. better-auth plugins are
|
|
65
|
-
* factory calls (`bearer()`, `twoFactor({ ... })`, `
|
|
65
|
+
* factory calls (`bearer()`, `twoFactor({ ... })`, `ban()`); the entry's id
|
|
66
66
|
* is the called function's name. Member-expression callees (`foo.bar()`) and
|
|
67
67
|
* non-call entries are ignored.
|
|
68
68
|
*/
|
package/dist/add/add-cli.js
CHANGED
|
@@ -392,6 +392,11 @@ function processOptions(logger, node, typeChecker, inspectorState, inspectorOpti
|
|
|
392
392
|
option.short = optProp.initializer.text;
|
|
393
393
|
}
|
|
394
394
|
break;
|
|
395
|
+
case 'type':
|
|
396
|
+
if (ts.isStringLiteral(optProp.initializer)) {
|
|
397
|
+
option.type = optProp.initializer.text;
|
|
398
|
+
}
|
|
399
|
+
break;
|
|
395
400
|
case 'default':
|
|
396
401
|
// Extract default value from expression
|
|
397
402
|
if (ts.isStringLiteral(optProp.initializer)) {
|
|
@@ -3,7 +3,7 @@ import { detectSchemaVendorOrError } from '../utils/detect-schema-vendor.js';
|
|
|
3
3
|
import { extractFunctionName, funcIdToTypeName, } from '../utils/extract-function-name.js';
|
|
4
4
|
import { extractFunctionNode } from '../utils/extract-function-node.js';
|
|
5
5
|
import { extractUsedWires } from '../utils/extract-services.js';
|
|
6
|
-
import { formatVersionedId, parseVersionedId } from '@pikku/core';
|
|
6
|
+
import { formatVersionedId, parseVersionedId } from '@pikku/core/utils';
|
|
7
7
|
/** Binding keys a `pikkuScenarioStep` may declare, in report order. */
|
|
8
8
|
const SCENARIO_SURFACE_KEYS = [
|
|
9
9
|
'browser',
|
|
@@ -415,6 +415,7 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
415
415
|
let workflowRetries;
|
|
416
416
|
let workflowTimeout;
|
|
417
417
|
let scenarioStepSurfaces;
|
|
418
|
+
let scenarioStepRequiresActor;
|
|
418
419
|
let scenarioStepAddon;
|
|
419
420
|
let scenarioStepTemplate;
|
|
420
421
|
let scopes;
|
|
@@ -549,6 +550,13 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
549
550
|
scenarioStepSurfaces = declaredSurfaces.length
|
|
550
551
|
? declaredSurfaces
|
|
551
552
|
: undefined;
|
|
553
|
+
// A browser binding cannot be provisioned without a window to open, so it
|
|
554
|
+
// requires an actor whether or not the step said so.
|
|
555
|
+
scenarioStepRequiresActor =
|
|
556
|
+
getPropertyValue(firstArg, 'actor') === true ||
|
|
557
|
+
declaredSurfaces.includes('browser')
|
|
558
|
+
? true
|
|
559
|
+
: undefined;
|
|
552
560
|
}
|
|
553
561
|
scenarioStepTemplate = getPropertyValue(firstArg, 'template');
|
|
554
562
|
scopes = getArrayPropertyValue(firstArg, 'scopes') ?? undefined;
|
|
@@ -992,6 +1000,7 @@ export const addFunctions = (logger, node, checker, state, options) => {
|
|
|
992
1000
|
workflowRetries: workflowRetries ?? undefined,
|
|
993
1001
|
workflowTimeout: workflowTimeout ?? undefined,
|
|
994
1002
|
scenarioStepSurfaces,
|
|
1003
|
+
scenarioStepRequiresActor,
|
|
995
1004
|
// `persona` is the default reading of an unmarked step, so it is left off
|
|
996
1005
|
// rather than written into every step meta a project already has.
|
|
997
1006
|
scenarioStepKind: scenarioStepKind && scenarioStepKind !== 'persona'
|