shieldcortex 2.7.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +2 -2
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +3 -3
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +3 -3
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_25b1b286._.js +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  31. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/static/chunks/00fd16d311d2adfc.css +3 -0
  34. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{3255204bf9fadccd.js → 1fd7f60bc5840039.js} +3 -3
  35. package/dashboard/.next/standalone/dashboard/.next/static/chunks/c1354725e21132d5.js +1 -0
  36. package/dashboard/.next/standalone/dashboard/.next/static/chunks/fc2dbf641aad1448.js +1 -0
  37. package/dist/api/session-token.d.ts +25 -0
  38. package/dist/api/session-token.d.ts.map +1 -0
  39. package/dist/api/session-token.js +78 -0
  40. package/dist/api/session-token.js.map +1 -0
  41. package/dist/api/visualization-server.d.ts.map +1 -1
  42. package/dist/api/visualization-server.js +103 -9
  43. package/dist/api/visualization-server.js.map +1 -1
  44. package/dist/cloud/cli.d.ts.map +1 -1
  45. package/dist/cloud/cli.js +18 -3
  46. package/dist/cloud/cli.js.map +1 -1
  47. package/dist/cloud/config.d.ts +11 -0
  48. package/dist/cloud/config.d.ts.map +1 -1
  49. package/dist/cloud/config.js +101 -4
  50. package/dist/cloud/config.js.map +1 -1
  51. package/dist/defence/index.d.ts +2 -2
  52. package/dist/defence/index.d.ts.map +1 -1
  53. package/dist/defence/index.js +1 -1
  54. package/dist/defence/index.js.map +1 -1
  55. package/dist/defence/pipeline.d.ts.map +1 -1
  56. package/dist/defence/pipeline.js +2 -1
  57. package/dist/defence/pipeline.js.map +1 -1
  58. package/package.json +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/static/chunks/d0e13004c4367a98.js +0 -1
  60. package/dashboard/.next/standalone/dashboard/.next/static/chunks/ddb21377f32257df.css +0 -3
  61. /package/dashboard/.next/standalone/dashboard/.next/static/{KiOawOT3npeojP9VgWK6u → bSoUro3f4mlKgOu3focG1}/_buildManifest.js +0 -0
  62. /package/dashboard/.next/standalone/dashboard/.next/static/{KiOawOT3npeojP9VgWK6u → bSoUro3f4mlKgOu3focG1}/_clientMiddlewareManifest.json +0 -0
  63. /package/dashboard/.next/standalone/dashboard/.next/static/{KiOawOT3npeojP9VgWK6u → bSoUro3f4mlKgOu3focG1}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,88069,45688,71921,94156,88969,e=>{"use strict";let t;var r=e.i(22534),s=e.i(11919),i=e.i(79736),n=e.i(96099),a=e.i(70207),o=e.i(32446),u=e.i(60904),c=e.i(62422),l=class extends a.Subscribable{constructor(e,t){super(),this.options=t,this.#e=e,this.#t=null,this.#r=(0,o.pendingThenable)(),this.bindMethods(),this.setOptions(t)}#e;#s=void 0;#i=void 0;#n=void 0;#a;#o;#r;#t;#u;#c;#l;#h;#d;#y;#f=new Set;bindMethods(){this.refetch=this.refetch.bind(this)}onSubscribe(){1===this.listeners.size&&(this.#s.addObserver(this),h(this.#s,this.options)?this.#p():this.updateResult(),this.#m())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return d(this.#s,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return d(this.#s,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.#v(),this.#b(),this.#s.removeObserver(this)}setOptions(e){let t=this.options,r=this.#s;if(this.options=this.#e.defaultQueryOptions(e),void 0!==this.options.enabled&&"boolean"!=typeof this.options.enabled&&"function"!=typeof this.options.enabled&&"boolean"!=typeof(0,u.resolveEnabled)(this.options.enabled,this.#s))throw Error("Expected enabled to be a boolean or a callback that returns a boolean");this.#S(),this.#s.setOptions(this.options),t._defaulted&&!(0,u.shallowEqualObjects)(this.options,t)&&this.#e.getQueryCache().notify({type:"observerOptionsUpdated",query:this.#s,observer:this});let s=this.hasListeners();s&&y(this.#s,r,this.options,t)&&this.#p(),this.updateResult(),s&&(this.#s!==r||(0,u.resolveEnabled)(this.options.enabled,this.#s)!==(0,u.resolveEnabled)(t.enabled,this.#s)||(0,u.resolveStaleTime)(this.options.staleTime,this.#s)!==(0,u.resolveStaleTime)(t.staleTime,this.#s))&&this.#R();let i=this.#g();s&&(this.#s!==r||(0,u.resolveEnabled)(this.options.enabled,this.#s)!==(0,u.resolveEnabled)(t.enabled,this.#s)||i!==this.#y)&&this.#Q(i)}getOptimisticResult(e){var t,r;let s=this.#e.getQueryCache().build(this.#e,e),i=this.createResult(s,e);return t=this,r=i,(0,u.shallowEqualObjects)(t.getCurrentResult(),r)||(this.#n=i,this.#o=this.options,this.#a=this.#s.state),i}getCurrentResult(){return this.#n}trackResult(e,t){return new Proxy(e,{get:(e,r)=>(this.trackProp(r),t?.(r),"promise"===r&&(this.trackProp("data"),this.options.experimental_prefetchInRender||"pending"!==this.#r.status||this.#r.reject(Error("experimental_prefetchInRender feature flag is not enabled"))),Reflect.get(e,r))})}trackProp(e){this.#f.add(e)}getCurrentQuery(){return this.#s}refetch({...e}={}){return this.fetch({...e})}fetchOptimistic(e){let t=this.#e.defaultQueryOptions(e),r=this.#e.getQueryCache().build(this.#e,t);return r.fetch().then(()=>this.createResult(r,t))}fetch(e){return this.#p({...e,cancelRefetch:e.cancelRefetch??!0}).then(()=>(this.updateResult(),this.#n))}#p(e){this.#S();let t=this.#s.fetch(this.options,e);return e?.throwOnError||(t=t.catch(u.noop)),t}#R(){this.#v();let e=(0,u.resolveStaleTime)(this.options.staleTime,this.#s);if(u.isServer||this.#n.isStale||!(0,u.isValidTimeout)(e))return;let t=(0,u.timeUntilStale)(this.#n.dataUpdatedAt,e);this.#h=c.timeoutManager.setTimeout(()=>{this.#n.isStale||this.updateResult()},t+1)}#g(){return("function"==typeof this.options.refetchInterval?this.options.refetchInterval(this.#s):this.options.refetchInterval)??!1}#Q(e){this.#b(),this.#y=e,!u.isServer&&!1!==(0,u.resolveEnabled)(this.options.enabled,this.#s)&&(0,u.isValidTimeout)(this.#y)&&0!==this.#y&&(this.#d=c.timeoutManager.setInterval(()=>{(this.options.refetchIntervalInBackground||s.focusManager.isFocused())&&this.#p()},this.#y))}#m(){this.#R(),this.#Q(this.#g())}#v(){this.#h&&(c.timeoutManager.clearTimeout(this.#h),this.#h=void 0)}#b(){this.#d&&(c.timeoutManager.clearInterval(this.#d),this.#d=void 0)}createResult(e,t){let r,s=this.#s,i=this.options,a=this.#n,c=this.#a,l=this.#o,d=e!==s?e.state:this.#i,{state:p}=e,m={...p},v=!1;if(t._optimisticResults){let r=this.hasListeners(),a=!r&&h(e,t),o=r&&y(e,s,t,i);(a||o)&&(m={...m,...(0,n.fetchState)(p.data,e.options)}),"isRestoring"===t._optimisticResults&&(m.fetchStatus="idle")}let{error:b,errorUpdatedAt:S,status:R}=m;r=m.data;let g=!1;if(void 0!==t.placeholderData&&void 0===r&&"pending"===R){let e;a?.isPlaceholderData&&t.placeholderData===l?.placeholderData?(e=a.data,g=!0):e="function"==typeof t.placeholderData?t.placeholderData(this.#l?.state.data,this.#l):t.placeholderData,void 0!==e&&(R="success",r=(0,u.replaceData)(a?.data,e,t),v=!0)}if(t.select&&void 0!==r&&!g)if(a&&r===c?.data&&t.select===this.#u)r=this.#c;else try{this.#u=t.select,r=t.select(r),r=(0,u.replaceData)(a?.data,r,t),this.#c=r,this.#t=null}catch(e){this.#t=e}this.#t&&(b=this.#t,r=this.#c,S=Date.now(),R="error");let Q="fetching"===m.fetchStatus,w="pending"===R,E="error"===R,T=w&&Q,q=void 0!==r,O={status:R,fetchStatus:m.fetchStatus,isPending:w,isSuccess:"success"===R,isError:E,isInitialLoading:T,isLoading:T,data:r,dataUpdatedAt:m.dataUpdatedAt,error:b,errorUpdatedAt:S,failureCount:m.fetchFailureCount,failureReason:m.fetchFailureReason,errorUpdateCount:m.errorUpdateCount,isFetched:m.dataUpdateCount>0||m.errorUpdateCount>0,isFetchedAfterMount:m.dataUpdateCount>d.dataUpdateCount||m.errorUpdateCount>d.errorUpdateCount,isFetching:Q,isRefetching:Q&&!w,isLoadingError:E&&!q,isPaused:"paused"===m.fetchStatus,isPlaceholderData:v,isRefetchError:E&&q,isStale:f(e,t),refetch:this.refetch,promise:this.#r,isEnabled:!1!==(0,u.resolveEnabled)(t.enabled,e)};if(this.options.experimental_prefetchInRender){let t=void 0!==O.data,r="error"===O.status&&!t,i=e=>{r?e.reject(O.error):t&&e.resolve(O.data)},n=()=>{i(this.#r=O.promise=(0,o.pendingThenable)())},a=this.#r;switch(a.status){case"pending":e.queryHash===s.queryHash&&i(a);break;case"fulfilled":(r||O.data!==a.value)&&n();break;case"rejected":r&&O.error===a.reason||n()}}return O}updateResult(){let e=this.#n,t=this.createResult(this.#s,this.options);if(this.#a=this.#s.state,this.#o=this.options,void 0!==this.#a.data&&(this.#l=this.#s),(0,u.shallowEqualObjects)(t,e))return;this.#n=t;let r=()=>{if(!e)return!0;let{notifyOnChangeProps:t}=this.options,r="function"==typeof t?t():t;if("all"===r||!r&&!this.#f.size)return!0;let s=new Set(r??this.#f);return this.options.throwOnError&&s.add("error"),Object.keys(this.#n).some(t=>this.#n[t]!==e[t]&&s.has(t))};this.#w({listeners:r()})}#S(){let e=this.#e.getQueryCache().build(this.#e,this.options);if(e===this.#s)return;let t=this.#s;this.#s=e,this.#i=e.state,this.hasListeners()&&(t?.removeObserver(this),e.addObserver(this))}onQueryUpdate(){this.updateResult(),this.hasListeners()&&this.#m()}#w(e){i.notifyManager.batch(()=>{e.listeners&&this.listeners.forEach(e=>{e(this.#n)}),this.#e.getQueryCache().notify({query:this.#s,type:"observerResultsUpdated"})})}};function h(e,t){return!1!==(0,u.resolveEnabled)(t.enabled,e)&&void 0===e.state.data&&("error"!==e.state.status||!1!==t.retryOnMount)||void 0!==e.state.data&&d(e,t,t.refetchOnMount)}function d(e,t,r){if(!1!==(0,u.resolveEnabled)(t.enabled,e)&&"static"!==(0,u.resolveStaleTime)(t.staleTime,e)){let s="function"==typeof r?r(e):r;return"always"===s||!1!==s&&f(e,t)}return!1}function y(e,t,r,s){return(e!==t||!1===(0,u.resolveEnabled)(s.enabled,e))&&(!r.suspense||"error"!==e.state.status)&&f(e,r)}function f(e,t){return!1!==(0,u.resolveEnabled)(t.enabled,e)&&e.isStaleByTime((0,u.resolveStaleTime)(t.staleTime,e))}var p=e.i(4),m=e.i(1235);e.i(27493);var v=p.createContext((t=!1,{clearReset:()=>{t=!1},reset:()=>{t=!0},isReset:()=>t})),b=p.createContext(!1);b.Provider;var S=(e,t,r)=>t.fetchOptimistic(e).catch(()=>{r.clearReset()});function R(e,t){return function(e,t,r){let s,n=p.useContext(b),a=p.useContext(v),o=(0,m.useQueryClient)(r),c=o.defaultQueryOptions(e);o.getDefaultOptions().queries?._experimental_beforeQuery?.(c);let l=o.getQueryCache().get(c.queryHash);if(c._optimisticResults=n?"isRestoring":"optimistic",c.suspense){let e=e=>"static"===e?e:Math.max(e??1e3,1e3),t=c.staleTime;c.staleTime="function"==typeof t?(...r)=>e(t(...r)):e(t),"number"==typeof c.gcTime&&(c.gcTime=Math.max(c.gcTime,1e3))}s=l?.state.error&&"function"==typeof c.throwOnError?(0,u.shouldThrowError)(c.throwOnError,[l.state.error,l]):c.throwOnError,(c.suspense||c.experimental_prefetchInRender||s)&&!a.isReset()&&(c.retryOnMount=!1),p.useEffect(()=>{a.clearReset()},[a]);let h=!o.getQueryCache().get(c.queryHash),[d]=p.useState(()=>new t(o,c)),y=d.getOptimisticResult(c),f=!n&&!1!==e.subscribed;if(p.useSyncExternalStore(p.useCallback(e=>{let t=f?d.subscribe(i.notifyManager.batchCalls(e)):u.noop;return d.updateResult(),t},[d,f]),()=>d.getCurrentResult(),()=>d.getCurrentResult()),p.useEffect(()=>{d.setOptions(c)},[c,d]),c?.suspense&&y.isPending)throw S(c,d,a);if((({result:e,errorResetBoundary:t,throwOnError:r,query:s,suspense:i})=>e.isError&&!t.isReset()&&!e.isFetching&&s&&(i&&void 0===e.data||(0,u.shouldThrowError)(r,[e.error,s])))({result:y,errorResetBoundary:a,throwOnError:c.throwOnError,query:l,suspense:c.suspense}))throw y.error;if(o.getDefaultOptions().queries?._experimental_afterQuery?.(c,y),c.experimental_prefetchInRender&&!u.isServer&&y.isLoading&&y.isFetching&&!n){let e=h?S(c,d,a):l?.promise;e?.catch(u.noop).finally(()=>{d.updateResult()})}return c.notifyOnChangeProps?y:d.trackResult(y)}(e,l,t)}e.s(["useQuery",()=>R],45688);var g=e.i(21230),Q=a,w=class extends Q.Subscribable{#e;#n=void 0;#E;#T;constructor(e,t){super(),this.#e=e,this.setOptions(t),this.bindMethods(),this.#q()}bindMethods(){this.mutate=this.mutate.bind(this),this.reset=this.reset.bind(this)}setOptions(e){let t=this.options;this.options=this.#e.defaultMutationOptions(e),(0,u.shallowEqualObjects)(this.options,t)||this.#e.getMutationCache().notify({type:"observerOptionsUpdated",mutation:this.#E,observer:this}),t?.mutationKey&&this.options.mutationKey&&(0,u.hashKey)(t.mutationKey)!==(0,u.hashKey)(this.options.mutationKey)?this.reset():this.#E?.state.status==="pending"&&this.#E.setOptions(this.options)}onUnsubscribe(){this.hasListeners()||this.#E?.removeObserver(this)}onMutationUpdate(e){this.#q(),this.#w(e)}getCurrentResult(){return this.#n}reset(){this.#E?.removeObserver(this),this.#E=void 0,this.#q(),this.#w()}mutate(e,t){return this.#T=t,this.#E?.removeObserver(this),this.#E=this.#e.getMutationCache().build(this.#e,this.options),this.#E.addObserver(this),this.#E.execute(e)}#q(){let e=this.#E?.state??(0,g.getDefaultState)();this.#n={...e,isPending:"pending"===e.status,isSuccess:"success"===e.status,isError:"error"===e.status,isIdle:"idle"===e.status,mutate:this.mutate,reset:this.reset}}#w(e){i.notifyManager.batch(()=>{if(this.#T&&this.hasListeners()){let t=this.#n.variables,r=this.#n.context,s={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};if(e?.type==="success"){try{this.#T.onSuccess?.(e.data,t,r,s)}catch(e){Promise.reject(e)}try{this.#T.onSettled?.(e.data,null,t,r,s)}catch(e){Promise.reject(e)}}else if(e?.type==="error"){try{this.#T.onError?.(e.error,t,r,s)}catch(e){Promise.reject(e)}try{this.#T.onSettled?.(void 0,e.error,t,r,s)}catch(e){Promise.reject(e)}}}this.listeners.forEach(e=>{e(this.#n)})})}};function E(e,t){let r=(0,m.useQueryClient)(t),[s]=p.useState(()=>new w(r,e));p.useEffect(()=>{s.setOptions(e)},[s,e]);let n=p.useSyncExternalStore(p.useCallback(e=>s.subscribe(i.notifyManager.batchCalls(e)),[s]),()=>s.getCurrentResult(),()=>s.getCurrentResult()),a=p.useCallback((e,t)=>{s.mutate(e,t).catch(u.noop)},[s]);if(n.error&&(0,u.shouldThrowError)(s.options.throwOnError,[n.error]))throw n.error;return{...n,mutate:a,mutateAsync:n.mutate}}e.s(["useMutation",()=>E],71921);let T=r.default.env.NEXT_PUBLIC_WS_URL||"ws://localhost:3001/ws/events";function q(e={}){let{enabled:t=!0,onMessage:r}=e,s=(0,m.useQueryClient)(),i=(0,p.useRef)(null),n=(0,p.useRef)(null),a=(0,p.useRef)(0),o=(0,p.useRef)(1e3),u=(0,p.useRef)(()=>{}),[c,l]=(0,p.useState)(!1),[h,d]=(0,p.useState)(null),y=(0,p.useRef)(r);(0,p.useEffect)(()=>{y.current=r},[r]);let f=(0,p.useCallback)(()=>{if(t&&i.current?.readyState!==WebSocket.OPEN){n.current&&(clearTimeout(n.current),n.current=null);try{let e=new WebSocket(T);i.current=e,e.onopen=()=>{l(!0),a.current=0,o.current=1e3,console.log("[WebSocket] Connected to memory server")},e.onmessage=e=>{try{let t=JSON.parse(e.data);switch(d({type:t.type,data:t.data,timestamp:t.timestamp||new Date().toISOString()}),y.current?.(t),t.type){case"initial_state":case"consolidation_complete":case"predictive_consolidation":s.invalidateQueries({queryKey:["memories"]}),s.invalidateQueries({queryKey:["stats"]}),s.invalidateQueries({queryKey:["links"]});break;case"memory_created":case"memory_updated":case"memory_deleted":s.invalidateQueries({queryKey:["memories"]}),s.invalidateQueries({queryKey:["stats"]});break;case"decay_tick":case"worker_light_tick":case"worker_medium_tick":break;case"link_discovered":s.invalidateQueries({queryKey:["links"]});break;case"defence_event":s.invalidateQueries({queryKey:["agents"]}),s.invalidateQueries({queryKey:["agent-timeline"]}),s.invalidateQueries({queryKey:["audit-logs"]}),s.invalidateQueries({queryKey:["audit-stats"]});break;case"update_started":case"update_complete":case"update_failed":"update_complete"===t.type&&(s.invalidateQueries({queryKey:["version"]}),s.invalidateQueries({queryKey:["version-check"]}));break;case"server_restarting":console.log("[WebSocket] Server restarting, will reconnect shortly...")}}catch(e){console.error("[WebSocket] Failed to parse message:",e)}},e.onerror=()=>{console.warn("[WebSocket] Connection failed - is the API server running?")},e.onclose=()=>{if(l(!1),console.log("[WebSocket] Disconnected"),t&&a.current<10){let e=o.current;a.current++,o.current=Math.min(2*o.current,3e4),console.log(`[WebSocket] Reconnecting in ${e}ms (attempt ${a.current}/10)...`),n.current=setTimeout(()=>{u.current()},e)}else a.current>=10&&console.error("[WebSocket] Max reconnection attempts reached. Use reconnect() to try again.")}}catch(e){console.error("[WebSocket] Failed to connect:",e)}}},[t,s]);return(0,p.useEffect)(()=>{u.current=f}),(0,p.useEffect)(()=>(t&&f(),()=>{n.current&&clearTimeout(n.current),i.current&&(i.current.close(),i.current=null)}),[t,f]),{isConnected:c,lastEvent:h,reconnect:(0,p.useCallback)(()=>{a.current=0,o.current=1e3,f()},[f])}}e.s(["useMemoryWebSocket",()=>q],94156);let O=r.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001",F=null,k=null;async function C(){if(F)return F;if(k)return k;k=(async()=>{let e=await fetch(`${O}/api/auth/session-token`);if(!e.ok)throw Error((await e.json().catch(()=>({}))).error||"Failed to fetch session token");let{token:t}=await e.json();return F=t,t})();try{return await k}finally{k=null}}async function M(e,t){if(["GET","HEAD","OPTIONS"].includes((t?.method||"GET").toUpperCase()))return fetch(e,t);let r=await C(),s=new Headers(t?.headers);return s.set("Authorization",`Bearer ${r}`),fetch(e,{...t,headers:s})}e.s(["authFetch",()=>M],88969);let j=r.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001";async function I(e){let t=new URLSearchParams;e?.project&&t.set("project",e.project),e?.type&&t.set("type",e.type),e?.category&&t.set("category",e.category),e?.limit&&t.set("limit",e.limit.toString()),e?.offset&&t.set("offset",e.offset.toString()),e?.mode&&t.set("mode",e.mode),e?.query&&t.set("query",e.query);let r=await fetch(`${j}/api/memories?${t}`);if(!r.ok)throw Error("Failed to fetch memories");return r.json()}async function P(e){let t=e?`?project=${e}`:"",r=await fetch(`${j}/api/stats${t}`);if(!r.ok)throw Error("Failed to fetch stats");return r.json()}async function K(e){let t=e?`?project=${e}`:"",r=await fetch(`${j}/api/links${t}`);if(!r.ok)throw Error("Failed to fetch links");return r.json()}async function $(){let e=await fetch(`${j}/api/projects`);if(!e.ok)throw Error("Failed to fetch projects");return e.json()}async function _(e){let t=await M(`${j}/api/memories/${e}/access`,{method:"POST"});if(!t.ok)throw Error("Failed to access memory");return t.json()}async function x(){let e=await M(`${j}/api/consolidate`,{method:"POST"});if(!e.ok)throw Error("Failed to consolidate");return e.json()}function U(e){return R({queryKey:["stats",e],queryFn:()=>P(e),refetchInterval:3e4})}function D(e){return R({queryKey:["links",e],queryFn:()=>K(e),refetchInterval:6e4})}function L(){return R({queryKey:["projects"],queryFn:$,refetchInterval:6e4})}function A(e){let t,r=q();return{...{...t=R({queryKey:["memories",e],queryFn:()=>I(e),refetchInterval:3e4}),data:t.data?.memories,pagination:t.data?.pagination},isConnected:r.isConnected,lastEvent:r.lastEvent}}function W(){let e=(0,m.useQueryClient)();return E({mutationFn:_,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function z(){let e=(0,m.useQueryClient)();return E({mutationFn:x,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}async function B(){let e=await fetch(`${j}/api/control/status`);if(!e.ok)throw Error("Failed to fetch control status");return e.json()}async function N(){let e=await M(`${j}/api/control/pause`,{method:"POST"});if(!e.ok)throw Error("Failed to pause");return e.json()}async function H(){let e=await M(`${j}/api/control/resume`,{method:"POST"});if(!e.ok)throw Error("Failed to resume");return e.json()}function J(){return R({queryKey:["control-status"],queryFn:B,refetchInterval:1e4})}function V(){let e=(0,m.useQueryClient)();return E({mutationFn:N,onSuccess:()=>{e.invalidateQueries({queryKey:["control-status"]})}})}function X(){let e=(0,m.useQueryClient)();return E({mutationFn:H,onSuccess:()=>{e.invalidateQueries({queryKey:["control-status"]})}})}async function G(){let e=await fetch(`${j}/api/version`);if(!e.ok)throw Error("Failed to fetch version");return e.json()}function Y(){return R({queryKey:["version"],queryFn:G,staleTime:1/0})}async function Z(e){let t=e?`?project=${e}`:"",r=await fetch(`${j}/api/contradictions${t}`);if(!r.ok)throw Error("Failed to fetch contradictions");return r.json()}function ee(e){return R({queryKey:["contradictions",e],queryFn:()=>Z(e),staleTime:3e5})}async function et(e){let t=await M(`${j}/api/memories/${e}/boost`,{method:"POST"});if(!t.ok)throw Error("Failed to boost memory");return t.json()}async function er(e){let t=await M(`${j}/api/memories/${e}/demote`,{method:"POST"});if(!t.ok)throw Error("Failed to demote memory");return t.json()}async function es(e){let t=await M(`${j}/api/memories/${e}/promote`,{method:"POST"});if(!t.ok)throw Error("Failed to promote memory");return t.json()}async function ei(e,t){let r=await M(`${j}/api/memories/${e}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok)throw Error("Failed to edit memory");return r.json()}async function en(e){let t=await M(`${j}/api/memories/${e}`,{method:"DELETE"});if(!t.ok)throw Error("Failed to delete memory");return t.json()}async function ea(e,t){let r=await M(`${j}/api/memories/${e}/quarantine`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reason:t})});if(!r.ok)throw Error("Failed to quarantine memory");return r.json()}async function eo(){let e=await fetch(`${j}/api/worker/status`);if(!e.ok)throw Error("Failed to fetch worker status");return e.json()}function eu(){let e=(0,m.useQueryClient)();return E({mutationFn:et,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function ec(){let e=(0,m.useQueryClient)();return E({mutationFn:er,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function el(){let e=(0,m.useQueryClient)();return E({mutationFn:es,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function eh(){let e=(0,m.useQueryClient)();return E({mutationFn:({id:e,updates:t})=>ei(e,t),onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function ed(){let e=(0,m.useQueryClient)();return E({mutationFn:en,onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]}),e.invalidateQueries({queryKey:["links"]})}})}function ey(){let e=(0,m.useQueryClient)();return E({mutationFn:({id:e,reason:t})=>ea(e,t),onSuccess:()=>{e.invalidateQueries({queryKey:["memories"]}),e.invalidateQueries({queryKey:["stats"]})}})}function ef(){return R({queryKey:["worker-status"],queryFn:eo,refetchInterval:15e3})}e.s(["useAccessMemory",()=>W,"useBoostMemory",()=>eu,"useConsolidate",()=>z,"useContradictions",()=>ee,"useControlStatus",()=>J,"useDeleteMemory",()=>ed,"useDemoteMemory",()=>ec,"useEditMemory",()=>eh,"useMemoriesWithRealtime",()=>A,"useMemoryLinks",()=>D,"usePauseMemory",()=>V,"useProjects",()=>L,"usePromoteMemory",()=>el,"useQuarantineMemory",()=>ey,"useResumeMemory",()=>X,"useStats",()=>U,"useVersion",()=>Y,"useWorkerStatus",()=>ef],88069)},42098,92618,e=>{"use strict";let t;var r=e.i(4);let s=e=>{let t,r=new Set,s=(e,s)=>{let i="function"==typeof e?e(t):e;if(!Object.is(i,t)){let e=t;t=(null!=s?s:"object"!=typeof i||null===i)?i:Object.assign({},t,i),r.forEach(r=>r(t,e))}},i=()=>t,n={setState:s,getState:i,getInitialState:()=>a,subscribe:e=>(r.add(e),()=>r.delete(e))},a=t=e(s,i,n);return n},i=e=>e?s(e):s;e.s(["createStore",()=>i],92618);let n=e=>{let t=i(e),s=e=>(function(e,t=e=>e){let s=r.default.useSyncExternalStore(e.subscribe,r.default.useCallback(()=>t(e.getState()),[e,t]),r.default.useCallback(()=>t(e.getInitialState()),[e,t]));return r.default.useDebugValue(s),s})(t,e);return Object.assign(s,t),s},a=(t=e=>({selectedMemory:null,setSelectedMemory:t=>e({selectedMemory:t}),viewMode:"shield",setViewMode:t=>e({viewMode:t}),typeFilter:null,categoryFilter:null,projectFilter:null,setTypeFilter:t=>e({typeFilter:t}),setCategoryFilter:t=>e({categoryFilter:t}),setProjectFilter:t=>e({projectFilter:t}),recentEvents:[],addEvent:t=>e(e=>({recentEvents:[t,...e.recentEvents].slice(0,50)})),clearEvents:()=>e({recentEvents:[]}),cameraPosition:[0,0,12],setCameraPosition:t=>e({cameraPosition:t}),showLeftSidebar:!0,showRightSidebar:!0,toggleLeftSidebar:()=>e(e=>({showLeftSidebar:!e.showLeftSidebar})),toggleRightSidebar:()=>e(e=>({showRightSidebar:!e.showRightSidebar})),searchQuery:"",setSearchQuery:t=>e({searchQuery:t})}))?n(t):n;e.s(["useDashboardStore",0,a],42098)},33368,e=>{"use strict";let t={architecture:{basePosition:{x:0,y:1.2,z:2.2},spread:1},pattern:{basePosition:{x:0,y:.3,z:-2.2},spread:.9},preference:{basePosition:{x:1.6,y:-.3,z:0},spread:.7},error:{basePosition:{x:-1.6,y:-.3,z:.3},spread:.8},context:{basePosition:{x:0,y:1.8,z:0},spread:1.2},learning:{basePosition:{x:0,y:-.3,z:0},spread:.8},todo:{basePosition:{x:.6,y:.8,z:1.8},spread:.7},note:{basePosition:{x:1.8,y:0,z:-.3},spread:1},relationship:{basePosition:{x:-1.8,y:.3,z:-.3},spread:.9},custom:{basePosition:{x:0,y:0,z:0},spread:1.5}},r={short_term:.6,episodic:0,long_term:-.4};function s(e){let t=43758.5453*Math.sin(12.9898*e);return t-Math.floor(t)}function i(e){let i=t[e.category]||t.custom,n=r[e.type]||0,a=s(e.id),o=s(e.id+1e3),u=s(e.id+2e3),c=i.spread,l=a*Math.PI*2,h=(o-.5)*Math.PI,d=u*c*.7+.3*c,y=d*Math.cos(h)*Math.cos(l),f=d*Math.sin(h)*.6,p=d*Math.cos(h)*Math.sin(l),m=i.basePosition.x+y,v=i.basePosition.y+f,b=i.basePosition.z+p+n,S=.4*e.salience,R=Math.sqrt(m*m+v*v+b*b);if(R>.1){let e=(R+S)/R;m*=e,v*=e,b*=e}let g=Math.sqrt((m/3.2)**2+(v/2.5)**2+(b/3.5)**2);if(g>.95){let e=.95/g;m*=e,v*=e,b*=e}return{x:m,y:v,z:b}}function n(e){if(!e.lastAccessed)return 1;let t=Date.now(),r=new Date(e.lastAccessed).getTime();return Math.pow({short_term:.995,long_term:.9995,episodic:.998}[e.type]||.995,(t-r)/36e5)}e.s(["calculateDecayFactor",()=>n,"calculateMemoryPosition",()=>i])},87353,e=>{"use strict";var t=e.i(22534),r=e.i(45688),s=e.i(71921),i=e.i(1235),n=e.i(88969);let a=t.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001";async function o(e){let t=new URLSearchParams;e?.startTime&&t.set("startTime",e.startTime),e?.endTime&&t.set("endTime",e.endTime),e?.source&&t.set("source",e.source),e?.firewallResult&&t.set("firewallResult",e.firewallResult),e?.project&&t.set("project",e.project),e?.limit&&t.set("limit",e.limit.toString());let r=await fetch(`${a}/api/v1/audit?${t}`);if(!r.ok)throw Error("Failed to fetch audit logs");return r.json()}async function u(e,t){let r=new URLSearchParams({timeRange:e});t&&r.set("project",t);let s=await fetch(`${a}/api/v1/audit/stats?${r}`);if(!s.ok)throw Error("Failed to fetch audit stats");return s.json()}async function c(e="pending",t=50,r){let s=new URLSearchParams({status:e,limit:t.toString()});r&&s.set("project",r);let i=await fetch(`${a}/api/v1/quarantine?${s}`);if(!i.ok)throw Error("Failed to fetch quarantine");return i.json()}async function l(e){let t=await (0,n.authFetch)(`${a}/api/v1/quarantine/${e}/approve`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reviewedBy:"dashboard"})});if(!t.ok)throw Error("Failed to approve");return t.json()}async function h(e,t){let r=await (0,n.authFetch)(`${a}/api/v1/quarantine/${e}/reject`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({reviewedBy:"dashboard",notes:t})});if(!r.ok)throw Error("Failed to reject");return r.json()}function d(e){return(0,r.useQuery)({queryKey:["audit-logs",e],queryFn:()=>o(e),refetchInterval:3e4,retry:2})}function y(e="24h",t){return(0,r.useQuery)({queryKey:["audit-stats",e,t],queryFn:()=>u(e,t),refetchInterval:3e4,retry:2})}function f(e="pending",t=50,s){return(0,r.useQuery)({queryKey:["quarantine",e,t,s],queryFn:()=>c(e,t,s),refetchInterval:3e4,retry:2})}function p(){let e=(0,i.useQueryClient)();return(0,s.useMutation)({mutationFn:l,onSuccess:()=>{e.invalidateQueries({queryKey:["quarantine"]}),e.invalidateQueries({queryKey:["audit-stats"]})}})}function m(){let e=(0,i.useQueryClient)();return(0,s.useMutation)({mutationFn:({id:e,notes:t})=>h(e,t),onSuccess:()=>{e.invalidateQueries({queryKey:["quarantine"]}),e.invalidateQueries({queryKey:["audit-stats"]})}})}function v(){return(0,r.useQuery)({queryKey:["defence-config"],queryFn:()=>fetch(`${a}/api/defence/config`).then(e=>e.json())})}function b(){let e=(0,i.useQueryClient)();return(0,s.useMutation)({mutationFn:e=>(0,n.authFetch)(`${a}/api/defence/config`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({mode:e})}).then(e=>e.json()),onSuccess:()=>{e.invalidateQueries({queryKey:["defence-config"]})}})}e.s(["useApproveQuarantine",()=>p,"useAuditLogs",()=>d,"useAuditStats",()=>y,"useDefenceConfig",()=>v,"useQuarantine",()=>f,"useRejectQuarantine",()=>m,"useSetDefenceMode",()=>b])}]);
@@ -0,0 +1 @@
1
+ (globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,97358,e=>{"use strict";let t={architecture:"#FFD700",pattern:"#FFB347",preference:"#FFA500",error:"#FF6B6B",context:"#FFC080",learning:"#FFE4B5",todo:"#FF8C00",note:"#FFCC66",relationship:"#00D4FF",custom:"#FFB347"},r={short_term:"#FFD700",episodic:"#FFB347",long_term:"#FF8C00"};function n(e){return t[e]||t.custom}function o(e){return r[e]||r.short_term}e.s(["CATEGORY_COLORS",0,{architecture:"#3B82F6",pattern:"#8B5CF6",preference:"#EC4899",error:"#EF4444",context:"#10B981",learning:"#F59E0B",todo:"#F97316",note:"#6B7280",relationship:"#06B6D4",custom:"#A855F7"},"getCategoryColor",()=>n,"getTypeColor",()=>o])},25903,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"BailoutToCSR",{enumerable:!0,get:function(){return o}});let n=e.r(40909);function o({reason:e,children:t}){if("u"<typeof window)throw Object.defineProperty(new n.BailoutToCSRError(e),"__NEXT_ERROR_CODE",{value:"E394",enumerable:!1,configurable:!0});return t}},27601,(e,t,r)=>{"use strict";function n(e){return e.split("/").map(e=>encodeURIComponent(e)).join("/")}Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"encodeURIPath",{enumerable:!0,get:function(){return n}})},54220,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"PreloadChunks",{enumerable:!0,get:function(){return a}});let n=e.r(27493),o=e.r(9854),l=e.r(13595),u=e.r(27601),i=e.r(54218);function a({moduleIds:e}){if("u">typeof window)return null;let t=l.workAsyncStorage.getStore();if(void 0===t)return null;let r=[];if(t.reactLoadableManifest&&e){let n=t.reactLoadableManifest;for(let t of e){if(!n[t])continue;let e=n[t].files;r.push(...e)}}if(0===r.length)return null;let a=(0,i.getDeploymentIdQueryOrEmptyString)();return(0,n.jsx)(n.Fragment,{children:r.map(e=>{let r=`${t.assetPrefix}/_next/${(0,u.encodeURIPath)(e)}${a}`;return e.endsWith(".css")?(0,n.jsx)("link",{precedence:"dynamic",href:r,rel:"stylesheet",as:"style",nonce:t.nonce},e):((0,o.preload)(r,{as:"script",fetchPriority:"low",nonce:t.nonce}),null)})})}},73735,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return s}});let n=e.r(27493),o=e.r(4),l=e.r(25903),u=e.r(54220);function i(e){return{default:e&&"default"in e?e.default:e}}let a={loader:()=>Promise.resolve(i(()=>null)),loading:null,ssr:!0},s=function(e){let t={...a,...e},r=(0,o.lazy)(()=>t.loader().then(i)),s=t.loading;function c(e){let i=s?(0,n.jsx)(s,{isLoading:!0,pastDelay:!0,error:null}):null,a=!t.ssr||!!t.loading,c=a?o.Suspense:o.Fragment,d=t.ssr?(0,n.jsxs)(n.Fragment,{children:["u"<typeof window?(0,n.jsx)(u.PreloadChunks,{moduleIds:t.modules}):null,(0,n.jsx)(r,{...e})]}):(0,n.jsx)(l.BailoutToCSR,{reason:"next/dynamic",children:(0,n.jsx)(r,{...e})});return(0,n.jsx)(c,{...a?{fallback:i}:{},children:d})}return c.displayName="LoadableComponent",c}},74133,(e,t,r)=>{"use strict";Object.defineProperty(r,"__esModule",{value:!0}),Object.defineProperty(r,"default",{enumerable:!0,get:function(){return o}});let n=e.r(77637)._(e.r(73735));function o(e,t){let r={};"function"==typeof e&&(r.loader=e);let o={...r,...t};return(0,n.default)({...o,modules:o.loadableGenerated?.modules})}("function"==typeof r.default||"object"==typeof r.default&&null!==r.default)&&void 0===r.default.__esModule&&(Object.defineProperty(r.default,"__esModule",{value:!0}),Object.assign(r.default,r),t.exports=r.default)},1369,e=>{e.v(t=>Promise.all(["static/chunks/a3989d0e6629bcf8.js"].map(t=>e.l(t))).then(()=>t(11570)))},62838,e=>{e.v(t=>Promise.all(["static/chunks/acf32ffeb20e4854.js"].map(t=>e.l(t))).then(()=>t(41740)))}]);
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Per-Session API Auth Token
3
+ *
4
+ * Generates a random token on server start, writes it to
5
+ * ~/.shieldcortex/.api-token (0600 permissions), and validates
6
+ * incoming requests against it. Cleaned up on shutdown.
7
+ */
8
+ /**
9
+ * Generate a new session token, write to disk, and return it.
10
+ * Called once on server start.
11
+ */
12
+ export declare function generateSessionToken(): string;
13
+ /**
14
+ * Read the current session token from disk (or cache).
15
+ */
16
+ export declare function getSessionToken(): string | null;
17
+ /**
18
+ * Validate a token using constant-time comparison.
19
+ */
20
+ export declare function validateSessionToken(token: string): boolean;
21
+ /**
22
+ * Delete the token file on shutdown.
23
+ */
24
+ export declare function cleanupSessionToken(): void;
25
+ //# sourceMappingURL=session-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-token.d.ts","sourceRoot":"","sources":["../../src/api/session-token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAW7C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAS/C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAW3D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Per-Session API Auth Token
3
+ *
4
+ * Generates a random token on server start, writes it to
5
+ * ~/.shieldcortex/.api-token (0600 permissions), and validates
6
+ * incoming requests against it. Cleaned up on shutdown.
7
+ */
8
+ import { randomBytes, timingSafeEqual } from 'crypto';
9
+ import { readFileSync, writeFileSync, unlinkSync, existsSync, mkdirSync, chmodSync } from 'fs';
10
+ import { join } from 'path';
11
+ import { homedir } from 'os';
12
+ const CONFIG_DIR = join(homedir(), '.shieldcortex');
13
+ const TOKEN_FILE = join(CONFIG_DIR, '.api-token');
14
+ // In-memory cache — avoids repeated file reads
15
+ let cachedToken = null;
16
+ /**
17
+ * Generate a new session token, write to disk, and return it.
18
+ * Called once on server start.
19
+ */
20
+ export function generateSessionToken() {
21
+ const token = randomBytes(32).toString('hex');
22
+ mkdirSync(CONFIG_DIR, { recursive: true });
23
+ writeFileSync(TOKEN_FILE, token, { mode: 0o600 });
24
+ try {
25
+ chmodSync(TOKEN_FILE, 0o600);
26
+ }
27
+ catch {
28
+ // Best-effort on platforms that don't support chmod
29
+ }
30
+ cachedToken = token;
31
+ return token;
32
+ }
33
+ /**
34
+ * Read the current session token from disk (or cache).
35
+ */
36
+ export function getSessionToken() {
37
+ if (cachedToken)
38
+ return cachedToken;
39
+ try {
40
+ if (existsSync(TOKEN_FILE)) {
41
+ cachedToken = readFileSync(TOKEN_FILE, 'utf-8').trim();
42
+ return cachedToken;
43
+ }
44
+ }
45
+ catch { /* ignore */ }
46
+ return null;
47
+ }
48
+ /**
49
+ * Validate a token using constant-time comparison.
50
+ */
51
+ export function validateSessionToken(token) {
52
+ const expected = getSessionToken();
53
+ if (!expected)
54
+ return false;
55
+ try {
56
+ const a = Buffer.from(token, 'utf-8');
57
+ const b = Buffer.from(expected, 'utf-8');
58
+ if (a.length !== b.length)
59
+ return false;
60
+ return timingSafeEqual(a, b);
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
66
+ /**
67
+ * Delete the token file on shutdown.
68
+ */
69
+ export function cleanupSessionToken() {
70
+ cachedToken = null;
71
+ try {
72
+ if (existsSync(TOKEN_FILE)) {
73
+ unlinkSync(TOKEN_FILE);
74
+ }
75
+ }
76
+ catch { /* ignore */ }
77
+ }
78
+ //# sourceMappingURL=session-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-token.js","sourceRoot":"","sources":["../../src/api/session-token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/F,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AACpD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;AAElD,+CAA+C;AAC/C,IAAI,WAAW,GAAkB,IAAI,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC;QACH,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,oDAAoD;IACtD,CAAC;IACD,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IACpC,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;YACvD,OAAO,WAAW,CAAC;QACrB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACxC,OAAO,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,WAAW,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,UAAU,CAAC,UAAU,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;AAC1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"visualization-server.d.ts","sourceRoot":"","sources":["../../src/api/visualization-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2DH;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAk5D9D"}
1
+ {"version":3,"file":"visualization-server.d.ts","sourceRoot":"","sources":["../../src/api/visualization-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6DH;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAm/D9D"}
@@ -9,6 +9,7 @@ import cors from 'cors';
9
9
  import { createServer } from 'http';
10
10
  import { existsSync, unlinkSync } from 'fs';
11
11
  import { homedir } from 'os';
12
+ import { generateSessionToken, cleanupSessionToken, validateSessionToken, getSessionToken } from './session-token.js';
12
13
  import { WebSocketServer, WebSocket } from 'ws';
13
14
  import { getDatabase, initDatabase, checkpointWal } from '../database/init.js';
14
15
  import { DEFAULT_CONFIG } from '../memory/types.js';
@@ -25,7 +26,8 @@ import { getCurrentVersion, checkForUpdates, performUpdate, scheduleRestart } fr
25
26
  import { runDefencePipeline } from '../defence/pipeline.js';
26
27
  import { DEFAULT_DEFENCE_CONFIG } from '../defence/types.js';
27
28
  import { queryAuditLogs, getAuditStats, queryAgentRegistry, queryAgentTimeline, queryAgentOperations } from '../defence/audit/queries.js';
28
- import { getCloudConfig, setCloudConfig, readRawConfig, getTrustedSkills, addTrustedSkill, removeTrustedSkill, getDeviceId, getDeviceName } from '../cloud/config.js';
29
+ import { logAudit } from '../defence/audit/index.js';
30
+ import { getCloudConfig, setCloudConfig, readRawConfig, getTrustedSkills, addTrustedSkill, removeTrustedSkill, getDeviceId, getDeviceName, getDefenceMode, setDefenceMode, isConfigTampered } from '../cloud/config.js';
29
31
  import { getQueueStats } from '../cloud/sync-queue.js';
30
32
  import { scanSkill, scanSkillContent, discoverSkillFiles } from '../defence/skill-scanner/index.js';
31
33
  const PORT = process.env.PORT || 3001;
@@ -55,6 +57,46 @@ export function startVisualizationServer(dbPath) {
55
57
  },
56
58
  }));
57
59
  app.use(express.json());
60
+ // ── Session Auth ────────────────────────────────────────
61
+ // Generate per-session token (written to ~/.shieldcortex/.api-token)
62
+ const sessionToken = generateSessionToken();
63
+ let tokenClaimed = false;
64
+ // Auth middleware: require Bearer token on all mutating requests
65
+ app.use((req, res, next) => {
66
+ // Allow GET, OPTIONS, HEAD — read-only
67
+ if (['GET', 'OPTIONS', 'HEAD'].includes(req.method)) {
68
+ return next();
69
+ }
70
+ // Allow the one-time token claim endpoint without auth
71
+ if (req.path === '/api/auth/session-token') {
72
+ return next();
73
+ }
74
+ const authHeader = req.headers.authorization;
75
+ if (!authHeader || !authHeader.startsWith('Bearer ')) {
76
+ res.status(401).json({ error: 'Unauthorized', code: 'AUTH_REQUIRED' });
77
+ return;
78
+ }
79
+ const token = authHeader.slice(7);
80
+ if (!validateSessionToken(token)) {
81
+ res.status(401).json({ error: 'Invalid token', code: 'AUTH_INVALID' });
82
+ return;
83
+ }
84
+ next();
85
+ });
86
+ // One-time token handshake — dashboard claims on first load
87
+ app.get('/api/auth/session-token', (_req, res) => {
88
+ if (tokenClaimed) {
89
+ res.status(403).json({ error: 'Token already claimed', code: 'TOKEN_CLAIMED' });
90
+ return;
91
+ }
92
+ const token = getSessionToken();
93
+ if (!token) {
94
+ res.status(500).json({ error: 'No session token available' });
95
+ return;
96
+ }
97
+ tokenClaimed = true;
98
+ res.json({ token });
99
+ });
58
100
  // ============================================
59
101
  // REST API ENDPOINTS
60
102
  // ============================================
@@ -493,6 +535,34 @@ export function startVisualizationServer(dbPath) {
493
535
  res.status(500).json({ error: error.message });
494
536
  }
495
537
  });
538
+ // ============================================
539
+ // DEFENCE CONFIG ENDPOINTS
540
+ // ============================================
541
+ // Get defence configuration (firewall mode + integrity status)
542
+ app.get('/api/defence/config', (_req, res) => {
543
+ try {
544
+ res.json({ mode: getDefenceMode(), tampered: isConfigTampered() });
545
+ }
546
+ catch (error) {
547
+ res.status(500).json({ error: error.message });
548
+ }
549
+ });
550
+ // Update defence configuration (firewall mode)
551
+ app.post('/api/defence/config', (req, res) => {
552
+ try {
553
+ const { mode } = req.body;
554
+ const validModes = ['strict', 'balanced', 'permissive'];
555
+ if (!mode || !validModes.includes(mode)) {
556
+ res.status(400).json({ error: `Invalid mode. Must be one of: ${validModes.join(', ')}` });
557
+ return;
558
+ }
559
+ setDefenceMode(mode);
560
+ res.json({ success: true, mode });
561
+ }
562
+ catch (error) {
563
+ res.status(500).json({ error: error.message });
564
+ }
565
+ });
496
566
  // Get cloud sync status (queue stats + config)
497
567
  app.get('/api/cloud/sync-status', (_req, res) => {
498
568
  try {
@@ -1282,19 +1352,41 @@ export function startVisualizationServer(dbPath) {
1282
1352
  // ============================================
1283
1353
  // ── Defence API v1 ──────────────────────────────────────────
1284
1354
  // Scan content through the defence pipeline
1355
+ // NOTE: config parameter is intentionally ignored — always uses persisted mode (security hardening)
1285
1356
  app.post('/api/v1/scan', (req, res) => {
1286
1357
  try {
1287
- const { content, title, source, config } = req.body;
1358
+ const { content, title, source } = req.body;
1288
1359
  if (!content || typeof content !== 'string') {
1289
1360
  return res.status(400).json({ error: 'content (string) is required' });
1290
1361
  }
1362
+ // Log if caller tried to override config (potential tampering)
1363
+ if (req.body.config) {
1364
+ try {
1365
+ logAudit({
1366
+ memory_id: null,
1367
+ project: null,
1368
+ timestamp: new Date().toISOString(),
1369
+ source_type: 'api',
1370
+ source_identifier: 'rest-api',
1371
+ trust_score: 0,
1372
+ sensitivity_level: 'INTERNAL',
1373
+ firewall_result: 'ALLOW',
1374
+ anomaly_score: 0.5,
1375
+ threat_indicators: '["config_tampering"]',
1376
+ blocked_patterns: '[]',
1377
+ reason: 'config_override_attempt: scan endpoint config parameter ignored',
1378
+ fragmentation_score: null,
1379
+ pipeline_duration_ms: 0,
1380
+ });
1381
+ }
1382
+ catch { /* audit is best-effort */ }
1383
+ }
1291
1384
  const defenceSource = {
1292
1385
  type: source?.type ?? 'api',
1293
1386
  identifier: source?.identifier ?? 'rest-api',
1294
1387
  };
1295
- const defenceConfig = config
1296
- ? { ...DEFAULT_DEFENCE_CONFIG, ...config }
1297
- : DEFAULT_DEFENCE_CONFIG;
1388
+ // Always use persisted config — no per-request overrides via HTTP
1389
+ const defenceConfig = { ...DEFAULT_DEFENCE_CONFIG, mode: getDefenceMode() };
1298
1390
  const result = runDefencePipeline(content, title ?? 'Untitled', defenceSource, defenceConfig);
1299
1391
  res.json(result);
1300
1392
  }
@@ -1303,9 +1395,10 @@ export function startVisualizationServer(dbPath) {
1303
1395
  }
1304
1396
  });
1305
1397
  // Batch scan multiple items
1398
+ // NOTE: config parameter is intentionally ignored — always uses persisted mode (security hardening)
1306
1399
  app.post('/api/v1/scan/batch', (req, res) => {
1307
1400
  try {
1308
- const { items, source, config } = req.body;
1401
+ const { items, source } = req.body;
1309
1402
  if (!Array.isArray(items) || items.length === 0) {
1310
1403
  return res.status(400).json({ error: 'items (array) is required' });
1311
1404
  }
@@ -1316,9 +1409,8 @@ export function startVisualizationServer(dbPath) {
1316
1409
  type: source?.type ?? 'api',
1317
1410
  identifier: source?.identifier ?? 'rest-api',
1318
1411
  };
1319
- const defenceConfig = config
1320
- ? { ...DEFAULT_DEFENCE_CONFIG, ...config }
1321
- : DEFAULT_DEFENCE_CONFIG;
1412
+ // Always use persisted config — no per-request overrides via HTTP
1413
+ const defenceConfig = { ...DEFAULT_DEFENCE_CONFIG, mode: getDefenceMode() };
1322
1414
  const results = items.map((item) => {
1323
1415
  if (!item.content || typeof item.content !== 'string') {
1324
1416
  return { error: 'content (string) is required', allowed: false };
@@ -1708,6 +1800,8 @@ export function startVisualizationServer(dbPath) {
1708
1800
  // Graceful shutdown handler
1709
1801
  function gracefulShutdown(signal) {
1710
1802
  console.log(`\n[Server] Received ${signal}, shutting down gracefully...`);
1803
+ // Clean up session token file
1804
+ cleanupSessionToken();
1711
1805
  // Stop the brain worker
1712
1806
  brainWorker.stop();
1713
1807
  // Clear polling intervals