@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.
- package/dist/application-development.d.ts +76 -0
- package/dist/application-development.d.ts.map +1 -0
- package/dist/application-development.js +137 -0
- package/dist/application-manifest.d.ts +5 -1
- package/dist/application-manifest.d.ts.map +1 -1
- package/dist/application-manifest.js +10 -3
- package/dist/canonical-application.d.ts +26 -0
- package/dist/canonical-application.d.ts.map +1 -0
- package/dist/canonical-application.js +45 -0
- package/dist/cli/ai-model-config.js +97 -0
- package/dist/cli/commands.js +485 -30
- package/dist/cli/index.js +1 -1
- package/dist/cli/proposal-client.js +54 -0
- package/dist/cli/publish-engine.js +162 -0
- package/dist/cli/source-sync.js +139 -0
- package/dist/create/cli.js +1 -1
- package/dist/create/create.js +30 -6
- package/dist/create/managed-account.js +14 -7
- package/dist/create/package-versions.js +1 -1
- package/dist/create/server-source/crates/feltdb/src/application.rs +31 -1
- package/dist/create/server-source/crates/feltdb/src/authority_failover.rs +847 -0
- package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +338 -29
- package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +72 -34
- package/dist/create/server-source/crates/feltdb/src/lib.rs +1 -0
- package/dist/create/server-source/crates/feltdb-server/src/identity.rs +46 -3
- package/dist/create/server-source/crates/feltdb-server/src/main.rs +315 -16
- package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +20 -0
- package/dist/create/template/default-project/README.md +57 -0
- package/dist/create/template/default-project/agents/activity-assistant.ts +18 -0
- package/dist/create/template/default-project/agents/project-assistant.ts +19 -0
- package/dist/create/template/default-project/capabilities/activity-summary.ts +14 -0
- package/dist/create/template/default-project/capabilities/project-search.ts +16 -0
- package/dist/create/template/default-project/capabilities/project-summary.ts +15 -0
- package/dist/create/template/default-project/feltdb.flow +169 -0
- package/dist/create/template/default-project/src/App.tsx +20 -0
- package/dist/create/template/default-project/src/context/AuthContext.tsx +27 -0
- package/dist/create/template/default-project/src/feltdb.ts +87 -0
- package/dist/create/template/default-project/src/index.tsx +14 -0
- package/dist/create/template/default-project/src/pages/Activity.tsx +7 -0
- package/dist/create/template/default-project/src/pages/Agents.tsx +15 -0
- package/dist/create/template/default-project/src/pages/Dashboard.tsx +17 -0
- package/dist/create/template/default-project/src/pages/Invitations.tsx +11 -0
- package/dist/create/template/default-project/src/pages/Projects.tsx +11 -0
- package/dist/create/template/default-project/src/pages/SignIn.tsx +8 -0
- package/dist/create/template/default-project/src/pages/SignUp.tsx +8 -0
- package/dist/create/template/default-project/src/styles-application.css +21 -0
- package/dist/create/template/default-project/src/styles.css +1 -0
- package/dist/create/template/default-project/workflows/agent-assisted-summary.ts +1 -0
- package/dist/create/template/default-project/workflows/invitation.ts +30 -0
- package/dist/create/template/default-project/workflows/project-created.ts +2 -0
- package/dist/db.d.ts +49 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +77 -0
- package/dist/error-codes.d.ts +20 -1
- package/dist/error-codes.d.ts.map +1 -1
- package/dist/error-codes.js +25 -0
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +27 -6
- package/dist/http-db.d.ts +15 -2
- package/dist/http-db.d.ts.map +1 -1
- package/dist/http-db.js +113 -5
- 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/proposal.d.ts +85 -0
- package/dist/proposal.d.ts.map +1 -0
- package/dist/proposal.js +105 -0
- package/dist/studio/app.d.ts +5 -1
- package/dist/studio/app.d.ts.map +1 -1
- package/dist/studio/components/ApplicationDesigner.d.ts +10 -1
- package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
- package/dist/studio/components/AskFeltDB.d.ts +20 -0
- package/dist/studio/components/AskFeltDB.d.ts.map +1 -0
- package/dist/studio/components/ProposalBrowser.d.ts +3 -0
- package/dist/studio/components/ProposalBrowser.d.ts.map +1 -0
- package/dist/studio/components/index.d.ts +2 -0
- package/dist/studio/components/index.d.ts.map +1 -1
- package/dist/studio/components/index.js +4 -4
- package/dist/studio/{components-C5p2TfIU.js → components-Bm4sjhcX.js} +531 -192
- package/dist/studio/index.js +184 -172
- package/dist/studio/studio.css +1 -1
- package/dist/studio-app/assets/dist-DA1MYSzp.js +1 -0
- package/dist/studio-app/assets/{feltdb_wasm-DVKsw75S.js → feltdb_wasm-B-Ccgccb.js} +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-wH3enJIA.wasm +0 -0
- package/dist/studio-app/assets/{index-C1GWyazR.css → index-BRrmvaKw.css} +1 -1
- package/dist/studio-app/assets/index-CEIqowCh.js +42 -0
- package/dist/studio-app/assets/lib-B2_7fcn7.js +69 -0
- package/dist/studio-app/assets/worker-CARZ5g7K.js +69 -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 +3 -0
- package/dist/workspace/local-development-authority.d.ts.map +1 -1
- package/dist/workspace/local-development-authority.js +62 -1
- package/package.json +1 -1
- package/dist/studio-app/assets/feltdb_wasm_bg-DNyNf0yy.wasm +0 -0
- 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,
|
|
1098
|
-
let
|
|
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
|
-
})()),
|
|
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
|
-
}),
|
|
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
|
-
|
|
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 || (
|
|
1126
|
+
t || (O(a.map((e) => ({
|
|
1124
1127
|
version: e.version,
|
|
1125
1128
|
source: f(e.spec),
|
|
1126
1129
|
savedAt: e.deployed_at
|
|
1127
|
-
}))),
|
|
1130
|
+
}))), A(`Loaded ${r.app} v${r.version}`));
|
|
1128
1131
|
} catch (e) {
|
|
1129
|
-
t ||
|
|
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(
|
|
1138
|
+
let e = window.setTimeout(() => window.localStorage.setItem(v, x), 200);
|
|
1136
1139
|
return () => window.clearTimeout(e);
|
|
1137
|
-
}, [
|
|
1138
|
-
let
|
|
1139
|
-
|
|
1140
|
+
}, [v, x]);
|
|
1141
|
+
let J = (e) => {
|
|
1142
|
+
S(e);
|
|
1140
1143
|
try {
|
|
1141
1144
|
let t = p(e), n = h(t);
|
|
1142
|
-
|
|
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
|
-
|
|
1147
|
+
E([{
|
|
1145
1148
|
severity: "error",
|
|
1146
1149
|
message: e instanceof Error ? e.message : String(e)
|
|
1147
|
-
}]),
|
|
1150
|
+
}]), A("DSL parse failed");
|
|
1148
1151
|
}
|
|
1149
1152
|
};
|
|
1150
1153
|
n(() => {
|
|
1151
1154
|
if (!o) return;
|
|
1152
1155
|
let e = f(o);
|
|
1153
|
-
|
|
1156
|
+
S(e), w(o), E(h(o)), A(`Loaded ${o.app} project model`);
|
|
1154
1157
|
}, [o]);
|
|
1155
|
-
let
|
|
1156
|
-
|
|
1157
|
-
},
|
|
1158
|
-
if (!
|
|
1159
|
-
let e =
|
|
1160
|
-
if (!/^[A-Z][A-Za-z0-9_]*$/.test(e)) return
|
|
1161
|
-
...
|
|
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 (
|
|
1165
|
-
...
|
|
1167
|
+
if (C.collections.some((t) => t.name === e)) return I({
|
|
1168
|
+
...F,
|
|
1166
1169
|
error: "That collection already exists."
|
|
1167
1170
|
});
|
|
1168
|
-
|
|
1169
|
-
...
|
|
1170
|
-
collections: [...
|
|
1171
|
+
Y({
|
|
1172
|
+
...C,
|
|
1173
|
+
collections: [...C.collections, {
|
|
1171
1174
|
name: e,
|
|
1172
1175
|
fields: [],
|
|
1173
1176
|
indexes: []
|
|
1174
1177
|
}]
|
|
1175
|
-
}),
|
|
1176
|
-
},
|
|
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
|
-
}),
|
|
1183
|
-
if (!
|
|
1184
|
-
let e =
|
|
1185
|
-
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)) return
|
|
1186
|
-
...
|
|
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
|
|
1190
|
-
...
|
|
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(
|
|
1200
|
-
...
|
|
1202
|
+
].includes(N.type) && !N.reference.trim()) return P({
|
|
1203
|
+
...N,
|
|
1201
1204
|
error: "Configure this field type."
|
|
1202
1205
|
});
|
|
1203
|
-
let n =
|
|
1204
|
-
|
|
1205
|
-
...
|
|
1206
|
-
collections:
|
|
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:
|
|
1214
|
+
optional: N.optional
|
|
1212
1215
|
}]
|
|
1213
1216
|
} : t)
|
|
1214
|
-
}),
|
|
1215
|
-
},
|
|
1216
|
-
let e = [...
|
|
1217
|
-
version:
|
|
1218
|
-
source:
|
|
1217
|
+
}), P(null);
|
|
1218
|
+
}, $ = () => {
|
|
1219
|
+
let e = [...D, {
|
|
1220
|
+
version: D.length + 1,
|
|
1221
|
+
source: x,
|
|
1219
1222
|
savedAt: Date.now()
|
|
1220
1223
|
}];
|
|
1221
|
-
|
|
1222
|
-
},
|
|
1223
|
-
if (!e) return
|
|
1224
|
-
if (
|
|
1225
|
-
if (
|
|
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(
|
|
1230
|
+
let t = await e.deployFlowSpec(C, j, L), n = [...D, {
|
|
1228
1231
|
version: t.version,
|
|
1229
|
-
source:
|
|
1232
|
+
source: x,
|
|
1230
1233
|
savedAt: Date.now()
|
|
1231
1234
|
}];
|
|
1232
|
-
|
|
1235
|
+
O(n), M(t.version), R(!1), A(`Applied locally as ${t.app} v${t.version}`);
|
|
1233
1236
|
} catch (e) {
|
|
1234
|
-
|
|
1237
|
+
A(`Local apply failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1235
1238
|
}
|
|
1236
|
-
},
|
|
1237
|
-
if (
|
|
1238
|
-
|
|
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 (
|
|
1242
|
-
...
|
|
1275
|
+
if (T.some((e) => e.severity === "error")) return U({
|
|
1276
|
+
...H,
|
|
1243
1277
|
error: "Resolve validation errors before publishing."
|
|
1244
1278
|
});
|
|
1245
|
-
|
|
1246
|
-
...
|
|
1279
|
+
U({
|
|
1280
|
+
...H,
|
|
1247
1281
|
publishing: !0,
|
|
1248
1282
|
error: void 0
|
|
1249
1283
|
});
|
|
1250
1284
|
let e = l({
|
|
1251
|
-
namespace:
|
|
1285
|
+
namespace: H.namespace.trim() || t,
|
|
1252
1286
|
server: {
|
|
1253
|
-
url:
|
|
1254
|
-
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(
|
|
1259
|
-
if (n.length && !
|
|
1260
|
-
...
|
|
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(
|
|
1266
|
-
window.sessionStorage.setItem(`feltdb-token:${
|
|
1267
|
-
...
|
|
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
|
-
}),
|
|
1304
|
+
}), V(!1), A(`Published ${r.app} v${r.version} to ${H.environment || "cloud"}`);
|
|
1272
1305
|
} catch (e) {
|
|
1273
|
-
|
|
1274
|
-
...
|
|
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
|
-
},
|
|
1282
|
-
let e = URL.createObjectURL(new Blob([
|
|
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
|
-
},
|
|
1285
|
-
e &&
|
|
1286
|
-
},
|
|
1287
|
-
["Data",
|
|
1288
|
-
["Capabilities",
|
|
1289
|
-
["Agents",
|
|
1290
|
-
["Workflows",
|
|
1291
|
-
["Triggers",
|
|
1292
|
-
["Policies",
|
|
1293
|
-
["Schedules",
|
|
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:
|
|
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:
|
|
1344
|
+
ref: W,
|
|
1312
1345
|
hidden: !0,
|
|
1313
1346
|
type: "file",
|
|
1314
1347
|
accept: ".flow,text/plain",
|
|
1315
|
-
onChange: (e) => void
|
|
1348
|
+
onChange: (e) => void re(e.target.files?.[0])
|
|
1316
1349
|
}),
|
|
1317
1350
|
/* @__PURE__ */ s("button", {
|
|
1318
1351
|
className: "btn btn-ghost",
|
|
1319
|
-
onClick: () =>
|
|
1352
|
+
onClick: () => W.current?.click(),
|
|
1320
1353
|
children: "Import"
|
|
1321
1354
|
}),
|
|
1322
1355
|
/* @__PURE__ */ s("button", {
|
|
1323
1356
|
className: "btn btn-ghost",
|
|
1324
|
-
onClick:
|
|
1357
|
+
onClick: ne,
|
|
1325
1358
|
children: "Export"
|
|
1326
1359
|
}),
|
|
1327
1360
|
/* @__PURE__ */ s("button", {
|
|
1328
1361
|
className: "btn btn-ghost",
|
|
1329
|
-
onClick:
|
|
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: () =>
|
|
1372
|
+
onClick: () => V((e) => !e),
|
|
1340
1373
|
children: "Publish to cloud"
|
|
1341
1374
|
})
|
|
1342
1375
|
]
|
|
1343
1376
|
})]
|
|
1344
1377
|
}),
|
|
1345
|
-
|
|
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:
|
|
1350
|
-
onChange: (e) =>
|
|
1351
|
-
}), /* @__PURE__ */ c("span", { children: ["Approve destructive local changes: ",
|
|
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
|
-
|
|
1386
|
+
B && /* @__PURE__ */ c("form", {
|
|
1354
1387
|
className: "cloud-publisher",
|
|
1355
1388
|
onSubmit: (e) => {
|
|
1356
|
-
e.preventDefault(),
|
|
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
|
|
1367
|
-
/* @__PURE__ */ s("p", { children: "FeltDB
|
|
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: () =>
|
|
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
|
-
|
|
1381
|
-
|
|
1382
|
-
onChange: (e) =>
|
|
1383
|
-
...
|
|
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:
|
|
1392
|
-
|
|
1393
|
-
|
|
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: "
|
|
1404
|
-
value:
|
|
1405
|
-
onChange: (e) =>
|
|
1406
|
-
...
|
|
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
|
-
(
|
|
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:
|
|
1418
|
-
onChange: (e) =>
|
|
1419
|
-
...
|
|
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",
|
|
1464
|
+
}), /* @__PURE__ */ c("span", { children: ["I reviewed and approve destructive model changes", H.destructive?.length ? `: ${H.destructive.join(", ")}` : "."] })]
|
|
1423
1465
|
}),
|
|
1424
|
-
|
|
1466
|
+
H.error && /* @__PURE__ */ s("div", {
|
|
1425
1467
|
className: "cloud-error",
|
|
1426
1468
|
role: "alert",
|
|
1427
|
-
children:
|
|
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: () =>
|
|
1476
|
+
onClick: () => V(!1),
|
|
1435
1477
|
children: "Cancel"
|
|
1436
1478
|
}), /* @__PURE__ */ s("button", {
|
|
1437
1479
|
className: "btn btn-primary",
|
|
1438
|
-
disabled:
|
|
1480
|
+
disabled: H.publishing,
|
|
1439
1481
|
type: "submit",
|
|
1440
|
-
children:
|
|
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 ${
|
|
1447
|
-
children: [/* @__PURE__ */ s("span", { children:
|
|
1448
|
-
|
|
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
|
-
|
|
1492
|
+
C.workflows.length,
|
|
1451
1493
|
" workflows · ",
|
|
1452
|
-
|
|
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: () =>
|
|
1507
|
+
onClick: () => I({ name: "" }),
|
|
1466
1508
|
children: "+"
|
|
1467
1509
|
})]
|
|
1468
1510
|
}),
|
|
1469
|
-
|
|
1511
|
+
F && /* @__PURE__ */ c("form", {
|
|
1470
1512
|
className: "collection-editor",
|
|
1471
1513
|
onSubmit: (e) => {
|
|
1472
|
-
e.preventDefault(),
|
|
1514
|
+
e.preventDefault(), X();
|
|
1473
1515
|
},
|
|
1474
1516
|
onKeyDown: (e) => {
|
|
1475
|
-
e.key === "Escape" &&
|
|
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:
|
|
1482
|
-
onChange: (e) =>
|
|
1523
|
+
value: F.name,
|
|
1524
|
+
onChange: (e) => I({ name: e.target.value })
|
|
1483
1525
|
})] }),
|
|
1484
|
-
|
|
1526
|
+
F.error && /* @__PURE__ */ s("div", {
|
|
1485
1527
|
className: "field-error",
|
|
1486
1528
|
role: "alert",
|
|
1487
|
-
children:
|
|
1529
|
+
children: F.error
|
|
1488
1530
|
}),
|
|
1489
1531
|
/* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("button", {
|
|
1490
1532
|
type: "button",
|
|
1491
|
-
onClick: () =>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1576
|
+
N?.collection === e.name ? /* @__PURE__ */ c("form", {
|
|
1535
1577
|
className: "field-editor",
|
|
1536
1578
|
onSubmit: (e) => {
|
|
1537
|
-
e.preventDefault(),
|
|
1579
|
+
e.preventDefault(), Q();
|
|
1538
1580
|
},
|
|
1539
1581
|
onKeyDown: (e) => {
|
|
1540
|
-
e.key === "Escape" &&
|
|
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:
|
|
1587
|
+
value: N.name,
|
|
1546
1588
|
placeholder: "e.g. publishedAt",
|
|
1547
|
-
onChange: (e) =>
|
|
1548
|
-
...
|
|
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:
|
|
1558
|
-
onChange: (e) =>
|
|
1559
|
-
...
|
|
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
|
-
|
|
1663
|
-
value:
|
|
1664
|
-
onChange: (e) =>
|
|
1665
|
-
...
|
|
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:
|
|
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
|
-
|
|
1716
|
+
N.type === "enum" && /* @__PURE__ */ c("label", { children: [/* @__PURE__ */ s("span", { children: "Values" }), /* @__PURE__ */ s("input", {
|
|
1675
1717
|
placeholder: "draft,active,done",
|
|
1676
|
-
value:
|
|
1677
|
-
onChange: (e) =>
|
|
1678
|
-
...
|
|
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
|
-
(
|
|
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:
|
|
1686
|
-
onChange: (e) =>
|
|
1687
|
-
...
|
|
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
|
-
|
|
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:
|
|
1697
|
-
onChange: (e) =>
|
|
1698
|
-
...
|
|
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:
|
|
1710
|
-
onChange: (e) =>
|
|
1711
|
-
...
|
|
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
|
-
|
|
1758
|
+
N.error && /* @__PURE__ */ s("div", {
|
|
1717
1759
|
className: "field-error",
|
|
1718
1760
|
role: "alert",
|
|
1719
|
-
children:
|
|
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: () =>
|
|
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: () =>
|
|
1778
|
+
onClick: () => Z(e.name),
|
|
1737
1779
|
children: "+ field"
|
|
1738
1780
|
})
|
|
1739
1781
|
]
|
|
1740
1782
|
}, e.name)),
|
|
1741
|
-
|
|
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
|
-
|
|
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: ["+ ",
|
|
1819
|
+
children: ["+ ", K.added.join(", ") || "none"]
|
|
1778
1820
|
}),
|
|
1779
1821
|
/* @__PURE__ */ c("span", {
|
|
1780
1822
|
className: "changed",
|
|
1781
|
-
children: ["~ ",
|
|
1823
|
+
children: ["~ ", K.changed.join(", ") || "none"]
|
|
1782
1824
|
}),
|
|
1783
1825
|
/* @__PURE__ */ c("span", {
|
|
1784
1826
|
className: "removed",
|
|
1785
|
-
children: ["− ",
|
|
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:
|
|
1802
|
-
onChange: (e) =>
|
|
1843
|
+
value: x,
|
|
1844
|
+
onChange: (e) => J(e.target.value)
|
|
1803
1845
|
}),
|
|
1804
|
-
|
|
1846
|
+
T.length > 0 && /* @__PURE__ */ s("div", {
|
|
1805
1847
|
className: "diagnostics",
|
|
1806
|
-
children:
|
|
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
|
-
|
|
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 };
|