@synapsor/runner 1.6.3 → 1.6.4
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/AGENTS.md +2 -2
- package/CHANGELOG.md +72 -8
- package/CONTRIBUTING.md +10 -3
- package/README.md +61 -93
- package/SECURITY.md +7 -3
- package/THREAT_MODEL.md +37 -0
- package/dist/authoring.mjs +98 -13
- package/dist/cli.d.ts +12 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/local-ui.d.ts +60 -0
- package/dist/local-ui.d.ts.map +1 -1
- package/dist/runner.mjs +7321 -2000
- package/dist/runtime.mjs +528 -51
- package/docs/README.md +14 -0
- package/docs/agent-guided-setup.md +7 -7
- package/docs/aggregate-reads.md +14 -5
- package/docs/app-owned-executors.md +5 -6
- package/docs/auto-boundary-and-scoped-explore.md +58 -6
- package/docs/capability-authoring.md +2 -2
- package/docs/client-recipes.md +1 -1
- package/docs/cloud-mode.md +7 -7
- package/docs/conformance.md +6 -3
- package/docs/current-scope.md +13 -2
- package/docs/cursor-plugin.md +3 -3
- package/docs/database-enforced-scope.md +6 -0
- package/docs/dsl-reference.md +12 -1
- package/docs/fresh-developer-usability.md +6 -6
- package/docs/getting-started-own-database.md +41 -41
- package/docs/guided-onboarding.md +98 -30
- package/docs/limitations.md +34 -14
- package/docs/local-mode.md +20 -20
- package/docs/mcp-audit.md +14 -14
- package/docs/mcp-client-setup.md +11 -14
- package/docs/mcp-clients.md +1 -1
- package/docs/migrating-to-synapsor-spec.md +5 -1
- package/docs/openai-agents-sdk.md +2 -2
- package/docs/proposal-evidence-freshness.md +7 -7
- package/docs/recipes.md +6 -6
- package/docs/release-notes.md +86 -10
- package/docs/release-policy.md +20 -7
- package/docs/reversible-change-sets.md +1 -1
- package/docs/reviewed-database-views.md +132 -0
- package/docs/reviewed-relationships.md +245 -0
- package/docs/rfcs/006-reviewed-reversible-change-sets.md +1 -1
- package/docs/runner-bundles.md +7 -7
- package/docs/schema-api-candidates.md +1 -1
- package/docs/security-boundary.md +30 -0
- package/docs/troubleshooting-first-run.md +52 -12
- package/docs/use-your-own-database.md +6 -4
- package/docs/workbench-ask.md +279 -0
- package/docs/writeback-executors.md +7 -7
- package/examples/auto-boundary-churn/README.md +1 -1
- package/examples/community-solar-clean-room/README.md +7 -0
- package/examples/community-solar-clean-room/docker-compose.yml +16 -0
- package/examples/community-solar-clean-room/package.json +15 -0
- package/examples/community-solar-clean-room/prisma/schema.prisma +171 -0
- package/examples/community-solar-clean-room/seed/postgres.sql +571 -0
- package/examples/fitflow-guided-onboarding/README.md +2 -2
- package/examples/openai-agents-http/Makefile +1 -1
- package/examples/openai-agents-http/README.md +1 -1
- package/examples/openai-agents-stdio/Makefile +1 -1
- package/examples/openai-agents-stdio/README.md +2 -2
- package/examples/openai-agents-stdio/agent.py +1 -4
- package/examples/reference-support-billing-app/README.md +16 -16
- package/examples/retail-clean-room/README.md +7 -0
- package/examples/retail-clean-room/docker-compose.yml +16 -0
- package/examples/retail-clean-room/package.json +9 -0
- package/examples/retail-clean-room/prisma/schema.prisma +239 -0
- package/examples/retail-clean-room/seed/postgres.sql +781 -0
- package/examples/retail-clean-room/view-recipe/average-retained-revenue.synapsor.sql +21 -0
- package/examples/retail-clean-room/view-recipe/synapsor.runner.json +25 -0
- package/examples/support-plan-credit/mcp-client-examples/claude-code.sh +1 -4
- package/examples/support-plan-credit/mcp-client-examples/claude-desktop.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/codex.config.toml +1 -4
- package/examples/support-plan-credit/mcp-client-examples/cursor-global.mcp.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/cursor-project.mcp.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.json +1 -4
- package/examples/support-plan-credit/mcp-client-examples/generic-stdio.mjs +1 -1
- package/examples/support-plan-credit/mcp-client-examples/google-adk.py +1 -1
- package/examples/support-plan-credit/mcp-client-examples/langchain.mjs +1 -1
- package/examples/support-plan-credit/mcp-client-examples/llamaindex.py +1 -1
- package/examples/support-plan-credit/mcp-client-examples/openai-agents-stdio.ts +1 -1
- package/examples/support-plan-credit/mcp-client-examples/vscode.mcp.json +1 -4
- package/fixtures/compatibility/published-1.6.3/manifest.json +76 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/aggregate-read.synapsor.sql +21 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/billing-late-fee.synapsor.sql +56 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/bounded-set-multi-term.synapsor.sql +30 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/dsl/examples/principal-row-scope.synapsor.sql +23 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/aggregate-read/contract.json +119 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/approval-quorum/contract.json +44 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/bounded-set-threats/contract.json +115 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/principal-row-scope/contract.json +78 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/proposal-capability/contract.json +101 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/conformance/reversible-change-sets/contract.json +98 -0
- package/fixtures/compatibility/published-1.6.3/sources/packages/spec/fixtures/valid/basic-read.contract.json +60 -0
- package/llms.txt +10 -5
- package/package.json +8 -2
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
DO $$
|
|
2
|
+
BEGIN
|
|
3
|
+
CREATE ROLE solar_technician_reader LOGIN PASSWORD 'solar_technician_reader_password';
|
|
4
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
5
|
+
END
|
|
6
|
+
$$;
|
|
7
|
+
|
|
8
|
+
DO $$
|
|
9
|
+
BEGIN
|
|
10
|
+
CREATE ROLE solar_writer LOGIN PASSWORD 'solar_writer_password';
|
|
11
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
12
|
+
END
|
|
13
|
+
$$;
|
|
14
|
+
|
|
15
|
+
DO $$
|
|
16
|
+
BEGIN
|
|
17
|
+
CREATE ROLE solar_setup LOGIN PASSWORD 'solar_setup_password';
|
|
18
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
19
|
+
END
|
|
20
|
+
$$;
|
|
21
|
+
|
|
22
|
+
ALTER ROLE solar_technician_reader SET default_transaction_read_only = on;
|
|
23
|
+
|
|
24
|
+
CREATE TABLE public.cooperatives (
|
|
25
|
+
id text PRIMARY KEY,
|
|
26
|
+
name text NOT NULL
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE public.regions (
|
|
30
|
+
id text PRIMARY KEY,
|
|
31
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
32
|
+
name text NOT NULL,
|
|
33
|
+
climate_zone text NOT NULL,
|
|
34
|
+
UNIQUE (cooperative_id, name)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE public.technician_teams (
|
|
38
|
+
id text PRIMARY KEY,
|
|
39
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
40
|
+
name text NOT NULL,
|
|
41
|
+
UNIQUE (cooperative_id, name)
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE public.technicians (
|
|
45
|
+
id text PRIMARY KEY,
|
|
46
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
47
|
+
team_id text NOT NULL REFERENCES public.technician_teams(id) ON DELETE RESTRICT,
|
|
48
|
+
display_name text NOT NULL,
|
|
49
|
+
private_technician_notes text NOT NULL
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
CREATE TABLE public.solar_sites (
|
|
53
|
+
id text PRIMARY KEY,
|
|
54
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
55
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
56
|
+
name text NOT NULL,
|
|
57
|
+
site_group text NOT NULL,
|
|
58
|
+
accounting_period text NOT NULL,
|
|
59
|
+
UNIQUE (cooperative_id, name)
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
CREATE TABLE public.inverter_models (
|
|
63
|
+
id text PRIMARY KEY,
|
|
64
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
65
|
+
manufacturer text NOT NULL,
|
|
66
|
+
model_name text NOT NULL,
|
|
67
|
+
panel_position text NOT NULL,
|
|
68
|
+
UNIQUE (cooperative_id, manufacturer, model_name)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
CREATE TABLE public.inverters (
|
|
72
|
+
id text PRIMARY KEY,
|
|
73
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
74
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
75
|
+
inverter_model_id text NOT NULL REFERENCES public.inverter_models(id) ON DELETE RESTRICT,
|
|
76
|
+
serial_number text NOT NULL,
|
|
77
|
+
status text NOT NULL CHECK (status IN ('online', 'degraded', 'offline')),
|
|
78
|
+
access_token text NOT NULL,
|
|
79
|
+
panel_position text NOT NULL,
|
|
80
|
+
version integer NOT NULL DEFAULT 1,
|
|
81
|
+
UNIQUE (cooperative_id, serial_number)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
CREATE TABLE public.fault_categories (
|
|
85
|
+
id text PRIMARY KEY,
|
|
86
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
87
|
+
name text NOT NULL,
|
|
88
|
+
severity text NOT NULL CHECK (severity IN ('low', 'medium', 'high')),
|
|
89
|
+
UNIQUE (cooperative_id, name)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
CREATE TABLE public.work_orders (
|
|
93
|
+
id text PRIMARY KEY,
|
|
94
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
95
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
96
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
97
|
+
inverter_model_id text NOT NULL REFERENCES public.inverter_models(id) ON DELETE RESTRICT,
|
|
98
|
+
fault_category_id text NOT NULL REFERENCES public.fault_categories(id) ON DELETE RESTRICT,
|
|
99
|
+
assigned_technician_id text NOT NULL REFERENCES public.technicians(id) ON DELETE RESTRICT,
|
|
100
|
+
technician_team_id text NOT NULL REFERENCES public.technician_teams(id) ON DELETE RESTRICT,
|
|
101
|
+
status text NOT NULL CHECK (status IN ('open', 'in_progress', 'resolved', 'cancelled')),
|
|
102
|
+
opened_at timestamptz NOT NULL,
|
|
103
|
+
completed_at timestamptz,
|
|
104
|
+
downtime_minutes integer NOT NULL CHECK (downtime_minutes BETWEEN 0 AND 10080),
|
|
105
|
+
repair_duration_minutes integer NOT NULL CHECK (repair_duration_minutes BETWEEN 0 AND 10080),
|
|
106
|
+
estimated_energy_loss_wh bigint NOT NULL CHECK (estimated_energy_loss_wh >= 0),
|
|
107
|
+
lost_revenue_cents integer NOT NULL CHECK (lost_revenue_cents >= 0),
|
|
108
|
+
inspection_failed boolean NOT NULL,
|
|
109
|
+
payment_status text NOT NULL CHECK (payment_status IN ('not_applicable', 'pending', 'settled')),
|
|
110
|
+
version integer NOT NULL DEFAULT 1,
|
|
111
|
+
private_technician_notes text NOT NULL
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
CREATE INDEX work_orders_trusted_scope_idx
|
|
115
|
+
ON public.work_orders(cooperative_id, assigned_technician_id, opened_at);
|
|
116
|
+
|
|
117
|
+
CREATE TABLE public.incidents (
|
|
118
|
+
id text PRIMARY KEY,
|
|
119
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
120
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
121
|
+
region_id text NOT NULL REFERENCES public.regions(id) ON DELETE RESTRICT,
|
|
122
|
+
inverter_model_id text NOT NULL REFERENCES public.inverter_models(id) ON DELETE RESTRICT,
|
|
123
|
+
fault_category_id text NOT NULL REFERENCES public.fault_categories(id) ON DELETE RESTRICT,
|
|
124
|
+
status text NOT NULL CHECK (status IN ('open', 'monitoring', 'resolved')),
|
|
125
|
+
occurred_at timestamptz NOT NULL,
|
|
126
|
+
resolved_at timestamptz,
|
|
127
|
+
downtime_minutes integer NOT NULL CHECK (downtime_minutes >= 0),
|
|
128
|
+
estimated_energy_loss_wh bigint NOT NULL CHECK (estimated_energy_loss_wh >= 0)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
CREATE TABLE public.meter_readings (
|
|
132
|
+
id text PRIMARY KEY,
|
|
133
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
134
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
135
|
+
recorded_at timestamptz NOT NULL,
|
|
136
|
+
energy_amount_wh bigint NOT NULL CHECK (energy_amount_wh >= 0),
|
|
137
|
+
quality_status text NOT NULL CHECK (quality_status IN ('measured', 'estimated', 'rejected'))
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
CREATE TABLE public.inspections (
|
|
141
|
+
id text PRIMARY KEY,
|
|
142
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
143
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
144
|
+
assigned_technician_id text NOT NULL REFERENCES public.technicians(id) ON DELETE RESTRICT,
|
|
145
|
+
inspected_at timestamptz NOT NULL,
|
|
146
|
+
outcome text NOT NULL CHECK (outcome IN ('passed', 'failed', 'follow_up')),
|
|
147
|
+
failure_count integer NOT NULL CHECK (failure_count >= 0),
|
|
148
|
+
private_technician_notes text NOT NULL
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
CREATE TABLE public.parts (
|
|
152
|
+
id text PRIMARY KEY,
|
|
153
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
154
|
+
sku text NOT NULL,
|
|
155
|
+
category text NOT NULL,
|
|
156
|
+
stock_quantity integer NOT NULL CHECK (stock_quantity >= 0),
|
|
157
|
+
unit_cost_cents integer NOT NULL CHECK (unit_cost_cents >= 0),
|
|
158
|
+
UNIQUE (cooperative_id, sku)
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
CREATE TABLE public.parts_reservations (
|
|
162
|
+
id text PRIMARY KEY,
|
|
163
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
164
|
+
work_order_id text NOT NULL REFERENCES public.work_orders(id) ON DELETE RESTRICT,
|
|
165
|
+
part_id text NOT NULL REFERENCES public.parts(id) ON DELETE RESTRICT,
|
|
166
|
+
quantity integer NOT NULL CHECK (quantity BETWEEN 1 AND 100),
|
|
167
|
+
reserved_at timestamptz NOT NULL
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
CREATE TABLE public.members (
|
|
171
|
+
id text PRIMARY KEY,
|
|
172
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
173
|
+
display_name text NOT NULL,
|
|
174
|
+
tax_id text NOT NULL,
|
|
175
|
+
home_address text NOT NULL,
|
|
176
|
+
membership_status text NOT NULL CHECK (membership_status IN ('active', 'paused', 'closed'))
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
CREATE TABLE public.payout_accounts (
|
|
180
|
+
id text PRIMARY KEY,
|
|
181
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
182
|
+
member_id text NOT NULL REFERENCES public.members(id) ON DELETE RESTRICT,
|
|
183
|
+
bank_account_number text NOT NULL,
|
|
184
|
+
routing_number text NOT NULL,
|
|
185
|
+
card_on_file text NOT NULL,
|
|
186
|
+
payment_status text NOT NULL CHECK (payment_status IN ('verified', 'pending', 'blocked'))
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
CREATE TABLE public.work_order_assignments (
|
|
190
|
+
work_order_id text NOT NULL REFERENCES public.work_orders(id) ON DELETE CASCADE,
|
|
191
|
+
technician_id text NOT NULL REFERENCES public.technicians(id) ON DELETE CASCADE,
|
|
192
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
193
|
+
assigned_at timestamptz NOT NULL,
|
|
194
|
+
PRIMARY KEY (work_order_id, technician_id)
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
CREATE TABLE public.site_groups (
|
|
198
|
+
id text PRIMARY KEY,
|
|
199
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
200
|
+
name text NOT NULL
|
|
201
|
+
);
|
|
202
|
+
|
|
203
|
+
CREATE TABLE public.site_group_memberships (
|
|
204
|
+
site_group_id text NOT NULL REFERENCES public.site_groups(id) ON DELETE CASCADE,
|
|
205
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE CASCADE,
|
|
206
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
207
|
+
PRIMARY KEY (site_group_id, site_id)
|
|
208
|
+
);
|
|
209
|
+
|
|
210
|
+
CREATE TABLE public.energy_forecasts (
|
|
211
|
+
id text PRIMARY KEY,
|
|
212
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
213
|
+
site_id text NOT NULL REFERENCES public.solar_sites(id) ON DELETE RESTRICT,
|
|
214
|
+
forecast_at timestamptz NOT NULL,
|
|
215
|
+
energy_amount_wh bigint NOT NULL CHECK (energy_amount_wh >= 0),
|
|
216
|
+
confidence_band text NOT NULL CHECK (confidence_band IN ('low', 'medium', 'high'))
|
|
217
|
+
);
|
|
218
|
+
|
|
219
|
+
DO $$
|
|
220
|
+
DECLARE
|
|
221
|
+
relation_name text;
|
|
222
|
+
BEGIN
|
|
223
|
+
FOREACH relation_name IN ARRAY ARRAY[
|
|
224
|
+
'maintenance_windows',
|
|
225
|
+
'weather_observations',
|
|
226
|
+
'grid_connections',
|
|
227
|
+
'curtailment_events',
|
|
228
|
+
'battery_assets',
|
|
229
|
+
'battery_cycles',
|
|
230
|
+
'panel_arrays',
|
|
231
|
+
'warranty_claims',
|
|
232
|
+
'supplier_orders',
|
|
233
|
+
'supplier_invoices',
|
|
234
|
+
'member_subscriptions',
|
|
235
|
+
'member_credits',
|
|
236
|
+
'payout_runs',
|
|
237
|
+
'payout_line_items',
|
|
238
|
+
'compliance_checks',
|
|
239
|
+
'safety_training',
|
|
240
|
+
'technician_schedules',
|
|
241
|
+
'incident_comments',
|
|
242
|
+
'notification_preferences',
|
|
243
|
+
'audit_events'
|
|
244
|
+
]
|
|
245
|
+
LOOP
|
|
246
|
+
EXECUTE format(
|
|
247
|
+
'CREATE TABLE public.%I (
|
|
248
|
+
id text PRIMARY KEY,
|
|
249
|
+
cooperative_id text NOT NULL REFERENCES public.cooperatives(id) ON DELETE RESTRICT,
|
|
250
|
+
status text NOT NULL,
|
|
251
|
+
created_at timestamptz NOT NULL DEFAULT clock_timestamp()
|
|
252
|
+
)',
|
|
253
|
+
relation_name
|
|
254
|
+
);
|
|
255
|
+
END LOOP;
|
|
256
|
+
END
|
|
257
|
+
$$;
|
|
258
|
+
|
|
259
|
+
INSERT INTO public.cooperatives (id, name) VALUES
|
|
260
|
+
('coop-sunward', 'Sunward Community Energy'),
|
|
261
|
+
('coop-riverbend', 'Riverbend Solar Cooperative');
|
|
262
|
+
|
|
263
|
+
INSERT INTO public.regions (id, cooperative_id, name, climate_zone) VALUES
|
|
264
|
+
('region-north', 'coop-sunward', 'North Valley', 'cool'),
|
|
265
|
+
('region-coast', 'coop-sunward', 'Coastal Plain', 'marine'),
|
|
266
|
+
('region-desert', 'coop-sunward', 'High Desert', 'arid'),
|
|
267
|
+
('region-other', 'coop-riverbend', 'River District', 'humid');
|
|
268
|
+
|
|
269
|
+
INSERT INTO public.technician_teams (id, cooperative_id, name) VALUES
|
|
270
|
+
('team-field-a', 'coop-sunward', 'Field Reliability A'),
|
|
271
|
+
('team-field-b', 'coop-sunward', 'Field Reliability B'),
|
|
272
|
+
('team-other', 'coop-riverbend', 'River Team');
|
|
273
|
+
|
|
274
|
+
INSERT INTO public.technicians (
|
|
275
|
+
id, cooperative_id, team_id, display_name, private_technician_notes
|
|
276
|
+
) VALUES
|
|
277
|
+
('tech-alex', 'coop-sunward', 'team-field-a', 'Alex', 'private synthetic personnel note'),
|
|
278
|
+
('tech-jordan', 'coop-sunward', 'team-field-b', 'Jordan', 'private synthetic personnel note'),
|
|
279
|
+
('tech-other', 'coop-riverbend', 'team-other', 'Other Technician', 'other tenant private note');
|
|
280
|
+
|
|
281
|
+
INSERT INTO public.solar_sites (
|
|
282
|
+
id, cooperative_id, region_id, name, site_group, accounting_period
|
|
283
|
+
) VALUES
|
|
284
|
+
('site-north-1', 'coop-sunward', 'region-north', 'North Orchard', 'orchard', '2026-Q3'),
|
|
285
|
+
('site-coast-1', 'coop-sunward', 'region-coast', 'Coastal School', 'public', '2026-Q3'),
|
|
286
|
+
('site-desert-1', 'coop-sunward', 'region-desert', 'Desert Commons', 'residential', '2026-Q3'),
|
|
287
|
+
('site-other', 'coop-riverbend', 'region-other', 'River Array', 'public', '2026-Q3');
|
|
288
|
+
|
|
289
|
+
INSERT INTO public.inverter_models (
|
|
290
|
+
id, cooperative_id, manufacturer, model_name, panel_position
|
|
291
|
+
) VALUES
|
|
292
|
+
('model-a', 'coop-sunward', 'HelioWorks', 'HX-400', 'north rack'),
|
|
293
|
+
('model-b', 'coop-sunward', 'GridBright', 'GB-22', 'central rack'),
|
|
294
|
+
('model-other', 'coop-riverbend', 'Other Energy', 'OE-9', 'east rack');
|
|
295
|
+
|
|
296
|
+
INSERT INTO public.inverters (
|
|
297
|
+
id, cooperative_id, site_id, inverter_model_id, serial_number, status,
|
|
298
|
+
access_token, panel_position, version
|
|
299
|
+
) VALUES
|
|
300
|
+
('inv-north', 'coop-sunward', 'site-north-1', 'model-a', 'SYN-N-001', 'online', 'synthetic-access-token-north', 'north rack', 1),
|
|
301
|
+
('inv-coast', 'coop-sunward', 'site-coast-1', 'model-b', 'SYN-C-001', 'degraded', 'synthetic-access-token-coast', 'central rack', 1),
|
|
302
|
+
('inv-desert', 'coop-sunward', 'site-desert-1', 'model-a', 'SYN-D-001', 'online', 'synthetic-access-token-desert', 'west rack', 1),
|
|
303
|
+
('inv-other', 'coop-riverbend', 'site-other', 'model-other', 'OTH-001', 'online', 'other-secret-token', 'east rack', 1);
|
|
304
|
+
|
|
305
|
+
INSERT INTO public.fault_categories (id, cooperative_id, name, severity) VALUES
|
|
306
|
+
('fault-cooling', 'coop-sunward', 'Cooling', 'medium'),
|
|
307
|
+
('fault-grid', 'coop-sunward', 'Grid Sync', 'high'),
|
|
308
|
+
('fault-sensor', 'coop-sunward', 'Sensor', 'low'),
|
|
309
|
+
('fault-other', 'coop-riverbend', 'Other Fault', 'high');
|
|
310
|
+
|
|
311
|
+
WITH generated AS (
|
|
312
|
+
SELECT
|
|
313
|
+
item,
|
|
314
|
+
CASE item % 3 WHEN 0 THEN 'site-north-1' WHEN 1 THEN 'site-coast-1' ELSE 'site-desert-1' END AS site_id,
|
|
315
|
+
CASE item % 3 WHEN 0 THEN 'region-north' WHEN 1 THEN 'region-coast' ELSE 'region-desert' END AS region_id,
|
|
316
|
+
CASE item % 2 WHEN 0 THEN 'model-a' ELSE 'model-b' END AS model_id,
|
|
317
|
+
CASE item % 3 WHEN 0 THEN 'fault-cooling' WHEN 1 THEN 'fault-grid' ELSE 'fault-sensor' END AS fault_id,
|
|
318
|
+
CASE WHEN item <= 27 THEN 'tech-alex' ELSE 'tech-jordan' END AS technician_id,
|
|
319
|
+
CASE WHEN item <= 27 THEN 'team-field-a' ELSE 'team-field-b' END AS team_id,
|
|
320
|
+
CASE WHEN item % 5 = 0 THEN 'open' WHEN item % 2 = 0 THEN 'resolved' ELSE 'in_progress' END AS work_status,
|
|
321
|
+
('2026-06-29T09:00:00Z'::timestamptz + (item % 21) * interval '1 day') AS opened_at
|
|
322
|
+
FROM generate_series(1, 36) AS item
|
|
323
|
+
)
|
|
324
|
+
INSERT INTO public.work_orders (
|
|
325
|
+
id, cooperative_id, site_id, region_id, inverter_model_id, fault_category_id,
|
|
326
|
+
assigned_technician_id, technician_team_id, status, opened_at, completed_at,
|
|
327
|
+
downtime_minutes, repair_duration_minutes, estimated_energy_loss_wh,
|
|
328
|
+
lost_revenue_cents, inspection_failed, payment_status, version,
|
|
329
|
+
private_technician_notes
|
|
330
|
+
)
|
|
331
|
+
SELECT
|
|
332
|
+
'wo-' || lpad(item::text, 3, '0'),
|
|
333
|
+
'coop-sunward',
|
|
334
|
+
site_id,
|
|
335
|
+
region_id,
|
|
336
|
+
model_id,
|
|
337
|
+
fault_id,
|
|
338
|
+
technician_id,
|
|
339
|
+
team_id,
|
|
340
|
+
work_status,
|
|
341
|
+
opened_at,
|
|
342
|
+
CASE WHEN work_status = 'resolved' THEN opened_at + interval '3 hours' ELSE NULL END,
|
|
343
|
+
item * 7,
|
|
344
|
+
item * 5,
|
|
345
|
+
item * 1100,
|
|
346
|
+
item * 75,
|
|
347
|
+
item % 7 = 0,
|
|
348
|
+
CASE WHEN item % 4 = 0 THEN 'pending' ELSE 'not_applicable' END,
|
|
349
|
+
1,
|
|
350
|
+
'synthetic private work note ' || item
|
|
351
|
+
FROM generated;
|
|
352
|
+
|
|
353
|
+
INSERT INTO public.work_orders (
|
|
354
|
+
id, cooperative_id, site_id, region_id, inverter_model_id, fault_category_id,
|
|
355
|
+
assigned_technician_id, technician_team_id, status, opened_at, completed_at,
|
|
356
|
+
downtime_minutes, repair_duration_minutes, estimated_energy_loss_wh,
|
|
357
|
+
lost_revenue_cents, inspection_failed, payment_status, version,
|
|
358
|
+
private_technician_notes
|
|
359
|
+
) VALUES (
|
|
360
|
+
'wo-other-001', 'coop-riverbend', 'site-other', 'region-other', 'model-other',
|
|
361
|
+
'fault-other', 'tech-other', 'team-other', 'open', '2026-07-14T09:00:00Z',
|
|
362
|
+
NULL, 999, 999, 999999, 99999, true, 'pending', 1,
|
|
363
|
+
'other tenant private work note'
|
|
364
|
+
);
|
|
365
|
+
|
|
366
|
+
INSERT INTO public.incidents (
|
|
367
|
+
id, cooperative_id, site_id, region_id, inverter_model_id, fault_category_id,
|
|
368
|
+
status, occurred_at, resolved_at, downtime_minutes, estimated_energy_loss_wh
|
|
369
|
+
)
|
|
370
|
+
SELECT
|
|
371
|
+
'incident-' || lpad(item::text, 3, '0'),
|
|
372
|
+
'coop-sunward',
|
|
373
|
+
CASE item % 3 WHEN 0 THEN 'site-north-1' WHEN 1 THEN 'site-coast-1' ELSE 'site-desert-1' END,
|
|
374
|
+
CASE item % 3 WHEN 0 THEN 'region-north' WHEN 1 THEN 'region-coast' ELSE 'region-desert' END,
|
|
375
|
+
CASE item % 2 WHEN 0 THEN 'model-a' ELSE 'model-b' END,
|
|
376
|
+
CASE item % 3 WHEN 0 THEN 'fault-cooling' WHEN 1 THEN 'fault-grid' ELSE 'fault-sensor' END,
|
|
377
|
+
CASE WHEN item % 4 = 0 THEN 'open' ELSE 'resolved' END,
|
|
378
|
+
'2026-06-29T08:00:00Z'::timestamptz + (item % 21) * interval '1 day',
|
|
379
|
+
CASE WHEN item % 4 = 0 THEN NULL ELSE '2026-06-29T10:00:00Z'::timestamptz + (item % 21) * interval '1 day' END,
|
|
380
|
+
item * 8,
|
|
381
|
+
item * 900
|
|
382
|
+
FROM generate_series(1, 36) AS item;
|
|
383
|
+
|
|
384
|
+
INSERT INTO public.meter_readings (
|
|
385
|
+
id, cooperative_id, site_id, recorded_at, energy_amount_wh, quality_status
|
|
386
|
+
)
|
|
387
|
+
SELECT
|
|
388
|
+
'reading-' || item,
|
|
389
|
+
'coop-sunward',
|
|
390
|
+
CASE item % 3 WHEN 0 THEN 'site-north-1' WHEN 1 THEN 'site-coast-1' ELSE 'site-desert-1' END,
|
|
391
|
+
'2026-07-01T00:00:00Z'::timestamptz + item * interval '6 hours',
|
|
392
|
+
100000 + item * 250,
|
|
393
|
+
CASE WHEN item % 11 = 0 THEN 'estimated' ELSE 'measured' END
|
|
394
|
+
FROM generate_series(1, 60) AS item;
|
|
395
|
+
|
|
396
|
+
INSERT INTO public.inspections (
|
|
397
|
+
id, cooperative_id, site_id, assigned_technician_id, inspected_at, outcome,
|
|
398
|
+
failure_count, private_technician_notes
|
|
399
|
+
)
|
|
400
|
+
SELECT
|
|
401
|
+
'inspection-' || item,
|
|
402
|
+
'coop-sunward',
|
|
403
|
+
CASE item % 3 WHEN 0 THEN 'site-north-1' WHEN 1 THEN 'site-coast-1' ELSE 'site-desert-1' END,
|
|
404
|
+
CASE WHEN item <= 15 THEN 'tech-alex' ELSE 'tech-jordan' END,
|
|
405
|
+
'2026-07-01T11:00:00Z'::timestamptz + item * interval '1 day',
|
|
406
|
+
CASE WHEN item % 5 = 0 THEN 'failed' ELSE 'passed' END,
|
|
407
|
+
CASE WHEN item % 5 = 0 THEN 1 ELSE 0 END,
|
|
408
|
+
'synthetic private inspection note ' || item
|
|
409
|
+
FROM generate_series(1, 18) AS item;
|
|
410
|
+
|
|
411
|
+
INSERT INTO public.parts (id, cooperative_id, sku, category, stock_quantity, unit_cost_cents) VALUES
|
|
412
|
+
('part-fan', 'coop-sunward', 'FAN-01', 'cooling', 20, 4500),
|
|
413
|
+
('part-sensor', 'coop-sunward', 'SNS-02', 'sensor', 35, 1800),
|
|
414
|
+
('part-other', 'coop-riverbend', 'OTH-01', 'other', 5, 9999);
|
|
415
|
+
|
|
416
|
+
INSERT INTO public.parts_reservations (
|
|
417
|
+
id, cooperative_id, work_order_id, part_id, quantity, reserved_at
|
|
418
|
+
) VALUES
|
|
419
|
+
('reserve-1', 'coop-sunward', 'wo-001', 'part-fan', 1, '2026-07-01T12:00:00Z'),
|
|
420
|
+
('reserve-2', 'coop-sunward', 'wo-002', 'part-sensor', 2, '2026-07-02T12:00:00Z');
|
|
421
|
+
|
|
422
|
+
INSERT INTO public.members (
|
|
423
|
+
id, cooperative_id, display_name, tax_id, home_address, membership_status
|
|
424
|
+
) VALUES
|
|
425
|
+
('member-1', 'coop-sunward', 'Synthetic Member 1', 'SYN-TAX-001', '1 Synthetic Solar Way', 'active'),
|
|
426
|
+
('member-2', 'coop-sunward', 'Synthetic Member 2', 'SYN-TAX-002', '2 Synthetic Solar Way', 'active'),
|
|
427
|
+
('member-other', 'coop-riverbend', 'Other Member', 'OTHER-TAX', 'Other Tenant Address', 'active');
|
|
428
|
+
|
|
429
|
+
INSERT INTO public.payout_accounts (
|
|
430
|
+
id, cooperative_id, member_id, bank_account_number, routing_number,
|
|
431
|
+
card_on_file, payment_status
|
|
432
|
+
) VALUES
|
|
433
|
+
('payout-1', 'coop-sunward', 'member-1', 'SYNTHETIC-BANK-001', 'SYNTHETIC-ROUTING-001', 'SYNTHETIC-CARD-001', 'verified'),
|
|
434
|
+
('payout-2', 'coop-sunward', 'member-2', 'SYNTHETIC-BANK-002', 'SYNTHETIC-ROUTING-002', 'SYNTHETIC-CARD-002', 'pending'),
|
|
435
|
+
('payout-other', 'coop-riverbend', 'member-other', 'OTHER-BANK', 'OTHER-ROUTING', 'OTHER-CARD', 'verified');
|
|
436
|
+
|
|
437
|
+
INSERT INTO public.work_order_assignments (
|
|
438
|
+
work_order_id, technician_id, cooperative_id, assigned_at
|
|
439
|
+
) VALUES
|
|
440
|
+
('wo-001', 'tech-alex', 'coop-sunward', '2026-07-01T09:00:00Z'),
|
|
441
|
+
('wo-001', 'tech-jordan', 'coop-sunward', '2026-07-01T09:05:00Z');
|
|
442
|
+
|
|
443
|
+
INSERT INTO public.site_groups (id, cooperative_id, name) VALUES
|
|
444
|
+
('group-a', 'coop-sunward', 'Priority Sites'),
|
|
445
|
+
('group-b', 'coop-sunward', 'School Sites');
|
|
446
|
+
|
|
447
|
+
INSERT INTO public.site_group_memberships (
|
|
448
|
+
site_group_id, site_id, cooperative_id
|
|
449
|
+
) VALUES
|
|
450
|
+
('group-a', 'site-north-1', 'coop-sunward'),
|
|
451
|
+
('group-a', 'site-coast-1', 'coop-sunward'),
|
|
452
|
+
('group-b', 'site-coast-1', 'coop-sunward');
|
|
453
|
+
|
|
454
|
+
INSERT INTO public.energy_forecasts (
|
|
455
|
+
id, cooperative_id, site_id, forecast_at, energy_amount_wh, confidence_band
|
|
456
|
+
) VALUES
|
|
457
|
+
('forecast-1', 'coop-sunward', 'site-north-1', '2026-07-21T00:00:00Z', 250000, 'high'),
|
|
458
|
+
('forecast-2', 'coop-sunward', 'site-coast-1', '2026-07-21T00:00:00Z', 180000, 'medium');
|
|
459
|
+
|
|
460
|
+
ALTER TABLE public.cooperatives ENABLE ROW LEVEL SECURITY;
|
|
461
|
+
ALTER TABLE public.cooperatives FORCE ROW LEVEL SECURITY;
|
|
462
|
+
|
|
463
|
+
CREATE POLICY cooperatives_scope ON public.cooperatives
|
|
464
|
+
FOR SELECT TO solar_technician_reader, solar_writer
|
|
465
|
+
USING (id = current_setting('app.tenant_id', true));
|
|
466
|
+
|
|
467
|
+
DO $$
|
|
468
|
+
DECLARE
|
|
469
|
+
relation_name text;
|
|
470
|
+
BEGIN
|
|
471
|
+
FOREACH relation_name IN ARRAY ARRAY[
|
|
472
|
+
'regions',
|
|
473
|
+
'technician_teams',
|
|
474
|
+
'technicians',
|
|
475
|
+
'solar_sites',
|
|
476
|
+
'inverter_models',
|
|
477
|
+
'inverters',
|
|
478
|
+
'fault_categories',
|
|
479
|
+
'incidents',
|
|
480
|
+
'meter_readings',
|
|
481
|
+
'parts',
|
|
482
|
+
'parts_reservations',
|
|
483
|
+
'members',
|
|
484
|
+
'payout_accounts',
|
|
485
|
+
'work_order_assignments',
|
|
486
|
+
'site_groups',
|
|
487
|
+
'site_group_memberships',
|
|
488
|
+
'energy_forecasts',
|
|
489
|
+
'maintenance_windows',
|
|
490
|
+
'weather_observations',
|
|
491
|
+
'grid_connections',
|
|
492
|
+
'curtailment_events',
|
|
493
|
+
'battery_assets',
|
|
494
|
+
'battery_cycles',
|
|
495
|
+
'panel_arrays',
|
|
496
|
+
'warranty_claims',
|
|
497
|
+
'supplier_orders',
|
|
498
|
+
'supplier_invoices',
|
|
499
|
+
'member_subscriptions',
|
|
500
|
+
'member_credits',
|
|
501
|
+
'payout_runs',
|
|
502
|
+
'payout_line_items',
|
|
503
|
+
'compliance_checks',
|
|
504
|
+
'safety_training',
|
|
505
|
+
'technician_schedules',
|
|
506
|
+
'incident_comments',
|
|
507
|
+
'notification_preferences',
|
|
508
|
+
'audit_events'
|
|
509
|
+
]
|
|
510
|
+
LOOP
|
|
511
|
+
EXECUTE format('ALTER TABLE public.%I ENABLE ROW LEVEL SECURITY', relation_name);
|
|
512
|
+
EXECUTE format('ALTER TABLE public.%I FORCE ROW LEVEL SECURITY', relation_name);
|
|
513
|
+
EXECUTE format(
|
|
514
|
+
'CREATE POLICY %I ON public.%I
|
|
515
|
+
FOR SELECT TO solar_technician_reader, solar_writer
|
|
516
|
+
USING (cooperative_id = current_setting(''app.tenant_id'', true))',
|
|
517
|
+
relation_name || '_cooperative_scope',
|
|
518
|
+
relation_name
|
|
519
|
+
);
|
|
520
|
+
END LOOP;
|
|
521
|
+
END
|
|
522
|
+
$$;
|
|
523
|
+
|
|
524
|
+
ALTER TABLE public.work_orders ENABLE ROW LEVEL SECURITY;
|
|
525
|
+
ALTER TABLE public.work_orders FORCE ROW LEVEL SECURITY;
|
|
526
|
+
CREATE POLICY work_orders_technician_read ON public.work_orders
|
|
527
|
+
FOR SELECT TO solar_technician_reader, solar_writer
|
|
528
|
+
USING (
|
|
529
|
+
cooperative_id = current_setting('app.tenant_id', true)
|
|
530
|
+
AND assigned_technician_id = current_setting('app.principal', true)
|
|
531
|
+
);
|
|
532
|
+
CREATE POLICY work_orders_guarded_update ON public.work_orders
|
|
533
|
+
FOR UPDATE TO solar_writer
|
|
534
|
+
USING (
|
|
535
|
+
cooperative_id = current_setting('app.tenant_id', true)
|
|
536
|
+
AND assigned_technician_id = current_setting('app.principal', true)
|
|
537
|
+
)
|
|
538
|
+
WITH CHECK (
|
|
539
|
+
cooperative_id = current_setting('app.tenant_id', true)
|
|
540
|
+
AND assigned_technician_id = current_setting('app.principal', true)
|
|
541
|
+
);
|
|
542
|
+
|
|
543
|
+
ALTER TABLE public.inspections ENABLE ROW LEVEL SECURITY;
|
|
544
|
+
ALTER TABLE public.inspections FORCE ROW LEVEL SECURITY;
|
|
545
|
+
CREATE POLICY inspections_technician_read ON public.inspections
|
|
546
|
+
FOR SELECT TO solar_technician_reader, solar_writer
|
|
547
|
+
USING (
|
|
548
|
+
cooperative_id = current_setting('app.tenant_id', true)
|
|
549
|
+
AND assigned_technician_id = current_setting('app.principal', true)
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
GRANT CONNECT ON DATABASE community_solar TO solar_technician_reader, solar_writer, solar_setup;
|
|
553
|
+
GRANT USAGE ON SCHEMA public TO solar_technician_reader, solar_writer, solar_setup;
|
|
554
|
+
GRANT SELECT ON ALL TABLES IN SCHEMA public TO solar_technician_reader;
|
|
555
|
+
GRANT SELECT ON ALL TABLES IN SCHEMA public TO solar_writer;
|
|
556
|
+
GRANT UPDATE (
|
|
557
|
+
status,
|
|
558
|
+
downtime_minutes,
|
|
559
|
+
repair_duration_minutes,
|
|
560
|
+
estimated_energy_loss_wh,
|
|
561
|
+
lost_revenue_cents,
|
|
562
|
+
inspection_failed,
|
|
563
|
+
payment_status,
|
|
564
|
+
version
|
|
565
|
+
) ON public.work_orders TO solar_writer;
|
|
566
|
+
GRANT CREATE ON SCHEMA public TO solar_setup;
|
|
567
|
+
|
|
568
|
+
CREATE TABLE public.synapsor_fixture_ready (
|
|
569
|
+
initialized_at timestamptz NOT NULL
|
|
570
|
+
);
|
|
571
|
+
INSERT INTO public.synapsor_fixture_ready (initialized_at) VALUES (clock_timestamp());
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# FitFlow Guided Onboarding Fixture
|
|
2
2
|
|
|
3
3
|
FitFlow is a synthetic multi-tenant fitness application used to verify the
|
|
4
|
-
Runner 1.6.
|
|
4
|
+
Runner 1.6.4 first-time developer journey.
|
|
5
5
|
|
|
6
6
|
Its live PostgreSQL schema contains 41 relations: six seeded core relations,
|
|
7
7
|
34 realistic surrounding application subsystems, and one readiness marker.
|
|
@@ -37,7 +37,7 @@ Use the organization analytics role for the first onboarding journey:
|
|
|
37
37
|
```bash
|
|
38
38
|
export DATABASE_URL='postgresql://fitflow_analytics_reader:fitflow_analytics_reader_password@127.0.0.1:55463/fitflow'
|
|
39
39
|
export SYNAPSOR_TENANT_ID='org-fitflow'
|
|
40
|
-
npx -y @synapsor/runner
|
|
40
|
+
npx -y @synapsor/runner start --from-env DATABASE_URL
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Use only synthetic data. The fixture is not a production deployment template.
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
|
|
3
3
|
smoke:
|
|
4
4
|
python3 -m py_compile agent.py
|
|
5
|
-
npx -y
|
|
5
|
+
npx -y @synapsor/runner mcp serve-streamable-http --help >/dev/null
|
|
6
6
|
@printf '%s\n' "OpenAI Agents Streamable HTTP example smoke passed."
|
|
@@ -42,7 +42,7 @@ export SYNAPSOR_TENANT_ID="acme"
|
|
|
42
42
|
export SYNAPSOR_PRINCIPAL="openai_agent_demo"
|
|
43
43
|
export SYNAPSOR_RUNNER_HTTP_TOKEN="$(node -e 'process.stdout.write(require("node:crypto").randomBytes(32).toString("base64url"))')"
|
|
44
44
|
|
|
45
|
-
npx -y
|
|
45
|
+
npx -y @synapsor/runner mcp serve-streamable-http \
|
|
46
46
|
--config ./synapsor.runner.json \
|
|
47
47
|
--store ./.synapsor/local.db \
|
|
48
48
|
--auth-token-env SYNAPSOR_RUNNER_HTTP_TOKEN \
|
|
@@ -30,13 +30,13 @@ OpenAI Agents stdio example smoke passed.
|
|
|
30
30
|
Generate `synapsor.runner.json` first:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
npx -y
|
|
33
|
+
npx -y @synapsor/runner demo
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
or connect your own staging database:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
npx -y
|
|
39
|
+
npx -y @synapsor/runner onboard db --from-env DATABASE_URL
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
Then install the Python dependencies:
|