@feltdb/core 0.7.2 → 0.7.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.
Files changed (96) hide show
  1. package/dist/application-development.d.ts +76 -0
  2. package/dist/application-development.d.ts.map +1 -0
  3. package/dist/application-development.js +137 -0
  4. package/dist/application-manifest.d.ts +5 -1
  5. package/dist/application-manifest.d.ts.map +1 -1
  6. package/dist/application-manifest.js +10 -3
  7. package/dist/canonical-application.d.ts +26 -0
  8. package/dist/canonical-application.d.ts.map +1 -0
  9. package/dist/canonical-application.js +45 -0
  10. package/dist/cli/ai-model-config.js +97 -0
  11. package/dist/cli/commands.js +485 -30
  12. package/dist/cli/index.js +1 -1
  13. package/dist/cli/proposal-client.js +54 -0
  14. package/dist/cli/publish-engine.js +162 -0
  15. package/dist/cli/source-sync.js +139 -0
  16. package/dist/create/cli.js +1 -1
  17. package/dist/create/create.js +30 -6
  18. package/dist/create/managed-account.js +14 -7
  19. package/dist/create/package-versions.js +1 -1
  20. package/dist/create/server-source/crates/feltdb/src/application.rs +31 -1
  21. package/dist/create/server-source/crates/feltdb/src/authority_failover.rs +847 -0
  22. package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +338 -29
  23. package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +72 -34
  24. package/dist/create/server-source/crates/feltdb/src/lib.rs +1 -0
  25. package/dist/create/server-source/crates/feltdb-server/src/identity.rs +46 -3
  26. package/dist/create/server-source/crates/feltdb-server/src/main.rs +315 -16
  27. package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +20 -0
  28. package/dist/create/template/default-project/README.md +57 -0
  29. package/dist/create/template/default-project/agents/activity-assistant.ts +18 -0
  30. package/dist/create/template/default-project/agents/project-assistant.ts +19 -0
  31. package/dist/create/template/default-project/capabilities/activity-summary.ts +14 -0
  32. package/dist/create/template/default-project/capabilities/project-search.ts +16 -0
  33. package/dist/create/template/default-project/capabilities/project-summary.ts +15 -0
  34. package/dist/create/template/default-project/feltdb.flow +169 -0
  35. package/dist/create/template/default-project/src/App.tsx +20 -0
  36. package/dist/create/template/default-project/src/context/AuthContext.tsx +27 -0
  37. package/dist/create/template/default-project/src/feltdb.ts +87 -0
  38. package/dist/create/template/default-project/src/index.tsx +14 -0
  39. package/dist/create/template/default-project/src/pages/Activity.tsx +7 -0
  40. package/dist/create/template/default-project/src/pages/Agents.tsx +15 -0
  41. package/dist/create/template/default-project/src/pages/Dashboard.tsx +17 -0
  42. package/dist/create/template/default-project/src/pages/Invitations.tsx +11 -0
  43. package/dist/create/template/default-project/src/pages/Projects.tsx +11 -0
  44. package/dist/create/template/default-project/src/pages/SignIn.tsx +8 -0
  45. package/dist/create/template/default-project/src/pages/SignUp.tsx +8 -0
  46. package/dist/create/template/default-project/src/styles-application.css +21 -0
  47. package/dist/create/template/default-project/src/styles.css +1 -0
  48. package/dist/create/template/default-project/workflows/agent-assisted-summary.ts +1 -0
  49. package/dist/create/template/default-project/workflows/invitation.ts +30 -0
  50. package/dist/create/template/default-project/workflows/project-created.ts +2 -0
  51. package/dist/db.d.ts +49 -1
  52. package/dist/db.d.ts.map +1 -1
  53. package/dist/db.js +77 -0
  54. package/dist/error-codes.d.ts +20 -1
  55. package/dist/error-codes.d.ts.map +1 -1
  56. package/dist/error-codes.js +25 -0
  57. package/dist/flowspec.d.ts.map +1 -1
  58. package/dist/flowspec.js +27 -6
  59. package/dist/http-db.d.ts +15 -2
  60. package/dist/http-db.d.ts.map +1 -1
  61. package/dist/http-db.js +113 -5
  62. package/dist/index-core.d.ts +3 -0
  63. package/dist/index-core.d.ts.map +1 -1
  64. package/dist/index-core.js +3 -0
  65. package/dist/proposal.d.ts +85 -0
  66. package/dist/proposal.d.ts.map +1 -0
  67. package/dist/proposal.js +105 -0
  68. package/dist/studio/app.d.ts +5 -1
  69. package/dist/studio/app.d.ts.map +1 -1
  70. package/dist/studio/components/ApplicationDesigner.d.ts +10 -1
  71. package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
  72. package/dist/studio/components/AskFeltDB.d.ts +20 -0
  73. package/dist/studio/components/AskFeltDB.d.ts.map +1 -0
  74. package/dist/studio/components/ProposalBrowser.d.ts +3 -0
  75. package/dist/studio/components/ProposalBrowser.d.ts.map +1 -0
  76. package/dist/studio/components/index.d.ts +2 -0
  77. package/dist/studio/components/index.d.ts.map +1 -1
  78. package/dist/studio/components/index.js +4 -4
  79. package/dist/studio/{components-C5p2TfIU.js → components-Bm4sjhcX.js} +531 -192
  80. package/dist/studio/index.js +184 -172
  81. package/dist/studio/studio.css +1 -1
  82. package/dist/studio-app/assets/dist-DA1MYSzp.js +1 -0
  83. package/dist/studio-app/assets/{feltdb_wasm-DVKsw75S.js → feltdb_wasm-B-Ccgccb.js} +1 -1
  84. package/dist/studio-app/assets/feltdb_wasm_bg-wH3enJIA.wasm +0 -0
  85. package/dist/studio-app/assets/{index-C1GWyazR.css → index-BRrmvaKw.css} +1 -1
  86. package/dist/studio-app/assets/index-CEIqowCh.js +42 -0
  87. package/dist/studio-app/assets/lib-B2_7fcn7.js +69 -0
  88. package/dist/studio-app/assets/worker-CARZ5g7K.js +69 -0
  89. package/dist/studio-app/index.html +2 -2
  90. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  91. package/dist/workspace/local-development-authority.d.ts +3 -0
  92. package/dist/workspace/local-development-authority.d.ts.map +1 -1
  93. package/dist/workspace/local-development-authority.js +62 -1
  94. package/package.json +1 -1
  95. package/dist/studio-app/assets/feltdb_wasm_bg-DNyNf0yy.wasm +0 -0
  96. package/dist/studio-app/assets/index-C71X92EK.js +0 -28
@@ -1094,22 +1094,25 @@ function R({ db: e, model: t, onSearch: r }) {
1094
1094
  //#endregion
1095
1095
  //#region src/components/ApplicationDesigner.tsx
1096
1096
  var z = f(d("Application"));
1097
- function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g }) {
1098
- let _ = `feltdb:studio:draft:${t}`, v = i((() => {
1097
+ function B({ db: e, namespace: t = "default", projectSpec: o, managedPublish: g, onSpecChange: _ }) {
1098
+ let v = `feltdb:studio:draft:${t}`, y = i((() => {
1099
1099
  if (typeof window > "u") return z;
1100
- let e = window.localStorage.getItem(_);
1100
+ let e = window.localStorage.getItem(v);
1101
1101
  if (!e) return z;
1102
1102
  try {
1103
1103
  return p(e), e;
1104
1104
  } catch {
1105
1105
  return z;
1106
1106
  }
1107
- })()), y = i(v.current !== z), [b, x] = a(v.current), [S, C] = a(() => p(v.current)), [w, T] = a([]), [E, D] = a([]), [O, k] = a("Draft is valid"), [A, j] = a(0), [M, N] = a(null), [P, F] = a(null), [I, L] = a(!1), [R, B] = a(!1), [V, H] = a({
1108
- url: "",
1109
- namespace: t,
1110
- token: "",
1107
+ })()), b = i(y.current !== z), [x, S] = a(y.current), [C, w] = a(() => p(y.current)), [T, E] = a([]), [D, O] = a([]), [k, A] = a("Draft is valid"), [j, M] = a(0), [N, P] = a(null), [F, I] = a(null), [L, R] = a(!1), [B, V] = a(!1), [H, U] = a(() => ({
1108
+ url: g?.url || "",
1109
+ namespace: g?.namespace || t,
1110
+ token: g?.token || "",
1111
+ environment: g?.environment,
1112
+ applicationId: g?.applicationId,
1113
+ publishEndpoint: g?.publishEndpoint,
1111
1114
  allowDestructive: !1
1112
- }), U = i(null), W = E.length ? E[E.length - 1].source : f(d(S.app)), G = r(() => u(p(W), S), [W, S]), K = r(() => m(p(W), S), [W, S]);
1115
+ })), W = i(null), G = D.length ? D[D.length - 1].source : f(d(C.app)), K = r(() => u(p(G), C), [G, C]), q = r(() => m(p(G), C), [G, C]);
1113
1116
  n(() => {
1114
1117
  if (!e || o) return;
1115
1118
  let t = !1;
@@ -1118,76 +1121,76 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1118
1121
  let n = await e.collection("_flow_apps").all(), r = n.find((e) => e.status === "active") ?? n[0];
1119
1122
  if (!r || t) return;
1120
1123
  let i = f(r.spec);
1121
- y.current || (C(r.spec), x(i)), j(r.version ?? 0);
1124
+ b.current || (w(r.spec), S(i)), M(r.version ?? 0);
1122
1125
  let a = (await e.collection("_flow_app_versions").all()).filter((e) => e.app === r.app).sort((e, t) => e.version - t.version);
1123
- t || (D(a.map((e) => ({
1126
+ t || (O(a.map((e) => ({
1124
1127
  version: e.version,
1125
1128
  source: f(e.spec),
1126
1129
  savedAt: e.deployed_at
1127
- }))), k(`Loaded ${r.app} v${r.version}`));
1130
+ }))), A(`Loaded ${r.app} v${r.version}`));
1128
1131
  } catch (e) {
1129
- t || k(`Could not load deployed model: ${e instanceof Error ? e.message : String(e)}`);
1132
+ t || A(`Could not load deployed model: ${e instanceof Error ? e.message : String(e)}`);
1130
1133
  }
1131
1134
  })(), () => {
1132
1135
  t = !0;
1133
1136
  };
1134
1137
  }, [e, o]), n(() => {
1135
- let e = window.setTimeout(() => window.localStorage.setItem(_, b), 200);
1138
+ let e = window.setTimeout(() => window.localStorage.setItem(v, x), 200);
1136
1139
  return () => window.clearTimeout(e);
1137
- }, [_, b]);
1138
- let q = (e) => {
1139
- x(e);
1140
+ }, [v, x]);
1141
+ let J = (e) => {
1142
+ S(e);
1140
1143
  try {
1141
1144
  let t = p(e), n = h(t);
1142
- C(t), g?.(t), T(n), k(n.some((e) => e.severity === "error") ? "Model has validation errors" : "Draft is valid");
1145
+ w(t), _?.(t), E(n), A(n.some((e) => e.severity === "error") ? "Model has validation errors" : "Draft is valid");
1143
1146
  } catch (e) {
1144
- T([{
1147
+ E([{
1145
1148
  severity: "error",
1146
1149
  message: e instanceof Error ? e.message : String(e)
1147
- }]), k("DSL parse failed");
1150
+ }]), A("DSL parse failed");
1148
1151
  }
1149
1152
  };
1150
1153
  n(() => {
1151
1154
  if (!o) return;
1152
1155
  let e = f(o);
1153
- x(e), C(o), T(h(o)), k(`Loaded ${o.app} project model`);
1156
+ S(e), w(o), E(h(o)), A(`Loaded ${o.app} project model`);
1154
1157
  }, [o]);
1155
- let J = (e) => {
1156
- C(e), q(f(e));
1157
- }, Y = () => {
1158
- if (!P) return F({ name: "" });
1159
- let e = P.name.trim();
1160
- if (!/^[A-Z][A-Za-z0-9_]*$/.test(e)) return F({
1161
- ...P,
1158
+ let Y = (e) => {
1159
+ w(e), J(f(e));
1160
+ }, X = () => {
1161
+ if (!F) return I({ name: "" });
1162
+ let e = F.name.trim();
1163
+ if (!/^[A-Z][A-Za-z0-9_]*$/.test(e)) return I({
1164
+ ...F,
1162
1165
  error: "Use a capitalized name with no spaces."
1163
1166
  });
1164
- if (S.collections.some((t) => t.name === e)) return F({
1165
- ...P,
1167
+ if (C.collections.some((t) => t.name === e)) return I({
1168
+ ...F,
1166
1169
  error: "That collection already exists."
1167
1170
  });
1168
- J({
1169
- ...S,
1170
- collections: [...S.collections, {
1171
+ Y({
1172
+ ...C,
1173
+ collections: [...C.collections, {
1171
1174
  name: e,
1172
1175
  fields: [],
1173
1176
  indexes: []
1174
1177
  }]
1175
- }), F(null);
1176
- }, X = (e) => N({
1178
+ }), I(null);
1179
+ }, Z = (e) => P({
1177
1180
  collection: e,
1178
1181
  name: "",
1179
1182
  type: "text",
1180
1183
  reference: "",
1181
1184
  optional: !1
1182
- }), Z = () => {
1183
- if (!M) return;
1184
- let e = M.name.trim(), t = S.collections.find((e) => e.name === M.collection);
1185
- if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)) return N({
1186
- ...M,
1185
+ }), Q = () => {
1186
+ if (!N) return;
1187
+ let e = N.name.trim(), t = C.collections.find((e) => e.name === N.collection);
1188
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)) return P({
1189
+ ...N,
1187
1190
  error: "Use a letter-led name with no spaces."
1188
1191
  });
1189
- if (t?.fields.some((t) => t.name === e)) return N({
1190
- ...M,
1192
+ if (t?.fields.some((t) => t.name === e)) return P({
1193
+ ...N,
1191
1194
  error: "That field already exists."
1192
1195
  });
1193
1196
  if ([
@@ -1196,101 +1199,131 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1196
1199
  "array",
1197
1200
  "map",
1198
1201
  "vector"
1199
- ].includes(M.type) && !M.reference.trim()) return N({
1200
- ...M,
1202
+ ].includes(N.type) && !N.reference.trim()) return P({
1203
+ ...N,
1201
1204
  error: "Configure this field type."
1202
1205
  });
1203
- let n = M.type === "ref" ? `ref ${M.reference}` : M.type === "enum" ? `enum(${M.reference.split(",").map((e) => e.trim()).filter(Boolean).join(",")})` : M.type === "array" ? `array<${M.reference.trim()}>` : M.type === "map" ? `map<${M.reference.trim()}>` : M.type === "vector" ? `vector<${M.reference.trim()}>` : M.type;
1204
- J({
1205
- ...S,
1206
- collections: S.collections.map((t) => t.name === M.collection ? {
1206
+ let n = N.type === "ref" ? `ref ${N.reference}` : N.type === "enum" ? `enum(${N.reference.split(",").map((e) => e.trim()).filter(Boolean).join(",")})` : N.type === "array" ? `array<${N.reference.trim()}>` : N.type === "map" ? `map<${N.reference.trim()}>` : N.type === "vector" ? `vector<${N.reference.trim()}>` : N.type;
1207
+ Y({
1208
+ ...C,
1209
+ collections: C.collections.map((t) => t.name === N.collection ? {
1207
1210
  ...t,
1208
1211
  fields: [...t.fields, {
1209
1212
  name: e,
1210
1213
  type: n,
1211
- optional: M.optional
1214
+ optional: N.optional
1212
1215
  }]
1213
1216
  } : t)
1214
- }), N(null);
1215
- }, Q = () => {
1216
- let e = [...E, {
1217
- version: E.length + 1,
1218
- source: b,
1217
+ }), P(null);
1218
+ }, $ = () => {
1219
+ let e = [...D, {
1220
+ version: D.length + 1,
1221
+ source: x,
1219
1222
  savedAt: Date.now()
1220
1223
  }];
1221
- D(e), k(`Saved local revision v${e.length}`);
1222
- }, $ = async () => {
1223
- if (!e) return k("Local embedded storage is unavailable");
1224
- if (w.some((e) => e.severity === "error")) return k("Resolve validation errors before deploying");
1225
- if (K.filter((e) => e.safety === "destructive").length && !I) return k("Review and approve destructive local changes before applying");
1224
+ O(e), A(`Saved local revision v${e.length}`);
1225
+ }, ee = async () => {
1226
+ if (!e) return A("Local embedded storage is unavailable");
1227
+ if (T.some((e) => e.severity === "error")) return A("Resolve validation errors before deploying");
1228
+ if (q.filter((e) => e.safety === "destructive").length && !L) return A("Review and approve destructive local changes before applying");
1226
1229
  try {
1227
- let t = await e.deployFlowSpec(S, A, I), n = [...E, {
1230
+ let t = await e.deployFlowSpec(C, j, L), n = [...D, {
1228
1231
  version: t.version,
1229
- source: b,
1232
+ source: x,
1230
1233
  savedAt: Date.now()
1231
1234
  }];
1232
- D(n), j(t.version), L(!1), k(`Applied locally as ${t.app} v${t.version}`);
1235
+ O(n), M(t.version), R(!1), A(`Applied locally as ${t.app} v${t.version}`);
1233
1236
  } catch (e) {
1234
- k(`Local apply failed: ${e instanceof Error ? e.message : String(e)}`);
1237
+ A(`Local apply failed: ${e instanceof Error ? e.message : String(e)}`);
1235
1238
  }
1236
- }, ee = async () => {
1237
- if (!V.url.trim() || !V.token.trim()) return H({
1238
- ...V,
1239
+ }, te = async () => {
1240
+ if (H.publishEndpoint) {
1241
+ U({
1242
+ ...H,
1243
+ publishing: !0,
1244
+ error: void 0
1245
+ });
1246
+ try {
1247
+ let e = await fetch(H.publishEndpoint, {
1248
+ method: "POST",
1249
+ headers: { "content-type": "application/json" },
1250
+ body: JSON.stringify({
1251
+ environment: H.environment,
1252
+ approveDestructive: H.allowDestructive
1253
+ })
1254
+ }), t = await e.json();
1255
+ if (!e.ok) throw Error(t.error || "Publish failed");
1256
+ U({
1257
+ ...H,
1258
+ publishing: !1,
1259
+ error: void 0
1260
+ }), V(!1), A(t.messages?.at(-1) || `Published immutable version ${t.version}`);
1261
+ return;
1262
+ } catch (e) {
1263
+ U({
1264
+ ...H,
1265
+ publishing: !1,
1266
+ error: e instanceof Error ? e.message : String(e)
1267
+ });
1268
+ return;
1269
+ }
1270
+ }
1271
+ if (!H.url.trim() || !H.token.trim()) return U({
1272
+ ...H,
1239
1273
  error: "Cloud URL and API key are required."
1240
1274
  });
1241
- if (w.some((e) => e.severity === "error")) return H({
1242
- ...V,
1275
+ if (T.some((e) => e.severity === "error")) return U({
1276
+ ...H,
1243
1277
  error: "Resolve validation errors before publishing."
1244
1278
  });
1245
- H({
1246
- ...V,
1279
+ U({
1280
+ ...H,
1247
1281
  publishing: !0,
1248
1282
  error: void 0
1249
1283
  });
1250
1284
  let e = l({
1251
- namespace: V.namespace.trim() || t,
1285
+ namespace: H.namespace.trim() || t,
1252
1286
  server: {
1253
- url: V.url.trim().replace(/\/$/, ""),
1254
- token: V.token
1287
+ url: H.url.trim().replace(/\/$/, ""),
1288
+ token: H.token
1255
1289
  }
1256
1290
  });
1257
1291
  try {
1258
- let t = await e.collection("_flow_apps").get(S.app), n = m(t?.spec ?? d(S.app), S).filter((e) => e.safety === "destructive");
1259
- if (n.length && !V.allowDestructive) return H({
1260
- ...V,
1292
+ let t = await e.collection("_flow_apps").get(C.app), n = m(t?.spec ?? d(C.app), C).filter((e) => e.safety === "destructive");
1293
+ if (n.length && !H.allowDestructive) return U({
1294
+ ...H,
1261
1295
  publishing: !1,
1262
1296
  destructive: n.map((e) => e.target),
1263
1297
  error: `Review and approve destructive changes: ${n.map((e) => e.target).join(", ")}`
1264
1298
  });
1265
- let r = await e.deployFlowSpec(S, t?.version ?? 0, V.allowDestructive);
1266
- window.sessionStorage.setItem(`feltdb-token:${V.url.trim()}`, V.token), H({
1267
- ...V,
1299
+ let r = await e.deployFlowSpec(C, t?.version ?? 0, H.allowDestructive);
1300
+ window.sessionStorage.setItem(`feltdb-token:${H.url.trim()}`, H.token), U({
1301
+ ...H,
1268
1302
  publishing: !1,
1269
- token: "",
1270
1303
  error: void 0
1271
- }), B(!1), k(`Published ${r.app} v${r.version} to cloud`);
1304
+ }), V(!1), A(`Published ${r.app} v${r.version} to ${H.environment || "cloud"}`);
1272
1305
  } catch (e) {
1273
- H({
1274
- ...V,
1306
+ U({
1307
+ ...H,
1275
1308
  publishing: !1,
1276
1309
  error: e instanceof Error ? e.message : String(e)
1277
1310
  });
1278
1311
  } finally {
1279
1312
  await e.close();
1280
1313
  }
1281
- }, te = () => {
1282
- let e = URL.createObjectURL(new Blob([b], { type: "text/plain" })), t = document.createElement("a");
1314
+ }, ne = () => {
1315
+ let e = URL.createObjectURL(new Blob([x], { type: "text/plain" })), t = document.createElement("a");
1283
1316
  t.href = e, t.download = "feltdb.flow", t.click(), URL.revokeObjectURL(e);
1284
- }, ne = async (e) => {
1285
- e && q(await e.text());
1286
- }, re = [
1287
- ["Data", S.collections.map((e) => e.name)],
1288
- ["Capabilities", S.capabilities.map((e) => e.name)],
1289
- ["Agents", S.agents.map((e) => e.name)],
1290
- ["Workflows", S.workflows.map((e) => e.name)],
1291
- ["Triggers", S.triggers.map((e) => e.event)],
1292
- ["Policies", S.policies.map((e) => e.name)],
1293
- ["Schedules", S.schedules.map((e) => e.name)]
1317
+ }, re = async (e) => {
1318
+ e && J(await e.text());
1319
+ }, ie = [
1320
+ ["Data", C.collections.map((e) => e.name)],
1321
+ ["Capabilities", C.capabilities.map((e) => e.name)],
1322
+ ["Agents", C.agents.map((e) => e.name)],
1323
+ ["Workflows", C.workflows.map((e) => e.name)],
1324
+ ["Triggers", C.triggers.map((e) => e.event)],
1325
+ ["Policies", C.policies.map((e) => e.name)],
1326
+ ["Schedules", C.schedules.map((e) => e.name)]
1294
1327
  ];
1295
1328
  return /* @__PURE__ */ c("div", {
1296
1329
  className: "application-designer",
@@ -1302,58 +1335,58 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1302
1335
  className: "eyebrow",
1303
1336
  children: "Application fabric"
1304
1337
  }),
1305
- /* @__PURE__ */ s("h1", { children: S.app }),
1338
+ /* @__PURE__ */ s("h1", { children: C.app }),
1306
1339
  /* @__PURE__ */ s("p", { children: "One model for state, intelligence, automation, security, and placement." })
1307
1340
  ] }), /* @__PURE__ */ c("div", {
1308
1341
  className: "designer-actions",
1309
1342
  children: [
1310
1343
  /* @__PURE__ */ s("input", {
1311
- ref: U,
1344
+ ref: W,
1312
1345
  hidden: !0,
1313
1346
  type: "file",
1314
1347
  accept: ".flow,text/plain",
1315
- onChange: (e) => void ne(e.target.files?.[0])
1348
+ onChange: (e) => void re(e.target.files?.[0])
1316
1349
  }),
1317
1350
  /* @__PURE__ */ s("button", {
1318
1351
  className: "btn btn-ghost",
1319
- onClick: () => U.current?.click(),
1352
+ onClick: () => W.current?.click(),
1320
1353
  children: "Import"
1321
1354
  }),
1322
1355
  /* @__PURE__ */ s("button", {
1323
1356
  className: "btn btn-ghost",
1324
- onClick: te,
1357
+ onClick: ne,
1325
1358
  children: "Export"
1326
1359
  }),
1327
1360
  /* @__PURE__ */ s("button", {
1328
1361
  className: "btn btn-ghost",
1329
- onClick: Q,
1362
+ onClick: $,
1330
1363
  children: "Version"
1331
1364
  }),
1332
1365
  /* @__PURE__ */ s("button", {
1333
1366
  className: "btn btn-ghost",
1334
- onClick: () => void $(),
1367
+ onClick: () => void ee(),
1335
1368
  children: "Apply locally"
1336
1369
  }),
1337
1370
  /* @__PURE__ */ s("button", {
1338
1371
  className: "btn btn-primary",
1339
- onClick: () => B((e) => !e),
1372
+ onClick: () => V((e) => !e),
1340
1373
  children: "Publish to cloud"
1341
1374
  })
1342
1375
  ]
1343
1376
  })]
1344
1377
  }),
1345
- K.some((e) => e.safety === "destructive") && /* @__PURE__ */ c("label", {
1378
+ q.some((e) => e.safety === "destructive") && /* @__PURE__ */ c("label", {
1346
1379
  className: "local-destructive",
1347
1380
  children: [/* @__PURE__ */ s("input", {
1348
1381
  type: "checkbox",
1349
- checked: I,
1350
- onChange: (e) => L(e.target.checked)
1351
- }), /* @__PURE__ */ c("span", { children: ["Approve destructive local changes: ", K.filter((e) => e.safety === "destructive").map((e) => e.target).join(", ")] })]
1382
+ checked: L,
1383
+ onChange: (e) => R(e.target.checked)
1384
+ }), /* @__PURE__ */ c("span", { children: ["Approve destructive local changes: ", q.filter((e) => e.safety === "destructive").map((e) => e.target).join(", ")] })]
1352
1385
  }),
1353
- R && /* @__PURE__ */ c("form", {
1386
+ B && /* @__PURE__ */ c("form", {
1354
1387
  className: "cloud-publisher",
1355
1388
  onSubmit: (e) => {
1356
- e.preventDefault(), ee();
1389
+ e.preventDefault(), te();
1357
1390
  },
1358
1391
  children: [
1359
1392
  /* @__PURE__ */ c("div", {
@@ -1363,12 +1396,12 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1363
1396
  className: "eyebrow",
1364
1397
  children: "Cloud release"
1365
1398
  }),
1366
- /* @__PURE__ */ s("h2", { children: "Publish this application model" }),
1367
- /* @__PURE__ */ s("p", { children: "FeltDB compares the cloud version, plans the migration, and publishes atomically." })
1399
+ /* @__PURE__ */ s("h2", { children: "Publish this application definition" }),
1400
+ /* @__PURE__ */ s("p", { children: "FeltDB validates an immutable revision and atomically promotes the environment." })
1368
1401
  ] }), /* @__PURE__ */ s("button", {
1369
1402
  type: "button",
1370
1403
  "aria-label": "Close cloud publisher",
1371
- onClick: () => B(!1),
1404
+ onClick: () => V(!1),
1372
1405
  children: "×"
1373
1406
  })]
1374
1407
  }),
@@ -1377,10 +1410,10 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1377
1410
  children: [
1378
1411
  /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "FeltDB Cloud URL" }), /* @__PURE__ */ s("input", {
1379
1412
  type: "url",
1380
- placeholder: "https://your-instance.feltdb.cloud",
1381
- value: V.url,
1382
- onChange: (e) => H({
1383
- ...V,
1413
+ value: H.url,
1414
+ readOnly: !!H.publishEndpoint,
1415
+ onChange: (e) => U({
1416
+ ...H,
1384
1417
  url: e.target.value,
1385
1418
  error: void 0,
1386
1419
  destructive: void 0,
@@ -1388,68 +1421,77 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1388
1421
  })
1389
1422
  })] }),
1390
1423
  /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Namespace" }), /* @__PURE__ */ s("input", {
1391
- value: V.namespace,
1392
- onChange: (e) => H({
1393
- ...V,
1424
+ value: H.namespace,
1425
+ readOnly: !!H.publishEndpoint,
1426
+ onChange: (e) => U({
1427
+ ...H,
1394
1428
  namespace: e.target.value,
1395
1429
  error: void 0,
1396
1430
  destructive: void 0,
1397
1431
  allowDestructive: !1
1398
1432
  })
1399
1433
  })] }),
1400
- /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "API key" }), /* @__PURE__ */ s("input", {
1434
+ !H.publishEndpoint && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "API key" }), /* @__PURE__ */ s("input", {
1401
1435
  type: "password",
1402
1436
  autoComplete: "off",
1403
- placeholder: "Stored for this browser session only",
1404
- value: V.token,
1405
- onChange: (e) => H({
1406
- ...V,
1437
+ placeholder: "Loaded securely from this project",
1438
+ value: H.token,
1439
+ onChange: (e) => U({
1440
+ ...H,
1407
1441
  token: e.target.value,
1408
1442
  error: void 0
1409
1443
  })
1444
+ })] }),
1445
+ H.environment && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Environment" }), /* @__PURE__ */ s("input", {
1446
+ value: H.environment,
1447
+ readOnly: !0
1448
+ })] }),
1449
+ H.applicationId && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Application" }), /* @__PURE__ */ s("input", {
1450
+ value: H.applicationId,
1451
+ readOnly: !0
1410
1452
  })] })
1411
1453
  ]
1412
1454
  }),
1413
- (V.destructive?.length || K.some((e) => e.safety === "destructive")) && /* @__PURE__ */ c("label", {
1455
+ (H.destructive?.length || q.some((e) => e.safety === "destructive")) && /* @__PURE__ */ c("label", {
1414
1456
  className: "cloud-destructive",
1415
1457
  children: [/* @__PURE__ */ s("input", {
1416
1458
  type: "checkbox",
1417
- checked: V.allowDestructive,
1418
- onChange: (e) => H({
1419
- ...V,
1459
+ checked: H.allowDestructive,
1460
+ onChange: (e) => U({
1461
+ ...H,
1420
1462
  allowDestructive: e.target.checked
1421
1463
  })
1422
- }), /* @__PURE__ */ c("span", { children: ["I reviewed and approve destructive model changes", V.destructive?.length ? `: ${V.destructive.join(", ")}` : "."] })]
1464
+ }), /* @__PURE__ */ c("span", { children: ["I reviewed and approve destructive model changes", H.destructive?.length ? `: ${H.destructive.join(", ")}` : "."] })]
1423
1465
  }),
1424
- V.error && /* @__PURE__ */ s("div", {
1466
+ H.error && /* @__PURE__ */ s("div", {
1425
1467
  className: "cloud-error",
1426
1468
  role: "alert",
1427
- children: V.error
1469
+ children: H.error
1428
1470
  }),
1429
1471
  /* @__PURE__ */ c("div", {
1430
1472
  className: "cloud-actions",
1431
1473
  children: [/* @__PURE__ */ s("button", {
1432
1474
  type: "button",
1433
1475
  className: "btn btn-ghost",
1434
- onClick: () => B(!1),
1476
+ onClick: () => V(!1),
1435
1477
  children: "Cancel"
1436
1478
  }), /* @__PURE__ */ s("button", {
1437
1479
  className: "btn btn-primary",
1438
- disabled: V.publishing,
1480
+ disabled: H.publishing,
1439
1481
  type: "submit",
1440
- children: V.publishing ? "Publishing…" : "Review and publish"
1482
+ children: H.publishing ? "Publishing…" : "Review and publish"
1441
1483
  })]
1442
1484
  })
1443
1485
  ]
1444
1486
  }),
1445
1487
  /* @__PURE__ */ c("div", {
1446
- className: `designer-status ${w.some((e) => e.severity === "error") ? "error" : ""}`,
1447
- children: [/* @__PURE__ */ s("span", { children: O }), /* @__PURE__ */ c("span", { children: [
1448
- S.collections.length,
1488
+ className: `designer-status ${T.some((e) => e.severity === "error") ? "error" : ""}`,
1489
+ children: [/* @__PURE__ */ s("span", { children: k }), /* @__PURE__ */ c("span", { children: [
1490
+ C.collections.length,
1449
1491
  " collections · ",
1450
- S.workflows.length,
1492
+ C.workflows.length,
1451
1493
  " workflows · ",
1452
- E.length ? `v${E.length}` : "draft"
1494
+ D.length ? `v${D.length}` : "draft"
1453
1495
  ] })]
1454
1496
  }),
1455
1497
  /* @__PURE__ */ c("div", {
@@ -1462,33 +1504,33 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1462
1504
  className: "panel-title",
1463
1505
  children: [/* @__PURE__ */ s("span", { children: "Application" }), /* @__PURE__ */ s("button", {
1464
1506
  "aria-label": "Add collection",
1465
- onClick: () => F({ name: "" }),
1507
+ onClick: () => I({ name: "" }),
1466
1508
  children: "+"
1467
1509
  })]
1468
1510
  }),
1469
- P && /* @__PURE__ */ c("form", {
1511
+ F && /* @__PURE__ */ c("form", {
1470
1512
  className: "collection-editor",
1471
1513
  onSubmit: (e) => {
1472
- e.preventDefault(), Y();
1514
+ e.preventDefault(), X();
1473
1515
  },
1474
1516
  onKeyDown: (e) => {
1475
- e.key === "Escape" && F(null);
1517
+ e.key === "Escape" && I(null);
1476
1518
  },
1477
1519
  children: [
1478
1520
  /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "New collection" }), /* @__PURE__ */ s("input", {
1479
1521
  autoFocus: !0,
1480
1522
  placeholder: "e.g. Customer",
1481
- value: P.name,
1482
- onChange: (e) => F({ name: e.target.value })
1523
+ value: F.name,
1524
+ onChange: (e) => I({ name: e.target.value })
1483
1525
  })] }),
1484
- P.error && /* @__PURE__ */ s("div", {
1526
+ F.error && /* @__PURE__ */ s("div", {
1485
1527
  className: "field-error",
1486
1528
  role: "alert",
1487
- children: P.error
1529
+ children: F.error
1488
1530
  }),
1489
1531
  /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("button", {
1490
1532
  type: "button",
1491
- onClick: () => F(null),
1533
+ onClick: () => I(null),
1492
1534
  children: "Cancel"
1493
1535
  }), /* @__PURE__ */ s("button", {
1494
1536
  className: "collection-save",
@@ -1497,7 +1539,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1497
1539
  })] })
1498
1540
  ]
1499
1541
  }),
1500
- re.map(([e, t]) => /* @__PURE__ */ c("section", { children: [/* @__PURE__ */ s("h3", { children: e }), t.length ? t.map((e) => /* @__PURE__ */ s("div", {
1542
+ ie.map(([e, t]) => /* @__PURE__ */ c("section", { children: [/* @__PURE__ */ s("h3", { children: e }), t.length ? t.map((e) => /* @__PURE__ */ s("div", {
1501
1543
  className: "tree-item",
1502
1544
  children: e
1503
1545
  }, e)) : /* @__PURE__ */ s("div", {
@@ -1519,7 +1561,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1519
1561
  /* @__PURE__ */ c("div", {
1520
1562
  className: "graph-board",
1521
1563
  children: [
1522
- S.collections.map((e) => /* @__PURE__ */ c("article", {
1564
+ C.collections.map((e) => /* @__PURE__ */ c("article", {
1523
1565
  className: "model-node",
1524
1566
  children: [
1525
1567
  /* @__PURE__ */ s("div", {
@@ -1531,21 +1573,21 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1531
1573
  className: "node-field",
1532
1574
  children: [/* @__PURE__ */ s("span", { children: e.name }), /* @__PURE__ */ c("code", { children: [e.type, e.optional ? "?" : ""] })]
1533
1575
  }, e.name)),
1534
- M?.collection === e.name ? /* @__PURE__ */ c("form", {
1576
+ N?.collection === e.name ? /* @__PURE__ */ c("form", {
1535
1577
  className: "field-editor",
1536
1578
  onSubmit: (e) => {
1537
- e.preventDefault(), Z();
1579
+ e.preventDefault(), Q();
1538
1580
  },
1539
1581
  onKeyDown: (e) => {
1540
- e.key === "Escape" && N(null);
1582
+ e.key === "Escape" && P(null);
1541
1583
  },
1542
1584
  children: [
1543
1585
  /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Field name" }), /* @__PURE__ */ s("input", {
1544
1586
  autoFocus: !0,
1545
- value: M.name,
1587
+ value: N.name,
1546
1588
  placeholder: "e.g. publishedAt",
1547
- onChange: (e) => N({
1548
- ...M,
1589
+ onChange: (e) => P({
1590
+ ...N,
1549
1591
  name: e.target.value,
1550
1592
  error: void 0
1551
1593
  })
@@ -1554,9 +1596,9 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1554
1596
  className: "field-editor-row",
1555
1597
  children: [
1556
1598
  /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Type" }), /* @__PURE__ */ c("select", {
1557
- value: M.type,
1558
- onChange: (e) => N({
1559
- ...M,
1599
+ value: N.type,
1600
+ onChange: (e) => P({
1601
+ ...N,
1560
1602
  type: e.target.value,
1561
1603
  error: void 0
1562
1604
  }),
@@ -1659,43 +1701,43 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1659
1701
  })
1660
1702
  ]
1661
1703
  })] }),
1662
- M.type === "ref" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Collection" }), /* @__PURE__ */ s("select", {
1663
- value: M.reference,
1664
- onChange: (e) => N({
1665
- ...M,
1704
+ N.type === "ref" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Collection" }), /* @__PURE__ */ s("select", {
1705
+ value: N.reference,
1706
+ onChange: (e) => P({
1707
+ ...N,
1666
1708
  reference: e.target.value,
1667
1709
  error: void 0
1668
1710
  }),
1669
- children: S.collections.filter((t) => t.name !== e.name).map((e) => /* @__PURE__ */ s("option", {
1711
+ children: C.collections.filter((t) => t.name !== e.name).map((e) => /* @__PURE__ */ s("option", {
1670
1712
  value: e.name,
1671
1713
  children: e.name
1672
1714
  }, e.name))
1673
1715
  })] }),
1674
- M.type === "enum" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Values" }), /* @__PURE__ */ s("input", {
1716
+ N.type === "enum" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Values" }), /* @__PURE__ */ s("input", {
1675
1717
  placeholder: "draft,active,done",
1676
- value: M.reference,
1677
- onChange: (e) => N({
1678
- ...M,
1718
+ value: N.reference,
1719
+ onChange: (e) => P({
1720
+ ...N,
1679
1721
  reference: e.target.value,
1680
1722
  error: void 0
1681
1723
  })
1682
1724
  })] }),
1683
- (M.type === "array" || M.type === "map") && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Item type" }), /* @__PURE__ */ s("input", {
1725
+ (N.type === "array" || N.type === "map") && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Item type" }), /* @__PURE__ */ s("input", {
1684
1726
  placeholder: "text, uuid, ref Project…",
1685
- value: M.reference,
1686
- onChange: (e) => N({
1687
- ...M,
1727
+ value: N.reference,
1728
+ onChange: (e) => P({
1729
+ ...N,
1688
1730
  reference: e.target.value,
1689
1731
  error: void 0
1690
1732
  })
1691
1733
  })] }),
1692
- M.type === "vector" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Dimensions" }), /* @__PURE__ */ s("input", {
1734
+ N.type === "vector" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Dimensions" }), /* @__PURE__ */ s("input", {
1693
1735
  type: "number",
1694
1736
  min: "1",
1695
1737
  placeholder: "1536",
1696
- value: M.reference,
1697
- onChange: (e) => N({
1698
- ...M,
1738
+ value: N.reference,
1739
+ onChange: (e) => P({
1740
+ ...N,
1699
1741
  reference: e.target.value,
1700
1742
  error: void 0
1701
1743
  })
@@ -1706,23 +1748,23 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1706
1748
  className: "field-optional",
1707
1749
  children: [/* @__PURE__ */ s("input", {
1708
1750
  type: "checkbox",
1709
- checked: M.optional,
1710
- onChange: (e) => N({
1711
- ...M,
1751
+ checked: N.optional,
1752
+ onChange: (e) => P({
1753
+ ...N,
1712
1754
  optional: e.target.checked
1713
1755
  })
1714
1756
  }), /* @__PURE__ */ s("span", { children: "Optional field" })]
1715
1757
  }),
1716
- M.error && /* @__PURE__ */ s("div", {
1758
+ N.error && /* @__PURE__ */ s("div", {
1717
1759
  className: "field-error",
1718
1760
  role: "alert",
1719
- children: M.error
1761
+ children: N.error
1720
1762
  }),
1721
1763
  /* @__PURE__ */ c("div", {
1722
1764
  className: "field-editor-actions",
1723
1765
  children: [/* @__PURE__ */ s("button", {
1724
1766
  type: "button",
1725
- onClick: () => N(null),
1767
+ onClick: () => P(null),
1726
1768
  children: "Cancel"
1727
1769
  }), /* @__PURE__ */ s("button", {
1728
1770
  className: "field-save",
@@ -1733,12 +1775,12 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1733
1775
  ]
1734
1776
  }) : /* @__PURE__ */ s("button", {
1735
1777
  className: "node-add",
1736
- onClick: () => X(e.name),
1778
+ onClick: () => Z(e.name),
1737
1779
  children: "+ field"
1738
1780
  })
1739
1781
  ]
1740
1782
  }, e.name)),
1741
- S.workflows.map((e) => /* @__PURE__ */ c("article", {
1783
+ C.workflows.map((e) => /* @__PURE__ */ c("article", {
1742
1784
  className: "model-node workflow-node",
1743
1785
  children: [
1744
1786
  /* @__PURE__ */ s("div", {
@@ -1752,7 +1794,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1752
1794
  }, e.name))
1753
1795
  ]
1754
1796
  }, e.name)),
1755
- S.agents.map((e) => /* @__PURE__ */ c("article", {
1797
+ C.agents.map((e) => /* @__PURE__ */ c("article", {
1756
1798
  className: "model-node agent-node",
1757
1799
  children: [
1758
1800
  /* @__PURE__ */ s("div", {
@@ -1774,15 +1816,15 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1774
1816
  /* @__PURE__ */ s("strong", { children: "Model diff" }),
1775
1817
  /* @__PURE__ */ c("span", {
1776
1818
  className: "added",
1777
- children: ["+ ", G.added.join(", ") || "none"]
1819
+ children: ["+ ", K.added.join(", ") || "none"]
1778
1820
  }),
1779
1821
  /* @__PURE__ */ c("span", {
1780
1822
  className: "changed",
1781
- children: ["~ ", G.changed.join(", ") || "none"]
1823
+ children: ["~ ", K.changed.join(", ") || "none"]
1782
1824
  }),
1783
1825
  /* @__PURE__ */ c("span", {
1784
1826
  className: "removed",
1785
- children: ["− ", G.removed.join(", ") || "none"]
1827
+ children: ["− ", K.removed.join(", ") || "none"]
1786
1828
  })
1787
1829
  ]
1788
1830
  })
@@ -1798,12 +1840,12 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1798
1840
  /* @__PURE__ */ s("textarea", {
1799
1841
  "aria-label": "Flow DSL",
1800
1842
  spellCheck: !1,
1801
- value: b,
1802
- onChange: (e) => q(e.target.value)
1843
+ value: x,
1844
+ onChange: (e) => J(e.target.value)
1803
1845
  }),
1804
- w.length > 0 && /* @__PURE__ */ s("div", {
1846
+ T.length > 0 && /* @__PURE__ */ s("div", {
1805
1847
  className: "diagnostics",
1806
- children: w.map((e, t) => /* @__PURE__ */ c("div", {
1848
+ children: T.map((e, t) => /* @__PURE__ */ c("div", {
1807
1849
  className: e.severity,
1808
1850
  children: [
1809
1851
  e.severity,
@@ -1820,4 +1862,301 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1820
1862
  });
1821
1863
  }
1822
1864
  //#endregion
1823
- export { _, F as a, y as b, M as c, O as d, D as f, v as g, b as h, I as i, j as l, w as m, R as n, P as o, E as p, L as r, N as s, B as t, k as u, x as v, g as x, S as y };
1865
+ //#region src/components/AskFeltDB.tsx
1866
+ function V({ configuration: e, onApplied: t }) {
1867
+ let [n, r] = a(""), [i, l] = a(), [u, d] = a(), [f, m] = a(""), [h, g] = a(0), [_, v] = a(!1), [y, b] = a([]), x = typeof navigator < "u" && "gpu" in navigator, S = e?.aiModel?.provider === "openai-compatible", C = !!(e?.enabled && (S ? e.aiModel?.credentialConfigured : e.webllmEnabled && x)), w = async () => {
1868
+ if (!(!C || !e)) {
1869
+ m("Loading local model…"), d(void 0), l(void 0);
1870
+ try {
1871
+ let t = await fetch("/_feltdb/contract", { cache: "no-store" }), r = await t.json();
1872
+ if (!t.ok) throw Error(r.error || "Could not load contract");
1873
+ if (r.drift && !r.drift.synchronized) throw Error("Contract drift detected. Review feltdb status before generating.");
1874
+ let i;
1875
+ if (S) {
1876
+ m(`Asking ${e.aiModel?.model} through the local CLI…`);
1877
+ let t = await fetch("/_feltdb/ai/generate", {
1878
+ method: "POST",
1879
+ headers: {
1880
+ "content-type": "application/json",
1881
+ "x-feltdb-studio-token": e.token
1882
+ },
1883
+ body: JSON.stringify({ intent: n })
1884
+ }), r = await t.json();
1885
+ if (!t.ok) throw Error(r.error || "Configured model failed");
1886
+ i = r.proposal;
1887
+ } else {
1888
+ let { WebLLMProvider: t } = await import("@feltdb/webllm"), a = new t({
1889
+ model: e.aiModel?.model,
1890
+ contract: r.snapshot,
1891
+ onProgress: (e) => {
1892
+ g(e.progress), m(e.text);
1893
+ }
1894
+ });
1895
+ try {
1896
+ i = await a.generateFlow(n, { currentFlow: r.source });
1897
+ } finally {
1898
+ await a.shutdown();
1899
+ }
1900
+ }
1901
+ let a = await fetch("/_feltdb/proposals", {
1902
+ method: "POST",
1903
+ headers: {
1904
+ "content-type": "application/json",
1905
+ "x-feltdb-studio-token": e.token
1906
+ },
1907
+ body: JSON.stringify({ proposal: i })
1908
+ }), o = await a.json();
1909
+ if (!a.ok) throw Error(o.error || "Proposal validation failed");
1910
+ l(i), d(o), b(p(i.proposedFlow).collections.map((e) => ({
1911
+ name: e.name,
1912
+ fields: e.fields.map((e) => e.name)
1913
+ }))), m("Validated proposal ready for review");
1914
+ } catch (e) {
1915
+ m(e instanceof Error ? e.message : String(e));
1916
+ }
1917
+ }
1918
+ }, T = async (t) => {
1919
+ if (!(!u || !e)) {
1920
+ m(t === "approve" ? "Recording approval…" : "Rejecting preview…");
1921
+ try {
1922
+ let n = await fetch(`/_feltdb/proposals/${t}`, {
1923
+ method: "POST",
1924
+ headers: {
1925
+ "content-type": "application/json",
1926
+ "x-feltdb-studio-token": e.token
1927
+ },
1928
+ body: JSON.stringify({
1929
+ proposalId: u.proposalId,
1930
+ confirm: !0,
1931
+ approveAuthorization: _
1932
+ })
1933
+ }), r = await n.json();
1934
+ if (!n.ok) throw Error(r.error || "Proposal decision failed");
1935
+ t === "approve" ? m(`Approved. Run ${r.command} in your project to synchronize the repository.`) : (l(void 0), d(void 0), b([]), m("Preview rejected. The application and repository are unchanged."));
1936
+ } catch (e) {
1937
+ m(e instanceof Error ? e.message : String(e));
1938
+ }
1939
+ }
1940
+ };
1941
+ return /* @__PURE__ */ c("section", {
1942
+ className: "ask-feltdb",
1943
+ children: [
1944
+ /* @__PURE__ */ c("div", { children: [
1945
+ /* @__PURE__ */ s("span", {
1946
+ className: "eyebrow",
1947
+ children: "Contract-aware proposal engine"
1948
+ }),
1949
+ /* @__PURE__ */ s("h2", { children: "Ask FeltDB" }),
1950
+ /* @__PURE__ */ s("p", { children: "Describe a contract change. Your selected model proposes; FeltDB validates, and the CLI owns source synchronization." })
1951
+ ] }),
1952
+ /* @__PURE__ */ c("p", {
1953
+ className: "ai-model-choice",
1954
+ children: [
1955
+ "Model: ",
1956
+ /* @__PURE__ */ s("strong", { children: e?.aiModel?.model ?? "SmolLM2-360M-Instruct" }),
1957
+ " (",
1958
+ S ? "bring-your-own provider; credential held by CLI" : "private local WebLLM",
1959
+ "). Change it with ",
1960
+ /* @__PURE__ */ s("code", { children: "feltdb ai model set" }),
1961
+ "."
1962
+ ]
1963
+ }),
1964
+ S && !e?.aiModel?.credentialConfigured ? /* @__PURE__ */ c("p", {
1965
+ className: "ai-unavailable",
1966
+ children: [
1967
+ "The selected hosted model needs a credential. Pipe it securely with ",
1968
+ /* @__PURE__ */ s("code", { children: "printf %s \"$KEY\" | feltdb ai model set ... --api-key-stdin" }),
1969
+ "."
1970
+ ]
1971
+ }) : !S && !e?.webllmEnabled ? /* @__PURE__ */ c("p", {
1972
+ className: "ai-unavailable",
1973
+ children: [
1974
+ "Local AI is not enabled for this project. Install ",
1975
+ /* @__PURE__ */ s("code", { children: "@feltdb/webllm" }),
1976
+ " to opt in, or configure your own model with ",
1977
+ /* @__PURE__ */ s("code", { children: "feltdb ai model set" }),
1978
+ "."
1979
+ ]
1980
+ }) : !S && !x ? /* @__PURE__ */ s("p", {
1981
+ className: "ai-unavailable",
1982
+ children: "Local FeltDB AI is unavailable because WebGPU is not available. You can configure an OpenAI-compatible model instead."
1983
+ }) : /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("textarea", {
1984
+ "aria-label": "Ask FeltDB",
1985
+ value: n,
1986
+ onChange: (e) => r(e.target.value),
1987
+ placeholder: "Add invitations so organization owners can invite users."
1988
+ }), /* @__PURE__ */ s("button", {
1989
+ className: "btn btn-primary",
1990
+ disabled: !n.trim(),
1991
+ onClick: () => void w(),
1992
+ children: "Generate proposal"
1993
+ })] }),
1994
+ h > 0 && h < 1 && /* @__PURE__ */ s("progress", {
1995
+ value: h,
1996
+ max: 1
1997
+ }),
1998
+ " ",
1999
+ f && /* @__PURE__ */ s("p", {
2000
+ className: "ai-status",
2001
+ children: f
2002
+ }),
2003
+ i && u && /* @__PURE__ */ c("div", {
2004
+ className: "proposal-review",
2005
+ children: [
2006
+ /* @__PURE__ */ s("h3", { children: "Ephemeral application preview" }),
2007
+ /* @__PURE__ */ s("p", { children: i.summary }),
2008
+ /* @__PURE__ */ s("ul", { children: u.changes.map((e) => /* @__PURE__ */ s("li", { children: e }, e)) }),
2009
+ /* @__PURE__ */ c("div", {
2010
+ className: "proposal-app-preview",
2011
+ "aria-label": "Proposed application preview",
2012
+ children: [/* @__PURE__ */ s("nav", { children: y.map((e) => /* @__PURE__ */ s("span", { children: e.name }, e.name)) }), y.map((e) => /* @__PURE__ */ c("section", { children: [/* @__PURE__ */ s("strong", { children: e.name }), /* @__PURE__ */ s("small", { children: e.fields.join(" · ") || "No fields" })] }, e.name))]
2013
+ }),
2014
+ /* @__PURE__ */ c("p", { children: [
2015
+ /* @__PURE__ */ s("strong", { children: "Source impact" }),
2016
+ ": ",
2017
+ u.sourcePlan.join(", ")
2018
+ ] }),
2019
+ i.warnings.length > 0 && /* @__PURE__ */ s("div", {
2020
+ className: "proposal-warning",
2021
+ children: i.warnings.join(" · ")
2022
+ }),
2023
+ u.authorizationChanges.length > 0 && /* @__PURE__ */ c("div", { children: [u.authorizationChanges.map((e) => /* @__PURE__ */ c("div", {
2024
+ className: "proposal-warning",
2025
+ children: [
2026
+ /* @__PURE__ */ c("strong", { children: ["AUTHORIZATION CHANGE", e.widening ? " — POSSIBLE WIDENING" : ""] }),
2027
+ /* @__PURE__ */ s("br", {}),
2028
+ e.policy,
2029
+ /* @__PURE__ */ s("br", {}),
2030
+ /* @__PURE__ */ c("code", { children: [
2031
+ (e.before ?? ["<absent>"]).join(" | "),
2032
+ " → ",
2033
+ (e.after ?? ["<removed>"]).join(" | ")
2034
+ ] })
2035
+ ]
2036
+ }, e.policy)), /* @__PURE__ */ c("label", {
2037
+ className: "authorization-approval",
2038
+ children: [/* @__PURE__ */ s("input", {
2039
+ type: "checkbox",
2040
+ checked: _,
2041
+ onChange: (e) => v(e.target.checked)
2042
+ }), /* @__PURE__ */ s("span", { children: "I explicitly approve this authorization change." })]
2043
+ })] }),
2044
+ /* @__PURE__ */ c("details", { children: [/* @__PURE__ */ s("summary", { children: "Proposed feltdb.flow" }), /* @__PURE__ */ s("pre", { children: i.proposedFlow })] }),
2045
+ !e?.previewOnly && /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("button", {
2046
+ className: "btn btn-primary",
2047
+ disabled: u.authorizationChanges.length > 0 && !_,
2048
+ onClick: () => void T("approve"),
2049
+ children: "Approve proposal"
2050
+ }), /* @__PURE__ */ s("button", {
2051
+ className: "btn",
2052
+ onClick: () => void T("reject"),
2053
+ children: "Reject preview"
2054
+ })] }),
2055
+ e?.previewOnly && /* @__PURE__ */ c("p", {
2056
+ className: "proposal-boundary",
2057
+ children: [/* @__PURE__ */ s("strong", { children: "Preview-only session:" }), " no proposal artifact or source file will be written."]
2058
+ }),
2059
+ /* @__PURE__ */ s("p", {
2060
+ className: "proposal-boundary",
2061
+ children: "This preview is ephemeral. Approval records a proposal artifact; Studio never writes application source, changes the running contract, or publishes."
2062
+ })
2063
+ ]
2064
+ })
2065
+ ]
2066
+ });
2067
+ }
2068
+ //#endregion
2069
+ //#region src/components/ProposalBrowser.tsx
2070
+ function H() {
2071
+ let [e, t] = a([]), [r, i] = a(), [l, u] = a(""), d = () => void fetch("/_feltdb/proposals/list", { cache: "no-store" }).then(async (e) => {
2072
+ let n = await e.json();
2073
+ if (!e.ok) throw Error(n.error || "Proposal service unavailable");
2074
+ t(n.proposals || []), u("");
2075
+ }).catch((e) => u(e instanceof Error ? e.message : String(e)));
2076
+ n(() => {
2077
+ d();
2078
+ let e = window.setInterval(d, 2e3);
2079
+ return () => window.clearInterval(e);
2080
+ }, []);
2081
+ let f = (e) => void fetch(`/_feltdb/proposals/${encodeURIComponent(e)}`, { cache: "no-store" }).then(async (e) => {
2082
+ let t = await e.json();
2083
+ if (!e.ok) throw Error(t.error);
2084
+ i(t);
2085
+ }).catch((e) => u(e instanceof Error ? e.message : String(e)));
2086
+ return /* @__PURE__ */ c("div", {
2087
+ className: "proposal-browser",
2088
+ children: [
2089
+ /* @__PURE__ */ c("header", { children: [
2090
+ /* @__PURE__ */ s("span", {
2091
+ className: "eyebrow",
2092
+ children: "Durable application state"
2093
+ }),
2094
+ /* @__PURE__ */ s("h1", { children: "Proposals" }),
2095
+ /* @__PURE__ */ c("p", { children: [
2096
+ "Contract-governed application changes stored in ",
2097
+ /* @__PURE__ */ s("code", { children: "_feltdb.Proposal" }),
2098
+ "."
2099
+ ] })
2100
+ ] }),
2101
+ l && /* @__PURE__ */ s("p", {
2102
+ className: "proposal-warning",
2103
+ children: l
2104
+ }),
2105
+ /* @__PURE__ */ c("div", {
2106
+ className: "proposal-browser-layout",
2107
+ children: [/* @__PURE__ */ c("section", {
2108
+ className: "studio-card",
2109
+ children: [
2110
+ /* @__PURE__ */ s("h2", { children: "History" }),
2111
+ !e.length && /* @__PURE__ */ s("p", { children: "No proposals yet." }),
2112
+ e.map((e) => /* @__PURE__ */ c("button", {
2113
+ className: "proposal-list-row",
2114
+ onClick: () => f(e.id),
2115
+ children: [/* @__PURE__ */ c("span", { children: [/* @__PURE__ */ s("strong", { children: e.summary }), /* @__PURE__ */ c("small", { children: [
2116
+ e.id,
2117
+ " · ",
2118
+ String(e.created_at)
2119
+ ] })] }), /* @__PURE__ */ s("b", { children: e.status })]
2120
+ }, e.id))
2121
+ ]
2122
+ }), /* @__PURE__ */ s("section", {
2123
+ className: "studio-card proposal-detail",
2124
+ children: r ? /* @__PURE__ */ c(o, { children: [
2125
+ /* @__PURE__ */ s("h2", { children: r.proposal.summary }),
2126
+ /* @__PURE__ */ c("p", { children: [
2127
+ /* @__PURE__ */ s("b", { children: r.proposal.status }),
2128
+ " · contract v",
2129
+ r.proposal.base_contract_version,
2130
+ /* @__PURE__ */ s("br", {}),
2131
+ /* @__PURE__ */ s("code", { children: r.proposal.base_contract_hash })
2132
+ ] }),
2133
+ /* @__PURE__ */ s("h3", { children: "Contract diff" }),
2134
+ /* @__PURE__ */ s("pre", { children: r.proposal.contract_diff.join("\n") || "Not validated" }),
2135
+ /* @__PURE__ */ s("h3", { children: "Source plan" }),
2136
+ /* @__PURE__ */ s("pre", { children: JSON.stringify(r.proposal.source_plan, null, 2) }),
2137
+ /* @__PURE__ */ s("h3", { children: "Warnings" }),
2138
+ /* @__PURE__ */ s("p", { children: r.proposal.warnings.join(" · ") || "None" }),
2139
+ /* @__PURE__ */ c("details", { children: [/* @__PURE__ */ s("summary", { children: "Proposed flow" }), /* @__PURE__ */ s("pre", { children: r.proposal.proposed_flow })] }),
2140
+ /* @__PURE__ */ s("h3", { children: "Status history" }),
2141
+ /* @__PURE__ */ s("ol", { children: r.history.map((e) => /* @__PURE__ */ c("li", { children: [
2142
+ String(e.created_at),
2143
+ " — ",
2144
+ e.from_status ? `${e.from_status} → ` : "",
2145
+ e.to_status
2146
+ ] }, e.id)) }),
2147
+ r.proposal.status === "approved" && /* @__PURE__ */ c("p", {
2148
+ className: "proposal-boundary",
2149
+ children: [
2150
+ "Approved. Run ",
2151
+ /* @__PURE__ */ c("code", { children: ["feltdb ai apply ", r.proposal.id] }),
2152
+ " in the project."
2153
+ ]
2154
+ })
2155
+ ] }) : /* @__PURE__ */ s("p", { children: "Select a proposal to inspect its flow, diff, source plan, warnings, and audit history." })
2156
+ })]
2157
+ })
2158
+ ]
2159
+ });
2160
+ }
2161
+ //#endregion
2162
+ export { g as C, y as S, b as _, L as a, x as b, P as c, j as d, k as f, w as g, E as h, R as i, N as l, D as m, V as n, I as o, O as p, B as r, F as s, H as t, M as u, v, S as x, _ as y };