@feltdb/core 0.8.0 → 0.8.1
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/dist/application-development.d.ts +7 -2
- package/dist/application-development.d.ts.map +1 -1
- package/dist/application-development.js +7 -13
- package/dist/application-manifest.d.ts +1 -0
- package/dist/application-manifest.d.ts.map +1 -1
- package/dist/application-manifest.js +1 -1
- package/dist/application-understanding.d.ts +76 -0
- package/dist/application-understanding.d.ts.map +1 -0
- package/dist/application-understanding.js +282 -0
- package/dist/cli/ai-model-config.js +3 -3
- package/dist/cli/commands.js +131 -38
- package/dist/cli/proposal-client.js +5 -1
- package/dist/cli/publish-engine.js +1 -1
- package/dist/cli/repository-evidence.js +55 -0
- package/dist/cli/source-sync.js +190 -75
- package/dist/convergence.d.ts +55 -0
- package/dist/convergence.d.ts.map +1 -0
- package/dist/convergence.js +63 -0
- package/dist/create/managed-account.js +1 -0
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/src/application.rs +4 -0
- package/dist/create/server-source/crates/feltdb-server/src/connections.rs +14 -0
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +174 -24
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +8 -1
- package/dist/create/template/default-project/src/context/AuthContext.tsx +9 -1
- package/dist/create/template/default-project/src/pages/SignUp.tsx +1 -1
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +6 -1
- package/dist/http-client.d.ts +32 -1
- package/dist/http-client.d.ts.map +1 -1
- package/dist/http-client.js +14 -2
- package/dist/http-db.d.ts +3 -0
- package/dist/http-db.d.ts.map +1 -1
- package/dist/http-db.js +28 -3
- package/dist/index-core.d.ts +3 -0
- package/dist/index-core.d.ts.map +1 -1
- package/dist/index-core.js +3 -0
- package/dist/intent.d.ts +98 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +343 -0
- package/dist/module-intent.d.ts +19 -5
- package/dist/module-intent.d.ts.map +1 -1
- package/dist/module-intent.js +211 -62
- package/dist/module.d.ts +41 -12
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js +543 -38
- package/dist/proposal.d.ts +13 -1
- package/dist/proposal.d.ts.map +1 -1
- package/dist/proposal.js +21 -4
- package/dist/studio/components/AskFeltDB.d.ts.map +1 -1
- package/dist/studio/components/ProposalBrowser.d.ts +1 -1
- package/dist/studio/components/ProposalBrowser.d.ts.map +1 -1
- package/dist/studio/components/index.js +1 -1
- package/dist/studio/{components-CNSNrmA9.js → components-Duq2xQWt.js} +251 -193
- package/dist/studio/index.js +1 -1
- package/dist/studio/studio.css +1 -1
- package/dist/studio/utils/proposal-api.d.ts +4 -1
- package/dist/studio/utils/proposal-api.d.ts.map +1 -1
- package/dist/studio/utils/proposal-api.js +3 -0
- package/dist/studio-app/assets/{feltdb_wasm-CSB6KVgw.js → feltdb_wasm-bIqcRzAr.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-BE79okwX.wasm +0 -0
- package/dist/studio-app/assets/{index-yazaWMUN.css → index-Cd_NPw14.css} +1 -1
- package/dist/studio-app/assets/index-XGYdlElN.js +29 -0
- package/dist/studio-app/index.html +2 -2
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/dist/workspace/local-development-authority.d.ts +2 -0
- package/dist/workspace/local-development-authority.d.ts.map +1 -1
- package/dist/workspace/local-development-authority.js +65 -2
- package/package.json +1 -1
- package/dist/studio-app/assets/dist-CCOk39Uc.js +0 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-Dd1fnO9U.wasm +0 -0
- package/dist/studio-app/assets/index-Bncji3aN.js +0 -43
- package/dist/studio-app/assets/lib-B2_7fcn7.js +0 -69
- package/dist/studio-app/assets/worker-CARZ5g7K.js +0 -69
package/dist/module.js
CHANGED
|
@@ -1,46 +1,535 @@
|
|
|
1
|
+
const model = (name, ownership = "external-authoritative") => ({
|
|
2
|
+
name,
|
|
3
|
+
authority: "external",
|
|
4
|
+
ownership,
|
|
5
|
+
fields: [
|
|
6
|
+
{
|
|
7
|
+
name: "id",
|
|
8
|
+
type: "text",
|
|
9
|
+
immutable: true,
|
|
10
|
+
externally_owned: true,
|
|
11
|
+
application_readable: true,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
name: "status",
|
|
15
|
+
type: "text",
|
|
16
|
+
optional: true,
|
|
17
|
+
externally_owned: true,
|
|
18
|
+
application_readable: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "created_at",
|
|
22
|
+
type: "datetime",
|
|
23
|
+
externally_owned: true,
|
|
24
|
+
application_readable: true,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "metadata",
|
|
28
|
+
type: "json",
|
|
29
|
+
optional: true,
|
|
30
|
+
externally_owned: true,
|
|
31
|
+
application_readable: true,
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
});
|
|
1
35
|
const stripe = {
|
|
2
|
-
id:
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
36
|
+
id: "stripe",
|
|
37
|
+
name: "Stripe-compatible billing",
|
|
38
|
+
version: "1.0.0",
|
|
39
|
+
provider: "stripe-compatible",
|
|
40
|
+
compatibility: ["stripe", "stripe-compatible"],
|
|
41
|
+
intent_keywords: ["stripe", "billing", "plan", "subscription"],
|
|
42
|
+
models: [
|
|
43
|
+
"Customer",
|
|
44
|
+
"Product",
|
|
45
|
+
"Price",
|
|
46
|
+
"Subscription",
|
|
47
|
+
"SubscriptionItem",
|
|
48
|
+
"Invoice",
|
|
49
|
+
"PaymentIntent",
|
|
50
|
+
"CheckoutSession",
|
|
51
|
+
"PaymentMethod",
|
|
52
|
+
"Refund",
|
|
53
|
+
"WebhookEvent",
|
|
54
|
+
].map((name) => model(name)),
|
|
11
55
|
relationships: [
|
|
12
|
-
{ from:
|
|
13
|
-
{ from:
|
|
14
|
-
{ from:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
56
|
+
{ from: "Customer", to: "Subscription", kind: "many" },
|
|
57
|
+
{ from: "Subscription", to: "SubscriptionItem", kind: "many" },
|
|
58
|
+
{ from: "SubscriptionItem", to: "Price", kind: "one" },
|
|
59
|
+
{ from: "Price", to: "Product", kind: "one" },
|
|
60
|
+
{ from: "Customer", to: "Invoice", kind: "many" },
|
|
61
|
+
{ from: "Invoice", to: "PaymentIntent", kind: "one" },
|
|
62
|
+
],
|
|
63
|
+
events: [
|
|
64
|
+
"stripe.customer.created",
|
|
65
|
+
"stripe.customer.updated",
|
|
66
|
+
"stripe.subscription.created",
|
|
67
|
+
"stripe.subscription.updated",
|
|
68
|
+
"stripe.subscription.deleted",
|
|
69
|
+
"stripe.invoice.paid",
|
|
70
|
+
"stripe.invoice.payment_failed",
|
|
71
|
+
"stripe.checkout.session.completed",
|
|
72
|
+
],
|
|
73
|
+
capabilities: [
|
|
74
|
+
"stripe.customer.read",
|
|
75
|
+
"stripe.customer.create",
|
|
76
|
+
"stripe.checkout.create",
|
|
77
|
+
"stripe.subscription.read",
|
|
78
|
+
"stripe.subscription.create",
|
|
79
|
+
"stripe.subscription.cancel",
|
|
80
|
+
"stripe.invoice.read",
|
|
81
|
+
"stripe.webhooks.receive",
|
|
82
|
+
],
|
|
83
|
+
workflows: ["ReconcileSubscription", "ReconcileFailedPayment"],
|
|
84
|
+
configuration: [
|
|
85
|
+
{
|
|
86
|
+
name: "STRIPE_PUBLISHABLE_KEY",
|
|
87
|
+
required: false,
|
|
88
|
+
description: "Browser-safe publishable provider key",
|
|
89
|
+
visibility: "browser",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
secrets: [
|
|
93
|
+
{
|
|
94
|
+
name: "STRIPE_SECRET_KEY",
|
|
95
|
+
required: true,
|
|
96
|
+
description: "Server-side provider credential",
|
|
97
|
+
visibility: "server",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
name: "STRIPE_WEBHOOK_SECRET",
|
|
101
|
+
required: true,
|
|
102
|
+
environments: ["production"],
|
|
103
|
+
description: "Webhook signature verification secret",
|
|
104
|
+
visibility: "server",
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
validation: [
|
|
108
|
+
"Webhook receivers must verify signatures",
|
|
109
|
+
"Checkout creation requires authenticated authorization",
|
|
110
|
+
],
|
|
111
|
+
dependencies: [
|
|
112
|
+
{
|
|
113
|
+
name: "authentication",
|
|
114
|
+
description: "Checkout requires an authenticated application identity",
|
|
115
|
+
any_collections: ["User", "Account"],
|
|
116
|
+
any_capabilities: ["auth.session.read", "authentication"],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
23
119
|
authorization: [
|
|
24
|
-
{
|
|
25
|
-
|
|
120
|
+
{
|
|
121
|
+
capability: "stripe.checkout.create",
|
|
122
|
+
subject: "authenticated",
|
|
123
|
+
implication: "A signed-in billing owner may create a hosted checkout session",
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
capability: "stripe.subscription.cancel",
|
|
127
|
+
subject: "owner",
|
|
128
|
+
implication: "Only the billing owner may cancel a subscription",
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
extension_application_models: [
|
|
132
|
+
{
|
|
133
|
+
name: "BillingPlan",
|
|
134
|
+
ownership: "application-authoritative",
|
|
135
|
+
purpose: "Application pricing and entitlement plan",
|
|
136
|
+
fields: [
|
|
137
|
+
{ name: "code", type: "text" },
|
|
138
|
+
{ name: "interval", type: "enum(monthly,annual)" },
|
|
139
|
+
{ name: "price", type: "ref $module.Price" },
|
|
140
|
+
{ name: "active", type: "boolean" },
|
|
141
|
+
],
|
|
142
|
+
},
|
|
26
143
|
],
|
|
27
144
|
patterns: [
|
|
28
|
-
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
{
|
|
34
|
-
|
|
35
|
-
|
|
145
|
+
{
|
|
146
|
+
name: "organization billing",
|
|
147
|
+
when: "The application contains an organizational owner",
|
|
148
|
+
owner_candidates: ["Organization", "Workspace"],
|
|
149
|
+
application_models: [
|
|
150
|
+
{
|
|
151
|
+
name: "BillingAccount",
|
|
152
|
+
ownership: "application-authoritative",
|
|
153
|
+
purpose: "Connect the application billing owner to provider state",
|
|
154
|
+
fields: [
|
|
155
|
+
{ name: "owner", type: "ref $owner" },
|
|
156
|
+
{ name: "customer", type: "ref $module.Customer" },
|
|
157
|
+
{
|
|
158
|
+
name: "subscription",
|
|
159
|
+
type: "ref $module.Subscription",
|
|
160
|
+
optional: true,
|
|
161
|
+
},
|
|
162
|
+
{ name: "status", type: "text" },
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: "Entitlement",
|
|
167
|
+
ownership: "derived",
|
|
168
|
+
purpose: "Materialize product access from reconciled subscription state",
|
|
169
|
+
fields: [
|
|
170
|
+
{ name: "billing_account", type: "ref BillingAccount" },
|
|
171
|
+
{ name: "key", type: "text" },
|
|
172
|
+
{ name: "active", type: "boolean" },
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "user billing",
|
|
179
|
+
when: "The application is user-centric",
|
|
180
|
+
owner_candidates: ["User", "Account"],
|
|
181
|
+
application_models: [
|
|
182
|
+
{
|
|
183
|
+
name: "BillingAccount",
|
|
184
|
+
ownership: "application-authoritative",
|
|
185
|
+
purpose: "Connect the user to provider state",
|
|
186
|
+
fields: [
|
|
187
|
+
{ name: "owner", type: "ref $owner" },
|
|
188
|
+
{ name: "customer", type: "ref $module.Customer" },
|
|
189
|
+
{
|
|
190
|
+
name: "subscription",
|
|
191
|
+
type: "ref $module.Subscription",
|
|
192
|
+
optional: true,
|
|
193
|
+
},
|
|
194
|
+
{ name: "status", type: "text" },
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: "Entitlement",
|
|
199
|
+
ownership: "derived",
|
|
200
|
+
purpose: "Materialize product access from reconciled subscription state",
|
|
201
|
+
fields: [
|
|
202
|
+
{ name: "billing_account", type: "ref BillingAccount" },
|
|
203
|
+
{ name: "key", type: "text" },
|
|
204
|
+
{ name: "active", type: "boolean" },
|
|
205
|
+
],
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
},
|
|
36
209
|
],
|
|
37
210
|
reconciliation: [
|
|
38
|
-
{
|
|
39
|
-
|
|
211
|
+
{
|
|
212
|
+
event: "stripe.subscription.updated",
|
|
213
|
+
workflow: "ReconcileSubscription",
|
|
214
|
+
reads: ["stripe.Subscription", "BillingAccount"],
|
|
215
|
+
writes: ["BillingAccount", "Entitlement"],
|
|
216
|
+
outcome: "Subscription changes become application entitlements",
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
event: "stripe.invoice.payment_failed",
|
|
220
|
+
workflow: "ReconcileFailedPayment",
|
|
221
|
+
reads: ["stripe.Invoice", "BillingAccount"],
|
|
222
|
+
writes: ["BillingAccount", "Entitlement"],
|
|
223
|
+
outcome: "Failed payment state restricts derived entitlements",
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
placement: {
|
|
227
|
+
owner_claim: "billing.owner",
|
|
228
|
+
primary_application_model: "BillingAccount",
|
|
229
|
+
owner_field: "owner",
|
|
230
|
+
},
|
|
231
|
+
source_artifacts: [
|
|
232
|
+
{
|
|
233
|
+
path: "src/integrations/stripe/domain.ts",
|
|
234
|
+
role: "module-domain",
|
|
235
|
+
purpose: "Application billing state",
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
path: "src/integrations/stripe/provider-boundary.ts",
|
|
239
|
+
role: "module-provider-boundary",
|
|
240
|
+
purpose: "Stripe operations and verified event boundary",
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
path: "src/integrations/stripe/reconcile.ts",
|
|
244
|
+
role: "module-reconciliation",
|
|
245
|
+
purpose: "Subscription to entitlement reconciliation",
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
path: "src/integrations/stripe/IntegrationView.tsx",
|
|
249
|
+
role: "module-ui",
|
|
250
|
+
purpose: "Billing application experience",
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
path: "src/integrations/stripe/module.test.ts",
|
|
254
|
+
role: "module-contract-test",
|
|
255
|
+
purpose: "Module contract test",
|
|
256
|
+
},
|
|
40
257
|
],
|
|
41
258
|
};
|
|
42
|
-
const
|
|
43
|
-
|
|
259
|
+
const github = {
|
|
260
|
+
id: "github",
|
|
261
|
+
name: "GitHub App collaboration",
|
|
262
|
+
version: "1.0.0",
|
|
263
|
+
provider: "github-app",
|
|
264
|
+
compatibility: ["github", "github-app"],
|
|
265
|
+
intent_keywords: ["github", "repository", "repositories", "issues"],
|
|
266
|
+
models: [
|
|
267
|
+
model("Organization"),
|
|
268
|
+
model("Repository"),
|
|
269
|
+
model("Installation", "synchronized"),
|
|
270
|
+
model("Issue"),
|
|
271
|
+
model("Membership"),
|
|
272
|
+
],
|
|
273
|
+
relationships: [
|
|
274
|
+
{ from: "Organization", to: "Repository", kind: "many" },
|
|
275
|
+
{ from: "Installation", to: "Repository", kind: "many" },
|
|
276
|
+
{ from: "Repository", to: "Issue", kind: "many" },
|
|
277
|
+
],
|
|
278
|
+
events: [
|
|
279
|
+
"github.repository.created",
|
|
280
|
+
"github.repository.updated",
|
|
281
|
+
"github.repository.deleted",
|
|
282
|
+
"github.installation.created",
|
|
283
|
+
"github.installation.deleted",
|
|
284
|
+
"github.membership.added",
|
|
285
|
+
"github.membership.removed",
|
|
286
|
+
],
|
|
287
|
+
capabilities: [
|
|
288
|
+
"github.repository.read",
|
|
289
|
+
"github.repository.create",
|
|
290
|
+
"github.issue.read",
|
|
291
|
+
"github.issue.write",
|
|
292
|
+
"github.webhooks.receive",
|
|
293
|
+
],
|
|
294
|
+
workflows: ["SynchronizeRepository", "SynchronizeInstallation"],
|
|
295
|
+
configuration: [
|
|
296
|
+
{
|
|
297
|
+
name: "GITHUB_APP_ID",
|
|
298
|
+
required: true,
|
|
299
|
+
description: "GitHub App identifier",
|
|
300
|
+
visibility: "server",
|
|
301
|
+
},
|
|
302
|
+
],
|
|
303
|
+
secrets: [
|
|
304
|
+
{
|
|
305
|
+
name: "GITHUB_PRIVATE_KEY",
|
|
306
|
+
required: true,
|
|
307
|
+
description: "GitHub App signing key",
|
|
308
|
+
visibility: "server",
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
name: "GITHUB_WEBHOOK_SECRET",
|
|
312
|
+
required: true,
|
|
313
|
+
description: "GitHub webhook verification secret",
|
|
314
|
+
visibility: "server",
|
|
315
|
+
},
|
|
316
|
+
],
|
|
317
|
+
validation: [
|
|
318
|
+
"Webhook receivers must verify signatures",
|
|
319
|
+
"Repository writes require explicit application authorization",
|
|
320
|
+
],
|
|
321
|
+
dependencies: [
|
|
322
|
+
{
|
|
323
|
+
name: "authentication",
|
|
324
|
+
description: "GitHub installation management requires authenticated identity",
|
|
325
|
+
any_collections: ["User", "Account"],
|
|
326
|
+
any_capabilities: ["auth.session.read", "authentication"],
|
|
327
|
+
},
|
|
328
|
+
],
|
|
329
|
+
authorization: [
|
|
330
|
+
{
|
|
331
|
+
capability: "github.repository.read",
|
|
332
|
+
subject: "authenticated",
|
|
333
|
+
implication: "Authenticated members may read connected repositories",
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
capability: "github.repository.create",
|
|
337
|
+
subject: "owner",
|
|
338
|
+
implication: "The integration owner controls repository creation",
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
patterns: [
|
|
342
|
+
{
|
|
343
|
+
name: "organizational collaboration",
|
|
344
|
+
when: "Projects belong to an organization or workspace",
|
|
345
|
+
owner_candidates: ["Organization", "Workspace"],
|
|
346
|
+
application_models: [
|
|
347
|
+
{
|
|
348
|
+
name: "GitHubConnection",
|
|
349
|
+
ownership: "application-authoritative",
|
|
350
|
+
purpose: "Bind an application owner to a GitHub App installation",
|
|
351
|
+
fields: [
|
|
352
|
+
{ name: "owner", type: "ref $owner" },
|
|
353
|
+
{ name: "installation", type: "ref $module.Installation" },
|
|
354
|
+
{ name: "status", type: "text" },
|
|
355
|
+
],
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
name: "RepositoryConnection",
|
|
359
|
+
ownership: "synchronized",
|
|
360
|
+
purpose: "Map provider repositories into application projects",
|
|
361
|
+
fields: [
|
|
362
|
+
{ name: "connection", type: "ref GitHubConnection" },
|
|
363
|
+
{ name: "repository", type: "ref $module.Repository" },
|
|
364
|
+
{ name: "project", type: "ref $project", optional: true },
|
|
365
|
+
{ name: "synchronized_at", type: "datetime" },
|
|
366
|
+
],
|
|
367
|
+
},
|
|
368
|
+
],
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: "personal collaboration",
|
|
372
|
+
when: "Projects belong directly to a user",
|
|
373
|
+
owner_candidates: ["User", "Account"],
|
|
374
|
+
application_models: [
|
|
375
|
+
{
|
|
376
|
+
name: "GitHubConnection",
|
|
377
|
+
ownership: "application-authoritative",
|
|
378
|
+
purpose: "Bind a user to a GitHub App installation",
|
|
379
|
+
fields: [
|
|
380
|
+
{ name: "owner", type: "ref $owner" },
|
|
381
|
+
{ name: "installation", type: "ref $module.Installation" },
|
|
382
|
+
{ name: "status", type: "text" },
|
|
383
|
+
],
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: "RepositoryConnection",
|
|
387
|
+
ownership: "synchronized",
|
|
388
|
+
purpose: "Map provider repositories into application projects",
|
|
389
|
+
fields: [
|
|
390
|
+
{ name: "connection", type: "ref GitHubConnection" },
|
|
391
|
+
{ name: "repository", type: "ref $module.Repository" },
|
|
392
|
+
{ name: "project", type: "ref $project", optional: true },
|
|
393
|
+
{ name: "synchronized_at", type: "datetime" },
|
|
394
|
+
],
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
},
|
|
398
|
+
],
|
|
399
|
+
reconciliation: [
|
|
400
|
+
{
|
|
401
|
+
event: "github.repository.updated",
|
|
402
|
+
workflow: "SynchronizeRepository",
|
|
403
|
+
reads: ["github.Repository", "RepositoryConnection"],
|
|
404
|
+
writes: ["RepositoryConnection"],
|
|
405
|
+
outcome: "Repository changes synchronize into application project state",
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
event: "github.installation.created",
|
|
409
|
+
workflow: "SynchronizeInstallation",
|
|
410
|
+
reads: ["github.Installation"],
|
|
411
|
+
writes: ["GitHubConnection"],
|
|
412
|
+
outcome: "GitHub App installations become application connections",
|
|
413
|
+
},
|
|
414
|
+
],
|
|
415
|
+
placement: {
|
|
416
|
+
owner_claim: "repository.owner",
|
|
417
|
+
primary_application_model: "GitHubConnection",
|
|
418
|
+
owner_field: "owner",
|
|
419
|
+
},
|
|
420
|
+
source_artifacts: [
|
|
421
|
+
{
|
|
422
|
+
path: "src/integrations/github/domain.ts",
|
|
423
|
+
role: "module-domain",
|
|
424
|
+
purpose: "GitHub connection state",
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
path: "src/integrations/github/provider-boundary.ts",
|
|
428
|
+
role: "module-provider-boundary",
|
|
429
|
+
purpose: "GitHub App operations and webhook verification",
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
path: "src/integrations/github/reconcile.ts",
|
|
433
|
+
role: "module-reconciliation",
|
|
434
|
+
purpose: "Repository synchronization",
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
path: "src/integrations/github/IntegrationView.tsx",
|
|
438
|
+
role: "module-ui",
|
|
439
|
+
purpose: "Repository connection experience",
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
path: "src/integrations/github/module.test.ts",
|
|
443
|
+
role: "module-contract-test",
|
|
444
|
+
purpose: "Module contract test",
|
|
445
|
+
},
|
|
446
|
+
],
|
|
447
|
+
};
|
|
448
|
+
const definitions = new Map();
|
|
449
|
+
export function validateFeltDBModule(module) {
|
|
450
|
+
const errors = [];
|
|
451
|
+
for (const key of ["id", "name", "version", "provider"])
|
|
452
|
+
if (!module[key])
|
|
453
|
+
errors.push(`missing:${key}`);
|
|
454
|
+
for (const name of [
|
|
455
|
+
"compatibility",
|
|
456
|
+
"models",
|
|
457
|
+
"relationships",
|
|
458
|
+
"events",
|
|
459
|
+
"workflows",
|
|
460
|
+
"capabilities",
|
|
461
|
+
"configuration",
|
|
462
|
+
"secrets",
|
|
463
|
+
"authorization",
|
|
464
|
+
"dependencies",
|
|
465
|
+
"patterns",
|
|
466
|
+
"reconciliation",
|
|
467
|
+
"source_artifacts",
|
|
468
|
+
])
|
|
469
|
+
if (!Array.isArray(module[name]))
|
|
470
|
+
errors.push(`missing:${name}`);
|
|
471
|
+
for (const item of module.models ?? [])
|
|
472
|
+
if (![
|
|
473
|
+
"external-authoritative",
|
|
474
|
+
"application-authoritative",
|
|
475
|
+
"derived",
|
|
476
|
+
"synchronized",
|
|
477
|
+
].includes(item.ownership))
|
|
478
|
+
errors.push(`invalid_ownership:${item.name}`);
|
|
479
|
+
if (!module.placement?.owner_claim ||
|
|
480
|
+
!module.placement?.primary_application_model ||
|
|
481
|
+
!module.placement?.owner_field)
|
|
482
|
+
errors.push("missing:placement");
|
|
483
|
+
for (const pattern of module.patterns ?? [])
|
|
484
|
+
for (const applicationModel of pattern.application_models)
|
|
485
|
+
if (!applicationModel.fields?.length)
|
|
486
|
+
errors.push(`missing_fields:${applicationModel.name}`);
|
|
487
|
+
const modelNames = new Set((module.models ?? []).map(value => value.name));
|
|
488
|
+
for (const relationship of module.relationships ?? []) {
|
|
489
|
+
if (!modelNames.has(relationship.from))
|
|
490
|
+
errors.push(`unknown_relationship_model:${relationship.from}`);
|
|
491
|
+
if (!modelNames.has(relationship.to))
|
|
492
|
+
errors.push(`unknown_relationship_model:${relationship.to}`);
|
|
493
|
+
}
|
|
494
|
+
const events = new Set(module.events ?? []);
|
|
495
|
+
const workflows = new Set(module.workflows ?? []);
|
|
496
|
+
const capabilities = new Set(module.capabilities ?? []);
|
|
497
|
+
for (const reconciliation of module.reconciliation ?? []) {
|
|
498
|
+
if (!events.has(reconciliation.event))
|
|
499
|
+
errors.push(`undeclared_reconciliation_event:${reconciliation.event}`);
|
|
500
|
+
if (!workflows.has(reconciliation.workflow))
|
|
501
|
+
errors.push(`undeclared_reconciliation_workflow:${reconciliation.workflow}`);
|
|
502
|
+
}
|
|
503
|
+
for (const authorization of module.authorization ?? [])
|
|
504
|
+
if (!capabilities.has(authorization.capability))
|
|
505
|
+
errors.push(`undeclared_authorization_capability:${authorization.capability}`);
|
|
506
|
+
for (const secret of module.secrets ?? [])
|
|
507
|
+
if (secret.visibility === 'browser' || secret.name.startsWith('VITE_'))
|
|
508
|
+
errors.push(`browser_secret:${secret.name}`);
|
|
509
|
+
const sourceRoles = new Set(['module-domain', 'module-provider-boundary', 'module-reconciliation', 'module-ui', 'module-contract-test']);
|
|
510
|
+
for (const artifact of module.source_artifacts ?? [])
|
|
511
|
+
if (!artifact.path.startsWith(`src/integrations/${module.id}/`) || !sourceRoles.has(artifact.role))
|
|
512
|
+
errors.push(`invalid_source_artifact:${artifact.path}`);
|
|
513
|
+
return [...new Set(errors)];
|
|
514
|
+
}
|
|
515
|
+
export function registerFeltDBModule(module) {
|
|
516
|
+
const errors = validateFeltDBModule(module);
|
|
517
|
+
if (errors.length)
|
|
518
|
+
throw new Error(`MODULE_CONFORMANCE_FAILED: ${errors.join(", ")}`);
|
|
519
|
+
if (definitions.has(module.id))
|
|
520
|
+
throw new Error(`MODULE_ALREADY_REGISTERED: ${module.id}`);
|
|
521
|
+
definitions.set(module.id, structuredClone(module));
|
|
522
|
+
return () => {
|
|
523
|
+
definitions.delete(module.id);
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
registerFeltDBModule(stripe);
|
|
527
|
+
registerFeltDBModule(github);
|
|
528
|
+
export function listFeltDBModules() {
|
|
529
|
+
return [...definitions.values()]
|
|
530
|
+
.map((value) => structuredClone(value))
|
|
531
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
532
|
+
}
|
|
44
533
|
export function resolveFeltDBModule(declaration) {
|
|
45
534
|
const definition = definitions.get(declaration.name);
|
|
46
535
|
if (!definition)
|
|
@@ -53,9 +542,25 @@ export function resolveFeltDBModule(declaration) {
|
|
|
53
542
|
}
|
|
54
543
|
export function findFeltDBModules(query) {
|
|
55
544
|
const normalized = query.trim().toLowerCase();
|
|
56
|
-
return listFeltDBModules().filter(module => module.id === normalized ||
|
|
545
|
+
return listFeltDBModules().filter((module) => module.id === normalized ||
|
|
546
|
+
module.name.toLowerCase().includes(normalized) ||
|
|
547
|
+
module.compatibility.some((value) => value.includes(normalized)) ||
|
|
548
|
+
module.intent_keywords.includes(normalized));
|
|
549
|
+
}
|
|
550
|
+
export function resolveFeltDBModules(declarations = []) {
|
|
551
|
+
return declarations
|
|
552
|
+
.map(resolveFeltDBModule)
|
|
553
|
+
.sort((a, b) => a.id.localeCompare(b.id));
|
|
57
554
|
}
|
|
58
|
-
export function
|
|
59
|
-
|
|
60
|
-
|
|
555
|
+
export function validateResolvedModules(modules, environment = "development") {
|
|
556
|
+
return modules.flatMap((module) => [
|
|
557
|
+
...validateFeltDBModule(module).map((value) => `${module.id}: ${value}`),
|
|
558
|
+
...module.secrets
|
|
559
|
+
.filter((value) => value.required &&
|
|
560
|
+
(!value.environments || value.environments.includes(environment)))
|
|
561
|
+
.map((value) => `${value.name} is required in ${environment} runtime configuration`),
|
|
562
|
+
...module.capabilities
|
|
563
|
+
.filter((value) => value.endsWith(".create"))
|
|
564
|
+
.map((value) => `${value} requires an explicit authorization policy`),
|
|
565
|
+
]);
|
|
61
566
|
}
|
package/dist/proposal.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import { type FeltDBContractSnapshot } from './application-development.js';
|
|
2
|
+
import { type ApplicationUnderstanding, type ObservedEvidenceInput } from './application-understanding.js';
|
|
2
3
|
export declare const FELTDB_PROPOSAL_COLLECTION = "_feltdb.Proposal";
|
|
3
4
|
export declare const FELTDB_PROPOSAL_EVENT_COLLECTION = "_feltdb.ProposalEvent";
|
|
4
5
|
export declare const FELTDB_PROPOSAL_PREVIEW_COLLECTION = "_feltdb.ProposalPreview";
|
|
6
|
+
export declare const FELTDB_CONVERGENCE_COLLECTION = "_feltdb.Convergence";
|
|
5
7
|
export declare const FELTDB_PROPOSAL_VERSION = 1;
|
|
6
8
|
export type ProposalStatus = 'proposed' | 'validated' | 'previewed' | 'approved' | 'applied' | 'rejected' | 'expired';
|
|
7
9
|
export interface ProposalSourceOperation {
|
|
8
10
|
path: string;
|
|
9
11
|
operation: 'add' | 'modify' | 'delete';
|
|
12
|
+
role?: string;
|
|
10
13
|
}
|
|
11
14
|
export interface FeltDBProposalRecord {
|
|
12
15
|
id: string;
|
|
@@ -43,6 +46,9 @@ export interface FeltDBProposalRecord {
|
|
|
43
46
|
provider: string;
|
|
44
47
|
version: string;
|
|
45
48
|
}[];
|
|
49
|
+
evidence_hash?: string;
|
|
50
|
+
understanding_hash?: string;
|
|
51
|
+
understanding?: ApplicationUnderstanding;
|
|
46
52
|
module_impact: {
|
|
47
53
|
modules: string[];
|
|
48
54
|
models: string[];
|
|
@@ -69,7 +75,7 @@ export interface FeltDBProposalEvent {
|
|
|
69
75
|
export interface ProposalReadiness {
|
|
70
76
|
status: ProposalStatus;
|
|
71
77
|
readiness: 'ready' | 'blocked';
|
|
72
|
-
blockers: ('contract_changed' | 'flow_changed' | 'module_versions_changed' | 'expired')[];
|
|
78
|
+
blockers: ('contract_changed' | 'flow_changed' | 'module_versions_changed' | 'evidence_changed' | 'expired')[];
|
|
73
79
|
notes: string[];
|
|
74
80
|
current_contract_hash: string;
|
|
75
81
|
proposal_contract_hash: string;
|
|
@@ -127,6 +133,7 @@ export interface ProposalStore {
|
|
|
127
133
|
export interface ProposalContext {
|
|
128
134
|
source: string;
|
|
129
135
|
snapshot: FeltDBContractSnapshot;
|
|
136
|
+
observations?: ObservedEvidenceInput[];
|
|
130
137
|
}
|
|
131
138
|
export declare class FeltDBProposalService {
|
|
132
139
|
private store;
|
|
@@ -145,6 +152,11 @@ export declare class FeltDBProposalService {
|
|
|
145
152
|
metadata?: Record<string, string>;
|
|
146
153
|
parent_proposal_id?: string;
|
|
147
154
|
expires_at?: string | number;
|
|
155
|
+
understanding?: ApplicationUnderstanding;
|
|
156
|
+
contract_diff?: string[];
|
|
157
|
+
source_plan?: {
|
|
158
|
+
files: ProposalSourceOperation[];
|
|
159
|
+
};
|
|
148
160
|
}): Promise<FeltDBProposalRecord>;
|
|
149
161
|
list(): Promise<FeltDBProposalRecord[]>;
|
|
150
162
|
get(id: string): Promise<FeltDBProposalRecord>;
|