@semiont/cli 0.3.4 → 0.3.5

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.
@@ -8,7 +8,7 @@ const require = (name) => {
8
8
  throw new Error('Unknown module: ' + name);
9
9
  };
10
10
 
11
- "use strict";var SemiontDashboard=(()=>{var y=Object.create;var u=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var z=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var C=(a=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(a,{get:(n,o)=>(typeof require<"u"?require:n)[o]}):a)(function(a){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+a+'" is not supported')});var B=(a,n)=>{for(var o in n)u(a,o,{get:n[o],enumerable:!0})},h=(a,n,o,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let i of w(n))!D.call(a,i)&&i!==o&&u(a,i,{get:()=>n[i],enumerable:!(r=S(n,i))||r.enumerable});return a};var A=(a,n,o)=>(o=a!=null?y(z(a)):{},h(n||!a||!a.__esModule?u(o,"default",{value:a,enumerable:!0}):o,a)),L=a=>h(u({},"__esModule",{value:!0}),a);var x={};B(x,{WebDashboardApp:()=>v});var s=A(C("react"),1),U=({status:a})=>{let n={healthy:"#48bb78",unhealthy:"#f56565",warning:"#ed8936",unknown:"#a0aec0"};return s.default.createElement("div",{className:`status-indicator status-${a}`,style:{background:n[a]}})},f=({services:a,title:n,showActions:o=!0})=>{let r=e=>{let t=[],l=e.awsRegion||"us-east-1";if(e.ecsServiceName&&e.ecsClusterName&&(t.push({label:"\u{1F4CA} Console",url:`https://console.aws.amazon.com/ecs/home?region=${l}#/clusters/${e.ecsClusterName}/services/${e.ecsServiceName}/details`,className:"console"}),e.logGroupName&&t.push({label:"\u{1F4DD} Logs",url:`https://console.aws.amazon.com/cloudwatch/home?region=${l}#logsV2:log-groups/log-group/${encodeURIComponent(e.logGroupName)}`,className:"logs"}),t.push({label:"\u{1F4C8} Metrics",url:`https://console.aws.amazon.com/cloudwatch/home?region=${l}#metricsV2:graph=~();query=~'*7bAWS*2fECS*2cClusterName*2cServiceName*7d*20${e.ecsClusterName}*20${e.ecsServiceName}`,className:"metrics"})),e.rdsInstanceId&&(t.push({label:"\u{1F4CA} Console",url:`https://console.aws.amazon.com/rds/home?region=${l}#database:id=${e.rdsInstanceId};is-cluster=false`,className:"console"}),t.push({label:"\u{1F4C8} Metrics",url:`https://console.aws.amazon.com/cloudwatch/home?region=${l}#metricsV2:graph=~();query=~'*7bAWS*2fRDS*2cDBInstanceIdentifier*7d*20${e.rdsInstanceId}`,className:"metrics"})),e.efsFileSystemId&&(t.push({label:"\u{1F4CA} Console",url:`https://console.aws.amazon.com/efs/home?region=${l}#/file-systems/${e.efsFileSystemId}`,className:"console"}),t.push({label:"\u{1F4C8} Metrics",url:`https://console.aws.amazon.com/cloudwatch/home?region=${l}#metricsV2:graph=~();query=~'*7bAWS*2fEFS*2cFileSystemId*7d*20${e.efsFileSystemId}`,className:"metrics"})),e.albArn){let d=e.albArn.split("/");if(d.length>=3){let p=d[d.length-2];t.push({label:"\u{1F4CA} Console",url:`https://console.aws.amazon.com/ec2/v2/home?region=${l}#LoadBalancers:search=${p};sort=loadBalancerName`,className:"console"})}t.push({label:"\u{1F4C8} Metrics",url:`https://console.aws.amazon.com/cloudwatch/home?region=${l}#metricsV2:graph=~();query=~'*7bAWS*2fApplicationELB*2cLoadBalancer*7d`,className:"metrics"})}return t},i=e=>{if(e===0)return"0 B";let t=1024,l=["B","KB","MB","GB","TB"],d=Math.floor(Math.log(e)/Math.log(t));return(e/Math.pow(t,d)).toFixed(2)+" "+l[d]};return s.default.createElement("div",{className:"dashboard-panel"},s.default.createElement("div",{className:"panel-title"},n),a.map((e,t)=>s.default.createElement("div",{key:t,className:"service-item",style:{marginBottom:"12px"}},s.default.createElement(U,{status:e.status}),s.default.createElement("div",{style:{flex:1}},s.default.createElement("div",{className:"service-name"},e.name,e.revision&&s.default.createElement("span",{style:{color:"#00bcd4",marginLeft:"8px",fontSize:"0.9em"}},"rev:",e.revision),e.runningCount!==void 0&&e.desiredCount!==void 0&&s.default.createElement("span",{style:{color:"#999",marginLeft:"8px",fontSize:"0.9em"}},"[",e.runningCount,"/",e.desiredCount,"]")),e.details&&s.default.createElement("div",{className:"service-details"},e.details),e.name==="Filesystem"&&e.storageTotalBytes&&s.default.createElement(s.default.Fragment,null,s.default.createElement("div",{className:"service-details",style:{color:"#2563eb",fontSize:"0.9em",marginTop:"8px"}},s.default.createElement("strong",null,"Storage:")),e.storageUsedBytes!==void 0&&e.storageTotalBytes&&s.default.createElement("div",{className:"service-details",style:{color:"#718096",fontSize:"0.9em",paddingLeft:"16px"}},"Used: ",i(e.storageUsedBytes)," / ",i(e.storageTotalBytes),e.storageUsedPercent!==void 0&&s.default.createElement("span",{style:{marginLeft:"8px",color:e.storageUsedPercent>90?"#ef4444":e.storageUsedPercent>70?"#f59e0b":"#10b981"}},"(",e.storageUsedPercent.toFixed(1),"%)")),e.storageAvailableBytes!==void 0&&s.default.createElement("div",{className:"service-details",style:{color:"#718096",fontSize:"0.9em",paddingLeft:"16px"}},"Available: ",i(e.storageAvailableBytes)),e.throughputUtilization!==void 0&&s.default.createElement("div",{className:"service-details",style:{color:"#718096",fontSize:"0.9em",paddingLeft:"16px"}},"Throughput: ",e.throughputUtilization.toFixed(1),"%"),e.clientConnections!==void 0&&s.default.createElement("div",{className:"service-details",style:{color:"#718096",fontSize:"0.9em",paddingLeft:"16px"}},"Connections: ",e.clientConnections)),e.name!=="Filesystem"&&(e.cpuUtilization!==void 0||e.memoryUtilization!==void 0)&&s.default.createElement("div",{className:"service-details",style:{color:"#718096",fontSize:"0.9em"}},e.cpuUtilization!==void 0&&s.default.createElement("span",null,"CPU: ",e.cpuUtilization.toFixed(1),"%"),e.cpuUtilization!==void 0&&e.memoryUtilization!==void 0&&s.default.createElement("span",{style:{margin:"0 8px"}},"\u2022"),e.memoryUtilization!==void 0&&s.default.createElement("span",null,"Memory: ",e.memoryUtilization.toFixed(1),"%")),e.deploymentStatus&&e.deploymentStatus!=="PRIMARY"&&s.default.createElement("div",{className:"service-details",style:{color:"#ff9800"}},"Deployment: ",e.deploymentStatus),e.loadBalancerDns&&s.default.createElement("div",{className:"service-details",style:{color:"#00bcd4",fontSize:"0.9em"}},"ALB: ",e.loadBalancerDns),e.wafWebAclId&&s.default.createElement("div",{className:"service-details",style:{color:"#4caf50",fontSize:"0.9em"}},"WAF: Protected \u2713"),o&&r(e).length>0&&s.default.createElement("div",{className:"action-buttons"},r(e).map((l,d)=>s.default.createElement("a",{key:d,href:l.url,target:"_blank",rel:"noopener noreferrer",className:`action-button ${l.className}`},l.label)))))))},$=({logs:a})=>{let n=o=>`log-level log-level-${o}`;return s.default.createElement("div",{className:"dashboard-panel logs-panel"},s.default.createElement("div",{className:"panel-title"},"Recent Logs"),a.length===0?s.default.createElement("div",{style:{padding:"20px",color:"#718096",textAlign:"center"}},"No recent logs"):a.slice(0,50).map((o,r)=>s.default.createElement("div",{key:r,className:"log-entry"},s.default.createElement("span",{className:"log-timestamp"},new Date(o.timestamp).toLocaleTimeString()),s.default.createElement("span",{className:"log-service"},o.service),s.default.createElement("span",{className:n(o.level)},o.level.toUpperCase()),s.default.createElement("span",{className:"log-message"},o.message))))},v=({environment:a,refreshInterval:n})=>{let[o,r]=(0,s.useState)(null),[i,e]=(0,s.useState)(!1),[t,l]=(0,s.useState)(null),[,d]=(0,s.useState)(null);(0,s.useEffect)(()=>{let m=window.io;if(!m){console.error("Socket.IO not loaded");return}let c=m();return d(c),c.on("connect",()=>{e(!0)}),c.on("disconnect",()=>{e(!1)}),c.on("dashboard-update",g=>{r(g),l(new Date)}),c.on("dashboard-error",g=>{console.error("Dashboard error:",g)}),()=>{c.disconnect()}},[]);let p=m=>m?m.toLocaleTimeString():"Never";if(!o)return s.default.createElement("div",{className:"dashboard-container"},s.default.createElement("div",{className:"dashboard-panel"},s.default.createElement("div",{className:"loading"},s.default.createElement("div",{className:"spinner"}))));let N=o.services.filter(m=>["Frontend","Backend","Load Balancer","WAF","DNS (Route 53)"].includes(m.name)),b=o.services.filter(m=>["Database","Filesystem"].includes(m.name));return s.default.createElement("div",{className:"dashboard-container"},s.default.createElement("div",{className:"dashboard-header"},s.default.createElement("div",null,s.default.createElement("div",{className:"dashboard-title"},"Semiont System Dashboard"),s.default.createElement("div",{className:"dashboard-subtitle"},"Environment: ",a)),s.default.createElement("div",{className:"refresh-info"},s.default.createElement("div",null,"Last updated: ",p(t)),s.default.createElement("div",null,"Auto-refresh: every ",n,"s"))),s.default.createElement("div",{className:"dashboard-grid"},s.default.createElement(f,{services:N,title:"App Services",showActions:!0}),s.default.createElement(f,{services:b,title:"Data",showActions:!0})),s.default.createElement($,{logs:o.logs}),s.default.createElement("div",{className:`connection-status ${i?"connected":"disconnected"}`},i?"\u{1F7E2} Connected":"\u{1F534} Disconnected"))};typeof window<"u"&&(window.SemiontDashboard=window.SemiontDashboard||{},window.SemiontDashboard.WebDashboardApp=v);return L(x);})();
11
+ "use strict";var SemiontDashboard=(()=>{var ee=Object.create;var S=Object.defineProperty;var se=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var ne=Object.getPrototypeOf,ae=Object.prototype.hasOwnProperty;var N=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(t,n)=>(typeof require<"u"?require:t)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var oe=(e,t)=>{for(var n in t)S(e,n,{get:t[n],enumerable:!0})},B=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of te(t))!ae.call(e,o)&&o!==n&&S(e,o,{get:()=>t[o],enumerable:!(a=se(t,o))||a.enumerable});return e};var y=(e,t,n)=>(n=e!=null?ee(ne(e)):{},B(t||!e||!e.__esModule?S(n,"default",{value:e,enumerable:!0}):n,e)),ie=e=>B(S({},"__esModule",{value:!0}),e);var Ne={};oe(Ne,{WebDashboardApp:()=>j});var s=y(N("react"),1);var i=y(N("react"),1),re="semiont-tag semiont-tag--secondary semiont-tag--compact",ce=new Set(["graph","neo4j","janusgraph","neptune"]),x=["proxy","frontend","backend","database"];function me(e){switch(e){case"healthy":return"semiont-indicator semiont-indicator--online";case"unhealthy":return"semiont-indicator semiont-indicator--offline";case"warning":return"semiont-indicator semiont-indicator--busy";default:return"semiont-indicator"}}function le(e){switch(e){case"healthy":return"healthy";case"unhealthy":return"unhealthy";case"warning":return"warning";default:return"unknown"}}function de(e){switch(e){case"healthy":return"semiont-badge semiont-badge--success";case"unhealthy":return"semiont-badge semiont-badge--error";case"warning":return"semiont-badge semiont-badge--warning";default:return"semiont-badge semiont-badge--info"}}var pe=({service:e})=>{let t=e.evidence&&e.evidence.length>0?[...e.evidence]:(()=>{let a=e.details||"",o=[],l=a.match(/[Pp][Ii][Dd]:\s*(\d+)/),u=a.match(/[Cc]ontainer:\s*(\S+)/);return l&&o.push(`pid ${l[1]}`),u&&o.push(`container ${u[1].slice(0,12)}`),e.runningCount!==void 0&&e.desiredCount!==void 0&&o.push(`${e.runningCount}/${e.desiredCount} tasks`),o})();e.checkedAt&&t.push(`checked ${new Date(e.checkedAt).toLocaleTimeString()}`);let n=ue(e);return i.default.createElement("div",{className:"service-row"},i.default.createElement("div",{className:"service-row__indicator"},i.default.createElement("span",{className:me(e.status)})),i.default.createElement("div",{className:"service-row__name"},e.name),i.default.createElement("div",{className:"service-row__host"},e.hostname?i.default.createElement("span",{className:"service-row__hostname"},e.hostname):i.default.createElement("span",{className:"service-row__hostname service-row__hostname--dim"},"\u2014")),i.default.createElement("div",{className:"service-row__status"},i.default.createElement("span",{className:de(e.status)},i.default.createElement("span",{className:"semiont-badge__text"},le(e.status)))),i.default.createElement("div",{className:"service-row__tags"},t.map((a,o)=>i.default.createElement("span",{key:o,className:re},a))),i.default.createElement("div",{className:"service-row__actions"},n.map((a,o)=>i.default.createElement("a",{key:o,href:a.url,target:"_blank",rel:"noopener noreferrer",className:"semiont-tag semiont-tag--info semiont-tag--compact"},a.label))))};function ue(e){let t=[],n=e.awsRegion||"us-east-1";return e.ecsServiceName&&e.ecsClusterName&&(t.push({label:"Console \u2197",url:`https://console.aws.amazon.com/ecs/home?region=${n}#/clusters/${e.ecsClusterName}/services/${e.ecsServiceName}/details`}),e.logGroupName&&t.push({label:"Logs \u2197",url:`https://console.aws.amazon.com/cloudwatch/home?region=${n}#logsV2:log-groups/log-group/${encodeURIComponent(e.logGroupName)}`})),e.rdsInstanceId&&t.push({label:"Console \u2197",url:`https://console.aws.amazon.com/rds/home?region=${n}#database:id=${e.rdsInstanceId};is-cluster=false`}),t}var G=({services:e})=>{let n=[...e.filter(a=>!ce.has(a.name.toLowerCase()))].sort((a,o)=>{let l=x.indexOf(a.name.toLowerCase()),u=x.indexOf(o.name.toLowerCase());return l===-1&&u===-1?a.name.localeCompare(o.name):l===-1?1:u===-1?-1:l-u});return i.default.createElement("div",{className:"service-list"},i.default.createElement("div",{className:"service-list__header"},i.default.createElement("div",{className:"service-row__indicator"}),i.default.createElement("div",{className:"service-row__name"},"Service"),i.default.createElement("div",{className:"service-row__host"},"Address"),i.default.createElement("div",{className:"service-row__status"},"Status"),i.default.createElement("div",{className:"service-row__tags"},"Details"),i.default.createElement("div",{className:"service-row__actions"})),n.map((a,o)=>i.default.createElement(pe,{key:o,service:a})))};var r=y(N("react"),1),ge="semiont-tag semiont-tag--secondary semiont-tag--compact";function F(e){if(e===0)return"0 B";let t=1024,n=["B","KB","MB","GB","TB"],a=Math.floor(Math.log(e)/Math.log(t));return`${(e/Math.pow(t,a)).toFixed(1)} ${n[a]}`}function L(e,t=40){return e.length<=t?e:"\u2026"+e.slice(e.length-t+1)}function ve(e){switch(e.state){case"active":return"semiont-indicator semiont-indicator--online semiont-indicator--pulse";case"idle":return"semiont-indicator semiont-indicator--online";case"error":return"semiont-indicator semiont-indicator--offline";default:return"semiont-indicator"}}function he(e){switch(e){case"healthy":return"semiont-indicator semiont-indicator--online";case"unhealthy":return"semiont-indicator semiont-indicator--offline";default:return"semiont-indicator"}}var f=({indicator:e,label:t,value:n,tags:a})=>r.default.createElement("div",{className:"mm-row"},r.default.createElement("div",{className:"mm-row__indicator"},r.default.createElement("span",{className:e})),r.default.createElement("div",{className:"mm-row__label"},t),r.default.createElement("div",{className:"mm-row__value"},n),r.default.createElement("div",{className:"mm-row__tags"},a==null?void 0:a.filter(Boolean).map((o,l)=>r.default.createElement("span",{key:l,className:ge},o)))),D=({title:e,children:t})=>r.default.createElement("div",{className:"mm-group"},r.default.createElement("div",{className:"mm-group__title"},e),r.default.createElement("div",{className:"mm-list"},t)),V=({makeMeaning:e})=>r.default.createElement("div",{className:"mm-sections"},r.default.createElement(D,{title:"System of Record"},r.default.createElement(f,{indicator:"semiont-indicator semiont-indicator--online",label:"Event Log",value:e.eventLog.eventCount!==void 0?e.eventLog.eventCount.toLocaleString()+" events":"unknown",tags:[e.eventLog.streamCount!==void 0&&`${e.eventLog.streamCount} streams`,e.eventLog.sizeBytes!==void 0&&F(e.eventLog.sizeBytes),e.eventLog.path&&L(e.eventLog.path)]}),r.default.createElement(f,{indicator:"semiont-indicator semiont-indicator--online",label:"Content Store",value:e.contentStore.sizeBytes!==void 0?F(e.contentStore.sizeBytes):"unknown",tags:[e.contentStore.fileCount!==void 0&&`${e.contentStore.fileCount} files`,e.contentStore.path&&L(e.contentStore.path)]})),r.default.createElement(D,{title:"Projections"},r.default.createElement(f,{indicator:he(e.graph.status),label:"Graph",value:e.graph.status,tags:[e.graph.address,e.graph.database,...e.graph.evidence??[]]}),r.default.createElement(f,{indicator:"semiont-indicator semiont-indicator--online",label:"Materialized Views",value:e.materializedViews.fileCount!==void 0?`${e.materializedViews.fileCount} projections`:"unknown",tags:[e.materializedViews.lastUpdated&&`updated ${new Date(e.materializedViews.lastUpdated).toLocaleTimeString()}`,e.materializedViews.path&&L(e.materializedViews.path)]})),r.default.createElement(D,{title:"Actors"},["gatherer","matcher","stower"].map(t=>{let n=e.actors[t];return r.default.createElement(f,{key:t,indicator:ve(n),label:t.charAt(0).toUpperCase()+t.slice(1),value:n.state,tags:[n.provider,n.model,n.errorMessage&&n.errorMessage.slice(0,40)]})})));var c=y(N("react"),1),A="semiont-tag semiont-tag--secondary semiont-tag--compact",fe={"reference-annotation":"Reference Annotation","highlight-annotation":"Highlight Annotation","assessment-annotation":"Assessment Annotation","comment-annotation":"Comment Annotation","tag-annotation":"Tag Annotation",generation:"Generation"};function be(e){return e.state==="error"?"semiont-indicator semiont-indicator--offline":e.activeCount>0?"semiont-indicator semiont-indicator--online semiont-indicator--pulse":e.pendingCount>10?"semiont-indicator semiont-indicator--busy":"semiont-indicator semiont-indicator--online"}var H=({workers:e})=>c.default.createElement("div",{className:"mm-list"},c.default.createElement("div",{className:"mm-row mm-row--header"},c.default.createElement("div",{className:"mm-row__indicator"}),c.default.createElement("div",{className:"mm-row__label"},"Worker"),c.default.createElement("div",{className:"mm-row__value"},"Status"),c.default.createElement("div",{className:"mm-row__tags"},"Details")),e.map((t,n)=>c.default.createElement("div",{key:n,className:"mm-row"},c.default.createElement("div",{className:"mm-row__indicator"},c.default.createElement("span",{className:be(t)})),c.default.createElement("div",{className:"mm-row__label"},fe[t.type]),c.default.createElement("div",{className:"mm-row__value"},t.state),c.default.createElement("div",{className:"mm-row__tags"},c.default.createElement("span",{className:t.activeCount>0?"semiont-tag semiont-tag--success semiont-tag--compact":A},t.activeCount," active"),c.default.createElement("span",{className:A},t.pendingCount," pending"),t.lastProcessed&&c.default.createElement("span",{className:A},"last ",new Date(t.lastProcessed).toLocaleTimeString())))));var we={eventLog:{path:""},contentStore:{path:""},graph:{status:"unknown"},materializedViews:{path:""},actors:{gatherer:{state:"unknown"},matcher:{state:"unknown"},stower:{state:"unknown"}}},T=({logs:e,service:t})=>{let n=t?e.filter(a=>a.service===t||!t):e;return s.default.createElement("div",{className:"semiont-panel semiont-panel--bordered dashboard-logs"},s.default.createElement("div",{className:"semiont-panel-header"},s.default.createElement("span",{className:"semiont-panel-header__title"},"Recent Logs")),n.length===0?s.default.createElement("div",{className:"logs-empty"},"No recent logs"):s.default.createElement("div",{className:"logs-list"},n.slice(0,50).map((a,o)=>s.default.createElement("div",{key:o,className:`log-entry log-entry--${a.level}`},s.default.createElement("span",{className:"log-timestamp"},new Date(a.timestamp).toLocaleTimeString()),s.default.createElement("span",{className:"log-service"},a.service),s.default.createElement("span",{className:`log-level semiont-badge semiont-badge--${a.level==="error"?"error":a.level==="warn"?"warning":"info"}`},s.default.createElement("span",{className:"semiont-badge__text"},a.level.toUpperCase())),s.default.createElement("span",{className:"log-message"},a.message)))))},Se=({active:e,onChange:t,webHealthy:n,webTotal:a,mmHealthy:o,mmTotal:l,wkHealthy:u,wkTotal:k})=>{let _=[{id:"web",label:"Web Interface",healthy:n,total:a},{id:"make-meaning",label:"Make Meaning",healthy:o,total:l},{id:"workers",label:"Job Workers",healthy:u,total:k}];function C(m,h){return h===0?"semiont-badge semiont-badge--info":m===h?"semiont-badge semiont-badge--success":m===0?"semiont-badge semiont-badge--error":"semiont-badge semiont-badge--warning"}return s.default.createElement("div",{className:"dashboard-tabs"},_.map(m=>s.default.createElement("button",{key:m.id,className:`dashboard-tab${e===m.id?" dashboard-tab--active":""}`,onClick:()=>t(m.id)},m.label,s.default.createElement("span",{className:C(m.healthy,m.total)},s.default.createElement("span",{className:"semiont-badge__text"},m.healthy,"/",m.total)))))},I=({time:e,label:t})=>s.default.createElement("span",{className:"tab-update-time"},t,": ",e?e.toLocaleTimeString():"\u2014"),j=({environment:e,refreshInterval:t})=>{let[n,a]=(0,s.useState)("web"),[o,l]=(0,s.useState)([]),[u,k]=(0,s.useState)([]),[_,C]=(0,s.useState)(null),[m,h]=(0,s.useState)(we),[K,U]=(0,s.useState)(null),[M,O]=(0,s.useState)([]),[J,q]=(0,s.useState)(null),[E,P]=(0,s.useState)(!1),[$,W]=(0,s.useState)(!1);if((0,s.useEffect)(()=>{let g=window.io;if(!g){console.error("Socket.IO not loaded");return}let v=g();return v.on("connect",()=>P(!0)),v.on("disconnect",()=>P(!1)),v.on("services-update",d=>{l(d.services),k(d.logs),C(new Date),W(!0)}),v.on("make-meaning-update",d=>{let{lastUpdate:w,...R}=d;h(R),U(w?new Date(w):new Date)}),v.on("actors-update",d=>{h(w=>({...w,actors:d.actors})),d.lastUpdate&&U(new Date(d.lastUpdate))}),v.on("workers-update",d=>{O(d.workers),q(d.lastUpdate?new Date(d.lastUpdate):new Date),$||W(!0)}),()=>v.disconnect()},[]),!$)return s.default.createElement("div",{className:"dashboard-container"},s.default.createElement("div",{className:"dashboard-loading"},s.default.createElement("div",{className:"semiont-spinner"})));let b=o.find(g=>g.name.toLowerCase()==="graph"),p=b?{...m,graph:{...m.graph,status:b.status==="healthy"?"healthy":b.status==="unhealthy"?"unhealthy":"unknown",evidence:b.evidence}}:m,Q=new Set(["graph","neo4j","janusgraph","neptune"]),z=o.filter(g=>!Q.has(g.name.toLowerCase())),X=z.filter(g=>g.status==="healthy").length,Y=[p.eventLog.path,p.contentStore.path,p.graph.status==="healthy",p.materializedViews.path,p.actors.gatherer.state!=="error"&&p.actors.gatherer.state!=="unknown",p.actors.matcher.state!=="error"&&p.actors.matcher.state!=="unknown",p.actors.stower.state!=="error"&&p.actors.stower.state!=="unknown"].filter(Boolean).length,Z=M.filter(g=>g.state!=="error").length;return s.default.createElement("div",{className:"dashboard-container"},s.default.createElement("header",{className:"dashboard-header semiont-panel semiont-panel--bordered"},s.default.createElement("div",{className:"dashboard-header-left"},s.default.createElement("h1",{className:"dashboard-title"},"Semiont Dashboard"),s.default.createElement("span",{className:"semiont-badge semiont-badge--info dashboard-env"},s.default.createElement("span",{className:"semiont-badge__text"},e))),s.default.createElement("div",{className:"dashboard-header-right"},s.default.createElement("span",{className:`semiont-indicator ${E?"semiont-indicator--online":"semiont-indicator--offline"}`}),s.default.createElement("span",{className:"dashboard-connection-label"},E?"Live":"Disconnected"))),s.default.createElement("div",{className:"semiont-panel semiont-panel--bordered dashboard-tab-panel"},s.default.createElement(Se,{active:n,onChange:a,webHealthy:X,webTotal:z.length,mmHealthy:Y,mmTotal:7,wkHealthy:Z,wkTotal:M.length}),s.default.createElement("div",{className:"tab-content"},n==="web"&&s.default.createElement(s.default.Fragment,null,s.default.createElement("div",{className:"tab-meta"},s.default.createElement(I,{time:_,label:"updated"})),s.default.createElement(G,{services:o}),s.default.createElement(T,{logs:u})),n==="make-meaning"&&s.default.createElement(s.default.Fragment,null,s.default.createElement("div",{className:"tab-meta"},s.default.createElement(I,{time:K,label:"updated"})),s.default.createElement(V,{makeMeaning:p}),s.default.createElement(T,{logs:[]})),n==="workers"&&s.default.createElement(s.default.Fragment,null,s.default.createElement("div",{className:"tab-meta"},s.default.createElement(I,{time:J,label:"updated"})),s.default.createElement(H,{workers:M}),s.default.createElement(T,{logs:[]})))))};typeof window<"u"&&(window.SemiontDashboard=window.SemiontDashboard||{},window.SemiontDashboard.WebDashboardApp=j);return ie(Ne);})();
12
12
  // Ensure global is set
13
13
  if (typeof window !== "undefined") { window.SemiontDashboard = SemiontDashboard; }
14
14
  //# sourceMappingURL=dashboard.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../src/core/dashboard/web-dashboard-app.tsx"],
4
- "sourcesContent": ["/**\n * Web Dashboard React Application\n * \n * This is the React app for the web dashboard that reuses the same components\n * as the terminal dashboard, eliminating duplication\n */\n\nimport React, { useState, useEffect } from 'react';\nimport { ServiceStatus, LogEntry, MetricData } from './dashboard-components';\n\n// Type declarations for browser globals\ndeclare const window: any;\n\n// Dashboard data interface (shared with terminal)\nexport interface DashboardData {\n services: ServiceStatus[];\n logs: LogEntry[];\n metrics: MetricData[];\n lastUpdate: Date;\n isRefreshing: boolean;\n}\n\n// Status indicator component\nconst StatusIndicator: React.FC<{ status: ServiceStatus['status'] }> = ({ status }) => {\n const colors = {\n healthy: '#48bb78',\n unhealthy: '#f56565',\n warning: '#ed8936',\n unknown: '#a0aec0'\n };\n \n return (\n <div \n className={`status-indicator status-${status}`}\n style={{ background: colors[status] }}\n />\n );\n};\n\n// Service panel component\nconst ServicePanel: React.FC<{ \n services: ServiceStatus[];\n title: string;\n showActions?: boolean;\n}> = ({ services, title, showActions = true }) => {\n const getConsoleLinks = (service: ServiceStatus) => {\n const links: Array<{ label: string; url: string; className: string }> = [];\n const region = service.awsRegion || 'us-east-1';\n \n // ECS Service links\n if (service.ecsServiceName && service.ecsClusterName) {\n links.push({\n label: '\uD83D\uDCCA Console',\n url: `https://console.aws.amazon.com/ecs/home?region=${region}#/clusters/${service.ecsClusterName}/services/${service.ecsServiceName}/details`,\n className: 'console'\n });\n if (service.logGroupName) {\n links.push({\n label: '\uD83D\uDCDD Logs',\n url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/${encodeURIComponent(service.logGroupName)}`,\n className: 'logs'\n });\n }\n links.push({\n label: '\uD83D\uDCC8 Metrics',\n url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#metricsV2:graph=~();query=~'*7bAWS*2fECS*2cClusterName*2cServiceName*7d*20${service.ecsClusterName}*20${service.ecsServiceName}`,\n className: 'metrics'\n });\n }\n \n // RDS Database link\n if (service.rdsInstanceId) {\n links.push({\n label: '\uD83D\uDCCA Console',\n url: `https://console.aws.amazon.com/rds/home?region=${region}#database:id=${service.rdsInstanceId};is-cluster=false`,\n className: 'console'\n });\n links.push({\n label: '\uD83D\uDCC8 Metrics',\n url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#metricsV2:graph=~();query=~'*7bAWS*2fRDS*2cDBInstanceIdentifier*7d*20${service.rdsInstanceId}`,\n className: 'metrics'\n });\n }\n \n // EFS Filesystem link\n if (service.efsFileSystemId) {\n links.push({\n label: '\uD83D\uDCCA Console',\n url: `https://console.aws.amazon.com/efs/home?region=${region}#/file-systems/${service.efsFileSystemId}`,\n className: 'console'\n });\n links.push({\n label: '\uD83D\uDCC8 Metrics',\n url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#metricsV2:graph=~();query=~'*7bAWS*2fEFS*2cFileSystemId*7d*20${service.efsFileSystemId}`,\n className: 'metrics'\n });\n }\n \n // Load Balancer link\n if (service.albArn) {\n const arnParts = service.albArn.split('/');\n if (arnParts.length >= 3) {\n const loadBalancerName = arnParts[arnParts.length - 2];\n links.push({\n label: '\uD83D\uDCCA Console',\n url: `https://console.aws.amazon.com/ec2/v2/home?region=${region}#LoadBalancers:search=${loadBalancerName};sort=loadBalancerName`,\n className: 'console'\n });\n }\n links.push({\n label: '\uD83D\uDCC8 Metrics',\n url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#metricsV2:graph=~();query=~'*7bAWS*2fApplicationELB*2cLoadBalancer*7d`,\n className: 'metrics'\n });\n }\n \n return links;\n };\n\n const formatBytes = (bytes: number): string => {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return (bytes / Math.pow(k, i)).toFixed(2) + ' ' + sizes[i];\n };\n\n return (\n <div className=\"dashboard-panel\">\n <div className=\"panel-title\">{title}</div>\n {services.map((service, index) => (\n <div key={index} className=\"service-item\" style={{ marginBottom: '12px' }}>\n <StatusIndicator status={service.status} />\n <div style={{ flex: 1 }}>\n <div className=\"service-name\">\n {service.name}\n {service.revision && (\n <span style={{ color: '#00bcd4', marginLeft: '8px', fontSize: '0.9em' }}>\n rev:{service.revision}\n </span>\n )}\n {service.runningCount !== undefined && service.desiredCount !== undefined && (\n <span style={{ color: '#999', marginLeft: '8px', fontSize: '0.9em' }}>\n [{service.runningCount}/{service.desiredCount}]\n </span>\n )}\n </div>\n {service.details && (\n <div className=\"service-details\">{service.details}</div>\n )}\n \n {/* EFS Storage Metrics */}\n {service.name === 'Filesystem' && service.storageTotalBytes && (\n <>\n <div className=\"service-details\" style={{ color: '#2563eb', fontSize: '0.9em', marginTop: '8px' }}>\n <strong>Storage:</strong>\n </div>\n {service.storageUsedBytes !== undefined && service.storageTotalBytes && (\n <div className=\"service-details\" style={{ color: '#718096', fontSize: '0.9em', paddingLeft: '16px' }}>\n Used: {formatBytes(service.storageUsedBytes)} / {formatBytes(service.storageTotalBytes)}\n {service.storageUsedPercent !== undefined && (\n <span style={{ \n marginLeft: '8px',\n color: service.storageUsedPercent > 90 ? '#ef4444' : \n service.storageUsedPercent > 70 ? '#f59e0b' : '#10b981'\n }}>\n ({service.storageUsedPercent.toFixed(1)}%)\n </span>\n )}\n </div>\n )}\n {service.storageAvailableBytes !== undefined && (\n <div className=\"service-details\" style={{ color: '#718096', fontSize: '0.9em', paddingLeft: '16px' }}>\n Available: {formatBytes(service.storageAvailableBytes)}\n </div>\n )}\n {service.throughputUtilization !== undefined && (\n <div className=\"service-details\" style={{ color: '#718096', fontSize: '0.9em', paddingLeft: '16px' }}>\n Throughput: {service.throughputUtilization.toFixed(1)}%\n </div>\n )}\n {service.clientConnections !== undefined && (\n <div className=\"service-details\" style={{ color: '#718096', fontSize: '0.9em', paddingLeft: '16px' }}>\n Connections: {service.clientConnections}\n </div>\n )}\n </>\n )}\n \n {/* Regular metrics for other services */}\n {service.name !== 'Filesystem' && (service.cpuUtilization !== undefined || service.memoryUtilization !== undefined) && (\n <div className=\"service-details\" style={{ color: '#718096', fontSize: '0.9em' }}>\n {service.cpuUtilization !== undefined && (\n <span>CPU: {service.cpuUtilization.toFixed(1)}%</span>\n )}\n {service.cpuUtilization !== undefined && service.memoryUtilization !== undefined && (\n <span style={{ margin: '0 8px' }}>\u2022</span>\n )}\n {service.memoryUtilization !== undefined && (\n <span>Memory: {service.memoryUtilization.toFixed(1)}%</span>\n )}\n </div>\n )}\n \n {service.deploymentStatus && service.deploymentStatus !== 'PRIMARY' && (\n <div className=\"service-details\" style={{ color: '#ff9800' }}>\n Deployment: {service.deploymentStatus}\n </div>\n )}\n \n {service.loadBalancerDns && (\n <div className=\"service-details\" style={{ color: '#00bcd4', fontSize: '0.9em' }}>\n ALB: {service.loadBalancerDns}\n </div>\n )}\n \n {service.wafWebAclId && (\n <div className=\"service-details\" style={{ color: '#4caf50', fontSize: '0.9em' }}>\n WAF: Protected \u2713\n </div>\n )}\n \n {/* Action Buttons */}\n {showActions && getConsoleLinks(service).length > 0 && (\n <div className=\"action-buttons\">\n {getConsoleLinks(service).map((link, linkIndex) => (\n <a \n key={linkIndex}\n href={link.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={`action-button ${link.className}`}\n >\n {link.label}\n </a>\n ))}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n );\n};\n\n// Log viewer component\nconst LogViewer: React.FC<{ logs: LogEntry[] }> = ({ logs }) => {\n const getLevelClass = (level: string) => {\n return `log-level log-level-${level}`;\n };\n\n return (\n <div className=\"dashboard-panel logs-panel\">\n <div className=\"panel-title\">Recent Logs</div>\n {logs.length === 0 ? (\n <div style={{ padding: '20px', color: '#718096', textAlign: 'center' }}>\n No recent logs\n </div>\n ) : (\n logs.slice(0, 50).map((log, index) => (\n <div key={index} className=\"log-entry\">\n <span className=\"log-timestamp\">\n {new Date(log.timestamp).toLocaleTimeString()}\n </span>\n <span className=\"log-service\">{log.service}</span>\n <span className={getLevelClass(log.level)}>\n {log.level.toUpperCase()}\n </span>\n <span className=\"log-message\">{log.message}</span>\n </div>\n ))\n )}\n </div>\n );\n};\n\n// Main Web Dashboard Component\nexport const WebDashboardApp: React.FC<{\n environment: string;\n refreshInterval: number;\n}> = ({ environment, refreshInterval }) => {\n const [data, setData] = useState<DashboardData | null>(null);\n const [connected, setConnected] = useState(false);\n const [lastUpdate, setLastUpdate] = useState<Date | null>(null);\n const [, setSocket] = useState<any>(null);\n\n useEffect(() => {\n // @ts-ignore - Socket.IO is loaded via script tag\n const io = window.io;\n if (!io) {\n console.error('Socket.IO not loaded');\n return;\n }\n\n const newSocket = io();\n setSocket(newSocket);\n \n newSocket.on('connect', () => {\n setConnected(true);\n });\n \n newSocket.on('disconnect', () => {\n setConnected(false);\n });\n \n newSocket.on('dashboard-update', (newData: DashboardData) => {\n setData(newData);\n setLastUpdate(new Date());\n });\n \n newSocket.on('dashboard-error', (error: any) => {\n console.error('Dashboard error:', error);\n });\n \n return () => {\n newSocket.disconnect();\n };\n }, []);\n\n const formatTime = (date: Date | null) => {\n if (!date) return 'Never';\n return date.toLocaleTimeString();\n };\n\n if (!data) {\n return (\n <div className=\"dashboard-container\">\n <div className=\"dashboard-panel\">\n <div className=\"loading\">\n <div className=\"spinner\"></div>\n </div>\n </div>\n </div>\n );\n }\n\n // Split services by category\n const appServices = data.services.filter(s => \n ['Frontend', 'Backend', 'Load Balancer', 'WAF', 'DNS (Route 53)'].includes(s.name)\n );\n const dataServices = data.services.filter(s => \n ['Database', 'Filesystem'].includes(s.name)\n );\n\n return (\n <div className=\"dashboard-container\">\n <div className=\"dashboard-header\">\n <div>\n <div className=\"dashboard-title\">Semiont System Dashboard</div>\n <div className=\"dashboard-subtitle\">Environment: {environment}</div>\n </div>\n <div className=\"refresh-info\">\n <div>Last updated: {formatTime(lastUpdate)}</div>\n <div>Auto-refresh: every {refreshInterval}s</div>\n </div>\n </div>\n \n <div className=\"dashboard-grid\">\n <ServicePanel \n services={appServices}\n title=\"App Services\"\n showActions={true}\n />\n \n <ServicePanel \n services={dataServices}\n title=\"Data\"\n showActions={true}\n />\n </div>\n \n <LogViewer logs={data.logs} />\n \n <div className={`connection-status ${connected ? 'connected' : 'disconnected'}`}>\n {connected ? '\uD83D\uDFE2 Connected' : '\uD83D\uDD34 Disconnected'}\n </div>\n </div>\n );\n};\n\n// Export for browser usage\nif (typeof window !== 'undefined') {\n window.SemiontDashboard = window.SemiontDashboard || {};\n window.SemiontDashboard.WebDashboardApp = WebDashboardApp;\n}"],
5
- "mappings": "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",
6
- "names": ["web_dashboard_app_exports", "__export", "WebDashboardApp", "import_react", "StatusIndicator", "status", "colors", "React", "ServicePanel", "services", "title", "showActions", "getConsoleLinks", "service", "links", "region", "arnParts", "loadBalancerName", "formatBytes", "bytes", "k", "sizes", "i", "index", "link", "linkIndex", "LogViewer", "logs", "getLevelClass", "level", "log", "environment", "refreshInterval", "data", "setData", "connected", "setConnected", "lastUpdate", "setLastUpdate", "setSocket", "io", "newSocket", "newData", "error", "formatTime", "date", "appServices", "s", "dataServices"]
3
+ "sources": ["../../src/core/dashboard/web-dashboard-app.tsx", "../../src/core/dashboard/sections/section-web-interface.tsx", "../../src/core/dashboard/sections/section-make-meaning.tsx", "../../src/core/dashboard/sections/section-workers.tsx"],
4
+ "sourcesContent": ["/**\n * Web Dashboard React Application\n */\n\nimport '@semiont/react-ui/styles/index.css';\nimport React, { useState, useEffect } from 'react';\nimport type { ServiceStatus, LogEntry, MakeMeaningStatus, WorkerStatus } from './dashboard-components.js';\nimport { SectionWebInterface } from './sections/section-web-interface.js';\nimport { SectionMakeMeaning } from './sections/section-make-meaning.js';\nimport { SectionWorkers } from './sections/section-workers.js';\n\ndeclare const window: any;\n\nconst DEFAULT_MAKE_MEANING: MakeMeaningStatus = {\n eventLog: { path: '' },\n contentStore: { path: '' },\n graph: { status: 'unknown' },\n materializedViews: { path: '' },\n actors: {\n gatherer: { state: 'unknown' },\n matcher: { state: 'unknown' },\n stower: { state: 'unknown' },\n },\n};\n\ntype TabId = 'web' | 'make-meaning' | 'workers';\n\nconst LogViewer: React.FC<{ logs: LogEntry[]; service?: string }> = ({ logs, service }) => {\n const filtered = service ? logs.filter(l => l.service === service || !service) : logs;\n return (\n <div className=\"semiont-panel semiont-panel--bordered dashboard-logs\">\n <div className=\"semiont-panel-header\">\n <span className=\"semiont-panel-header__title\">Recent Logs</span>\n </div>\n {filtered.length === 0 ? (\n <div className=\"logs-empty\">No recent logs</div>\n ) : (\n <div className=\"logs-list\">\n {filtered.slice(0, 50).map((log, i) => (\n <div key={i} className={`log-entry log-entry--${log.level}`}>\n <span className=\"log-timestamp\">{new Date(log.timestamp).toLocaleTimeString()}</span>\n <span className=\"log-service\">{log.service}</span>\n <span className={`log-level semiont-badge semiont-badge--${log.level === 'error' ? 'error' : log.level === 'warn' ? 'warning' : 'info'}`}>\n <span className=\"semiont-badge__text\">{log.level.toUpperCase()}</span>\n </span>\n <span className=\"log-message\">{log.message}</span>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n};\n\nconst TabBar: React.FC<{\n active: TabId;\n onChange: (t: TabId) => void;\n webHealthy: number; webTotal: number;\n mmHealthy: number; mmTotal: number;\n wkHealthy: number; wkTotal: number;\n}> = ({ active, onChange, webHealthy, webTotal, mmHealthy, mmTotal, wkHealthy, wkTotal }) => {\n const tabs: { id: TabId; label: string; healthy: number; total: number }[] = [\n { id: 'web', label: 'Web Interface', healthy: webHealthy, total: webTotal },\n { id: 'make-meaning', label: 'Make Meaning', healthy: mmHealthy, total: mmTotal },\n { id: 'workers', label: 'Job Workers', healthy: wkHealthy, total: wkTotal },\n ];\n\n function badgeClass(healthy: number, total: number) {\n if (total === 0) return 'semiont-badge semiont-badge--info';\n if (healthy === total) return 'semiont-badge semiont-badge--success';\n if (healthy === 0) return 'semiont-badge semiont-badge--error';\n return 'semiont-badge semiont-badge--warning';\n }\n\n return (\n <div className=\"dashboard-tabs\">\n {tabs.map(tab => (\n <button\n key={tab.id}\n className={`dashboard-tab${active === tab.id ? ' dashboard-tab--active' : ''}`}\n onClick={() => onChange(tab.id)}\n >\n {tab.label}\n <span className={badgeClass(tab.healthy, tab.total)}>\n <span className=\"semiont-badge__text\">{tab.healthy}/{tab.total}</span>\n </span>\n </button>\n ))}\n </div>\n );\n};\n\nconst UpdateTime: React.FC<{ time: Date | null; label: string }> = ({ time, label }) => (\n <span className=\"tab-update-time\">\n {label}: {time ? time.toLocaleTimeString() : '\u2014'}\n </span>\n);\n\nexport const WebDashboardApp: React.FC<{\n environment: string;\n refreshInterval: number;\n}> = ({ environment, refreshInterval }) => {\n const [activeTab, setActiveTab] = useState<TabId>('web');\n\n const [services, setServices] = useState<ServiceStatus[]>([]);\n const [serviceLogs, setServiceLogs] = useState<LogEntry[]>([]);\n const [servicesUpdated, setServicesUpdated] = useState<Date | null>(null);\n\n const [makeMeaning, setMakeMeaning] = useState<MakeMeaningStatus>(DEFAULT_MAKE_MEANING);\n const [mmUpdated, setMmUpdated] = useState<Date | null>(null);\n\n const [workers, setWorkers] = useState<WorkerStatus[]>([]);\n const [workersUpdated, setWorkersUpdated] = useState<Date | null>(null);\n\n const [connected, setConnected] = useState(false);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n const io = window.io;\n if (!io) { console.error('Socket.IO not loaded'); return; }\n\n const socket = io();\n socket.on('connect', () => setConnected(true));\n socket.on('disconnect', () => setConnected(false));\n\n socket.on('services-update', (d: { services: ServiceStatus[]; logs: LogEntry[]; lastUpdate: Date }) => {\n setServices(d.services);\n setServiceLogs(d.logs);\n setServicesUpdated(new Date());\n setReady(true);\n });\n\n socket.on('make-meaning-update', (d: MakeMeaningStatus & { lastUpdate?: Date }) => {\n const { lastUpdate, ...mm } = d as any;\n setMakeMeaning(mm);\n setMmUpdated(lastUpdate ? new Date(lastUpdate) : new Date());\n });\n\n socket.on('actors-update', (d: { actors: MakeMeaningStatus['actors']; lastUpdate?: Date }) => {\n setMakeMeaning(prev => ({ ...prev, actors: d.actors }));\n if (d.lastUpdate) setMmUpdated(new Date(d.lastUpdate));\n });\n\n socket.on('workers-update', (d: { workers: WorkerStatus[]; lastUpdate?: Date }) => {\n setWorkers(d.workers);\n setWorkersUpdated(d.lastUpdate ? new Date(d.lastUpdate) : new Date());\n if (!ready) setReady(true);\n });\n\n return () => socket.disconnect();\n }, []);\n\n void refreshInterval;\n\n if (!ready) {\n return (\n <div className=\"dashboard-container\">\n <div className=\"dashboard-loading\">\n <div className=\"semiont-spinner\" />\n </div>\n </div>\n );\n }\n\n // Bridge graph status from services array into makeMeaning\n const graphService = services.find((s: ServiceStatus) => s.name.toLowerCase() === 'graph');\n const mm: MakeMeaningStatus = graphService\n ? { ...makeMeaning, graph: { ...makeMeaning.graph,\n status: graphService.status === 'healthy' ? 'healthy'\n : graphService.status === 'unhealthy' ? 'unhealthy' : 'unknown',\n evidence: graphService.evidence } }\n : makeMeaning;\n\n const MAKE_MEANING_SERVICES = new Set(['graph', 'neo4j', 'janusgraph', 'neptune']);\n const webServices = services.filter(s => !MAKE_MEANING_SERVICES.has(s.name.toLowerCase()));\n const webHealthy = webServices.filter(s => s.status === 'healthy').length;\n\n // Make Meaning healthy count (mirrors section-make-meaning countHealthy)\n const mmHealthy = [\n mm.eventLog.path,\n mm.contentStore.path,\n mm.graph.status === 'healthy',\n mm.materializedViews.path,\n mm.actors.gatherer.state !== 'error' && mm.actors.gatherer.state !== 'unknown',\n mm.actors.matcher.state !== 'error' && mm.actors.matcher.state !== 'unknown',\n mm.actors.stower.state !== 'error' && mm.actors.stower.state !== 'unknown',\n ].filter(Boolean).length;\n\n const wkHealthy = workers.filter(w => w.state !== 'error').length;\n\n return (\n <div className=\"dashboard-container\">\n <header className=\"dashboard-header semiont-panel semiont-panel--bordered\">\n <div className=\"dashboard-header-left\">\n <h1 className=\"dashboard-title\">Semiont Dashboard</h1>\n <span className=\"semiont-badge semiont-badge--info dashboard-env\">\n <span className=\"semiont-badge__text\">{environment}</span>\n </span>\n </div>\n <div className=\"dashboard-header-right\">\n <span className={`semiont-indicator ${connected ? 'semiont-indicator--online' : 'semiont-indicator--offline'}`} />\n <span className=\"dashboard-connection-label\">{connected ? 'Live' : 'Disconnected'}</span>\n </div>\n </header>\n\n <div className=\"semiont-panel semiont-panel--bordered dashboard-tab-panel\">\n <TabBar\n active={activeTab} onChange={setActiveTab}\n webHealthy={webHealthy} webTotal={webServices.length}\n mmHealthy={mmHealthy} mmTotal={7}\n wkHealthy={wkHealthy} wkTotal={workers.length}\n />\n\n <div className=\"tab-content\">\n {activeTab === 'web' && (\n <>\n <div className=\"tab-meta\">\n <UpdateTime time={servicesUpdated} label=\"updated\" />\n </div>\n <SectionWebInterface services={services} />\n <LogViewer logs={serviceLogs} />\n </>\n )}\n\n {activeTab === 'make-meaning' && (\n <>\n <div className=\"tab-meta\">\n <UpdateTime time={mmUpdated} label=\"updated\" />\n </div>\n <SectionMakeMeaning makeMeaning={mm} />\n <LogViewer logs={[]} />\n </>\n )}\n\n {activeTab === 'workers' && (\n <>\n <div className=\"tab-meta\">\n <UpdateTime time={workersUpdated} label=\"updated\" />\n </div>\n <SectionWorkers workers={workers} />\n <LogViewer logs={[]} />\n </>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nif (typeof window !== 'undefined') {\n window.SemiontDashboard = window.SemiontDashboard || {};\n window.SemiontDashboard.WebDashboardApp = WebDashboardApp;\n}\n", "import React from 'react';\nimport type { ServiceStatus } from '../dashboard-components.js';\n\nconst TAG = 'semiont-tag semiont-tag--secondary semiont-tag--compact';\n\nconst MAKE_MEANING_SERVICES = new Set(['graph', 'neo4j', 'janusgraph', 'neptune']);\n\n// Display order for web interface services\nconst SERVICE_ORDER = ['proxy', 'frontend', 'backend', 'database'];\n\nfunction indicatorClass(status: ServiceStatus['status']): string {\n switch (status) {\n case 'healthy': return 'semiont-indicator semiont-indicator--online';\n case 'unhealthy': return 'semiont-indicator semiont-indicator--offline';\n case 'warning': return 'semiont-indicator semiont-indicator--busy';\n default: return 'semiont-indicator';\n }\n}\n\nfunction statusLabel(status: ServiceStatus['status']): string {\n switch (status) {\n case 'healthy': return 'healthy';\n case 'unhealthy': return 'unhealthy';\n case 'warning': return 'warning';\n default: return 'unknown';\n }\n}\n\nfunction statusBadgeClass(status: ServiceStatus['status']): string {\n switch (status) {\n case 'healthy': return 'semiont-badge semiont-badge--success';\n case 'unhealthy': return 'semiont-badge semiont-badge--error';\n case 'warning': return 'semiont-badge semiont-badge--warning';\n default: return 'semiont-badge semiont-badge--info';\n }\n}\n\nconst ServiceRow: React.FC<{ service: ServiceStatus }> = ({ service }) => {\n // Evidence tags: prefer structured evidence, fall back to parsing details string\n const tags: string[] = service.evidence && service.evidence.length > 0\n ? [...service.evidence]\n : (() => {\n const details = service.details || '';\n const out: string[] = [];\n const pidMatch = details.match(/[Pp][Ii][Dd]:\\s*(\\d+)/);\n const containerMatch = details.match(/[Cc]ontainer:\\s*(\\S+)/);\n if (pidMatch) out.push(`pid ${pidMatch[1]}`);\n if (containerMatch) out.push(`container ${containerMatch[1].slice(0, 12)}`);\n if (service.runningCount !== undefined && service.desiredCount !== undefined) {\n out.push(`${service.runningCount}/${service.desiredCount} tasks`);\n }\n return out;\n })();\n\n if (service.checkedAt) {\n tags.push(`checked ${new Date(service.checkedAt).toLocaleTimeString()}`);\n }\n\n const consoleLinks = getConsoleLinks(service);\n\n return (\n <div className=\"service-row\">\n <div className=\"service-row__indicator\">\n <span className={indicatorClass(service.status)} />\n </div>\n <div className=\"service-row__name\">{service.name}</div>\n <div className=\"service-row__host\">\n {service.hostname\n ? <span className=\"service-row__hostname\">{service.hostname}</span>\n : <span className=\"service-row__hostname service-row__hostname--dim\">\u2014</span>\n }\n </div>\n <div className=\"service-row__status\">\n <span className={statusBadgeClass(service.status)}>\n <span className=\"semiont-badge__text\">{statusLabel(service.status)}</span>\n </span>\n </div>\n <div className=\"service-row__tags\">\n {tags.map((t, i) => <span key={i} className={TAG}>{t}</span>)}\n </div>\n <div className=\"service-row__actions\">\n {consoleLinks.map((link, i) => (\n <a key={i} href={link.url} target=\"_blank\" rel=\"noopener noreferrer\"\n className=\"semiont-tag semiont-tag--info semiont-tag--compact\">\n {link.label}\n </a>\n ))}\n </div>\n </div>\n );\n};\n\nfunction getConsoleLinks(service: ServiceStatus) {\n const links: { label: string; url: string }[] = [];\n const region = service.awsRegion || 'us-east-1';\n if (service.ecsServiceName && service.ecsClusterName) {\n links.push({ label: 'Console \u2197', url: `https://console.aws.amazon.com/ecs/home?region=${region}#/clusters/${service.ecsClusterName}/services/${service.ecsServiceName}/details` });\n if (service.logGroupName) {\n links.push({ label: 'Logs \u2197', url: `https://console.aws.amazon.com/cloudwatch/home?region=${region}#logsV2:log-groups/log-group/${encodeURIComponent(service.logGroupName)}` });\n }\n }\n if (service.rdsInstanceId) {\n links.push({ label: 'Console \u2197', url: `https://console.aws.amazon.com/rds/home?region=${region}#database:id=${service.rdsInstanceId};is-cluster=false` });\n }\n return links;\n}\n\ninterface Props {\n services: ServiceStatus[];\n}\n\nexport const SectionWebInterface: React.FC<Props> = ({ services }) => {\n const webServices = services.filter(s => !MAKE_MEANING_SERVICES.has(s.name.toLowerCase()));\n\n // Sort by preferred order, then alphabetically for anything unknown\n const sorted = [...webServices].sort((a, b) => {\n const ai = SERVICE_ORDER.indexOf(a.name.toLowerCase());\n const bi = SERVICE_ORDER.indexOf(b.name.toLowerCase());\n if (ai === -1 && bi === -1) return a.name.localeCompare(b.name);\n if (ai === -1) return 1;\n if (bi === -1) return -1;\n return ai - bi;\n });\n\n return (\n <div className=\"service-list\">\n <div className=\"service-list__header\">\n <div className=\"service-row__indicator\" />\n <div className=\"service-row__name\">Service</div>\n <div className=\"service-row__host\">Address</div>\n <div className=\"service-row__status\">Status</div>\n <div className=\"service-row__tags\">Details</div>\n <div className=\"service-row__actions\" />\n </div>\n {sorted.map((s, i) => <ServiceRow key={i} service={s} />)}\n </div>\n );\n};\n", "import React from 'react';\nimport type { MakeMeaningStatus, ActorStatus } from '../dashboard-components.js';\n\nconst TAG = 'semiont-tag semiont-tag--secondary semiont-tag--compact';\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return '0 B';\n const k = 1024;\n const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;\n}\n\nfunction truncatePath(p: string, max = 40): string {\n if (p.length <= max) return p;\n return '\u2026' + p.slice(p.length - max + 1);\n}\n\nfunction actorIndicatorClass(actor: ActorStatus): string {\n switch (actor.state) {\n case 'active': return 'semiont-indicator semiont-indicator--online semiont-indicator--pulse';\n case 'idle': return 'semiont-indicator semiont-indicator--online';\n case 'error': return 'semiont-indicator semiont-indicator--offline';\n default: return 'semiont-indicator';\n }\n}\n\nfunction graphIndicatorClass(status: MakeMeaningStatus['graph']['status']): string {\n switch (status) {\n case 'healthy': return 'semiont-indicator semiont-indicator--online';\n case 'unhealthy': return 'semiont-indicator semiont-indicator--offline';\n default: return 'semiont-indicator';\n }\n}\n\nconst MmRow: React.FC<{\n indicator: string;\n label: string;\n value: string;\n tags?: (string | undefined | false)[];\n}> = ({ indicator, label, value, tags }) => (\n <div className=\"mm-row\">\n <div className=\"mm-row__indicator\"><span className={indicator} /></div>\n <div className=\"mm-row__label\">{label}</div>\n <div className=\"mm-row__value\">{value}</div>\n <div className=\"mm-row__tags\">\n {tags?.filter(Boolean).map((t, i) => (\n <span key={i} className={TAG}>{t as string}</span>\n ))}\n </div>\n </div>\n);\n\nconst MmGroup: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => (\n <div className=\"mm-group\">\n <div className=\"mm-group__title\">{title}</div>\n <div className=\"mm-list\">{children}</div>\n </div>\n);\n\ninterface Props {\n makeMeaning: MakeMeaningStatus;\n}\n\nexport const SectionMakeMeaning: React.FC<Props> = ({ makeMeaning: mm }) => {\n return (\n <div className=\"mm-sections\">\n\n <MmGroup title=\"System of Record\">\n <MmRow\n indicator=\"semiont-indicator semiont-indicator--online\"\n label=\"Event Log\"\n value={mm.eventLog.eventCount !== undefined\n ? mm.eventLog.eventCount.toLocaleString() + ' events'\n : 'unknown'}\n tags={[\n mm.eventLog.streamCount !== undefined && `${mm.eventLog.streamCount} streams`,\n mm.eventLog.sizeBytes !== undefined && formatBytes(mm.eventLog.sizeBytes),\n mm.eventLog.path && truncatePath(mm.eventLog.path),\n ]}\n />\n <MmRow\n indicator=\"semiont-indicator semiont-indicator--online\"\n label=\"Content Store\"\n value={mm.contentStore.sizeBytes !== undefined\n ? formatBytes(mm.contentStore.sizeBytes)\n : 'unknown'}\n tags={[\n mm.contentStore.fileCount !== undefined && `${mm.contentStore.fileCount} files`,\n mm.contentStore.path && truncatePath(mm.contentStore.path),\n ]}\n />\n </MmGroup>\n\n <MmGroup title=\"Projections\">\n <MmRow\n indicator={graphIndicatorClass(mm.graph.status)}\n label=\"Graph\"\n value={mm.graph.status}\n tags={[\n mm.graph.address,\n mm.graph.database,\n ...(mm.graph.evidence ?? []),\n ]}\n />\n <MmRow\n indicator=\"semiont-indicator semiont-indicator--online\"\n label=\"Materialized Views\"\n value={mm.materializedViews.fileCount !== undefined\n ? `${mm.materializedViews.fileCount} projections`\n : 'unknown'}\n tags={[\n mm.materializedViews.lastUpdated &&\n `updated ${new Date(mm.materializedViews.lastUpdated).toLocaleTimeString()}`,\n mm.materializedViews.path && truncatePath(mm.materializedViews.path),\n ]}\n />\n </MmGroup>\n\n <MmGroup title=\"Actors\">\n {(['gatherer', 'matcher', 'stower'] as const).map(name => {\n const actor = mm.actors[name];\n return (\n <MmRow\n key={name}\n indicator={actorIndicatorClass(actor)}\n label={name.charAt(0).toUpperCase() + name.slice(1)}\n value={actor.state}\n tags={[\n actor.provider,\n actor.model,\n actor.errorMessage && actor.errorMessage.slice(0, 40),\n ]}\n />\n );\n })}\n </MmGroup>\n\n </div>\n );\n};\n", "import React from 'react';\nimport type { WorkerStatus } from '../dashboard-components.js';\n\nconst TAG_SEC = 'semiont-tag semiont-tag--secondary semiont-tag--compact';\n\nconst WORKER_LABELS: Record<WorkerStatus['type'], string> = {\n 'reference-annotation': 'Reference Annotation',\n 'highlight-annotation': 'Highlight Annotation',\n 'assessment-annotation': 'Assessment Annotation',\n 'comment-annotation': 'Comment Annotation',\n 'tag-annotation': 'Tag Annotation',\n 'generation': 'Generation',\n};\n\nfunction workerIndicatorClass(w: WorkerStatus): string {\n if (w.state === 'error') return 'semiont-indicator semiont-indicator--offline';\n if (w.activeCount > 0) return 'semiont-indicator semiont-indicator--online semiont-indicator--pulse';\n if (w.pendingCount > 10) return 'semiont-indicator semiont-indicator--busy';\n return 'semiont-indicator semiont-indicator--online';\n}\n\ninterface Props {\n workers: WorkerStatus[];\n}\n\nexport const SectionWorkers: React.FC<Props> = ({ workers }) => {\n return (\n <div className=\"mm-list\">\n <div className=\"mm-row mm-row--header\">\n <div className=\"mm-row__indicator\" />\n <div className=\"mm-row__label\">Worker</div>\n <div className=\"mm-row__value\">Status</div>\n <div className=\"mm-row__tags\">Details</div>\n </div>\n {workers.map((w, i) => (\n <div key={i} className=\"mm-row\">\n <div className=\"mm-row__indicator\"><span className={workerIndicatorClass(w)} /></div>\n <div className=\"mm-row__label\">{WORKER_LABELS[w.type]}</div>\n <div className=\"mm-row__value\">{w.state}</div>\n <div className=\"mm-row__tags\">\n <span className={w.activeCount > 0 ? 'semiont-tag semiont-tag--success semiont-tag--compact' : TAG_SEC}>\n {w.activeCount} active\n </span>\n <span className={TAG_SEC}>{w.pendingCount} pending</span>\n {w.lastProcessed && (\n <span className={TAG_SEC}>last {new Date(w.lastProcessed).toLocaleTimeString()}</span>\n )}\n </div>\n </div>\n ))}\n </div>\n );\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["web_dashboard_app_exports", "__export", "WebDashboardApp", "import_react", "import_react", "TAG", "MAKE_MEANING_SERVICES", "SERVICE_ORDER", "indicatorClass", "status", "statusLabel", "statusBadgeClass", "ServiceRow", "service", "tags", "details", "out", "pidMatch", "containerMatch", "consoleLinks", "getConsoleLinks", "React", "t", "i", "link", "links", "region", "SectionWebInterface", "services", "sorted", "s", "b", "ai", "bi", "import_react", "TAG", "formatBytes", "bytes", "k", "sizes", "i", "truncatePath", "p", "max", "actorIndicatorClass", "actor", "graphIndicatorClass", "status", "MmRow", "indicator", "label", "value", "tags", "React", "t", "MmGroup", "title", "children", "SectionMakeMeaning", "mm", "name", "import_react", "TAG_SEC", "WORKER_LABELS", "workerIndicatorClass", "w", "SectionWorkers", "workers", "React", "i", "DEFAULT_MAKE_MEANING", "LogViewer", "logs", "service", "filtered", "l", "React", "log", "i", "TabBar", "active", "onChange", "webHealthy", "webTotal", "mmHealthy", "mmTotal", "wkHealthy", "wkTotal", "tabs", "badgeClass", "healthy", "total", "tab", "UpdateTime", "time", "label", "WebDashboardApp", "environment", "refreshInterval", "activeTab", "setActiveTab", "services", "setServices", "serviceLogs", "setServiceLogs", "servicesUpdated", "setServicesUpdated", "makeMeaning", "setMakeMeaning", "mmUpdated", "setMmUpdated", "workers", "setWorkers", "workersUpdated", "setWorkersUpdated", "connected", "setConnected", "ready", "setReady", "io", "socket", "lastUpdate", "mm", "prev", "graphService", "s", "MAKE_MEANING_SERVICES", "webServices", "w", "SectionWebInterface", "SectionMakeMeaning", "SectionWorkers"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semiont/cli",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "Semiont CLI - Unified environment management tool",
5
5
  "_comment": "AWS SDK dependencies (@aws-sdk/*) are only used by platforms/aws",
6
6
  "type": "module",
@@ -64,31 +64,33 @@
64
64
  "@aws-sdk/client-secrets-manager": "^3.600.0",
65
65
  "@aws-sdk/client-sts": "^3.859.0",
66
66
  "@aws-sdk/client-wafv2": "^3.859.0",
67
- "@semiont/api-client": "0.3.4",
68
- "@semiont/content": "0.3.4",
69
- "@semiont/core": "0.3.4",
70
- "@semiont/event-sourcing": "0.3.4",
71
- "@semiont/graph": "0.3.4",
72
- "@semiont/make-meaning": "0.3.4",
67
+ "@semiont/api-client": "0.3.5",
68
+ "@semiont/content": "0.3.5",
69
+ "@semiont/core": "0.3.5",
70
+ "@semiont/event-sourcing": "0.3.5",
71
+ "@semiont/graph": "0.3.5",
72
+ "@semiont/make-meaning": "0.3.5",
73
+ "@vitest/ui": "4.0.18",
73
74
  "arg": "^5.0.2",
74
75
  "argon2": "^0.43.0",
75
76
  "express": "^5.2.1",
76
77
  "ink": "^6.8.0",
77
78
  "js-yaml": "^4.1.0",
78
79
  "neo4j-driver": "^6.0.1",
80
+ "smol-toml": "^1.6.0",
79
81
  "react": "^19.2.4",
80
82
  "socket.io": "^4.5.4",
81
83
  "zod": "^3.23.8"
82
84
  },
83
85
  "devDependencies": {
84
- "@prisma/client": "^6.13.0",
86
+ "@prisma/client": "^7.5.0",
85
87
  "@types/express": "^5.0.6",
86
88
  "@types/js-yaml": "^4.0.9",
87
89
  "@types/react": "^19.2.14",
88
- "@vitest/coverage-v8": "^4.1.0",
90
+ "@vitest/coverage-v8": "^4.0.18",
89
91
  "chalk": "^5.3.0",
90
92
  "typescript": "^5.9.2",
91
- "vitest": "^4.1.0"
93
+ "vitest": "^4.0.18"
92
94
  },
93
95
  "overrides": {
94
96
  "esbuild": "0.27.2"
@@ -1,67 +0,0 @@
1
- {
2
- "name": "ci",
3
- "site": {
4
- "domain": "localhost",
5
- "oauthAllowedDomains": ["example.com", "test.example.com"]
6
- },
7
- "platform": {
8
- "default": "posix"
9
- },
10
- "env": {
11
- "NODE_ENV": "development"
12
- },
13
- "logLevel": "debug",
14
- "services": {
15
- "backend": {
16
- "platform": {
17
- "type": "posix"
18
- },
19
- "port": 4000,
20
- "publicURL": "http://localhost:4000",
21
- "corsOrigin": "http://localhost:3000"
22
- },
23
- "frontend": {
24
- "platform": {
25
- "type": "posix"
26
- },
27
- "port": 3000,
28
- "publicURL": "http://localhost:3000",
29
- "siteName": "CI Test Site"
30
- },
31
- "filesystem": {
32
- "platform": {
33
- "type": "posix"
34
- },
35
- "path": "data",
36
- "description": "CI filesystem storage"
37
- },
38
- "database": {
39
- "platform": {
40
- "type": "external"
41
- },
42
- "type": "postgres",
43
- "host": "localhost",
44
- "port": 5432
45
- },
46
- "graph": {
47
- "platform": {
48
- "type": "posix"
49
- },
50
- "type": "memory"
51
- },
52
- "mcp": {
53
- "platform": {
54
- "type": "posix"
55
- },
56
- "dependsOn": ["backend"]
57
- },
58
- "inference": {
59
- "platform": {
60
- "type": "posix"
61
- },
62
- "type": "anthropic",
63
- "model": "claude-3-5-sonnet-20241022",
64
- "apiKey": "sk-ant-test-key-for-ci-environment-do-not-use"
65
- }
66
- }
67
- }
@@ -1,91 +0,0 @@
1
- {
2
- "name": "local",
3
- "platform": {
4
- "default": "container"
5
- },
6
- "deployment": {
7
- "imageTagStrategy": "mutable"
8
- },
9
- "site": {
10
- "domain": "localhost:8080",
11
- "oauthAllowedDomains": ["example.com", "localhost:8080"]
12
- },
13
- "env": {
14
- "NODE_ENV": "development"
15
- },
16
- "logLevel": "debug",
17
- "services": {
18
- "backend": {
19
- "platform": {
20
- "type": "posix"
21
- },
22
- "command": "npm run dev",
23
- "port": 4000,
24
- "publicURL": "http://localhost:8080",
25
- "corsOrigin": "http://localhost:8080"
26
- },
27
- "frontend": {
28
- "platform": {
29
- "type": "posix"
30
- },
31
- "command": "npm run dev",
32
- "port": 3000,
33
- "publicURL": "http://localhost:8080",
34
- "siteName": "Semiont"
35
- },
36
- "database": {
37
- "platform": {
38
- "type": "container"
39
- },
40
- "type": "postgres",
41
- "name": "semiont-local-db",
42
- "host": "localhost",
43
- "image": "postgres:15-alpine",
44
- "port": 5432,
45
- "environment": {
46
- "POSTGRES_DB": "semiont",
47
- "POSTGRES_USER": "postgres",
48
- "POSTGRES_PASSWORD": "localpass"
49
- }
50
- },
51
- "graph": {
52
- "platform": {
53
- "type": "external"
54
- },
55
- "type": "neo4j",
56
- "name": "neo4j",
57
- "uri": "${NEO4J_URI}",
58
- "username": "${NEO4J_USERNAME}",
59
- "password": "${NEO4J_PASSWORD}",
60
- "database": "${NEO4J_DATABASE}"
61
- },
62
- "filesystem": {
63
- "platform": {
64
- "type": "posix"
65
- },
66
- "path": "./data/uploads",
67
- "description": "Local filesystem storage for uploads and assets"
68
- },
69
- "inference": {
70
- "platform": {
71
- "type": "external"
72
- },
73
- "type": "anthropic",
74
- "model": "claude-sonnet-4-5-20250929",
75
- "maxTokens": 8192,
76
- "endpoint": "https://api.anthropic.com",
77
- "apiKey": "${ANTHROPIC_API_KEY}"
78
- },
79
- "proxy": {
80
- "platform": {
81
- "type": "container"
82
- },
83
- "type": "envoy",
84
- "port": 8080,
85
- "adminPort": 9901,
86
- "backendPort": 4000,
87
- "frontendPort": 3000,
88
- "image": "envoyproxy/envoy:v1.28-latest"
89
- }
90
- }
91
- }
@@ -1,58 +0,0 @@
1
- {
2
- "name": "production",
3
- "platform": {
4
- "default": "aws"
5
- },
6
- "deployment": {
7
- "imageTagStrategy": "immutable"
8
- },
9
- "env": {
10
- "NODE_ENV": "production"
11
- },
12
- "logLevel": "info",
13
- "aws": {
14
- "region": "us-east-1",
15
- "accountId": "YOUR_AWS_ACCOUNT_ID",
16
- "hostedZoneId": "YOUR_HOSTED_ZONE_ID",
17
- "certificateArn": "arn:aws:acm:REGION:ACCOUNT:certificate/YOUR_CERT_ID",
18
- "profile": "default",
19
- "stacks": {
20
- "data": "SemiontDataStack",
21
- "app": "SemiontAppStack"
22
- }
23
- },
24
- "services": {
25
- "backend": {
26
- "image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/semiont-backend:latest"
27
- },
28
- "frontend": {
29
- "image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/semiont-frontend:latest"
30
- },
31
- "database": {
32
- "platform": {
33
- "type": "aws"
34
- },
35
- "comment": "Provisioned via CDK data stack (RDS PostgreSQL)"
36
- },
37
- "filesystem": {
38
- "platform": {
39
- "type": "aws"
40
- },
41
- "comment": "Provisioned via CDK data stack (EFS)"
42
- },
43
- "graph": {
44
- "platform": {
45
- "type": "aws"
46
- },
47
- "type": "neptune",
48
- "port": 8182,
49
- "comment": "Provisioned via CDK data stack (Amazon Neptune)"
50
- },
51
- "mcp": {
52
- "platform": {
53
- "type": "posix"
54
- },
55
- "dependsOn": ["backend"]
56
- }
57
- }
58
- }
@@ -1,50 +0,0 @@
1
- {
2
- "name": "staging",
3
- "platform": {
4
- "default": "aws"
5
- },
6
- "deployment": {
7
- "imageTagStrategy": "immutable"
8
- },
9
- "env": {
10
- "NODE_ENV": "production"
11
- },
12
- "logLevel": "http",
13
- "aws": {
14
- "region": "us-east-1",
15
- "accountId": "YOUR_AWS_ACCOUNT_ID",
16
- "hostedZoneId": "YOUR_HOSTED_ZONE_ID",
17
- "certificateArn": "arn:aws:acm:REGION:ACCOUNT:certificate/YOUR_CERT_ID",
18
- "profile": "default",
19
- "stacks": {
20
- "data": "SemiontDataStack-Staging",
21
- "app": "SemiontAppStack-Staging"
22
- }
23
- },
24
- "services": {
25
- "backend": {
26
- "image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/semiont-backend:staging"
27
- },
28
- "frontend": {
29
- "image": "YOUR_AWS_ACCOUNT_ID.dkr.ecr.YOUR_REGION.amazonaws.com/semiont-frontend:staging"
30
- },
31
- "database": {
32
- "platform": {
33
- "type": "aws"
34
- },
35
- "comment": "Provisioned via CDK data stack (RDS PostgreSQL)"
36
- },
37
- "filesystem": {
38
- "platform": {
39
- "type": "aws"
40
- },
41
- "comment": "Provisioned via CDK data stack (EFS)"
42
- },
43
- "mcp": {
44
- "platform": {
45
- "type": "posix"
46
- },
47
- "dependsOn": ["backend"]
48
- }
49
- }
50
- }
@@ -1,68 +0,0 @@
1
- {
2
- "name": "test",
3
- "site": {
4
- "domain": "localhost",
5
- "oauthAllowedDomains": ["example.com", "test.example.com"]
6
- },
7
- "platform": {
8
- "default": "container"
9
- },
10
- "env": {
11
- "NODE_ENV": "test"
12
- },
13
- "logLevel": "error",
14
- "services": {
15
- "backend": {
16
- "platform": {
17
- "type": "container"
18
- },
19
- "image": "semiont-backend:test",
20
- "port": 4000,
21
- "publicURL": "http://localhost:4000",
22
- "corsOrigin": "http://localhost:3000"
23
- },
24
- "frontend": {
25
- "platform": {
26
- "type": "container"
27
- },
28
- "image": "semiont-frontend:test",
29
- "port": 3000,
30
- "publicURL": "http://localhost:3000",
31
- "siteName": "Test Site"
32
- },
33
- "filesystem": {
34
- "platform": {
35
- "type": "posix"
36
- },
37
- "path": "data",
38
- "description": "Test filesystem storage"
39
- },
40
- "database": {
41
- "platform": {
42
- "type": "container"
43
- },
44
- "type": "postgres",
45
- "host": "localhost",
46
- "image": "postgres:15-alpine",
47
- "name": "semiont-test-db",
48
- "port": 5432,
49
- "environment": {
50
- "POSTGRES_DB": "semiont_test",
51
- "POSTGRES_USER": "semiont",
52
- "POSTGRES_PASSWORD": "testpass"
53
- }
54
- },
55
- "graph": {
56
- "platform": {
57
- "type": "posix"
58
- },
59
- "type": "memory"
60
- },
61
- "mcp": {
62
- "platform": {
63
- "type": "posix"
64
- },
65
- "dependsOn": ["backend"]
66
- }
67
- }
68
- }