@condition-sh/runner 2026.9.1 → 2026.9.3

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.
Files changed (2) hide show
  1. package/index.js +21 -11
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // packages/runner/src/server.ts
2
- import { describeProject, inboxAddress } from "@condition-sh/core";
2
+ import { buildState, describeProject, inboxAddress, resolveTraits } from "@condition-sh/core";
3
3
 
4
4
  // packages/runner/src/signature.ts
5
5
  import { createHmac, timingSafeEqual } from "node:crypto";
@@ -58,14 +58,21 @@ async function perform(project, route, body) {
58
58
  if (typeof id !== "string" || !runPattern.test(id))
59
59
  throw new RunnerError(400, "invalid run ID");
60
60
  const inboxDomain = typeof body.inboxDomain === "string" ? body.inboxDomain : undefined;
61
+ let traits;
62
+ try {
63
+ traits = resolveTraits(scenario.traits, body.traits ?? {});
64
+ } catch (error) {
65
+ throw new RunnerError(400, error.message);
66
+ }
61
67
  const context = {
62
68
  runId: id,
63
69
  input: body.input ?? {},
70
+ traits,
64
71
  inbox: inboxDomain ? { address: (actor) => inboxAddress(actor, id, inboxDomain) } : undefined
65
72
  };
66
73
  switch (step) {
67
74
  case undefined:
68
- return { output: await scenario.prepare(context) ?? null };
75
+ return { output: await buildState(scenario.prepare, scenario.traits, context) ?? null };
69
76
  case "verify":
70
77
  await scenario.verify({ ...context, output: body.output });
71
78
  return { verified: true };
@@ -166,24 +173,27 @@ async function fetchScenarios(connection) {
166
173
  throw new Error("runner returned no scenario list");
167
174
  return result;
168
175
  }
169
- function remoteScenario(connection, { name, description, input, actors }, inboxDomain) {
176
+ function remoteScenario(connection, { name, description, input, actors, traits }, inboxDomain) {
170
177
  const present = (kind) => async (value) => (await call(connection, "POST", "/present", { scenario: name, kind, value })).presented;
171
178
  const mail = (inbox) => inbox && inboxDomain ? { inboxDomain } : {};
172
179
  return {
173
180
  description,
174
181
  ...input ? { input } : {},
175
182
  ...actors ? { actors } : {},
176
- async prepare({ runId, input: input2, inbox }) {
177
- return (await call(connection, "POST", "/runs", { runId, scenario: name, input: input2, ...mail(inbox) })).output;
183
+ ...traits ? { traits: Object.fromEntries(Object.entries(traits).map(([trait, summary]) => [trait, { ...summary, apply: async () => {
184
+ return;
185
+ } }])) } : {},
186
+ async prepare({ runId, input: input2, traits: chosen, inbox }) {
187
+ return (await call(connection, "POST", "/runs", { runId, scenario: name, input: input2, traits: chosen, ...mail(inbox) })).output;
178
188
  },
179
- async verify({ runId, input: input2, output, inbox }) {
180
- await call(connection, "POST", `/runs/${runId}/verify`, { scenario: name, input: input2, output, ...mail(inbox) });
189
+ async verify({ runId, input: input2, traits: chosen, output, inbox }) {
190
+ await call(connection, "POST", `/runs/${runId}/verify`, { scenario: name, input: input2, traits: chosen, output, ...mail(inbox) });
181
191
  },
182
- async cleanup({ runId, input: input2, output, inbox }) {
183
- await call(connection, "POST", `/runs/${runId}/cleanup`, { scenario: name, input: input2, output, ...mail(inbox) });
192
+ async cleanup({ runId, input: input2, traits: chosen, output, inbox }) {
193
+ await call(connection, "POST", `/runs/${runId}/cleanup`, { scenario: name, input: input2, traits: chosen, output, ...mail(inbox) });
184
194
  },
185
- async login({ runId, input: input2, output, actor, inbox }) {
186
- return (await call(connection, "POST", `/runs/${runId}/login`, { scenario: name, input: input2, output, actor, ...mail(inbox) })).login;
195
+ async login({ runId, input: input2, traits: chosen, output, actor, inbox }) {
196
+ return (await call(connection, "POST", `/runs/${runId}/login`, { scenario: name, input: input2, traits: chosen, output, actor, ...mail(inbox) })).login;
187
197
  },
188
198
  present: present("output"),
189
199
  presentInput: present("input")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@condition-sh/runner",
3
- "version": "2026.9.1",
3
+ "version": "2026.9.3",
4
4
  "description": "Mount a signed Condition runner inside your app.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -17,7 +17,7 @@
17
17
  }
18
18
  },
19
19
  "dependencies": {
20
- "@condition-sh/core": "^2026.9.1"
20
+ "@condition-sh/core": "^2026.9.3"
21
21
  },
22
22
  "publishConfig": {
23
23
  "access": "public"