@feltdb/core 0.4.11 → 0.4.12

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.
@@ -7,7 +7,7 @@ import http from 'http';
7
7
  import { createRequire } from 'module';
8
8
  import { spawn, spawnSync } from 'child_process';
9
9
  import { createFeltDB, diffFlowSpec, formatFlowSpec, parseFlowSpec, planFlowSpecMigration, validateFlowSpec } from '@feltdb/core';
10
- const RELEASE_VERSION = '0.4.11';
10
+ const RELEASE_VERSION = '0.4.12';
11
11
  function loadProjectEnvironment(file = path.resolve('.env.local')) {
12
12
  if (!fs.existsSync(file))
13
13
  return;
package/dist/cli/index.js CHANGED
@@ -23,7 +23,7 @@ import * as path from 'path';
23
23
  import * as readline from 'readline';
24
24
  import { getClient } from './api-client.js';
25
25
  import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
26
- const VERSION = '0.4.11';
26
+ const VERSION = '0.4.12';
27
27
  function prompt(question) {
28
28
  const rl = readline.createInterface({
29
29
  input: process.stdin,
@@ -1,4 +1,4 @@
1
1
  // One release train keeps generated applications installable. The repository
2
2
  // validation script checks these values against every workspace manifest.
3
- export const FELTDB_PACKAGE_VERSION = '0.4.11';
3
+ export const FELTDB_PACKAGE_VERSION = '0.4.12';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
@@ -1 +1 @@
1
- {"version":3,"file":"ApplicationDesigner.d.ts","sourceRoot":"","sources":["../../src/components/ApplicationDesigner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAkB,MAAM,cAAc,CAAC;AAU3E,MAAM,WAAW,wBAAwB;IAAG,EAAE,CAAC,EAAE,YAAY,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;CAAE;AAE3J,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,SAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,wBAAwB,qBAsGrH;AACD,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ApplicationDesigner.d.ts","sourceRoot":"","sources":["../../src/components/ApplicationDesigner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAkB,MAAM,cAAc,CAAC;AAO3E,MAAM,WAAW,wBAAwB;IAAG,EAAE,CAAC,EAAE,YAAY,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAA;CAAE;AAE3J,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,EAAE,SAAqB,EAAE,WAAW,EAAE,YAAY,EAAE,EAAE,wBAAwB,qBA+GrH;AACD,eAAe,mBAAmB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p, x as m } from "../components-q43NSTTH.js";
1
+ import { a as e, c as t, d as n, f as r, i, l as a, m as o, n as s, o as c, p as l, r as u, s as d, t as f, u as p, x as m } from "../components-Q0Nx6gLE.js";
2
2
  import { t as h } from "../KeyManagementPanel-DZuSeWBK.js";
3
3
  import { ManagedInstancePanel as g } from "./ManagedInstancePanel.js";
4
4
  export { c as AgentExplorer, f as ApplicationDesigner, p as CapabilityExplorer, t as ConflictExplorer, a as ExecutionViewer, s as GlobalSearch, i as HealthCenter, h as KeyManagementPanel, g as ManagedInstancePanel, r as OperationsExplorer, m as OverviewDashboard, n as PeerMap, e as ProvenanceViewer, l as ReferenceExplorer, u as SettingsPanel, o as StateExplorer, d as WorkflowVisualizer };
@@ -1076,46 +1076,7 @@ function R({ db: e, model: t, onSearch: r }) {
1076
1076
  }
1077
1077
  //#endregion
1078
1078
  //#region src/components/ApplicationDesigner.tsx
1079
- var z = f({
1080
- ...d("ResearchPlatform"),
1081
- collections: [{
1082
- name: "User",
1083
- fields: [{
1084
- name: "name",
1085
- type: "text",
1086
- optional: !1
1087
- }, {
1088
- name: "email",
1089
- type: "text",
1090
- optional: !1
1091
- }],
1092
- indexes: []
1093
- }, {
1094
- name: "Document",
1095
- fields: [
1096
- {
1097
- name: "title",
1098
- type: "text",
1099
- optional: !1
1100
- },
1101
- {
1102
- name: "content",
1103
- type: "text",
1104
- optional: !1
1105
- },
1106
- {
1107
- name: "author",
1108
- type: "ref User",
1109
- optional: !1
1110
- }
1111
- ],
1112
- indexes: [{
1113
- name: "search",
1114
- kind: "fulltext",
1115
- expression: "(content)"
1116
- }]
1117
- }]
1118
- });
1079
+ var z = f(d("Application"));
1119
1080
  function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g }) {
1120
1081
  let _ = `feltdb:studio:draft:${t}`, v = i((() => {
1121
1082
  if (typeof window > "u") return z;
@@ -1133,7 +1094,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1133
1094
  allowDestructive: !1
1134
1095
  }), 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]);
1135
1096
  n(() => {
1136
- if (!e) return;
1097
+ if (!e || o) return;
1137
1098
  let t = !1;
1138
1099
  return (async () => {
1139
1100
  try {
@@ -1153,7 +1114,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1153
1114
  })(), () => {
1154
1115
  t = !0;
1155
1116
  };
1156
- }, [e]), n(() => {
1117
+ }, [e, o]), n(() => {
1157
1118
  let e = window.setTimeout(() => window.localStorage.setItem(_, b), 200);
1158
1119
  return () => window.clearTimeout(e);
1159
1120
  }, [_, b]);
@@ -1170,7 +1131,7 @@ function B({ db: e, namespace: t = "default", projectSpec: o, onSpecChange: g })
1170
1131
  }
1171
1132
  };
1172
1133
  n(() => {
1173
- if (!o || y.current && S.app === o.app) return;
1134
+ if (!o) return;
1174
1135
  let e = f(o);
1175
1136
  x(e), C(o), T(h(o)), k(`Loaded ${o.app} project model`);
1176
1137
  }, [o]);
@@ -1,4 +1,4 @@
1
- import { _ as e, a as t, b as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _, v, x as y, y as b } from "./components-q43NSTTH.js";
1
+ import { _ as e, a as t, b as n, c as r, d as i, f as a, g as o, h as s, i as c, l, m as u, n as d, o as f, p, r as m, s as h, t as g, u as _, v, x as y, y as b } from "./components-Q0Nx6gLE.js";
2
2
  import { t as x } from "./KeyManagementPanel-DZuSeWBK.js";
3
3
  import { ManagedInstanceUtil as S } from "./utils/managed-instance.js";
4
4
  import { ManagedInstancePanel as C } from "./components/ManagedInstancePanel.js";
@@ -25,4 +25,4 @@ Please change the parent <Route path="${e}"> to <Route path="${e===`/`?`*`:`${e}
25
25
  `)}\n }`);for(let n of e.triggers)t.push(` trigger on ${n.event} {\n${n.statements.map(e=>` ${e}`).join(`
26
26
  `)}\n }`);for(let n of e.policies)t.push(Dr(`policy`,n));for(let n of e.schedules)t.push(Dr(`schedule`,n));return`app ${e.app} {\n${t.join(`
27
27
 
28
- `)}\n}\n`}function kr(e,t){let n=e=>new Map([...e.collections.map(e=>[`collection ${e.name}`,JSON.stringify(e)]),...e.capabilities.map(e=>[`capability ${e.name}`,JSON.stringify(e)]),...e.agents.map(e=>[`agent ${e.name}`,JSON.stringify(e)]),...e.workflows.map(e=>[`workflow ${e.name}`,JSON.stringify(e)]),...e.triggers.map(e=>[`trigger ${e.event}`,JSON.stringify(e)]),...e.policies.map(e=>[`policy ${e.name}`,JSON.stringify(e)]),...e.schedules.map(e=>[`schedule ${e.name}`,JSON.stringify(e)])]),r=n(e),i=n(t);return{added:[...i.keys()].filter(e=>!r.has(e)),removed:[...r.keys()].filter(e=>!i.has(e)),changed:[...i.keys()].filter(e=>r.has(e)&&r.get(e)!==i.get(e))}}function Ar(e,t){let n=[],r=new Map(e.collections.map(e=>[e.name,e])),i=new Map(t.collections.map(e=>[e.name,e]));for(let[e,t]of i){let i=r.get(e);if(!i){n.push({kind:`add`,target:`collection ${e}`,safety:`safe`,detail:`Create collection model`});continue}let a=new Map(i.fields.map(e=>[e.name,e])),o=new Map(t.fields.map(e=>[e.name,e]));for(let[t,r]of o){let i=a.get(t);i?(i.type!==r.type||i.optional!==r.optional)&&n.push({kind:`change`,target:`${e}.${t}`,safety:`requires_transform`,detail:`${i.type}${i.optional?`?`:``} → ${r.type}${r.optional?`?`:``}`}):n.push({kind:`add`,target:`${e}.${t}`,safety:r.optional?`safe`:`requires_transform`,detail:r.optional?`Add optional field`:`Required field needs a backfill`})}for(let t of a.keys())o.has(t)||n.push({kind:`remove`,target:`${e}.${t}`,safety:`destructive`,detail:`Field is no longer declared`})}for(let e of r.keys())i.has(e)||n.push({kind:`remove`,target:`collection ${e}`,safety:`destructive`,detail:`Collection model is no longer declared`});let a=kr(e,t);for(let e of a.added.filter(e=>!e.startsWith(`collection `)))n.push({kind:`add`,target:e,safety:`safe`,detail:`Deploy application primitive`});for(let e of a.changed.filter(e=>!e.startsWith(`collection `)))n.push({kind:`change`,target:e,safety:`safe`,detail:`Version application primitive`});for(let e of a.removed.filter(e=>!e.startsWith(`collection `)))n.push({kind:`remove`,target:e,safety:`destructive`,detail:`Application primitive is no longer declared`});return n}function jr(e=`MyApp`){return{version:1,app:e,collections:[],capabilities:[],agents:[],workflows:[],triggers:[],policies:[],schedules:[]}}var Mr=class{constructor(e=`offline`){this.value=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),e(this.value),()=>this.listeners.delete(e)}set(e){this.value=e;for(let t of this.listeners)t(e)}get(){return this.value}},Nr=class{constructor(e){this.config=e,this.status=new Mr,this.fetcher=e.fetcher||fetch,this.restore()}key(){return`feltdb:sync:v1:${this.config.device.application_id}:${this.config.device.device_id}`}restore(){if(!(typeof localStorage>`u`))try{let e=JSON.parse(localStorage.getItem(this.key())||`{}`);this.sessionId=e.sessionId,this.cursor=e.cursor,this.error=e.error}catch{}}persist(){typeof localStorage<`u`&&localStorage.setItem(this.key(),JSON.stringify({sessionId:this.sessionId,cursor:this.cursor,error:this.error,outbox:this.readOutbox()}))}readOutbox(){if(typeof localStorage>`u`)return[];try{return JSON.parse(localStorage.getItem(`${this.key()}:outbox`)||`[]`)}catch{return[]}}writeOutbox(e){typeof localStorage<`u`&&localStorage.setItem(`${this.key()}:outbox`,JSON.stringify(e))}async request(e,t){let n=await this.fetcher(`${this.config.endpoint||``}/v1/sync/${e}`,{method:`POST`,credentials:`include`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(r.error||`sync ${e} failed (${n.status})`);return r}async start(){this.status.set(`connecting`);try{if(!this.sessionId){let e={resources:this.config.scope.resources||this.config.scope.collections?.map(e=>`flow://${this.config.device.application_id}/${e}/*`)||[],fields:this.config.scope.fields||{}},t=await this.request(`session`,{device:{...this.config.device,created_at:Math.floor(Date.now()/1e3)},scope:e,offline_grant:this.config.offlineGrant});this.sessionId=t.session_id,this.cursor=t.cursor,this.persist()}return await this.flush(),this.timer=setInterval(()=>void this.flush(),5e3),this}catch(e){throw this.error=String(e),this.status.set(`degraded`),this.persist(),e}}async stop(){this.timer&&clearInterval(this.timer),this.sessionId&&await this.request(`close`,{session_id:this.sessionId}),this.status.set(`offline`)}enqueue(e){let t=this.readOutbox();return t.some(t=>t.operation_id===e.operation_id)||(t.push(e),this.writeOutbox(t)),e.operation_id}async flush(){if(!(!this.sessionId||!this.cursor)){this.status.set(`syncing`);try{let e=this.readOutbox();if(e.length){let t=await this.request(`push`,{session_id:this.sessionId,operations:e}),n=new Set([...t.acknowledgements.map(e=>e.operation_id),...t.rejections.filter(e=>!e.retryable).map(e=>e.operation_id)]);this.writeOutbox(e.filter(e=>!n.has(e.operation_id))),this.cursor=t.cursor}let t=await this.request(`pull`,{session_id:this.sessionId,cursor:this.cursor,limit:250});this.cursor=t.cursor,await this.request(`ack`,{session_id:this.sessionId,cursor:this.cursor}),this.error=void 0,this.status.set(`synced`),this.persist()}catch(e){this.error=String(e),this.status.set(typeof navigator<`u`&&!navigator.onLine?`offline`:`degraded`),this.persist()}}}pending(){return this.readOutbox()}conflicts(){return this.readOutbox().filter(e=>e.status===`CONFLICTED`)}lastCursor(){return this.cursor}lastError(){return this.error}},Pr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`,...t?.headers||{}},...t}),r=n.status===204?void 0:await n.json();if(!n.ok)throw Error(r?.error||`Workload request failed (${n.status})`);return r}create(e){return this.json(`/v1/workloads`,{method:`POST`,body:JSON.stringify({...e,created_at:e.created_at||Math.floor(Date.now()/1e3)})})}list(e){return this.json(`/v1/workloads?application_id=${encodeURIComponent(e)}`)}inspect(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}`)}claim(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/claim`,{method:`POST`,body:JSON.stringify(t)})}start(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/start`,{method:`POST`,body:JSON.stringify(t)})}heartbeat(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/heartbeat`,{method:`POST`,body:JSON.stringify(t)})}checkpoint(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/checkpoint`,{method:`POST`,body:JSON.stringify(t)})}complete(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/complete`,{method:`POST`,body:JSON.stringify(t)})}fail(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/fail`,{method:`POST`,body:JSON.stringify(t)})}confirmCancelled(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/cancelled`,{method:`POST`,body:JSON.stringify(t)})}executionContext(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/context`,{method:`POST`,body:JSON.stringify(t)})}cancel(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/cancel`,{method:`POST`,body:JSON.stringify({grant:t})})}retry(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/retry`,{method:`POST`,body:JSON.stringify({grant:t})})}history(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/history`)}result(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/result`)}},Fr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`,...t?.headers||{}},...t}),r=n.status===204?void 0:await n.json();if(!n.ok)throw Error(r?.error||`Mesh request failed (${n.status})`);return r}},Ir=class extends Fr{register(e){return this.json(`/v1/workers/register`,{method:`POST`,body:JSON.stringify({...e,registered_at:e.registered_at||Math.floor(Date.now()/1e3)})})}list(e){return this.json(`/v1/workers?application_id=${encodeURIComponent(e)}`)}inspect(e){return this.json(`/v1/workers/${encodeURIComponent(e)}`)}heartbeat(e,t,n){return this.json(`/v1/workers/${encodeURIComponent(e)}/heartbeat`,{method:`POST`,body:JSON.stringify({heartbeat:t,grant:n})})}drain(e,t){return this.json(`/v1/workers/${encodeURIComponent(e)}/drain`,{method:`POST`,body:JSON.stringify({grant:t})})}recover(e,t){return this.json(`/v1/workers/${encodeURIComponent(e)}/recover`,{method:`POST`,body:JSON.stringify({grant:t})})}reconcile(e,t,n){return this.json(`/v1/workers/${encodeURIComponent(e)}/reconcile`,{method:`POST`,body:JSON.stringify({reconciliation:t,grant:n})})}},Lr=class extends Fr{list(e){return this.json(`/v1/worker-pools?application_id=${encodeURIComponent(e)}`)}create(e,t){return this.json(`/v1/worker-pools`,{method:`POST`,body:JSON.stringify({pool:e,grant:t})})}inspect(e){return this.json(`/v1/worker-pools/${encodeURIComponent(e)}`)}},Rr=class extends Fr{async status(e){let[t,n]=await Promise.all([new Ir(this.baseUrl,this.fetcher).list(e),new Lr(this.baseUrl,this.fetcher).list(e)]);return{workers:t.workers,pools:n.pools,ready:t.workers.filter(e=>e.lifecycle===`READY`).length,busy:t.workers.filter(e=>e.lifecycle===`BUSY`).length}}eligibleWorkers(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/eligible-workers`)}},zr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Artifact request failed (${n.status})`);return r}async create(e){let t=new URLSearchParams({application_id:e.applicationId,kind:typeof e.kind==`string`?e.kind:`OTHER(${e.kind.OTHER})`,name:e.name,content_type:e.contentType,producer_kind:e.producerKind||`human`,producer_id:e.producerId||``});for(let n of e.parents||[])t.append(`parents`,n);for(let[n,r]of Object.entries({supersedes:e.supersedes,revision:e.revision,workload:e.workload,execution:e.execution}))r&&t.set(n,r);return this.json(`/v1/artifacts?${t}`,{method:`POST`,headers:{"content-type":e.contentType},body:(e.content instanceof Blob||e.content instanceof Uint8Array,e.content)})}list(e){return this.json(`/v1/artifacts?application_id=${encodeURIComponent(e)}`)}get(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}`)}async content(e){let t=await this.fetcher(`${this.baseUrl}/v1/artifacts/${encodeURIComponent(e)}/content`,{credentials:`include`});if(!t.ok)throw Error(`Artifact content failed (${t.status})`);return new Uint8Array(await t.arrayBuffer())}provenance(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/provenance`)}parents(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/parents`)}children(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/children`)}archive(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/archive`,{method:`POST`})}restore(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/restore`,{method:`POST`})}},Br=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Bundle request failed (${n.status})`);return r}export(e,t={}){return this.json(`/v1/bundles/export`,{method:`POST`,body:JSON.stringify({application_id:e,options:t})})}inspect(e){return this.json(`/v1/bundles/${encodeURIComponent(e)}`)}verify(e){return this.json(`/v1/bundles/${encodeURIComponent(e)}/verify`,{method:`POST`})}planImport(e,t,n,r){return this.json(`/v1/bundles/import/plan`,{method:`POST`,body:JSON.stringify({bundle:e,mode:t,destination_tenant:n,destination_application:r})})}import(e,t,n,r){return this.json(`/v1/bundles/import/apply`,{method:`POST`,body:JSON.stringify({bundle:e,mode:t,destination_tenant:n,destination_application:r})})}},Vr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Release request failed (${n.status})`);return r}create(e){return this.json(`/v1/releases`,{method:`POST`,body:JSON.stringify({manifest:e})})}list(e){return this.json(`/v1/releases?application_id=${encodeURIComponent(e)}`)}get(e){return this.json(`/v1/releases/${encodeURIComponent(e)}`)}verify(e){return this.json(`/v1/releases/${encodeURIComponent(e)}/verify`,{method:`POST`})}promote(e,t,n){return this.json(`/v1/releases/${encodeURIComponent(e)}/promote`,{method:`POST`,body:JSON.stringify({application_id:t,environment:n})})}plan(e,t,n){return this.json(`/v1/deployments/plan`,{method:`POST`,body:JSON.stringify({release_id:e,environment:t,rollback_target:n})})}deploy(e){return this.json(`/v1/deployments`,{method:`POST`,body:JSON.stringify({plan:e})})}status(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}`)}health(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}/health`)}stop(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}/stop`,{method:`POST`})}},Hr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Observe request failed (${n.status})`);return r}events(e){return this.json(`/v1/observability/events?application_id=${encodeURIComponent(e)}`)}cause(e){return this.json(`/v1/observability/causes/${encodeURIComponent(e)}`)}workload(e){return this.json(`/v1/observability/workloads/${encodeURIComponent(e)}/timeline`)}execution(e){return this.json(`/v1/observability/executions/${encodeURIComponent(e)}/timeline`)}revision(e){return this.json(`/v1/observability/revisions/${encodeURIComponent(e)}/timeline`)}append(e){return this.json(`/v1/observability/events`,{method:`POST`,body:JSON.stringify({event:e})})}},Ur=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Provider request failed (${n.status})`);return r}list(){return this.json(`/v1/providers`)}inspect(e){return this.json(`/v1/providers/${encodeURIComponent(e)}`)}install(e,t,n){return this.json(`/v1/providers`,{method:`POST`,body:JSON.stringify({manifest:e,tenant_id:t,application_id:n})})}enable(e){return this.status(e,`ENABLED`)}disable(e){return this.status(e,`DISABLED`)}revoke(e){return this.status(e,`REVOKED`)}status(e,t){return this.json(`/v1/providers/${encodeURIComponent(e)}/status`,{method:`POST`,body:JSON.stringify({status:t})})}health(e){return this.json(`/v1/providers/${encodeURIComponent(e)}/health`)}dependencies(e){return this.json(`/v1/providers/${encodeURIComponent(e)}/dependencies`)}};function Wr(e){if(!e?.namespace?.trim())throw Error(`createFeltDB requires a non-empty namespace`);return new Gr(e.server?new I(e.server):`browser`in e&&e.browser?new Sr(e.namespace):new xr(e.namespace))}var Gr=class{constructor(e){this.collections=new Map,this.capabilityWorkers=new Map,this.workloads=new Pr,this.artifacts=new zr,this.bundle=new Br,this.releases=new Vr,this.observe=new Hr,this.providers=new Ur,this.workers=new Ir,this.workerPools=new Lr,this.mesh=new Rr,this.jsDb=e,this.runtimeInfo=this.detectRuntime(),this.agentRegistry=new _r;let t={persistent:this.runtimeInfo.persistent,executionTimeoutMs:3e4,supportsReactiveTriggers:!0,defaultRetryPolicy:{maxAttempts:3,backoffMs:1e3}};this.agentRuntime=new yr(this.agentRegistry,t)}detectRuntime(){let e=typeof window<`u`&&typeof document<`u`,t=typeof globalThis<`u`&&`versions`in globalThis&&`node`in globalThis.versions,n=this.jsDb instanceof xr,r=this.jsDb instanceof I,i=this.jsDb instanceof Sr,a=`memory`,o=!1;return r?(a=`remote`,o=!0):n?a=`memory`:i?(a=`indexeddb`,o=!0):t&&(a=`file`,o=!0),{runtime:r?`remote`:i||e?`browser`:t?`node`:`wasm`,storage:a,persistent:o,reactive:!0,durable:o,version:`0.1.0`,supportsCheckpointing:o,supportsLifecycle:e||i}}runtime(){return{...this.runtimeInfo}}collection(e){return this.collections.has(e)||this.collections.set(e,new mr(this.jsDb,e)),this.collections.get(e)}async acquire(e,t){return this.jsDb instanceof I?this.jsDb.acquire(e,t):this.collection(e).get(t)}async search(e,t,n=50){if(this.jsDb instanceof I)return this.jsDb.search(e,t,n);let r=t.toLowerCase();return(await this.collection(e).all()).filter(e=>JSON.stringify(e).toLowerCase().includes(r)).slice(0,n)}async defineCapability(e,t){if(!(this.jsDb instanceof I))throw Error(`Distributed capabilities require a server runtime`);return this.jsDb.command(`/capabilities/${encodeURIComponent(e)}`,{steps:t})}registerCapabilityWorker(e,t){if(this.jsDb instanceof I)throw Error(`Remote capability workers are installed on the server`);return this.capabilityWorkers.set(e,t),()=>this.capabilityWorkers.delete(e)}async executeCapability(e,t){if(this.jsDb instanceof I)return this.jsDb.command(`/capabilities/${encodeURIComponent(e)}/execute`,t);let n=this.capabilityWorkers.get(e);if(!n)throw Error(`No embedded capability worker registered for ${e}`);let r=`cap-${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,i=this.collection(`_flow_executions`);await i.insert({id:r,capability:e,input:t,status:`running`,owner:this.instanceId(),started_at:Date.now()},r);try{let e=await n(t);return await i.update(r,{status:`completed`,output:e,completed_at:Date.now()}),e}catch(e){throw await i.update(r,{status:`failed`,error:e instanceof Error?e.message:String(e),completed_at:Date.now()}),e}}async changeClusterMembership(e,t){if(!(this.jsDb instanceof I))throw Error(`Cluster membership requires a server runtime`);return this.jsDb.command(`/cluster/members`,{expected_epoch:e,peers:t})}async deployFlowSpec(e,t,n=!1){let r=Er(e).filter(e=>e.severity===`error`);if(r.length)throw Error(r.map(e=>e.message).join(`; `));let i=this.collection(`_flow_apps`),a=await i.get(e.app),o=(a?.version??0)+1;if(t!==void 0&&(a?.version??0)!==t)throw Error(`FlowSpec version conflict: expected ${t}, found ${a?.version??0}`);let s=Ar(a?.spec??jr(e.app),e),c=s.filter(e=>e.safety===`destructive`);if(c.length&&!n)throw Error(`Destructive migration requires explicit approval: ${c.map(e=>e.target).join(`, `)}`);let l={id:e.app,app:e.app,version:o,status:`deploying`,spec:e,migration:s,deployed_at:Date.now()};a?await i.update(e.app,l):await i.insert(l,e.app);let u=(t,n)=>`${e.app}-${t}-${n}`.replace(/[^A-Za-z0-9_-]/g,`_`),d=async(t,n,r,i)=>{let a=this.collection(t),s=new Set(i.map(e=>e.name??e.event??`unnamed`));for(let e of r){let t=e.name??e.event??`unnamed`;s.has(t)||await a.delete(u(n,t))}for(let t of i){let r=t.name??t.event??`unnamed`,i=u(n,r),s={id:i,app:e.app,version:o,...t};await a.get(i)?await a.update(i,s):await a.insert(s,i)}},f=a?.spec??jr(e.app);if(await d(`_flow_collection_models`,`collection`,f.collections,e.collections),await d(`_flow_capability_models`,`capability`,f.capabilities,e.capabilities),await d(`_flow_trigger_models`,`trigger`,f.triggers,e.triggers),await d(`_flow_policy_models`,`policy`,f.policies,e.policies),await d(`_flow_schedule_models`,`schedule`,f.schedules,e.schedules),this.jsDb instanceof I){for(let t of f.workflows)e.workflows.some(e=>e.name===t.name)||await this.collection(`_flow_workflows`).delete(u(`workflow`,t.name));for(let t of f.agents)e.agents.some(e=>e.name===t.name)||await this.collection(`_flow_agents`).delete(u(`agent`,t.name));for(let t of e.workflows)await this.defineWorkflow(u(`workflow`,t.name),t.steps.map(e=>e.name));for(let t of e.agents){let n=t.statements.filter(e=>e.startsWith(`capability `)).map(e=>e.slice(11).trim());await this.defineStateAgent(u(`agent`,t.name),n,{flowspec_app:e.app,flowspec_version:o})}}else await d(`_flow_workflows`,`workflow`,f.workflows,e.workflows),await d(`_flow_agents`,`agent`,f.agents,e.agents);let p={...l,status:`active`};return await i.update(e.app,p),await this.collection(`_flow_app_versions`).insert({id:`${e.app}-${o}`,app:e.app,version:o,spec:e,migration:s,deployed_at:p.deployed_at},`${e.app}-${o}`),{app:e.app,version:o,status:`active`}}async auditEvents(){return this.jsDb.audit_events?await this.jsDb.audit_events():[]}async exportOperations(e=0){if(!this.jsDb.export_operations)throw Error(`This runtime uses server-managed replication`);return await this.jsDb.export_operations(e)}async applyOperations(e){if(!this.jsDb.apply_remote_operations)throw Error(`This runtime uses server-managed replication`);return await this.jsDb.apply_remote_operations(e)}async synchronizeWith(e){let t=await this.exportOperations(),n=await e.exportOperations();await this.addSyncPeer(e.instanceId()),await e.addSyncPeer(this.instanceId());let r=await e.applyOperations(t),i=await this.applyOperations(n);return{sent:t.length,received:n.length,applied:i.applied+r.applied,ignored:i.ignored+r.ignored}}async executeCapabilityWithFailover(e,t,n=[]){let r=this.collection(`_flow_capability_routes`),i=`route-${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,a=[this,...n],o=[];await r.insert({id:i,capability:e,status:`routing`,input:t,candidates:a.map(e=>e.instanceId()),started_at:Date.now()},i);for(let n of a)try{let a=await n.executeCapability(e,t);return await r.update(i,{status:`completed`,provider:n.instanceId(),attempts:o.length+1,failures:o,completed_at:Date.now()}),{output:a,provider:n.instanceId(),attempts:o.length+1}}catch(e){o.push({provider:n.instanceId(),error:e instanceof Error?e.message:String(e)})}throw await r.update(i,{status:`failed`,attempts:o.length,failures:o,completed_at:Date.now()}),Error(`No provider could execute capability ${e}: ${o.map(e=>e.error).join(`; `)}`)}async recordProvenance(e,t){if(!(this.jsDb instanceof I))throw Error(`Causal provenance requires a server runtime`);return this.jsDb.provenance(e,t)}async storeContent(e){if(!(this.jsDb instanceof I))throw Error(`Durable content storage requires a server runtime`);return this.jsDb.storeContent(e)}async acquireContent(e){if(!(this.jsDb instanceof I))throw Error(`Network content acquisition requires a server runtime`);return this.jsDb.acquireContent(e)}async defineWorkflow(e,t){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflows/${encodeURIComponent(e)}`,{steps:t})}async startWorkflow(e,t=null){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflows/${encodeURIComponent(e)}/runs`,{input:t})}async claimWorkflowStep(e,t,n,r=3e4){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflow-runs/${encodeURIComponent(e)}/steps/${encodeURIComponent(t)}/claim`,{worker:n,lease_ms:r})}async completeWorkflowStep(e,t,n,r=null){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflow-runs/${encodeURIComponent(e)}/steps/${encodeURIComponent(t)}/complete`,{claim_id:n,result:r})}async defineStateAgent(e,t=[],n=null){if(!(this.jsDb instanceof I))throw Error(`Durable agent coordination requires a server runtime`);return this.jsDb.command(`/agents/${encodeURIComponent(e)}`,{capabilities:t,constraints:n})}async startStateAgent(e,t,n=null){if(!(this.jsDb instanceof I))throw Error(`Durable agent coordination requires a server runtime`);return this.jsDb.command(`/agents/${encodeURIComponent(e)}/runs`,{goal:t,input:n})}defineAgent(e){let t=hr(e.name,e.version);return this.agentRegistry.register(t,e),t}agent(e){return this.agentRegistry.getByName(e)?.agentRef}getAgentRegistry(){return this.agentRegistry}getAgentRuntime(){return this.agentRuntime}async createAgentExecution(e,t,n){let r=await this.agentRuntime.createExecution(this,e,t,n);return await this.collection(`_flow_agent_executions`).insert(this.agentExecutionRecord(r),r.executionId),r}agentExecutionRecord(e){return{...e,id:e.executionId,agentRef:e.agentRef.toString()}}async startAgentExecution(e,t=this.instanceId()){await this.agentRuntime.start(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async transitionAgentExecution(e,t){await this.agentRuntime.transition(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async completeAgentExecution(e,t){await this.agentRuntime.complete(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async failAgentExecution(e,t){await this.agentRuntime.fail(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async close(){for(let e of this.collections.values())e.close();this.collections.clear(),await this.jsDb.close?.()}sync(e){if(e)return new Nr(e);let t=this.jsDb.sync_info();if(!t.success||!t.data)throw Error(t.error||`Failed to get sync info`);return JSON.parse(t.data)}async addSyncPeer(e){let t=this.jsDb.add_sync_peer(e);if(!t.success)throw Error(t.error||`Failed to add peer`)}async removeSyncPeer(e){let t=this.jsDb.remove_sync_peer(e);if(!t.success)throw Error(t.error||`Failed to remove peer`)}async getPendingForPeer(e,t){let n=this.jsDb.get_pending_for_peer(e,t);if(!n.success||!n.data)throw Error(n.error||`Failed to get pending operations`);return JSON.parse(n.data)}async acknowledgePeerOperations(e,t){let n=this.jsDb.acknowledge_peer_operations(e,t);if(!n.success)throw Error(n.error||`Failed to acknowledge operations`)}instanceId(){return this.jsDb.instance_id()}getSequence(){return this.jsDb.get_sequence()}async registerTrigger(e){}async scheduleCron(e){}async getPendingExecutions(){return[]}async completeExecution(e,t){}provenance(e){let[t,...n]=e.split(`://`)[1]?.split(`/`)||[],r={id:e,type:`Record`,label:n.join(`/`)||e,created_ms:Date.now()};return{root:r,nodes:[r],edges:[]}}health(){let e=this.sync(),t=this.runtime(),n=e.is_connected&&e.pending_operations===0?`healthy`:`degraded`,r=[];e.pending_operations>0&&r.push({severity:`info`,component:`sync`,message:`${e.pending_operations} pending operations`}),e.is_connected||r.push({severity:`warning`,component:`sync`,message:`Network disconnected`}),e.conflicts_detected>0&&r.push({severity:`warning`,component:`sync`,message:`${e.conflicts_detected} conflicts detected`});let i=r.length>0?`degraded`:`healthy`;return{runtime:{status:`healthy`,wasm:t.runtime===`wasm`||t.runtime===`browser`,reactive:t.reactive},storage:{status:`healthy`,backend:t.storage,persistent:t.persistent,durable:t.durable},sync:{status:n,connected:e.is_connected,peers:e.connected_peers.length,pendingOperations:e.pending_operations},fabric:{status:`healthy`,references:0,peers:e.connected_peers.length},capabilities:{status:`healthy`,count:0,available:0},execution:{status:`healthy`,pending:0,running:0,failed:0},workflow:{status:`healthy`,total:0,active:0},status:i,issues:r}}},Kr;(function(e){e.Insert=`Insert`,e.Update=`Update`,e.Delete=`Delete`,e.Query=`Query`,e.Upsert=`Upsert`})(Kr||={});var qr;(function(e){e.Pending=`Pending`,e.Running=`Running`,e.Succeeded=`Succeeded`,e.Failed=`Failed`,e.RetryScheduled=`RetryScheduled`,e.DeadLettered=`DeadLettered`})(qr||={});var Jr=Or({...jr(`ResearchPlatform`),collections:[{name:`User`,fields:[{name:`name`,type:`text`,optional:!1},{name:`email`,type:`text`,optional:!1}],indexes:[]},{name:`Document`,fields:[{name:`title`,type:`text`,optional:!1},{name:`content`,type:`text`,optional:!1},{name:`author`,type:`ref User`,optional:!1}],indexes:[{name:`search`,kind:`fulltext`,expression:`(content)`}]}]});function Yr({db:e,namespace:t=`default`,projectSpec:n,onSpecChange:r}){let i=`feltdb:studio:draft:${t}`,a=(0,g.useRef)((()=>{if(typeof window>`u`)return Jr;let e=window.localStorage.getItem(i);if(!e)return Jr;try{return Tr(e),e}catch{return Jr}})()),o=(0,g.useRef)(a.current!==Jr),[s,c]=(0,g.useState)(a.current),[l,u]=(0,g.useState)(()=>Tr(a.current)),[d,f]=(0,g.useState)([]),[p,m]=(0,g.useState)([]),[h,_]=(0,g.useState)(`Draft is valid`),[v,y]=(0,g.useState)(0),[b,x]=(0,g.useState)(null),[S,C]=(0,g.useState)(null),[w,T]=(0,g.useState)(!1),[ee,te]=(0,g.useState)(!1),[E,D]=(0,g.useState)({url:``,namespace:t,token:``,allowDestructive:!1}),ne=(0,g.useRef)(null),re=p.length?p[p.length-1].source:Or(jr(l.app)),ie=(0,g.useMemo)(()=>kr(Tr(re),l),[re,l]),ae=(0,g.useMemo)(()=>Ar(Tr(re),l),[re,l]);(0,g.useEffect)(()=>{if(!e)return;let t=!1;return(async()=>{try{let n=await e.collection(`_flow_apps`).all(),r=n.find(e=>e.status===`active`)??n[0];if(!r||t)return;let i=Or(r.spec);o.current||(u(r.spec),c(i)),y(r.version??0);let a=(await e.collection(`_flow_app_versions`).all()).filter(e=>e.app===r.app).sort((e,t)=>e.version-t.version);t||(m(a.map(e=>({version:e.version,source:Or(e.spec),savedAt:e.deployed_at}))),_(`Loaded ${r.app} v${r.version}`))}catch(e){t||_(`Could not load deployed model: ${e instanceof Error?e.message:String(e)}`)}})(),()=>{t=!0}},[e]),(0,g.useEffect)(()=>{let e=window.setTimeout(()=>window.localStorage.setItem(i,s),200);return()=>window.clearTimeout(e)},[i,s]);let O=e=>{c(e);try{let t=Tr(e),n=Er(t);u(t),r?.(t),f(n),_(n.some(e=>e.severity===`error`)?`Model has validation errors`:`Draft is valid`)}catch(e){f([{severity:`error`,message:e instanceof Error?e.message:String(e)}]),_(`DSL parse failed`)}};(0,g.useEffect)(()=>{if(!n||o.current&&l.app===n.app)return;let e=Or(n);c(e),u(n),f(Er(n)),_(`Loaded ${n.app} project model`)},[n]);let oe=e=>{u(e),O(Or(e))},se=()=>{if(!S)return C({name:``});let e=S.name.trim();if(!/^[A-Z][A-Za-z0-9_]*$/.test(e))return C({...S,error:`Use a capitalized name with no spaces.`});if(l.collections.some(t=>t.name===e))return C({...S,error:`That collection already exists.`});oe({...l,collections:[...l.collections,{name:e,fields:[],indexes:[]}]}),C(null)},ce=e=>x({collection:e,name:``,type:`text`,reference:l.collections.find(t=>t.name!==e)?.name??``,optional:!1}),le=()=>{if(!b)return;let e=b.name.trim(),t=l.collections.find(e=>e.name===b.collection);if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))return x({...b,error:`Use a letter-led name with no spaces.`});if(t?.fields.some(t=>t.name===e))return x({...b,error:`That field already exists.`});if(b.type===`ref`&&!b.reference)return x({...b,error:`Choose a referenced collection.`});let n=b.type===`ref`?`ref ${b.reference}`:b.type;oe({...l,collections:l.collections.map(t=>t.name===b.collection?{...t,fields:[...t.fields,{name:e,type:n,optional:b.optional}]}:t)}),x(null)},k=()=>{let e=[...p,{version:p.length+1,source:s,savedAt:Date.now()}];m(e),_(`Saved local revision v${e.length}`)},ue=async()=>{if(!e)return _(`Local embedded storage is unavailable`);if(d.some(e=>e.severity===`error`))return _(`Resolve validation errors before deploying`);if(ae.filter(e=>e.safety===`destructive`).length&&!w)return _(`Review and approve destructive local changes before applying`);try{let t=await e.deployFlowSpec(l,v,w),n=[...p,{version:t.version,source:s,savedAt:Date.now()}];m(n),y(t.version),T(!1),_(`Applied locally as ${t.app} v${t.version}`)}catch(e){_(`Local apply failed: ${e instanceof Error?e.message:String(e)}`)}},de=async()=>{if(!E.url.trim()||!E.token.trim())return D({...E,error:`Cloud URL and API key are required.`});if(d.some(e=>e.severity===`error`))return D({...E,error:`Resolve validation errors before publishing.`});D({...E,publishing:!0,error:void 0});let e=Wr({namespace:E.namespace.trim()||t,server:{url:E.url.trim().replace(/\/$/,``),token:E.token}});try{let t=await e.collection(`_flow_apps`).get(l.app),n=Ar(t?.spec??jr(l.app),l).filter(e=>e.safety===`destructive`);if(n.length&&!E.allowDestructive)return D({...E,publishing:!1,destructive:n.map(e=>e.target),error:`Review and approve destructive changes: ${n.map(e=>e.target).join(`, `)}`});let r=await e.deployFlowSpec(l,t?.version??0,E.allowDestructive);window.sessionStorage.setItem(`feltdb-token:${E.url.trim()}`,E.token),D({...E,publishing:!1,token:``,error:void 0}),te(!1),_(`Published ${r.app} v${r.version} to cloud`)}catch(e){D({...E,publishing:!1,error:e instanceof Error?e.message:String(e)})}finally{await e.close()}},fe=()=>{let e=URL.createObjectURL(new Blob([s],{type:`text/plain`})),t=document.createElement(`a`);t.href=e,t.download=`feltdb.flow`,t.click(),URL.revokeObjectURL(e)},pe=async e=>{e&&O(await e.text())},me=[[`Data`,l.collections.map(e=>e.name)],[`Capabilities`,l.capabilities.map(e=>e.name)],[`Agents`,l.agents.map(e=>e.name)],[`Workflows`,l.workflows.map(e=>e.name)],[`Triggers`,l.triggers.map(e=>e.event)],[`Policies`,l.policies.map(e=>e.name)],[`Schedules`,l.schedules.map(e=>e.name)]];return(0,P.jsxs)(`div`,{className:`application-designer`,children:[(0,P.jsxs)(`header`,{className:`designer-header`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`span`,{className:`eyebrow`,children:`Application fabric`}),(0,P.jsx)(`h1`,{children:l.app}),(0,P.jsx)(`p`,{children:`One model for state, intelligence, automation, security, and placement.`})]}),(0,P.jsxs)(`div`,{className:`designer-actions`,children:[(0,P.jsx)(`input`,{ref:ne,hidden:!0,type:`file`,accept:`.flow,text/plain`,onChange:e=>void pe(e.target.files?.[0])}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>ne.current?.click(),children:`Import`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:fe,children:`Export`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:k,children:`Version`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>void ue(),children:`Apply locally`}),(0,P.jsx)(`button`,{className:`btn btn-primary`,onClick:()=>te(e=>!e),children:`Publish to cloud`})]})]}),ae.some(e=>e.safety===`destructive`)&&(0,P.jsxs)(`label`,{className:`local-destructive`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:w,onChange:e=>T(e.target.checked)}),(0,P.jsxs)(`span`,{children:[`Approve destructive local changes: `,ae.filter(e=>e.safety===`destructive`).map(e=>e.target).join(`, `)]})]}),ee&&(0,P.jsxs)(`form`,{className:`cloud-publisher`,onSubmit:e=>{e.preventDefault(),de()},children:[(0,P.jsxs)(`div`,{className:`cloud-publisher-heading`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`span`,{className:`eyebrow`,children:`Cloud release`}),(0,P.jsx)(`h2`,{children:`Publish this application model`}),(0,P.jsx)(`p`,{children:`FeltDB compares the cloud version, plans the migration, and publishes atomically.`})]}),(0,P.jsx)(`button`,{type:`button`,"aria-label":`Close cloud publisher`,onClick:()=>te(!1),children:`×`})]}),(0,P.jsxs)(`div`,{className:`cloud-fields`,children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`FeltDB Cloud URL`}),(0,P.jsx)(`input`,{type:`url`,placeholder:`https://your-instance.feltdb.cloud`,value:E.url,onChange:e=>D({...E,url:e.target.value,error:void 0,destructive:void 0,allowDestructive:!1})})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Namespace`}),(0,P.jsx)(`input`,{value:E.namespace,onChange:e=>D({...E,namespace:e.target.value,error:void 0,destructive:void 0,allowDestructive:!1})})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`API key`}),(0,P.jsx)(`input`,{type:`password`,autoComplete:`off`,placeholder:`Stored for this browser session only`,value:E.token,onChange:e=>D({...E,token:e.target.value,error:void 0})})]})]}),(E.destructive?.length||ae.some(e=>e.safety===`destructive`))&&(0,P.jsxs)(`label`,{className:`cloud-destructive`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:E.allowDestructive,onChange:e=>D({...E,allowDestructive:e.target.checked})}),(0,P.jsxs)(`span`,{children:[`I reviewed and approve destructive model changes`,E.destructive?.length?`: ${E.destructive.join(`, `)}`:`.`]})]}),E.error&&(0,P.jsx)(`div`,{className:`cloud-error`,role:`alert`,children:E.error}),(0,P.jsxs)(`div`,{className:`cloud-actions`,children:[(0,P.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,onClick:()=>te(!1),children:`Cancel`}),(0,P.jsx)(`button`,{className:`btn btn-primary`,disabled:E.publishing,type:`submit`,children:E.publishing?`Publishing…`:`Review and publish`})]})]}),(0,P.jsxs)(`div`,{className:`designer-status ${d.some(e=>e.severity===`error`)?`error`:``}`,children:[(0,P.jsx)(`span`,{children:h}),(0,P.jsxs)(`span`,{children:[l.collections.length,` collections · `,l.workflows.length,` workflows · `,p.length?`v${p.length}`:`draft`]})]}),(0,P.jsxs)(`div`,{className:`designer-grid`,children:[(0,P.jsxs)(`aside`,{className:`model-tree`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Application`}),(0,P.jsx)(`button`,{"aria-label":`Add collection`,onClick:()=>C({name:``}),children:`+`})]}),S&&(0,P.jsxs)(`form`,{className:`collection-editor`,onSubmit:e=>{e.preventDefault(),se()},onKeyDown:e=>{e.key===`Escape`&&C(null)},children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`New collection`}),(0,P.jsx)(`input`,{autoFocus:!0,placeholder:`e.g. Customer`,value:S.name,onChange:e=>C({name:e.target.value})})]}),S.error&&(0,P.jsx)(`div`,{className:`field-error`,role:`alert`,children:S.error}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`button`,{type:`button`,onClick:()=>C(null),children:`Cancel`}),(0,P.jsx)(`button`,{className:`collection-save`,type:`submit`,children:`Add`})]})]}),me.map(([e,t])=>(0,P.jsxs)(`section`,{children:[(0,P.jsx)(`h3`,{children:e}),t.length?t.map(e=>(0,P.jsx)(`div`,{className:`tree-item`,children:e},e)):(0,P.jsx)(`div`,{className:`tree-empty`,children:`None`})]},e))]}),(0,P.jsxs)(`section`,{className:`model-canvas`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Application graph`}),(0,P.jsx)(`span`,{className:`graph-legend`,children:`intent → fabric`})]}),(0,P.jsxs)(`div`,{className:`graph-board`,children:[l.collections.map(e=>(0,P.jsxs)(`article`,{className:`model-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`collection`}),(0,P.jsx)(`h3`,{children:e.name}),e.fields.map(e=>(0,P.jsxs)(`div`,{className:`node-field`,children:[(0,P.jsx)(`span`,{children:e.name}),(0,P.jsxs)(`code`,{children:[e.type,e.optional?`?`:``]})]},e.name)),b?.collection===e.name?(0,P.jsxs)(`form`,{className:`field-editor`,onSubmit:e=>{e.preventDefault(),le()},onKeyDown:e=>{e.key===`Escape`&&x(null)},children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Field name`}),(0,P.jsx)(`input`,{autoFocus:!0,value:b.name,placeholder:`e.g. publishedAt`,onChange:e=>x({...b,name:e.target.value,error:void 0})})]}),(0,P.jsxs)(`div`,{className:`field-editor-row`,children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Type`}),(0,P.jsxs)(`select`,{value:b.type,onChange:e=>x({...b,type:e.target.value,error:void 0}),children:[(0,P.jsx)(`option`,{value:`text`,children:`Text`}),(0,P.jsx)(`option`,{value:`number`,children:`Number`}),(0,P.jsx)(`option`,{value:`boolean`,children:`Boolean`}),(0,P.jsx)(`option`,{value:`datetime`,children:`Date & time`}),(0,P.jsx)(`option`,{value:`json`,children:`JSON`}),(0,P.jsx)(`option`,{value:`ref`,children:`Reference`})]})]}),b.type===`ref`&&(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Collection`}),(0,P.jsx)(`select`,{value:b.reference,onChange:e=>x({...b,reference:e.target.value,error:void 0}),children:l.collections.filter(t=>t.name!==e.name).map(e=>(0,P.jsx)(`option`,{value:e.name,children:e.name},e.name))})]})]}),(0,P.jsxs)(`label`,{className:`field-optional`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:b.optional,onChange:e=>x({...b,optional:e.target.checked})}),(0,P.jsx)(`span`,{children:`Optional field`})]}),b.error&&(0,P.jsx)(`div`,{className:`field-error`,role:`alert`,children:b.error}),(0,P.jsxs)(`div`,{className:`field-editor-actions`,children:[(0,P.jsx)(`button`,{type:`button`,onClick:()=>x(null),children:`Cancel`}),(0,P.jsx)(`button`,{className:`field-save`,type:`submit`,children:`Add field`})]})]}):(0,P.jsx)(`button`,{className:`node-add`,onClick:()=>ce(e.name),children:`+ field`})]},e.name)),l.workflows.map(e=>(0,P.jsxs)(`article`,{className:`model-node workflow-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`workflow`}),(0,P.jsx)(`h3`,{children:e.name}),e.steps.map(e=>(0,P.jsx)(`div`,{className:`node-step`,children:e.name},e.name))]},e.name)),l.agents.map(e=>(0,P.jsxs)(`article`,{className:`model-node agent-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`agent`}),(0,P.jsx)(`h3`,{children:e.name}),e.statements.map(e=>(0,P.jsx)(`div`,{className:`node-step`,children:e},e))]},e.name))]}),(0,P.jsxs)(`div`,{className:`change-strip`,children:[(0,P.jsx)(`strong`,{children:`Model diff`}),(0,P.jsxs)(`span`,{className:`added`,children:[`+ `,ie.added.join(`, `)||`none`]}),(0,P.jsxs)(`span`,{className:`changed`,children:[`~ `,ie.changed.join(`, `)||`none`]}),(0,P.jsxs)(`span`,{className:`removed`,children:[`− `,ie.removed.join(`, `)||`none`]})]})]}),(0,P.jsxs)(`section`,{className:`dsl-panel`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Flow DSL`}),(0,P.jsx)(`span`,{children:`feltdb.flow`})]}),(0,P.jsx)(`textarea`,{"aria-label":`Flow DSL`,spellCheck:!1,value:s,onChange:e=>O(e.target.value)}),d.length>0&&(0,P.jsx)(`div`,{className:`diagnostics`,children:d.map((e,t)=>(0,P.jsxs)(`div`,{className:e.severity,children:[e.severity,`: `,e.message]},t))})]})]})]})}var L={panel:`_panel_1cbba_1`,header:`_header_1cbba_8`,createButton:`_createButton_1cbba_23`,error:`_error_1cbba_38`,createForm:`_createForm_1cbba_47`,formGroup:`_formGroup_1cbba_55`,scopeList:`_scopeList_1cbba_76`,scopeCheckbox:`_scopeCheckbox_1cbba_82`,submitButton:`_submitButton_1cbba_94`,empty:`_empty_1cbba_109`,keysList:`_keysList_1cbba_117`,keyCard:`_keyCard_1cbba_123`,keyHeader:`_keyHeader_1cbba_135`,namespace:`_namespace_1cbba_150`,status:`_status_1cbba_156`,active:`_active_1cbba_163`,expired:`_expired_1cbba_168`,keyDetails:`_keyDetails_1cbba_173`,detail:`_detail_1cbba_179`,copyBtn:`_copyBtn_1cbba_203`,daysLeft:`_daysLeft_1cbba_217`,scopes:`_scopes_1cbba_223`,scopeTags:`_scopeTags_1cbba_227`,scopeTag:`_scopeTag_1cbba_227`,keyActions:`_keyActions_1cbba_243`,revokeBtn:`_revokeBtn_1cbba_250`,info:`_info_1cbba_265`},Xr=({apiUrl:e,token:t,namespace:n=`app-store-sherpa`,onConfigure:r})=>{let[i,a]=(0,g.useState)([]),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)(!1),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(``),[_,v]=(0,g.useState)([`state:read`,`state:write`,`events:read`]),y=[`state:read`,`state:write`,`events:read`,`backup:create`,`backup:restore`,`admin:logs`,`admin:restart`],b=[`state:read`,`state:write`,`events:read`,`backup:create`,`backup:restore`,`admin:logs`,`admin:restart`];(0,g.useEffect)(()=>{x()},[e,t]);let x=async()=>{try{if(s(!0),l(null),!e){l(`A server or managed API URL is not configured.`),s(!1);return}let n=await fetch(`${e}/api/keys`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)});if(n.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(n.status===403)throw Error(`Forbidden: Your account does not have permission to manage API keys`);if(!n.ok)throw Error(`Failed to fetch keys: ${n.status} ${n.statusText}`);let r=await n.json();a(r.tokens||[])}catch(t){let n=t instanceof TypeError?`Connection error: Unable to reach ${e}. Is the server running?`:t instanceof Error?t.message:`Failed to fetch keys`;l(n),console.error(`Error fetching API keys:`,t)}finally{s(!1)}},S=async r=>{r.preventDefault();try{let r=await fetch(`${e}/api/keys`,{method:`POST`,headers:{...t?{Authorization:`Bearer ${t}`}:{},"Content-Type":`application/json`},body:JSON.stringify({id:m||`key-${Date.now()}`,namespace:n,scopes:_.length>0?_:b}),signal:AbortSignal.timeout(1e4)});if(r.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(r.status===409)throw Error(`A key with this name already exists`);if(!r.ok)throw Error(`Failed to create key: ${r.status} ${r.statusText}`);let i=await r.json();ee(i.secret),h(``),v(b),d(!1),await x()}catch(e){let t=e instanceof TypeError?`Connection error: Unable to reach the API server`:e instanceof Error?e.message:`Failed to create key`;l(t),console.error(`Error creating API key:`,e)}},C=async n=>{if(confirm(`Revoke key "${n}"? This cannot be undone.`))try{let r=await fetch(`${e}/api/keys/${n}`,{method:`DELETE`,headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)});if(r.status===404)throw Error(`Key not found`);if(r.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(!r.ok)throw Error(`Failed to revoke key: ${r.status} ${r.statusText}`);await x()}catch(e){let t=e instanceof TypeError?`Connection error: Unable to reach the API server`:e instanceof Error?e.message:`Failed to revoke key`;l(t),console.error(`Error revoking API key:`,e)}},w=(e,t)=>{navigator.clipboard.writeText(e),p(t),setTimeout(()=>p(null),2e3)},[T,ee]=(0,g.useState)(null);return o?(0,P.jsx)(`div`,{className:L.panel,children:`Loading keys...`}):(0,P.jsxs)(`div`,{className:L.panel,children:[(0,P.jsxs)(`div`,{className:L.header,children:[(0,P.jsx)(`h2`,{children:`API Key Management`}),(0,P.jsx)(`button`,{className:L.createButton,onClick:()=>d(!u),disabled:!e,children:u?`✕ Cancel`:`+ New Key`})]}),c&&(0,P.jsxs)(`div`,{className:L.error,children:[(0,P.jsxs)(`strong`,{children:[`⚠ `,c]}),(0,P.jsx)(`div`,{style:{fontSize:`12px`,marginTop:`8px`,lineHeight:`1.5`},children:c.includes(`Connection error`)&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(`p`,{children:`To use API key management, ensure:`}),(0,P.jsxs)(`ul`,{style:{margin:`4px 0`,paddingLeft:`20px`},children:[(0,P.jsxs)(`li`,{children:[`FeltDB server is running on `,(0,P.jsx)(`code`,{children:e})]}),(0,P.jsx)(`li`,{children:`VITE_FELTDB_URL environment variable is set correctly`}),(0,P.jsx)(`li`,{children:`Your API token has proper scopes`})]}),(0,P.jsx)(`button`,{onClick:()=>x(),style:{marginTop:`8px`,padding:`4px 12px`,fontSize:`12px`,background:`#667eea`,color:`white`,border:`none`,borderRadius:`4px`,cursor:`pointer`},children:`Retry`})]})})]}),!e&&(0,P.jsxs)(`div`,{className:L.error,children:[(0,P.jsx)(`strong`,{children:`Connect Studio to a server or managed runtime before managing keys.`}),r&&(0,P.jsx)(`button`,{onClick:r,children:`Open connection settings`})]}),T&&(0,P.jsxs)(`div`,{className:L.info,children:[(0,P.jsx)(`strong`,{children:`New secret — copy it now; it will not be shown again.`}),(0,P.jsx)(`code`,{children:T}),(0,P.jsx)(`button`,{onClick:()=>w(T,`created`),children:f===`created`?`✓ Copied`:`Copy secret`})]}),u&&(0,P.jsxs)(`form`,{onSubmit:S,className:L.createForm,children:[(0,P.jsxs)(`div`,{className:L.formGroup,children:[(0,P.jsx)(`label`,{children:`Key Name (optional)`}),(0,P.jsx)(`input`,{type:`text`,value:m,onChange:e=>h(e.target.value),placeholder:`e.g., staging-key-001`})]}),(0,P.jsxs)(`div`,{className:L.formGroup,children:[(0,P.jsx)(`label`,{children:`Scopes`}),(0,P.jsx)(`div`,{className:L.scopeList,children:y.map(e=>(0,P.jsxs)(`label`,{className:L.scopeCheckbox,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:_.includes(e),onChange:t=>{t.target.checked?v([..._,e]):v(_.filter(t=>t!==e))}}),e]},e))})]}),(0,P.jsx)(`button`,{type:`submit`,className:L.submitButton,children:`Create Key`})]}),i.length===0?(0,P.jsx)(`div`,{className:L.empty,children:`No API keys configured. Create one to get started.`}):(0,P.jsx)(`div`,{className:L.keysList,children:i.map(e=>(0,P.jsxs)(`div`,{className:L.keyCard,children:[(0,P.jsxs)(`div`,{className:L.keyHeader,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:e.name||e.id}),(0,P.jsxs)(`p`,{className:L.namespace,children:[`Namespaces: `,e.namespaces.join(`, `)]})]}),(0,P.jsx)(`span`,{className:`${L.status} ${e.revoked?L.expired:L.active}`,children:e.revoked?`Revoked`:`Active`})]}),(0,P.jsx)(`div`,{className:L.keyDetails,children:(0,P.jsxs)(`div`,{className:L.scopes,children:[(0,P.jsx)(`strong`,{children:`Scopes:`}),(0,P.jsx)(`div`,{className:L.scopeTags,children:e.scopes.map(e=>(0,P.jsx)(`span`,{className:L.scopeTag,children:e},e))})]})}),(0,P.jsx)(`div`,{className:L.keyActions,children:(0,P.jsx)(`button`,{className:L.revokeBtn,onClick:()=>C(e.id),disabled:e.revoked,children:`Revoke`})})]},e.id))}),(0,P.jsx)(`div`,{className:L.info,children:(0,P.jsxs)(`p`,{children:[(0,P.jsx)(`strong`,{children:`Security:`}),` Store tokens securely. Never commit to version control. Secrets are shown once. Revoke and replace a key if its secret is lost.`]})})]})};function Zr({db:e,remoteUrl:t=``,token:n=``,namespace:r=`default`,deploymentRuntime:i=`browser`,applicationUrl:a=``,onConnect:o}){let[s,c]=(0,g.useState)(null),l=In(e||null,r),u=Ln(e||null,s,r),{diagnostics:d}=Rn(e||null),f=Bn(e||null),p=e?.sync?.(),[m,h]=(0,g.useState)(),_=!!(s?.workflows.length||s?.agents.length),v=!!(f.length||d?.sync.pendingOperations||p?.conflicts_detected),y=i!==`browser`||!!t;return(0,g.useEffect)(()=>{let t=!0;return fetch(`/_feltdb/project`,{cache:`no-store`}).then(async e=>{if(!e.ok)throw Error(`No project model endpoint`);let n=await e.json();t&&c(Tr(n.source))}).catch(async()=>{let n=e?await e.collection(`_flow_apps`).all():[];t&&n[0]?.spec&&c(n[0].spec)}),()=>{t=!1}},[e]),(0,P.jsx)(Cn,{children:(0,P.jsxs)(`div`,{className:`studio-app`,children:[(0,P.jsxs)(`nav`,{className:`studio-nav`,children:[(0,P.jsxs)(`div`,{className:`nav-header`,children:[(0,P.jsx)(`h1`,{children:`FeltDB Studio`}),l&&(0,P.jsx)(`div`,{className:`instance-info`,children:l.namespace})]}),(0,P.jsx)(`div`,{className:`nav-search`,children:(0,P.jsx)(nr,{db:e,model:s})}),(0,P.jsxs)(`ul`,{className:`nav-menu`,children:[(0,P.jsx)(`li`,{className:`nav-section`,children:`Design`}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/`,children:`Application`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/capabilities`,children:`Capabilities`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/workflows`,children:`Workflows`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/agents`,children:`Agents`})}),(0,P.jsx)(`li`,{className:`nav-section`,children:`Observe`}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/overview`,children:`Overview`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/data`,children:`Data`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/references`,children:`References`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/operations`,children:`Operations`})}),y&&_&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/executions`,children:`Executions`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/peers`,children:`Peers`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/provenance`,children:`Provenance`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/conflicts`,children:`Conflicts`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/health`,children:`Health`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/settings`,children:`Settings`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/api-keys`,children:`API Keys`})})]})]}),(0,P.jsxs)(`main`,{className:`studio-content`,children:[!y&&(0,P.jsx)(`div`,{className:`runtime-notice`,children:`Browser data is read live from the generated application origin through the local Studio bridge.`}),(0,P.jsxs)(zt,{children:[(0,P.jsx)(j,{path:`/`,element:(0,P.jsx)(Yr,{db:e,namespace:r,projectSpec:s,onSpecChange:c})}),(0,P.jsx)(j,{path:`/overview`,element:(0,P.jsx)(Fn,{stats:u})}),(0,P.jsx)(j,{path:`/data`,element:(0,P.jsx)(Hn,{db:e,model:s,namespace:r,applicationUrl:i===`browser`?a:``})}),(0,P.jsx)(j,{path:`/state`,element:(0,P.jsx)(Hn,{db:e,model:s,namespace:r,applicationUrl:i===`browser`?a:``})}),(0,P.jsx)(j,{path:`/references`,element:(0,P.jsx)(Wn,{db:e,model:s,namespace:r})}),(0,P.jsx)(j,{path:`/operations`,element:(0,P.jsx)(Gn,{db:e,model:s,namespace:r})}),(0,P.jsx)(j,{path:`/peers`,element:(0,P.jsx)(Kn,{peers:f,localInstance:l?.instanceId})}),(0,P.jsx)(j,{path:`/capabilities`,element:(0,P.jsx)(qn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/executions`,element:(0,P.jsx)(Yn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/workflows`,element:(0,P.jsx)(Zn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/agents`,element:(0,P.jsx)(Qn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/provenance`,element:(0,P.jsx)($n,{db:e,model:s,namespace:r,reference:m})}),(0,P.jsx)(j,{path:`/conflicts`,element:(0,P.jsx)(Xn,{db:e,diagnostics:d})}),(0,P.jsx)(j,{path:`/health`,element:(0,P.jsx)(er,{diagnostics:d,model:s})}),(0,P.jsx)(j,{path:`/settings`,element:(0,P.jsx)(tr,{db:e,remoteUrl:t,token:n,onConnect:o})}),(0,P.jsx)(j,{path:`/api-keys`,element:(0,P.jsxs)(`div`,{style:{padding:`2rem`},children:[(0,P.jsx)(`h1`,{children:`API Key Management`}),(0,P.jsx)(Xr,{apiUrl:t,token:n,namespace:r,onConfigure:()=>window.location.assign(`/settings`)})]})})]})]})]})})}var Qr=new URLSearchParams(window.location.search),$r=Qr.get(`connect`)||``,ei=Qr.get(`namespace`)||`default`,ti=Qr.get(`runtime`)||($r?`remote`:`browser`),ni=Qr.get(`app`)||``;function ri(){let[e,t]=(0,g.useState)($r),[n,r]=(0,g.useState)(()=>$r&&window.sessionStorage.getItem(`feltdb-token:${$r}`)||``),i=(0,g.useMemo)(()=>window.feltdb||Wr(e?{namespace:ei,server:{url:e,token:n}}:{namespace:ei,browser:!0}),[e,n]);return(0,P.jsx)(Zr,{db:i,remoteUrl:e,token:n,namespace:ei,deploymentRuntime:ti,applicationUrl:ni,onConnect:(e,n)=>{let i=e.trim().replace(/\/$/,``);i&&n&&window.sessionStorage.setItem(`feltdb-token:${i}`,n),t(i),r(n)}})}_.createRoot(document.getElementById(`root`)).render((0,P.jsx)(g.StrictMode,{children:(0,P.jsx)(ri,{})}));
28
+ `)}\n}\n`}function kr(e,t){let n=e=>new Map([...e.collections.map(e=>[`collection ${e.name}`,JSON.stringify(e)]),...e.capabilities.map(e=>[`capability ${e.name}`,JSON.stringify(e)]),...e.agents.map(e=>[`agent ${e.name}`,JSON.stringify(e)]),...e.workflows.map(e=>[`workflow ${e.name}`,JSON.stringify(e)]),...e.triggers.map(e=>[`trigger ${e.event}`,JSON.stringify(e)]),...e.policies.map(e=>[`policy ${e.name}`,JSON.stringify(e)]),...e.schedules.map(e=>[`schedule ${e.name}`,JSON.stringify(e)])]),r=n(e),i=n(t);return{added:[...i.keys()].filter(e=>!r.has(e)),removed:[...r.keys()].filter(e=>!i.has(e)),changed:[...i.keys()].filter(e=>r.has(e)&&r.get(e)!==i.get(e))}}function Ar(e,t){let n=[],r=new Map(e.collections.map(e=>[e.name,e])),i=new Map(t.collections.map(e=>[e.name,e]));for(let[e,t]of i){let i=r.get(e);if(!i){n.push({kind:`add`,target:`collection ${e}`,safety:`safe`,detail:`Create collection model`});continue}let a=new Map(i.fields.map(e=>[e.name,e])),o=new Map(t.fields.map(e=>[e.name,e]));for(let[t,r]of o){let i=a.get(t);i?(i.type!==r.type||i.optional!==r.optional)&&n.push({kind:`change`,target:`${e}.${t}`,safety:`requires_transform`,detail:`${i.type}${i.optional?`?`:``} → ${r.type}${r.optional?`?`:``}`}):n.push({kind:`add`,target:`${e}.${t}`,safety:r.optional?`safe`:`requires_transform`,detail:r.optional?`Add optional field`:`Required field needs a backfill`})}for(let t of a.keys())o.has(t)||n.push({kind:`remove`,target:`${e}.${t}`,safety:`destructive`,detail:`Field is no longer declared`})}for(let e of r.keys())i.has(e)||n.push({kind:`remove`,target:`collection ${e}`,safety:`destructive`,detail:`Collection model is no longer declared`});let a=kr(e,t);for(let e of a.added.filter(e=>!e.startsWith(`collection `)))n.push({kind:`add`,target:e,safety:`safe`,detail:`Deploy application primitive`});for(let e of a.changed.filter(e=>!e.startsWith(`collection `)))n.push({kind:`change`,target:e,safety:`safe`,detail:`Version application primitive`});for(let e of a.removed.filter(e=>!e.startsWith(`collection `)))n.push({kind:`remove`,target:e,safety:`destructive`,detail:`Application primitive is no longer declared`});return n}function jr(e=`MyApp`){return{version:1,app:e,collections:[],capabilities:[],agents:[],workflows:[],triggers:[],policies:[],schedules:[]}}var Mr=class{constructor(e=`offline`){this.value=e,this.listeners=new Set}subscribe(e){return this.listeners.add(e),e(this.value),()=>this.listeners.delete(e)}set(e){this.value=e;for(let t of this.listeners)t(e)}get(){return this.value}},Nr=class{constructor(e){this.config=e,this.status=new Mr,this.fetcher=e.fetcher||fetch,this.restore()}key(){return`feltdb:sync:v1:${this.config.device.application_id}:${this.config.device.device_id}`}restore(){if(!(typeof localStorage>`u`))try{let e=JSON.parse(localStorage.getItem(this.key())||`{}`);this.sessionId=e.sessionId,this.cursor=e.cursor,this.error=e.error}catch{}}persist(){typeof localStorage<`u`&&localStorage.setItem(this.key(),JSON.stringify({sessionId:this.sessionId,cursor:this.cursor,error:this.error,outbox:this.readOutbox()}))}readOutbox(){if(typeof localStorage>`u`)return[];try{return JSON.parse(localStorage.getItem(`${this.key()}:outbox`)||`[]`)}catch{return[]}}writeOutbox(e){typeof localStorage<`u`&&localStorage.setItem(`${this.key()}:outbox`,JSON.stringify(e))}async request(e,t){let n=await this.fetcher(`${this.config.endpoint||``}/v1/sync/${e}`,{method:`POST`,credentials:`include`,headers:{"content-type":`application/json`},body:JSON.stringify(t)}),r=await n.json().catch(()=>({}));if(!n.ok)throw Error(r.error||`sync ${e} failed (${n.status})`);return r}async start(){this.status.set(`connecting`);try{if(!this.sessionId){let e={resources:this.config.scope.resources||this.config.scope.collections?.map(e=>`flow://${this.config.device.application_id}/${e}/*`)||[],fields:this.config.scope.fields||{}},t=await this.request(`session`,{device:{...this.config.device,created_at:Math.floor(Date.now()/1e3)},scope:e,offline_grant:this.config.offlineGrant});this.sessionId=t.session_id,this.cursor=t.cursor,this.persist()}return await this.flush(),this.timer=setInterval(()=>void this.flush(),5e3),this}catch(e){throw this.error=String(e),this.status.set(`degraded`),this.persist(),e}}async stop(){this.timer&&clearInterval(this.timer),this.sessionId&&await this.request(`close`,{session_id:this.sessionId}),this.status.set(`offline`)}enqueue(e){let t=this.readOutbox();return t.some(t=>t.operation_id===e.operation_id)||(t.push(e),this.writeOutbox(t)),e.operation_id}async flush(){if(!(!this.sessionId||!this.cursor)){this.status.set(`syncing`);try{let e=this.readOutbox();if(e.length){let t=await this.request(`push`,{session_id:this.sessionId,operations:e}),n=new Set([...t.acknowledgements.map(e=>e.operation_id),...t.rejections.filter(e=>!e.retryable).map(e=>e.operation_id)]);this.writeOutbox(e.filter(e=>!n.has(e.operation_id))),this.cursor=t.cursor}let t=await this.request(`pull`,{session_id:this.sessionId,cursor:this.cursor,limit:250});this.cursor=t.cursor,await this.request(`ack`,{session_id:this.sessionId,cursor:this.cursor}),this.error=void 0,this.status.set(`synced`),this.persist()}catch(e){this.error=String(e),this.status.set(typeof navigator<`u`&&!navigator.onLine?`offline`:`degraded`),this.persist()}}}pending(){return this.readOutbox()}conflicts(){return this.readOutbox().filter(e=>e.status===`CONFLICTED`)}lastCursor(){return this.cursor}lastError(){return this.error}},Pr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`,...t?.headers||{}},...t}),r=n.status===204?void 0:await n.json();if(!n.ok)throw Error(r?.error||`Workload request failed (${n.status})`);return r}create(e){return this.json(`/v1/workloads`,{method:`POST`,body:JSON.stringify({...e,created_at:e.created_at||Math.floor(Date.now()/1e3)})})}list(e){return this.json(`/v1/workloads?application_id=${encodeURIComponent(e)}`)}inspect(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}`)}claim(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/claim`,{method:`POST`,body:JSON.stringify(t)})}start(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/start`,{method:`POST`,body:JSON.stringify(t)})}heartbeat(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/heartbeat`,{method:`POST`,body:JSON.stringify(t)})}checkpoint(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/checkpoint`,{method:`POST`,body:JSON.stringify(t)})}complete(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/complete`,{method:`POST`,body:JSON.stringify(t)})}fail(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/fail`,{method:`POST`,body:JSON.stringify(t)})}confirmCancelled(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/cancelled`,{method:`POST`,body:JSON.stringify(t)})}executionContext(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/context`,{method:`POST`,body:JSON.stringify(t)})}cancel(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/cancel`,{method:`POST`,body:JSON.stringify({grant:t})})}retry(e,t){return this.json(`/v1/workloads/${encodeURIComponent(e)}/retry`,{method:`POST`,body:JSON.stringify({grant:t})})}history(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/history`)}result(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/result`)}},Fr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`,...t?.headers||{}},...t}),r=n.status===204?void 0:await n.json();if(!n.ok)throw Error(r?.error||`Mesh request failed (${n.status})`);return r}},Ir=class extends Fr{register(e){return this.json(`/v1/workers/register`,{method:`POST`,body:JSON.stringify({...e,registered_at:e.registered_at||Math.floor(Date.now()/1e3)})})}list(e){return this.json(`/v1/workers?application_id=${encodeURIComponent(e)}`)}inspect(e){return this.json(`/v1/workers/${encodeURIComponent(e)}`)}heartbeat(e,t,n){return this.json(`/v1/workers/${encodeURIComponent(e)}/heartbeat`,{method:`POST`,body:JSON.stringify({heartbeat:t,grant:n})})}drain(e,t){return this.json(`/v1/workers/${encodeURIComponent(e)}/drain`,{method:`POST`,body:JSON.stringify({grant:t})})}recover(e,t){return this.json(`/v1/workers/${encodeURIComponent(e)}/recover`,{method:`POST`,body:JSON.stringify({grant:t})})}reconcile(e,t,n){return this.json(`/v1/workers/${encodeURIComponent(e)}/reconcile`,{method:`POST`,body:JSON.stringify({reconciliation:t,grant:n})})}},Lr=class extends Fr{list(e){return this.json(`/v1/worker-pools?application_id=${encodeURIComponent(e)}`)}create(e,t){return this.json(`/v1/worker-pools`,{method:`POST`,body:JSON.stringify({pool:e,grant:t})})}inspect(e){return this.json(`/v1/worker-pools/${encodeURIComponent(e)}`)}},Rr=class extends Fr{async status(e){let[t,n]=await Promise.all([new Ir(this.baseUrl,this.fetcher).list(e),new Lr(this.baseUrl,this.fetcher).list(e)]);return{workers:t.workers,pools:n.pools,ready:t.workers.filter(e=>e.lifecycle===`READY`).length,busy:t.workers.filter(e=>e.lifecycle===`BUSY`).length}}eligibleWorkers(e){return this.json(`/v1/workloads/${encodeURIComponent(e)}/eligible-workers`)}},zr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Artifact request failed (${n.status})`);return r}async create(e){let t=new URLSearchParams({application_id:e.applicationId,kind:typeof e.kind==`string`?e.kind:`OTHER(${e.kind.OTHER})`,name:e.name,content_type:e.contentType,producer_kind:e.producerKind||`human`,producer_id:e.producerId||``});for(let n of e.parents||[])t.append(`parents`,n);for(let[n,r]of Object.entries({supersedes:e.supersedes,revision:e.revision,workload:e.workload,execution:e.execution}))r&&t.set(n,r);return this.json(`/v1/artifacts?${t}`,{method:`POST`,headers:{"content-type":e.contentType},body:(e.content instanceof Blob||e.content instanceof Uint8Array,e.content)})}list(e){return this.json(`/v1/artifacts?application_id=${encodeURIComponent(e)}`)}get(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}`)}async content(e){let t=await this.fetcher(`${this.baseUrl}/v1/artifacts/${encodeURIComponent(e)}/content`,{credentials:`include`});if(!t.ok)throw Error(`Artifact content failed (${t.status})`);return new Uint8Array(await t.arrayBuffer())}provenance(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/provenance`)}parents(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/parents`)}children(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/children`)}archive(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/archive`,{method:`POST`})}restore(e){return this.json(`/v1/artifacts/${encodeURIComponent(e)}/restore`,{method:`POST`})}},Br=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Bundle request failed (${n.status})`);return r}export(e,t={}){return this.json(`/v1/bundles/export`,{method:`POST`,body:JSON.stringify({application_id:e,options:t})})}inspect(e){return this.json(`/v1/bundles/${encodeURIComponent(e)}`)}verify(e){return this.json(`/v1/bundles/${encodeURIComponent(e)}/verify`,{method:`POST`})}planImport(e,t,n,r){return this.json(`/v1/bundles/import/plan`,{method:`POST`,body:JSON.stringify({bundle:e,mode:t,destination_tenant:n,destination_application:r})})}import(e,t,n,r){return this.json(`/v1/bundles/import/apply`,{method:`POST`,body:JSON.stringify({bundle:e,mode:t,destination_tenant:n,destination_application:r})})}},Vr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Release request failed (${n.status})`);return r}create(e){return this.json(`/v1/releases`,{method:`POST`,body:JSON.stringify({manifest:e})})}list(e){return this.json(`/v1/releases?application_id=${encodeURIComponent(e)}`)}get(e){return this.json(`/v1/releases/${encodeURIComponent(e)}`)}verify(e){return this.json(`/v1/releases/${encodeURIComponent(e)}/verify`,{method:`POST`})}promote(e,t,n){return this.json(`/v1/releases/${encodeURIComponent(e)}/promote`,{method:`POST`,body:JSON.stringify({application_id:t,environment:n})})}plan(e,t,n){return this.json(`/v1/deployments/plan`,{method:`POST`,body:JSON.stringify({release_id:e,environment:t,rollback_target:n})})}deploy(e){return this.json(`/v1/deployments`,{method:`POST`,body:JSON.stringify({plan:e})})}status(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}`)}health(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}/health`)}stop(e){return this.json(`/v1/deployments/${encodeURIComponent(e)}/stop`,{method:`POST`})}},Hr=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Observe request failed (${n.status})`);return r}events(e){return this.json(`/v1/observability/events?application_id=${encodeURIComponent(e)}`)}cause(e){return this.json(`/v1/observability/causes/${encodeURIComponent(e)}`)}workload(e){return this.json(`/v1/observability/workloads/${encodeURIComponent(e)}/timeline`)}execution(e){return this.json(`/v1/observability/executions/${encodeURIComponent(e)}/timeline`)}revision(e){return this.json(`/v1/observability/revisions/${encodeURIComponent(e)}/timeline`)}append(e){return this.json(`/v1/observability/events`,{method:`POST`,body:JSON.stringify({event:e})})}},Ur=class{constructor(e=``,t=fetch){this.baseUrl=e,this.fetcher=t}async json(e,t){let n=await this.fetcher(`${this.baseUrl}${e}`,{credentials:`include`,headers:{"content-type":`application/json`},...t}),r=await n.json();if(!n.ok)throw Error(r?.error||`Provider request failed (${n.status})`);return r}list(){return this.json(`/v1/providers`)}inspect(e){return this.json(`/v1/providers/${encodeURIComponent(e)}`)}install(e,t,n){return this.json(`/v1/providers`,{method:`POST`,body:JSON.stringify({manifest:e,tenant_id:t,application_id:n})})}enable(e){return this.status(e,`ENABLED`)}disable(e){return this.status(e,`DISABLED`)}revoke(e){return this.status(e,`REVOKED`)}status(e,t){return this.json(`/v1/providers/${encodeURIComponent(e)}/status`,{method:`POST`,body:JSON.stringify({status:t})})}health(e){return this.json(`/v1/providers/${encodeURIComponent(e)}/health`)}dependencies(e){return this.json(`/v1/providers/${encodeURIComponent(e)}/dependencies`)}};function Wr(e){if(!e?.namespace?.trim())throw Error(`createFeltDB requires a non-empty namespace`);return new Gr(e.server?new I(e.server):`browser`in e&&e.browser?new Sr(e.namespace):new xr(e.namespace))}var Gr=class{constructor(e){this.collections=new Map,this.capabilityWorkers=new Map,this.workloads=new Pr,this.artifacts=new zr,this.bundle=new Br,this.releases=new Vr,this.observe=new Hr,this.providers=new Ur,this.workers=new Ir,this.workerPools=new Lr,this.mesh=new Rr,this.jsDb=e,this.runtimeInfo=this.detectRuntime(),this.agentRegistry=new _r;let t={persistent:this.runtimeInfo.persistent,executionTimeoutMs:3e4,supportsReactiveTriggers:!0,defaultRetryPolicy:{maxAttempts:3,backoffMs:1e3}};this.agentRuntime=new yr(this.agentRegistry,t)}detectRuntime(){let e=typeof window<`u`&&typeof document<`u`,t=typeof globalThis<`u`&&`versions`in globalThis&&`node`in globalThis.versions,n=this.jsDb instanceof xr,r=this.jsDb instanceof I,i=this.jsDb instanceof Sr,a=`memory`,o=!1;return r?(a=`remote`,o=!0):n?a=`memory`:i?(a=`indexeddb`,o=!0):t&&(a=`file`,o=!0),{runtime:r?`remote`:i||e?`browser`:t?`node`:`wasm`,storage:a,persistent:o,reactive:!0,durable:o,version:`0.1.0`,supportsCheckpointing:o,supportsLifecycle:e||i}}runtime(){return{...this.runtimeInfo}}collection(e){return this.collections.has(e)||this.collections.set(e,new mr(this.jsDb,e)),this.collections.get(e)}async acquire(e,t){return this.jsDb instanceof I?this.jsDb.acquire(e,t):this.collection(e).get(t)}async search(e,t,n=50){if(this.jsDb instanceof I)return this.jsDb.search(e,t,n);let r=t.toLowerCase();return(await this.collection(e).all()).filter(e=>JSON.stringify(e).toLowerCase().includes(r)).slice(0,n)}async defineCapability(e,t){if(!(this.jsDb instanceof I))throw Error(`Distributed capabilities require a server runtime`);return this.jsDb.command(`/capabilities/${encodeURIComponent(e)}`,{steps:t})}registerCapabilityWorker(e,t){if(this.jsDb instanceof I)throw Error(`Remote capability workers are installed on the server`);return this.capabilityWorkers.set(e,t),()=>this.capabilityWorkers.delete(e)}async executeCapability(e,t){if(this.jsDb instanceof I)return this.jsDb.command(`/capabilities/${encodeURIComponent(e)}/execute`,t);let n=this.capabilityWorkers.get(e);if(!n)throw Error(`No embedded capability worker registered for ${e}`);let r=`cap-${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,i=this.collection(`_flow_executions`);await i.insert({id:r,capability:e,input:t,status:`running`,owner:this.instanceId(),started_at:Date.now()},r);try{let e=await n(t);return await i.update(r,{status:`completed`,output:e,completed_at:Date.now()}),e}catch(e){throw await i.update(r,{status:`failed`,error:e instanceof Error?e.message:String(e),completed_at:Date.now()}),e}}async changeClusterMembership(e,t){if(!(this.jsDb instanceof I))throw Error(`Cluster membership requires a server runtime`);return this.jsDb.command(`/cluster/members`,{expected_epoch:e,peers:t})}async deployFlowSpec(e,t,n=!1){let r=Er(e).filter(e=>e.severity===`error`);if(r.length)throw Error(r.map(e=>e.message).join(`; `));let i=this.collection(`_flow_apps`),a=await i.get(e.app),o=(a?.version??0)+1;if(t!==void 0&&(a?.version??0)!==t)throw Error(`FlowSpec version conflict: expected ${t}, found ${a?.version??0}`);let s=Ar(a?.spec??jr(e.app),e),c=s.filter(e=>e.safety===`destructive`);if(c.length&&!n)throw Error(`Destructive migration requires explicit approval: ${c.map(e=>e.target).join(`, `)}`);let l={id:e.app,app:e.app,version:o,status:`deploying`,spec:e,migration:s,deployed_at:Date.now()};a?await i.update(e.app,l):await i.insert(l,e.app);let u=(t,n)=>`${e.app}-${t}-${n}`.replace(/[^A-Za-z0-9_-]/g,`_`),d=async(t,n,r,i)=>{let a=this.collection(t),s=new Set(i.map(e=>e.name??e.event??`unnamed`));for(let e of r){let t=e.name??e.event??`unnamed`;s.has(t)||await a.delete(u(n,t))}for(let t of i){let r=t.name??t.event??`unnamed`,i=u(n,r),s={id:i,app:e.app,version:o,...t};await a.get(i)?await a.update(i,s):await a.insert(s,i)}},f=a?.spec??jr(e.app);if(await d(`_flow_collection_models`,`collection`,f.collections,e.collections),await d(`_flow_capability_models`,`capability`,f.capabilities,e.capabilities),await d(`_flow_trigger_models`,`trigger`,f.triggers,e.triggers),await d(`_flow_policy_models`,`policy`,f.policies,e.policies),await d(`_flow_schedule_models`,`schedule`,f.schedules,e.schedules),this.jsDb instanceof I){for(let t of f.workflows)e.workflows.some(e=>e.name===t.name)||await this.collection(`_flow_workflows`).delete(u(`workflow`,t.name));for(let t of f.agents)e.agents.some(e=>e.name===t.name)||await this.collection(`_flow_agents`).delete(u(`agent`,t.name));for(let t of e.workflows)await this.defineWorkflow(u(`workflow`,t.name),t.steps.map(e=>e.name));for(let t of e.agents){let n=t.statements.filter(e=>e.startsWith(`capability `)).map(e=>e.slice(11).trim());await this.defineStateAgent(u(`agent`,t.name),n,{flowspec_app:e.app,flowspec_version:o})}}else await d(`_flow_workflows`,`workflow`,f.workflows,e.workflows),await d(`_flow_agents`,`agent`,f.agents,e.agents);let p={...l,status:`active`};return await i.update(e.app,p),await this.collection(`_flow_app_versions`).insert({id:`${e.app}-${o}`,app:e.app,version:o,spec:e,migration:s,deployed_at:p.deployed_at},`${e.app}-${o}`),{app:e.app,version:o,status:`active`}}async auditEvents(){return this.jsDb.audit_events?await this.jsDb.audit_events():[]}async exportOperations(e=0){if(!this.jsDb.export_operations)throw Error(`This runtime uses server-managed replication`);return await this.jsDb.export_operations(e)}async applyOperations(e){if(!this.jsDb.apply_remote_operations)throw Error(`This runtime uses server-managed replication`);return await this.jsDb.apply_remote_operations(e)}async synchronizeWith(e){let t=await this.exportOperations(),n=await e.exportOperations();await this.addSyncPeer(e.instanceId()),await e.addSyncPeer(this.instanceId());let r=await e.applyOperations(t),i=await this.applyOperations(n);return{sent:t.length,received:n.length,applied:i.applied+r.applied,ignored:i.ignored+r.ignored}}async executeCapabilityWithFailover(e,t,n=[]){let r=this.collection(`_flow_capability_routes`),i=`route-${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,a=[this,...n],o=[];await r.insert({id:i,capability:e,status:`routing`,input:t,candidates:a.map(e=>e.instanceId()),started_at:Date.now()},i);for(let n of a)try{let a=await n.executeCapability(e,t);return await r.update(i,{status:`completed`,provider:n.instanceId(),attempts:o.length+1,failures:o,completed_at:Date.now()}),{output:a,provider:n.instanceId(),attempts:o.length+1}}catch(e){o.push({provider:n.instanceId(),error:e instanceof Error?e.message:String(e)})}throw await r.update(i,{status:`failed`,attempts:o.length,failures:o,completed_at:Date.now()}),Error(`No provider could execute capability ${e}: ${o.map(e=>e.error).join(`; `)}`)}async recordProvenance(e,t){if(!(this.jsDb instanceof I))throw Error(`Causal provenance requires a server runtime`);return this.jsDb.provenance(e,t)}async storeContent(e){if(!(this.jsDb instanceof I))throw Error(`Durable content storage requires a server runtime`);return this.jsDb.storeContent(e)}async acquireContent(e){if(!(this.jsDb instanceof I))throw Error(`Network content acquisition requires a server runtime`);return this.jsDb.acquireContent(e)}async defineWorkflow(e,t){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflows/${encodeURIComponent(e)}`,{steps:t})}async startWorkflow(e,t=null){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflows/${encodeURIComponent(e)}/runs`,{input:t})}async claimWorkflowStep(e,t,n,r=3e4){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflow-runs/${encodeURIComponent(e)}/steps/${encodeURIComponent(t)}/claim`,{worker:n,lease_ms:r})}async completeWorkflowStep(e,t,n,r=null){if(!(this.jsDb instanceof I))throw Error(`Durable workflow coordination requires a server runtime`);return this.jsDb.command(`/workflow-runs/${encodeURIComponent(e)}/steps/${encodeURIComponent(t)}/complete`,{claim_id:n,result:r})}async defineStateAgent(e,t=[],n=null){if(!(this.jsDb instanceof I))throw Error(`Durable agent coordination requires a server runtime`);return this.jsDb.command(`/agents/${encodeURIComponent(e)}`,{capabilities:t,constraints:n})}async startStateAgent(e,t,n=null){if(!(this.jsDb instanceof I))throw Error(`Durable agent coordination requires a server runtime`);return this.jsDb.command(`/agents/${encodeURIComponent(e)}/runs`,{goal:t,input:n})}defineAgent(e){let t=hr(e.name,e.version);return this.agentRegistry.register(t,e),t}agent(e){return this.agentRegistry.getByName(e)?.agentRef}getAgentRegistry(){return this.agentRegistry}getAgentRuntime(){return this.agentRuntime}async createAgentExecution(e,t,n){let r=await this.agentRuntime.createExecution(this,e,t,n);return await this.collection(`_flow_agent_executions`).insert(this.agentExecutionRecord(r),r.executionId),r}agentExecutionRecord(e){return{...e,id:e.executionId,agentRef:e.agentRef.toString()}}async startAgentExecution(e,t=this.instanceId()){await this.agentRuntime.start(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async transitionAgentExecution(e,t){await this.agentRuntime.transition(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async completeAgentExecution(e,t){await this.agentRuntime.complete(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async failAgentExecution(e,t){await this.agentRuntime.fail(e,t),await this.collection(`_flow_agent_executions`).update(e.executionId,this.agentExecutionRecord(e))}async close(){for(let e of this.collections.values())e.close();this.collections.clear(),await this.jsDb.close?.()}sync(e){if(e)return new Nr(e);let t=this.jsDb.sync_info();if(!t.success||!t.data)throw Error(t.error||`Failed to get sync info`);return JSON.parse(t.data)}async addSyncPeer(e){let t=this.jsDb.add_sync_peer(e);if(!t.success)throw Error(t.error||`Failed to add peer`)}async removeSyncPeer(e){let t=this.jsDb.remove_sync_peer(e);if(!t.success)throw Error(t.error||`Failed to remove peer`)}async getPendingForPeer(e,t){let n=this.jsDb.get_pending_for_peer(e,t);if(!n.success||!n.data)throw Error(n.error||`Failed to get pending operations`);return JSON.parse(n.data)}async acknowledgePeerOperations(e,t){let n=this.jsDb.acknowledge_peer_operations(e,t);if(!n.success)throw Error(n.error||`Failed to acknowledge operations`)}instanceId(){return this.jsDb.instance_id()}getSequence(){return this.jsDb.get_sequence()}async registerTrigger(e){}async scheduleCron(e){}async getPendingExecutions(){return[]}async completeExecution(e,t){}provenance(e){let[t,...n]=e.split(`://`)[1]?.split(`/`)||[],r={id:e,type:`Record`,label:n.join(`/`)||e,created_ms:Date.now()};return{root:r,nodes:[r],edges:[]}}health(){let e=this.sync(),t=this.runtime(),n=e.is_connected&&e.pending_operations===0?`healthy`:`degraded`,r=[];e.pending_operations>0&&r.push({severity:`info`,component:`sync`,message:`${e.pending_operations} pending operations`}),e.is_connected||r.push({severity:`warning`,component:`sync`,message:`Network disconnected`}),e.conflicts_detected>0&&r.push({severity:`warning`,component:`sync`,message:`${e.conflicts_detected} conflicts detected`});let i=r.length>0?`degraded`:`healthy`;return{runtime:{status:`healthy`,wasm:t.runtime===`wasm`||t.runtime===`browser`,reactive:t.reactive},storage:{status:`healthy`,backend:t.storage,persistent:t.persistent,durable:t.durable},sync:{status:n,connected:e.is_connected,peers:e.connected_peers.length,pendingOperations:e.pending_operations},fabric:{status:`healthy`,references:0,peers:e.connected_peers.length},capabilities:{status:`healthy`,count:0,available:0},execution:{status:`healthy`,pending:0,running:0,failed:0},workflow:{status:`healthy`,total:0,active:0},status:i,issues:r}}},Kr;(function(e){e.Insert=`Insert`,e.Update=`Update`,e.Delete=`Delete`,e.Query=`Query`,e.Upsert=`Upsert`})(Kr||={});var qr;(function(e){e.Pending=`Pending`,e.Running=`Running`,e.Succeeded=`Succeeded`,e.Failed=`Failed`,e.RetryScheduled=`RetryScheduled`,e.DeadLettered=`DeadLettered`})(qr||={});var Jr=Or(jr(`Application`));function Yr({db:e,namespace:t=`default`,projectSpec:n,onSpecChange:r}){let i=`feltdb:studio:draft:${t}`,a=(0,g.useRef)((()=>{if(typeof window>`u`)return Jr;let e=window.localStorage.getItem(i);if(!e)return Jr;try{return Tr(e),e}catch{return Jr}})()),o=(0,g.useRef)(a.current!==Jr),[s,c]=(0,g.useState)(a.current),[l,u]=(0,g.useState)(()=>Tr(a.current)),[d,f]=(0,g.useState)([]),[p,m]=(0,g.useState)([]),[h,_]=(0,g.useState)(`Draft is valid`),[v,y]=(0,g.useState)(0),[b,x]=(0,g.useState)(null),[S,C]=(0,g.useState)(null),[w,T]=(0,g.useState)(!1),[ee,te]=(0,g.useState)(!1),[E,D]=(0,g.useState)({url:``,namespace:t,token:``,allowDestructive:!1}),ne=(0,g.useRef)(null),re=p.length?p[p.length-1].source:Or(jr(l.app)),ie=(0,g.useMemo)(()=>kr(Tr(re),l),[re,l]),ae=(0,g.useMemo)(()=>Ar(Tr(re),l),[re,l]);(0,g.useEffect)(()=>{if(!e||n)return;let t=!1;return(async()=>{try{let n=await e.collection(`_flow_apps`).all(),r=n.find(e=>e.status===`active`)??n[0];if(!r||t)return;let i=Or(r.spec);o.current||(u(r.spec),c(i)),y(r.version??0);let a=(await e.collection(`_flow_app_versions`).all()).filter(e=>e.app===r.app).sort((e,t)=>e.version-t.version);t||(m(a.map(e=>({version:e.version,source:Or(e.spec),savedAt:e.deployed_at}))),_(`Loaded ${r.app} v${r.version}`))}catch(e){t||_(`Could not load deployed model: ${e instanceof Error?e.message:String(e)}`)}})(),()=>{t=!0}},[e,n]),(0,g.useEffect)(()=>{let e=window.setTimeout(()=>window.localStorage.setItem(i,s),200);return()=>window.clearTimeout(e)},[i,s]);let O=e=>{c(e);try{let t=Tr(e),n=Er(t);u(t),r?.(t),f(n),_(n.some(e=>e.severity===`error`)?`Model has validation errors`:`Draft is valid`)}catch(e){f([{severity:`error`,message:e instanceof Error?e.message:String(e)}]),_(`DSL parse failed`)}};(0,g.useEffect)(()=>{if(!n)return;let e=Or(n);c(e),u(n),f(Er(n)),_(`Loaded ${n.app} project model`)},[n]);let oe=e=>{u(e),O(Or(e))},se=()=>{if(!S)return C({name:``});let e=S.name.trim();if(!/^[A-Z][A-Za-z0-9_]*$/.test(e))return C({...S,error:`Use a capitalized name with no spaces.`});if(l.collections.some(t=>t.name===e))return C({...S,error:`That collection already exists.`});oe({...l,collections:[...l.collections,{name:e,fields:[],indexes:[]}]}),C(null)},ce=e=>x({collection:e,name:``,type:`text`,reference:l.collections.find(t=>t.name!==e)?.name??``,optional:!1}),le=()=>{if(!b)return;let e=b.name.trim(),t=l.collections.find(e=>e.name===b.collection);if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(e))return x({...b,error:`Use a letter-led name with no spaces.`});if(t?.fields.some(t=>t.name===e))return x({...b,error:`That field already exists.`});if(b.type===`ref`&&!b.reference)return x({...b,error:`Choose a referenced collection.`});let n=b.type===`ref`?`ref ${b.reference}`:b.type;oe({...l,collections:l.collections.map(t=>t.name===b.collection?{...t,fields:[...t.fields,{name:e,type:n,optional:b.optional}]}:t)}),x(null)},k=()=>{let e=[...p,{version:p.length+1,source:s,savedAt:Date.now()}];m(e),_(`Saved local revision v${e.length}`)},ue=async()=>{if(!e)return _(`Local embedded storage is unavailable`);if(d.some(e=>e.severity===`error`))return _(`Resolve validation errors before deploying`);if(ae.filter(e=>e.safety===`destructive`).length&&!w)return _(`Review and approve destructive local changes before applying`);try{let t=await e.deployFlowSpec(l,v,w),n=[...p,{version:t.version,source:s,savedAt:Date.now()}];m(n),y(t.version),T(!1),_(`Applied locally as ${t.app} v${t.version}`)}catch(e){_(`Local apply failed: ${e instanceof Error?e.message:String(e)}`)}},de=async()=>{if(!E.url.trim()||!E.token.trim())return D({...E,error:`Cloud URL and API key are required.`});if(d.some(e=>e.severity===`error`))return D({...E,error:`Resolve validation errors before publishing.`});D({...E,publishing:!0,error:void 0});let e=Wr({namespace:E.namespace.trim()||t,server:{url:E.url.trim().replace(/\/$/,``),token:E.token}});try{let t=await e.collection(`_flow_apps`).get(l.app),n=Ar(t?.spec??jr(l.app),l).filter(e=>e.safety===`destructive`);if(n.length&&!E.allowDestructive)return D({...E,publishing:!1,destructive:n.map(e=>e.target),error:`Review and approve destructive changes: ${n.map(e=>e.target).join(`, `)}`});let r=await e.deployFlowSpec(l,t?.version??0,E.allowDestructive);window.sessionStorage.setItem(`feltdb-token:${E.url.trim()}`,E.token),D({...E,publishing:!1,token:``,error:void 0}),te(!1),_(`Published ${r.app} v${r.version} to cloud`)}catch(e){D({...E,publishing:!1,error:e instanceof Error?e.message:String(e)})}finally{await e.close()}},fe=()=>{let e=URL.createObjectURL(new Blob([s],{type:`text/plain`})),t=document.createElement(`a`);t.href=e,t.download=`feltdb.flow`,t.click(),URL.revokeObjectURL(e)},pe=async e=>{e&&O(await e.text())},me=[[`Data`,l.collections.map(e=>e.name)],[`Capabilities`,l.capabilities.map(e=>e.name)],[`Agents`,l.agents.map(e=>e.name)],[`Workflows`,l.workflows.map(e=>e.name)],[`Triggers`,l.triggers.map(e=>e.event)],[`Policies`,l.policies.map(e=>e.name)],[`Schedules`,l.schedules.map(e=>e.name)]];return(0,P.jsxs)(`div`,{className:`application-designer`,children:[(0,P.jsxs)(`header`,{className:`designer-header`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`span`,{className:`eyebrow`,children:`Application fabric`}),(0,P.jsx)(`h1`,{children:l.app}),(0,P.jsx)(`p`,{children:`One model for state, intelligence, automation, security, and placement.`})]}),(0,P.jsxs)(`div`,{className:`designer-actions`,children:[(0,P.jsx)(`input`,{ref:ne,hidden:!0,type:`file`,accept:`.flow,text/plain`,onChange:e=>void pe(e.target.files?.[0])}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>ne.current?.click(),children:`Import`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:fe,children:`Export`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:k,children:`Version`}),(0,P.jsx)(`button`,{className:`btn btn-ghost`,onClick:()=>void ue(),children:`Apply locally`}),(0,P.jsx)(`button`,{className:`btn btn-primary`,onClick:()=>te(e=>!e),children:`Publish to cloud`})]})]}),ae.some(e=>e.safety===`destructive`)&&(0,P.jsxs)(`label`,{className:`local-destructive`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:w,onChange:e=>T(e.target.checked)}),(0,P.jsxs)(`span`,{children:[`Approve destructive local changes: `,ae.filter(e=>e.safety===`destructive`).map(e=>e.target).join(`, `)]})]}),ee&&(0,P.jsxs)(`form`,{className:`cloud-publisher`,onSubmit:e=>{e.preventDefault(),de()},children:[(0,P.jsxs)(`div`,{className:`cloud-publisher-heading`,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`span`,{className:`eyebrow`,children:`Cloud release`}),(0,P.jsx)(`h2`,{children:`Publish this application model`}),(0,P.jsx)(`p`,{children:`FeltDB compares the cloud version, plans the migration, and publishes atomically.`})]}),(0,P.jsx)(`button`,{type:`button`,"aria-label":`Close cloud publisher`,onClick:()=>te(!1),children:`×`})]}),(0,P.jsxs)(`div`,{className:`cloud-fields`,children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`FeltDB Cloud URL`}),(0,P.jsx)(`input`,{type:`url`,placeholder:`https://your-instance.feltdb.cloud`,value:E.url,onChange:e=>D({...E,url:e.target.value,error:void 0,destructive:void 0,allowDestructive:!1})})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Namespace`}),(0,P.jsx)(`input`,{value:E.namespace,onChange:e=>D({...E,namespace:e.target.value,error:void 0,destructive:void 0,allowDestructive:!1})})]}),(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`API key`}),(0,P.jsx)(`input`,{type:`password`,autoComplete:`off`,placeholder:`Stored for this browser session only`,value:E.token,onChange:e=>D({...E,token:e.target.value,error:void 0})})]})]}),(E.destructive?.length||ae.some(e=>e.safety===`destructive`))&&(0,P.jsxs)(`label`,{className:`cloud-destructive`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:E.allowDestructive,onChange:e=>D({...E,allowDestructive:e.target.checked})}),(0,P.jsxs)(`span`,{children:[`I reviewed and approve destructive model changes`,E.destructive?.length?`: ${E.destructive.join(`, `)}`:`.`]})]}),E.error&&(0,P.jsx)(`div`,{className:`cloud-error`,role:`alert`,children:E.error}),(0,P.jsxs)(`div`,{className:`cloud-actions`,children:[(0,P.jsx)(`button`,{type:`button`,className:`btn btn-ghost`,onClick:()=>te(!1),children:`Cancel`}),(0,P.jsx)(`button`,{className:`btn btn-primary`,disabled:E.publishing,type:`submit`,children:E.publishing?`Publishing…`:`Review and publish`})]})]}),(0,P.jsxs)(`div`,{className:`designer-status ${d.some(e=>e.severity===`error`)?`error`:``}`,children:[(0,P.jsx)(`span`,{children:h}),(0,P.jsxs)(`span`,{children:[l.collections.length,` collections · `,l.workflows.length,` workflows · `,p.length?`v${p.length}`:`draft`]})]}),(0,P.jsxs)(`div`,{className:`designer-grid`,children:[(0,P.jsxs)(`aside`,{className:`model-tree`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Application`}),(0,P.jsx)(`button`,{"aria-label":`Add collection`,onClick:()=>C({name:``}),children:`+`})]}),S&&(0,P.jsxs)(`form`,{className:`collection-editor`,onSubmit:e=>{e.preventDefault(),se()},onKeyDown:e=>{e.key===`Escape`&&C(null)},children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`New collection`}),(0,P.jsx)(`input`,{autoFocus:!0,placeholder:`e.g. Customer`,value:S.name,onChange:e=>C({name:e.target.value})})]}),S.error&&(0,P.jsx)(`div`,{className:`field-error`,role:`alert`,children:S.error}),(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`button`,{type:`button`,onClick:()=>C(null),children:`Cancel`}),(0,P.jsx)(`button`,{className:`collection-save`,type:`submit`,children:`Add`})]})]}),me.map(([e,t])=>(0,P.jsxs)(`section`,{children:[(0,P.jsx)(`h3`,{children:e}),t.length?t.map(e=>(0,P.jsx)(`div`,{className:`tree-item`,children:e},e)):(0,P.jsx)(`div`,{className:`tree-empty`,children:`None`})]},e))]}),(0,P.jsxs)(`section`,{className:`model-canvas`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Application graph`}),(0,P.jsx)(`span`,{className:`graph-legend`,children:`intent → fabric`})]}),(0,P.jsxs)(`div`,{className:`graph-board`,children:[l.collections.map(e=>(0,P.jsxs)(`article`,{className:`model-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`collection`}),(0,P.jsx)(`h3`,{children:e.name}),e.fields.map(e=>(0,P.jsxs)(`div`,{className:`node-field`,children:[(0,P.jsx)(`span`,{children:e.name}),(0,P.jsxs)(`code`,{children:[e.type,e.optional?`?`:``]})]},e.name)),b?.collection===e.name?(0,P.jsxs)(`form`,{className:`field-editor`,onSubmit:e=>{e.preventDefault(),le()},onKeyDown:e=>{e.key===`Escape`&&x(null)},children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Field name`}),(0,P.jsx)(`input`,{autoFocus:!0,value:b.name,placeholder:`e.g. publishedAt`,onChange:e=>x({...b,name:e.target.value,error:void 0})})]}),(0,P.jsxs)(`div`,{className:`field-editor-row`,children:[(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Type`}),(0,P.jsxs)(`select`,{value:b.type,onChange:e=>x({...b,type:e.target.value,error:void 0}),children:[(0,P.jsx)(`option`,{value:`text`,children:`Text`}),(0,P.jsx)(`option`,{value:`number`,children:`Number`}),(0,P.jsx)(`option`,{value:`boolean`,children:`Boolean`}),(0,P.jsx)(`option`,{value:`datetime`,children:`Date & time`}),(0,P.jsx)(`option`,{value:`json`,children:`JSON`}),(0,P.jsx)(`option`,{value:`ref`,children:`Reference`})]})]}),b.type===`ref`&&(0,P.jsxs)(`label`,{children:[(0,P.jsx)(`span`,{children:`Collection`}),(0,P.jsx)(`select`,{value:b.reference,onChange:e=>x({...b,reference:e.target.value,error:void 0}),children:l.collections.filter(t=>t.name!==e.name).map(e=>(0,P.jsx)(`option`,{value:e.name,children:e.name},e.name))})]})]}),(0,P.jsxs)(`label`,{className:`field-optional`,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:b.optional,onChange:e=>x({...b,optional:e.target.checked})}),(0,P.jsx)(`span`,{children:`Optional field`})]}),b.error&&(0,P.jsx)(`div`,{className:`field-error`,role:`alert`,children:b.error}),(0,P.jsxs)(`div`,{className:`field-editor-actions`,children:[(0,P.jsx)(`button`,{type:`button`,onClick:()=>x(null),children:`Cancel`}),(0,P.jsx)(`button`,{className:`field-save`,type:`submit`,children:`Add field`})]})]}):(0,P.jsx)(`button`,{className:`node-add`,onClick:()=>ce(e.name),children:`+ field`})]},e.name)),l.workflows.map(e=>(0,P.jsxs)(`article`,{className:`model-node workflow-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`workflow`}),(0,P.jsx)(`h3`,{children:e.name}),e.steps.map(e=>(0,P.jsx)(`div`,{className:`node-step`,children:e.name},e.name))]},e.name)),l.agents.map(e=>(0,P.jsxs)(`article`,{className:`model-node agent-node`,children:[(0,P.jsx)(`div`,{className:`node-kind`,children:`agent`}),(0,P.jsx)(`h3`,{children:e.name}),e.statements.map(e=>(0,P.jsx)(`div`,{className:`node-step`,children:e},e))]},e.name))]}),(0,P.jsxs)(`div`,{className:`change-strip`,children:[(0,P.jsx)(`strong`,{children:`Model diff`}),(0,P.jsxs)(`span`,{className:`added`,children:[`+ `,ie.added.join(`, `)||`none`]}),(0,P.jsxs)(`span`,{className:`changed`,children:[`~ `,ie.changed.join(`, `)||`none`]}),(0,P.jsxs)(`span`,{className:`removed`,children:[`− `,ie.removed.join(`, `)||`none`]})]})]}),(0,P.jsxs)(`section`,{className:`dsl-panel`,children:[(0,P.jsxs)(`div`,{className:`panel-title`,children:[(0,P.jsx)(`span`,{children:`Flow DSL`}),(0,P.jsx)(`span`,{children:`feltdb.flow`})]}),(0,P.jsx)(`textarea`,{"aria-label":`Flow DSL`,spellCheck:!1,value:s,onChange:e=>O(e.target.value)}),d.length>0&&(0,P.jsx)(`div`,{className:`diagnostics`,children:d.map((e,t)=>(0,P.jsxs)(`div`,{className:e.severity,children:[e.severity,`: `,e.message]},t))})]})]})]})}var L={panel:`_panel_1cbba_1`,header:`_header_1cbba_8`,createButton:`_createButton_1cbba_23`,error:`_error_1cbba_38`,createForm:`_createForm_1cbba_47`,formGroup:`_formGroup_1cbba_55`,scopeList:`_scopeList_1cbba_76`,scopeCheckbox:`_scopeCheckbox_1cbba_82`,submitButton:`_submitButton_1cbba_94`,empty:`_empty_1cbba_109`,keysList:`_keysList_1cbba_117`,keyCard:`_keyCard_1cbba_123`,keyHeader:`_keyHeader_1cbba_135`,namespace:`_namespace_1cbba_150`,status:`_status_1cbba_156`,active:`_active_1cbba_163`,expired:`_expired_1cbba_168`,keyDetails:`_keyDetails_1cbba_173`,detail:`_detail_1cbba_179`,copyBtn:`_copyBtn_1cbba_203`,daysLeft:`_daysLeft_1cbba_217`,scopes:`_scopes_1cbba_223`,scopeTags:`_scopeTags_1cbba_227`,scopeTag:`_scopeTag_1cbba_227`,keyActions:`_keyActions_1cbba_243`,revokeBtn:`_revokeBtn_1cbba_250`,info:`_info_1cbba_265`},Xr=({apiUrl:e,token:t,namespace:n=`app-store-sherpa`,onConfigure:r})=>{let[i,a]=(0,g.useState)([]),[o,s]=(0,g.useState)(!0),[c,l]=(0,g.useState)(null),[u,d]=(0,g.useState)(!1),[f,p]=(0,g.useState)(null),[m,h]=(0,g.useState)(``),[_,v]=(0,g.useState)([`state:read`,`state:write`,`events:read`]),y=[`state:read`,`state:write`,`events:read`,`backup:create`,`backup:restore`,`admin:logs`,`admin:restart`],b=[`state:read`,`state:write`,`events:read`,`backup:create`,`backup:restore`,`admin:logs`,`admin:restart`];(0,g.useEffect)(()=>{x()},[e,t]);let x=async()=>{try{if(s(!0),l(null),!e){l(`A server or managed API URL is not configured.`),s(!1);return}let n=await fetch(`${e}/api/keys`,{headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)});if(n.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(n.status===403)throw Error(`Forbidden: Your account does not have permission to manage API keys`);if(!n.ok)throw Error(`Failed to fetch keys: ${n.status} ${n.statusText}`);let r=await n.json();a(r.tokens||[])}catch(t){let n=t instanceof TypeError?`Connection error: Unable to reach ${e}. Is the server running?`:t instanceof Error?t.message:`Failed to fetch keys`;l(n),console.error(`Error fetching API keys:`,t)}finally{s(!1)}},S=async r=>{r.preventDefault();try{let r=await fetch(`${e}/api/keys`,{method:`POST`,headers:{...t?{Authorization:`Bearer ${t}`}:{},"Content-Type":`application/json`},body:JSON.stringify({id:m||`key-${Date.now()}`,namespace:n,scopes:_.length>0?_:b}),signal:AbortSignal.timeout(1e4)});if(r.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(r.status===409)throw Error(`A key with this name already exists`);if(!r.ok)throw Error(`Failed to create key: ${r.status} ${r.statusText}`);let i=await r.json();ee(i.secret),h(``),v(b),d(!1),await x()}catch(e){let t=e instanceof TypeError?`Connection error: Unable to reach the API server`:e instanceof Error?e.message:`Failed to create key`;l(t),console.error(`Error creating API key:`,e)}},C=async n=>{if(confirm(`Revoke key "${n}"? This cannot be undone.`))try{let r=await fetch(`${e}/api/keys/${n}`,{method:`DELETE`,headers:t?{Authorization:`Bearer ${t}`}:{},signal:AbortSignal.timeout(1e4)});if(r.status===404)throw Error(`Key not found`);if(r.status===401)throw Error(`Unauthorized: Invalid or expired API token`);if(!r.ok)throw Error(`Failed to revoke key: ${r.status} ${r.statusText}`);await x()}catch(e){let t=e instanceof TypeError?`Connection error: Unable to reach the API server`:e instanceof Error?e.message:`Failed to revoke key`;l(t),console.error(`Error revoking API key:`,e)}},w=(e,t)=>{navigator.clipboard.writeText(e),p(t),setTimeout(()=>p(null),2e3)},[T,ee]=(0,g.useState)(null);return o?(0,P.jsx)(`div`,{className:L.panel,children:`Loading keys...`}):(0,P.jsxs)(`div`,{className:L.panel,children:[(0,P.jsxs)(`div`,{className:L.header,children:[(0,P.jsx)(`h2`,{children:`API Key Management`}),(0,P.jsx)(`button`,{className:L.createButton,onClick:()=>d(!u),disabled:!e,children:u?`✕ Cancel`:`+ New Key`})]}),c&&(0,P.jsxs)(`div`,{className:L.error,children:[(0,P.jsxs)(`strong`,{children:[`⚠ `,c]}),(0,P.jsx)(`div`,{style:{fontSize:`12px`,marginTop:`8px`,lineHeight:`1.5`},children:c.includes(`Connection error`)&&(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(`p`,{children:`To use API key management, ensure:`}),(0,P.jsxs)(`ul`,{style:{margin:`4px 0`,paddingLeft:`20px`},children:[(0,P.jsxs)(`li`,{children:[`FeltDB server is running on `,(0,P.jsx)(`code`,{children:e})]}),(0,P.jsx)(`li`,{children:`VITE_FELTDB_URL environment variable is set correctly`}),(0,P.jsx)(`li`,{children:`Your API token has proper scopes`})]}),(0,P.jsx)(`button`,{onClick:()=>x(),style:{marginTop:`8px`,padding:`4px 12px`,fontSize:`12px`,background:`#667eea`,color:`white`,border:`none`,borderRadius:`4px`,cursor:`pointer`},children:`Retry`})]})})]}),!e&&(0,P.jsxs)(`div`,{className:L.error,children:[(0,P.jsx)(`strong`,{children:`Connect Studio to a server or managed runtime before managing keys.`}),r&&(0,P.jsx)(`button`,{onClick:r,children:`Open connection settings`})]}),T&&(0,P.jsxs)(`div`,{className:L.info,children:[(0,P.jsx)(`strong`,{children:`New secret — copy it now; it will not be shown again.`}),(0,P.jsx)(`code`,{children:T}),(0,P.jsx)(`button`,{onClick:()=>w(T,`created`),children:f===`created`?`✓ Copied`:`Copy secret`})]}),u&&(0,P.jsxs)(`form`,{onSubmit:S,className:L.createForm,children:[(0,P.jsxs)(`div`,{className:L.formGroup,children:[(0,P.jsx)(`label`,{children:`Key Name (optional)`}),(0,P.jsx)(`input`,{type:`text`,value:m,onChange:e=>h(e.target.value),placeholder:`e.g., staging-key-001`})]}),(0,P.jsxs)(`div`,{className:L.formGroup,children:[(0,P.jsx)(`label`,{children:`Scopes`}),(0,P.jsx)(`div`,{className:L.scopeList,children:y.map(e=>(0,P.jsxs)(`label`,{className:L.scopeCheckbox,children:[(0,P.jsx)(`input`,{type:`checkbox`,checked:_.includes(e),onChange:t=>{t.target.checked?v([..._,e]):v(_.filter(t=>t!==e))}}),e]},e))})]}),(0,P.jsx)(`button`,{type:`submit`,className:L.submitButton,children:`Create Key`})]}),i.length===0?(0,P.jsx)(`div`,{className:L.empty,children:`No API keys configured. Create one to get started.`}):(0,P.jsx)(`div`,{className:L.keysList,children:i.map(e=>(0,P.jsxs)(`div`,{className:L.keyCard,children:[(0,P.jsxs)(`div`,{className:L.keyHeader,children:[(0,P.jsxs)(`div`,{children:[(0,P.jsx)(`h3`,{children:e.name||e.id}),(0,P.jsxs)(`p`,{className:L.namespace,children:[`Namespaces: `,e.namespaces.join(`, `)]})]}),(0,P.jsx)(`span`,{className:`${L.status} ${e.revoked?L.expired:L.active}`,children:e.revoked?`Revoked`:`Active`})]}),(0,P.jsx)(`div`,{className:L.keyDetails,children:(0,P.jsxs)(`div`,{className:L.scopes,children:[(0,P.jsx)(`strong`,{children:`Scopes:`}),(0,P.jsx)(`div`,{className:L.scopeTags,children:e.scopes.map(e=>(0,P.jsx)(`span`,{className:L.scopeTag,children:e},e))})]})}),(0,P.jsx)(`div`,{className:L.keyActions,children:(0,P.jsx)(`button`,{className:L.revokeBtn,onClick:()=>C(e.id),disabled:e.revoked,children:`Revoke`})})]},e.id))}),(0,P.jsx)(`div`,{className:L.info,children:(0,P.jsxs)(`p`,{children:[(0,P.jsx)(`strong`,{children:`Security:`}),` Store tokens securely. Never commit to version control. Secrets are shown once. Revoke and replace a key if its secret is lost.`]})})]})};function Zr({db:e,remoteUrl:t=``,token:n=``,namespace:r=`default`,deploymentRuntime:i=`browser`,applicationUrl:a=``,onConnect:o}){let[s,c]=(0,g.useState)(null),l=In(e||null,r),u=Ln(e||null,s,r),{diagnostics:d}=Rn(e||null),f=Bn(e||null),p=e?.sync?.(),[m,h]=(0,g.useState)(),_=!!(s?.workflows.length||s?.agents.length),v=!!(f.length||d?.sync.pendingOperations||p?.conflicts_detected),y=i!==`browser`||!!t;return(0,g.useEffect)(()=>{let t=!0;return fetch(`/_feltdb/project`,{cache:`no-store`}).then(async e=>{if(!e.ok)throw Error(`No project model endpoint`);let n=await e.json();t&&c(Tr(n.source))}).catch(async()=>{let n=e?await e.collection(`_flow_apps`).all():[];t&&n[0]?.spec&&c(n[0].spec)}),()=>{t=!1}},[e]),(0,P.jsx)(Cn,{children:(0,P.jsxs)(`div`,{className:`studio-app`,children:[(0,P.jsxs)(`nav`,{className:`studio-nav`,children:[(0,P.jsxs)(`div`,{className:`nav-header`,children:[(0,P.jsx)(`h1`,{children:`FeltDB Studio`}),l&&(0,P.jsx)(`div`,{className:`instance-info`,children:l.namespace})]}),(0,P.jsx)(`div`,{className:`nav-search`,children:(0,P.jsx)(nr,{db:e,model:s})}),(0,P.jsxs)(`ul`,{className:`nav-menu`,children:[(0,P.jsx)(`li`,{className:`nav-section`,children:`Design`}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/`,children:`Application`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/capabilities`,children:`Capabilities`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/workflows`,children:`Workflows`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/agents`,children:`Agents`})}),(0,P.jsx)(`li`,{className:`nav-section`,children:`Observe`}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/overview`,children:`Overview`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/data`,children:`Data`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/references`,children:`References`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/operations`,children:`Operations`})}),y&&_&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/executions`,children:`Executions`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/peers`,children:`Peers`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/provenance`,children:`Provenance`})}),v&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/conflicts`,children:`Conflicts`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/health`,children:`Health`})}),(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/settings`,children:`Settings`})}),y&&(0,P.jsx)(`li`,{children:(0,P.jsx)(N,{to:`/api-keys`,children:`API Keys`})})]})]}),(0,P.jsxs)(`main`,{className:`studio-content`,children:[!y&&(0,P.jsx)(`div`,{className:`runtime-notice`,children:`Browser data is read live from the generated application origin through the local Studio bridge.`}),(0,P.jsxs)(zt,{children:[(0,P.jsx)(j,{path:`/`,element:(0,P.jsx)(Yr,{db:e,namespace:r,projectSpec:s,onSpecChange:c})}),(0,P.jsx)(j,{path:`/overview`,element:(0,P.jsx)(Fn,{stats:u})}),(0,P.jsx)(j,{path:`/data`,element:(0,P.jsx)(Hn,{db:e,model:s,namespace:r,applicationUrl:i===`browser`?a:``})}),(0,P.jsx)(j,{path:`/state`,element:(0,P.jsx)(Hn,{db:e,model:s,namespace:r,applicationUrl:i===`browser`?a:``})}),(0,P.jsx)(j,{path:`/references`,element:(0,P.jsx)(Wn,{db:e,model:s,namespace:r})}),(0,P.jsx)(j,{path:`/operations`,element:(0,P.jsx)(Gn,{db:e,model:s,namespace:r})}),(0,P.jsx)(j,{path:`/peers`,element:(0,P.jsx)(Kn,{peers:f,localInstance:l?.instanceId})}),(0,P.jsx)(j,{path:`/capabilities`,element:(0,P.jsx)(qn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/executions`,element:(0,P.jsx)(Yn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/workflows`,element:(0,P.jsx)(Zn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/agents`,element:(0,P.jsx)(Qn,{db:e,model:s})}),(0,P.jsx)(j,{path:`/provenance`,element:(0,P.jsx)($n,{db:e,model:s,namespace:r,reference:m})}),(0,P.jsx)(j,{path:`/conflicts`,element:(0,P.jsx)(Xn,{db:e,diagnostics:d})}),(0,P.jsx)(j,{path:`/health`,element:(0,P.jsx)(er,{diagnostics:d,model:s})}),(0,P.jsx)(j,{path:`/settings`,element:(0,P.jsx)(tr,{db:e,remoteUrl:t,token:n,onConnect:o})}),(0,P.jsx)(j,{path:`/api-keys`,element:(0,P.jsxs)(`div`,{style:{padding:`2rem`},children:[(0,P.jsx)(`h1`,{children:`API Key Management`}),(0,P.jsx)(Xr,{apiUrl:t,token:n,namespace:r,onConfigure:()=>window.location.assign(`/settings`)})]})})]})]})]})})}var Qr=new URLSearchParams(window.location.search),$r=Qr.get(`connect`)||``,ei=Qr.get(`namespace`)||`default`,ti=Qr.get(`runtime`)||($r?`remote`:`browser`),ni=Qr.get(`app`)||``;function ri(){let[e,t]=(0,g.useState)($r),[n,r]=(0,g.useState)(()=>$r&&window.sessionStorage.getItem(`feltdb-token:${$r}`)||``),i=(0,g.useMemo)(()=>window.feltdb||Wr(e?{namespace:ei,server:{url:e,token:n}}:{namespace:ei,browser:!0}),[e,n]);return(0,P.jsx)(Zr,{db:i,remoteUrl:e,token:n,namespace:ei,deploymentRuntime:ti,applicationUrl:ni,onConnect:(e,n)=>{let i=e.trim().replace(/\/$/,``);i&&n&&window.sessionStorage.setItem(`feltdb-token:${i}`,n),t(i),r(n)}})}_.createRoot(document.getElementById(`root`)).render((0,P.jsx)(g.StrictMode,{children:(0,P.jsx)(ri,{})}));
@@ -1,3 +1,3 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-DZpBoVMp.js"></script>
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-BHOmLZF-.js"></script>
2
2
  <link rel="stylesheet" crossorigin href="/assets/index-C1GWyazR.css">
3
3
  </head><body><div id="root"></div></body></html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feltdb/core",
3
- "version": "0.4.11",
3
+ "version": "0.4.12",
4
4
  "description": "FeltDB Core - Application-facing database API with state-first reactivity",
5
5
  "license": "MIT",
6
6
  "type": "module",