kiro-memory 2.1.0 → 3.0.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.
- package/README.md +5 -1
- package/package.json +3 -3
- package/plugin/dist/cli/contextkit.js +2315 -180
- package/plugin/dist/hooks/agentSpawn.js +548 -49
- package/plugin/dist/hooks/kiro-hooks.js +548 -49
- package/plugin/dist/hooks/postToolUse.js +556 -56
- package/plugin/dist/hooks/stop.js +548 -49
- package/plugin/dist/hooks/userPromptSubmit.js +551 -50
- package/plugin/dist/index.js +549 -50
- package/plugin/dist/plugins/github/github-client.js +152 -0
- package/plugin/dist/plugins/github/index.js +412 -0
- package/plugin/dist/plugins/github/issue-parser.js +54 -0
- package/plugin/dist/plugins/slack/formatter.js +90 -0
- package/plugin/dist/plugins/slack/index.js +215 -0
- package/plugin/dist/sdk/index.js +548 -49
- package/plugin/dist/servers/mcp-server.js +4461 -397
- package/plugin/dist/services/search/EmbeddingService.js +64 -20
- package/plugin/dist/services/search/HybridSearch.js +380 -38
- package/plugin/dist/services/search/VectorSearch.js +65 -21
- package/plugin/dist/services/search/index.js +380 -38
- package/plugin/dist/services/sqlite/Backup.js +416 -0
- package/plugin/dist/services/sqlite/Database.js +71 -0
- package/plugin/dist/services/sqlite/ImportExport.js +452 -0
- package/plugin/dist/services/sqlite/Observations.js +291 -7
- package/plugin/dist/services/sqlite/Prompts.js +1 -1
- package/plugin/dist/services/sqlite/Search.js +10 -10
- package/plugin/dist/services/sqlite/Summaries.js +4 -4
- package/plugin/dist/services/sqlite/index.js +1323 -28
- package/plugin/dist/viewer.css +1 -1
- package/plugin/dist/viewer.js +16 -8
- package/plugin/dist/viewer.js.map +4 -4
- package/plugin/dist/worker-service.js +326 -75
- package/plugin/dist/worker-service.js.map +4 -4
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
import { createRequire } from 'module';const require = createRequire(import.meta.url);
|
|
2
|
-
var Jr=Object.create;var Ae=Object.defineProperty;var Qr=Object.getOwnPropertyDescriptor;var Zr=Object.getOwnPropertyNames;var es=Object.getPrototypeOf,ts=Object.prototype.hasOwnProperty;var At=(t,e)=>()=>(t&&(e=t(t=0)),e);var F=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),Nt=(t,e)=>{for(var r in e)Ae(t,r,{get:e[r],enumerable:!0})},rs=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Zr(e))!ts.call(t,n)&&n!==r&&Ae(t,n,{get:()=>e[n],enumerable:!(s=Qr(e,n))||s.enumerable});return t};var ss=(t,e,r)=>(r=t!=null?Jr(es(t)):{},rs(e||!t||!t.__esModule?Ae(r,"default",{value:t,enumerable:!0}):r,t));var pe=F(q=>{"use strict";Object.defineProperty(q,"__esModule",{value:!0});q.isInSubnet=Ts;q.isCorrect=vs;q.numberToPaddedHex=Pt;q.stringToPaddedHex=Os;q.testBit=ws;function Ts(t){return this.subnetMask<t.subnetMask?!1:this.mask(t.subnetMask)===t.mask()}function vs(t){return function(){return this.addressMinusSuffix!==this.correctForm()?!1:this.subnetMask===t&&!this.parsedSubnet?!0:this.parsedSubnet===String(this.subnetMask)}}function Pt(t){return t.toString(16).padStart(2,"0")}function Os(t){return Pt(parseInt(t,10))}function ws(t,e){let{length:r}=t;if(e>r)return!1;let s=r-e;return t.substring(s,s+1)==="1"}});var Me=F(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});M.RE_SUBNET_STRING=M.RE_ADDRESS=M.GROUPS=M.BITS=void 0;M.BITS=32;M.GROUPS=4;M.RE_ADDRESS=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;M.RE_SUBNET_STRING=/\/\d{1,2}$/});var fe=F(me=>{"use strict";Object.defineProperty(me,"__esModule",{value:!0});me.AddressError=void 0;var Pe=class extends Error{constructor(e,r){super(e),this.name="AddressError",this.parseMessage=r}};me.AddressError=Pe});var Fe=F(P=>{"use strict";var Ds=P&&P.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),Is=P&&P.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Ft=P&&P.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&Ds(e,t,r);return Is(e,t),e};Object.defineProperty(P,"__esModule",{value:!0});P.Address4=void 0;var Y=Ft(pe()),j=Ft(Me()),kt=fe(),ke=class t{constructor(e){this.groups=j.GROUPS,this.parsedAddress=[],this.parsedSubnet="",this.subnet="/32",this.subnetMask=32,this.v4=!0,this.isCorrect=Y.isCorrect(j.BITS),this.isInSubnet=Y.isInSubnet,this.address=e;let r=j.RE_SUBNET_STRING.exec(e);if(r){if(this.parsedSubnet=r[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,this.subnetMask<0||this.subnetMask>j.BITS)throw new kt.AddressError("Invalid subnet mask.");e=e.replace(j.RE_SUBNET_STRING,"")}this.addressMinusSuffix=e,this.parsedAddress=this.parse(e)}static isValid(e){try{return new t(e),!0}catch{return!1}}parse(e){let r=e.split(".");if(!e.match(j.RE_ADDRESS))throw new kt.AddressError("Invalid IPv4 address.");return r}correctForm(){return this.parsedAddress.map(e=>parseInt(e,10)).join(".")}static fromHex(e){let r=e.replace(/:/g,"").padStart(8,"0"),s=[],n;for(n=0;n<8;n+=2){let o=r.slice(n,n+2);s.push(parseInt(o,16))}return new t(s.join("."))}static fromInteger(e){return t.fromHex(e.toString(16))}static fromArpa(e){let s=e.replace(/(\.in-addr\.arpa)?\.$/,"").split(".").reverse().join(".");return new t(s)}toHex(){return this.parsedAddress.map(e=>Y.stringToPaddedHex(e)).join(":")}toArray(){return this.parsedAddress.map(e=>parseInt(e,10))}toGroup6(){let e=[],r;for(r=0;r<j.GROUPS;r+=2)e.push(`${Y.stringToPaddedHex(this.parsedAddress[r])}${Y.stringToPaddedHex(this.parsedAddress[r+1])}`);return e.join(":")}bigInt(){return BigInt(`0x${this.parsedAddress.map(e=>Y.stringToPaddedHex(e)).join("")}`)}_startAddress(){return BigInt(`0b${this.mask()+"0".repeat(j.BITS-this.subnetMask)}`)}startAddress(){return t.fromBigInt(this._startAddress())}startAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._startAddress()+e)}_endAddress(){return BigInt(`0b${this.mask()+"1".repeat(j.BITS-this.subnetMask)}`)}endAddress(){return t.fromBigInt(this._endAddress())}endAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._endAddress()-e)}static fromBigInt(e){return t.fromHex(e.toString(16))}mask(e){return e===void 0&&(e=this.subnetMask),this.getBitsBase2(0,e)}getBitsBase2(e,r){return this.binaryZeroPad().slice(e,r)}reverseForm(e){e||(e={});let r=this.correctForm().split(".").reverse().join(".");return e.omitSuffix?r:`${r}.in-addr.arpa.`}isMulticast(){return this.isInSubnet(new t("224.0.0.0/4"))}binaryZeroPad(){return this.bigInt().toString(2).padStart(j.BITS,"0")}groupForV6(){let e=this.parsedAddress;return this.address.replace(j.RE_ADDRESS,`<span class="hover-group group-v4 group-6">${e.slice(0,2).join(".")}</span>.<span class="hover-group group-v4 group-7">${e.slice(2,4).join(".")}</span>`)}};P.Address4=ke});var Be=F(S=>{"use strict";Object.defineProperty(S,"__esModule",{value:!0});S.RE_URL_WITH_PORT=S.RE_URL=S.RE_ZONE_STRING=S.RE_SUBNET_STRING=S.RE_BAD_ADDRESS=S.RE_BAD_CHARACTERS=S.TYPES=S.SCOPES=S.GROUPS=S.BITS=void 0;S.BITS=128;S.GROUPS=8;S.SCOPES={0:"Reserved",1:"Interface local",2:"Link local",4:"Admin local",5:"Site local",8:"Organization local",14:"Global",15:"Reserved"};S.TYPES={"ff01::1/128":"Multicast (All nodes on this interface)","ff01::2/128":"Multicast (All routers on this interface)","ff02::1/128":"Multicast (All nodes on this link)","ff02::2/128":"Multicast (All routers on this link)","ff05::2/128":"Multicast (All routers in this site)","ff02::5/128":"Multicast (OSPFv3 AllSPF routers)","ff02::6/128":"Multicast (OSPFv3 AllDR routers)","ff02::9/128":"Multicast (RIP routers)","ff02::a/128":"Multicast (EIGRP routers)","ff02::d/128":"Multicast (PIM routers)","ff02::16/128":"Multicast (MLDv2 reports)","ff01::fb/128":"Multicast (mDNSv6)","ff02::fb/128":"Multicast (mDNSv6)","ff05::fb/128":"Multicast (mDNSv6)","ff02::1:2/128":"Multicast (All DHCP servers and relay agents on this link)","ff05::1:2/128":"Multicast (All DHCP servers and relay agents in this site)","ff02::1:3/128":"Multicast (All DHCP servers on this link)","ff05::1:3/128":"Multicast (All DHCP servers in this site)","::/128":"Unspecified","::1/128":"Loopback","ff00::/8":"Multicast","fe80::/10":"Link-local unicast"};S.RE_BAD_CHARACTERS=/([^0-9a-f:/%])/gi;S.RE_BAD_ADDRESS=/([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;S.RE_SUBNET_STRING=/\/\d{1,3}(?=%|$)/;S.RE_ZONE_STRING=/%.*$/;S.RE_URL=/^\[{0,1}([0-9a-f:]+)\]{0,1}/;S.RE_URL_WITH_PORT=/\[([0-9a-f:]+)\]:([0-9]{1,5})/});var $e=F(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.spanAllZeroes=Bt;V.spanAll=As;V.spanLeadingZeroes=Ns;V.simpleGroup=Cs;function Bt(t){return t.replace(/(0+)/g,'<span class="zero">$1</span>')}function As(t,e=0){return t.split("").map((s,n)=>`<span class="digit value-${s} position-${n+e}">${Bt(s)}</span>`).join("")}function $t(t){return t.replace(/^(0+)/,'<span class="zero">$1</span>')}function Ns(t){return t.split(":").map(r=>$t(r)).join(":")}function Cs(t,e=0){return t.split(":").map((s,n)=>/group-v4/.test(s)?s:`<span class="hover-group group-${n+e}">${$t(s)}</span>`)}});var Ht=F(L=>{"use strict";var Ls=L&&L.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),xs=L&&L.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),js=L&&L.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&Ls(e,t,r);return xs(e,t),e};Object.defineProperty(L,"__esModule",{value:!0});L.ADDRESS_BOUNDARY=void 0;L.groupPossibilities=Ee;L.padGroup=he;L.simpleRegularExpression=Ps;L.possibleElisions=ks;var Ms=js(Be());function Ee(t){return`(${t.join("|")})`}function he(t){return t.length<4?`0{0,${4-t.length}}${t}`:t}L.ADDRESS_BOUNDARY="[^A-Fa-f0-9:]";function Ps(t){let e=[];t.forEach((s,n)=>{parseInt(s,16)===0&&e.push(n)});let r=e.map(s=>t.map((n,o)=>{if(o===s){let i=o===0||o===Ms.GROUPS-1?":":"";return Ee([he(n),i])}return he(n)}).join(":"));return r.push(t.map(he).join(":")),Ee(r)}function ks(t,e,r){let s=e?"":":",n=r?"":":",o=[];!e&&!r&&o.push("::"),e&&r&&o.push(""),(r&&!e||!r&&e)&&o.push(":"),o.push(`${s}(:0{1,4}){1,${t-1}}`),o.push(`(0{1,4}:){1,${t-1}}${n}`),o.push(`(0{1,4}:){${t-1}}0{1,4}`);for(let i=1;i<t-1;i++)for(let a=1;a<t-i;a++)o.push(`(0{1,4}:){${a}}:(0{1,4}:){${t-a-i-1}}0{1,4}`);return Ee(o)}});var Gt=F(k=>{"use strict";var Fs=k&&k.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),Bs=k&&k.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),_e=k&&k.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&Fs(e,t,r);return Bs(e,t),e};Object.defineProperty(k,"__esModule",{value:!0});k.Address6=void 0;var Ut=_e(pe()),He=_e(Me()),b=_e(Be()),Ue=_e($e()),W=Fe(),G=Ht(),B=fe(),ge=pe();function be(t){if(!t)throw new Error("Assertion failed.")}function $s(t){let e=/(\d+)(\d{3})/;for(;e.test(t);)t=t.replace(e,"$1,$2");return t}function Hs(t){return t=t.replace(/^(0{1,})([1-9]+)$/,'<span class="parse-error">$1</span>$2'),t=t.replace(/^(0{1,})(0)$/,'<span class="parse-error">$1</span>$2'),t}function Us(t,e){let r=[],s=[],n;for(n=0;n<t.length;n++)n<e[0]?r.push(t[n]):n>e[1]&&s.push(t[n]);return r.concat(["compact"]).concat(s)}function qt(t){return parseInt(t,16).toString(16).padStart(4,"0")}function Wt(t){return t&255}var qe=class t{constructor(e,r){this.addressMinusSuffix="",this.parsedSubnet="",this.subnet="/128",this.subnetMask=128,this.v4=!1,this.zone="",this.isInSubnet=Ut.isInSubnet,this.isCorrect=Ut.isCorrect(b.BITS),r===void 0?this.groups=b.GROUPS:this.groups=r,this.address=e;let s=b.RE_SUBNET_STRING.exec(e);if(s){if(this.parsedSubnet=s[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,Number.isNaN(this.subnetMask)||this.subnetMask<0||this.subnetMask>b.BITS)throw new B.AddressError("Invalid subnet mask.");e=e.replace(b.RE_SUBNET_STRING,"")}else if(/\//.test(e))throw new B.AddressError("Invalid subnet mask.");let n=b.RE_ZONE_STRING.exec(e);n&&(this.zone=n[0],e=e.replace(b.RE_ZONE_STRING,"")),this.addressMinusSuffix=e,this.parsedAddress=this.parse(this.addressMinusSuffix)}static isValid(e){try{return new t(e),!0}catch{return!1}}static fromBigInt(e){let r=e.toString(16).padStart(32,"0"),s=[],n;for(n=0;n<b.GROUPS;n++)s.push(r.slice(n*4,(n+1)*4));return new t(s.join(":"))}static fromURL(e){let r,s=null,n;if(e.indexOf("[")!==-1&&e.indexOf("]:")!==-1){if(n=b.RE_URL_WITH_PORT.exec(e),n===null)return{error:"failed to parse address with port",address:null,port:null};r=n[1],s=n[2]}else if(e.indexOf("/")!==-1){if(e=e.replace(/^[a-z0-9]+:\/\//,""),n=b.RE_URL.exec(e),n===null)return{error:"failed to parse address from URL",address:null,port:null};r=n[1]}else r=e;return s?(s=parseInt(s,10),(s<0||s>65536)&&(s=null)):s=null,{address:new t(r),port:s}}static fromAddress4(e){let r=new W.Address4(e),s=b.BITS-(He.BITS-r.subnetMask);return new t(`::ffff:${r.correctForm()}/${s}`)}static fromArpa(e){let r=e.replace(/(\.ip6\.arpa)?\.$/,""),s=7;if(r.length!==63)throw new B.AddressError("Invalid 'ip6.arpa' form.");let n=r.split(".").reverse();for(let o=s;o>0;o--){let i=o*4;n.splice(i,0,":")}return r=n.join(""),new t(r)}microsoftTranscription(){return`${this.correctForm().replace(/:/g,"-")}.ipv6-literal.net`}mask(e=this.subnetMask){return this.getBitsBase2(0,e)}possibleSubnets(e=128){let r=b.BITS-this.subnetMask,s=Math.abs(e-b.BITS),n=r-s;return n<0?"0":$s((BigInt("2")**BigInt(n)).toString(10))}_startAddress(){return BigInt(`0b${this.mask()+"0".repeat(b.BITS-this.subnetMask)}`)}startAddress(){return t.fromBigInt(this._startAddress())}startAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._startAddress()+e)}_endAddress(){return BigInt(`0b${this.mask()+"1".repeat(b.BITS-this.subnetMask)}`)}endAddress(){return t.fromBigInt(this._endAddress())}endAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._endAddress()-e)}getScope(){let e=b.SCOPES[parseInt(this.getBits(12,16).toString(10),10)];return this.getType()==="Global unicast"&&e!=="Link local"&&(e="Global"),e||"Unknown"}getType(){for(let e of Object.keys(b.TYPES))if(this.isInSubnet(new t(e)))return b.TYPES[e];return"Global unicast"}getBits(e,r){return BigInt(`0b${this.getBitsBase2(e,r)}`)}getBitsBase2(e,r){return this.binaryZeroPad().slice(e,r)}getBitsBase16(e,r){let s=r-e;if(s%4!==0)throw new Error("Length of bits to retrieve must be divisible by four");return this.getBits(e,r).toString(16).padStart(s/4,"0")}getBitsPastSubnet(){return this.getBitsBase2(this.subnetMask,b.BITS)}reverseForm(e){e||(e={});let r=Math.floor(this.subnetMask/4),s=this.canonicalForm().replace(/:/g,"").split("").slice(0,r).reverse().join(".");return r>0?e.omitSuffix?s:`${s}.ip6.arpa.`:e.omitSuffix?"":"ip6.arpa."}correctForm(){let e,r=[],s=0,n=[];for(e=0;e<this.parsedAddress.length;e++){let a=parseInt(this.parsedAddress[e],16);a===0&&s++,a!==0&&s>0&&(s>1&&n.push([e-s,e-1]),s=0)}s>1&&n.push([this.parsedAddress.length-s,this.parsedAddress.length-1]);let o=n.map(a=>a[1]-a[0]+1);if(n.length>0){let a=o.indexOf(Math.max(...o));r=Us(this.parsedAddress,n[a])}else r=this.parsedAddress;for(e=0;e<r.length;e++)r[e]!=="compact"&&(r[e]=parseInt(r[e],16).toString(16));let i=r.join(":");return i=i.replace(/^compact$/,"::"),i=i.replace(/(^compact)|(compact$)/,":"),i=i.replace(/compact/,""),i}binaryZeroPad(){return this.bigInt().toString(2).padStart(b.BITS,"0")}parse4in6(e){let r=e.split(":"),n=r.slice(-1)[0].match(He.RE_ADDRESS);if(n){this.parsedAddress4=n[0],this.address4=new W.Address4(this.parsedAddress4);for(let o=0;o<this.address4.groups;o++)if(/^0[0-9]+/.test(this.address4.parsedAddress[o]))throw new B.AddressError("IPv4 addresses can't have leading zeroes.",e.replace(He.RE_ADDRESS,this.address4.parsedAddress.map(Hs).join(".")));this.v4=!0,r[r.length-1]=this.address4.toGroup6(),e=r.join(":")}return e}parse(e){e=this.parse4in6(e);let r=e.match(b.RE_BAD_CHARACTERS);if(r)throw new B.AddressError(`Bad character${r.length>1?"s":""} detected in address: ${r.join("")}`,e.replace(b.RE_BAD_CHARACTERS,'<span class="parse-error">$1</span>'));let s=e.match(b.RE_BAD_ADDRESS);if(s)throw new B.AddressError(`Address failed regex: ${s.join("")}`,e.replace(b.RE_BAD_ADDRESS,'<span class="parse-error">$1</span>'));let n=[],o=e.split("::");if(o.length===2){let i=o[0].split(":"),a=o[1].split(":");i.length===1&&i[0]===""&&(i=[]),a.length===1&&a[0]===""&&(a=[]);let c=this.groups-(i.length+a.length);if(!c)throw new B.AddressError("Error parsing groups");this.elidedGroups=c,this.elisionBegin=i.length,this.elisionEnd=i.length+this.elidedGroups,n=n.concat(i);for(let u=0;u<c;u++)n.push("0");n=n.concat(a)}else if(o.length===1)n=e.split(":"),this.elidedGroups=0;else throw new B.AddressError("Too many :: groups found");if(n=n.map(i=>parseInt(i,16).toString(16)),n.length!==this.groups)throw new B.AddressError("Incorrect number of groups found");return n}canonicalForm(){return this.parsedAddress.map(qt).join(":")}decimal(){return this.parsedAddress.map(e=>parseInt(e,16).toString(10).padStart(5,"0")).join(":")}bigInt(){return BigInt(`0x${this.parsedAddress.map(qt).join("")}`)}to4(){let e=this.binaryZeroPad().split("");return W.Address4.fromHex(BigInt(`0b${e.slice(96,128).join("")}`).toString(16))}to4in6(){let e=this.to4(),s=new t(this.parsedAddress.slice(0,6).join(":"),6).correctForm(),n="";return/:$/.test(s)||(n=":"),s+n+e.address}inspectTeredo(){let e=this.getBitsBase16(0,32),s=(this.getBits(80,96)^BigInt("0xffff")).toString(),n=W.Address4.fromHex(this.getBitsBase16(32,64)),o=this.getBits(96,128),i=W.Address4.fromHex((o^BigInt("0xffffffff")).toString(16)),a=this.getBitsBase2(64,80),c=(0,ge.testBit)(a,15),u=(0,ge.testBit)(a,14),d=(0,ge.testBit)(a,8),l=(0,ge.testBit)(a,9),m=BigInt(`0b${a.slice(2,6)+a.slice(8,16)}`).toString(10);return{prefix:`${e.slice(0,4)}:${e.slice(4,8)}`,server4:n.address,client4:i.address,flags:a,coneNat:c,microsoft:{reserved:u,universalLocal:l,groupIndividual:d,nonce:m},udpPort:s}}inspect6to4(){let e=this.getBitsBase16(0,16),r=W.Address4.fromHex(this.getBitsBase16(16,48));return{prefix:e.slice(0,4),gateway:r.address}}to6to4(){if(!this.is4())return null;let e=["2002",this.getBitsBase16(96,112),this.getBitsBase16(112,128),"","/16"].join(":");return new t(e)}toByteArray(){let e=this.bigInt().toString(16),s=`${"0".repeat(e.length%2)}${e}`,n=[];for(let o=0,i=s.length;o<i;o+=2)n.push(parseInt(s.substring(o,o+2),16));return n}toUnsignedByteArray(){return this.toByteArray().map(Wt)}static fromByteArray(e){return this.fromUnsignedByteArray(e.map(Wt))}static fromUnsignedByteArray(e){let r=BigInt("256"),s=BigInt("0"),n=BigInt("1");for(let o=e.length-1;o>=0;o--)s+=n*BigInt(e[o].toString(10)),n*=r;return t.fromBigInt(s)}isCanonical(){return this.addressMinusSuffix===this.canonicalForm()}isLinkLocal(){return this.getBitsBase2(0,64)==="1111111010000000000000000000000000000000000000000000000000000000"}isMulticast(){return this.getType()==="Multicast"}is4(){return this.v4}isTeredo(){return this.isInSubnet(new t("2001::/32"))}is6to4(){return this.isInSubnet(new t("2002::/16"))}isLoopback(){return this.getType()==="Loopback"}href(e){return e===void 0?e="":e=`:${e}`,`http://[${this.correctForm()}]${e}/`}link(e){e||(e={}),e.className===void 0&&(e.className=""),e.prefix===void 0&&(e.prefix="/#address="),e.v4===void 0&&(e.v4=!1);let r=this.correctForm;e.v4&&(r=this.to4in6);let s=r.call(this);return e.className?`<a href="${e.prefix}${s}" class="${e.className}">${s}</a>`:`<a href="${e.prefix}${s}">${s}</a>`}group(){if(this.elidedGroups===0)return Ue.simpleGroup(this.address).join(":");be(typeof this.elidedGroups=="number"),be(typeof this.elisionBegin=="number");let e=[],[r,s]=this.address.split("::");r.length?e.push(...Ue.simpleGroup(r)):e.push("");let n=["hover-group"];for(let o=this.elisionBegin;o<this.elisionBegin+this.elidedGroups;o++)n.push(`group-${o}`);return e.push(`<span class="${n.join(" ")}"></span>`),s.length?e.push(...Ue.simpleGroup(s,this.elisionEnd)):e.push(""),this.is4()&&(be(this.address4 instanceof W.Address4),e.pop(),e.push(this.address4.groupForV6())),e.join(":")}regularExpressionString(e=!1){let r=[],s=new t(this.correctForm());if(s.elidedGroups===0)r.push((0,G.simpleRegularExpression)(s.parsedAddress));else if(s.elidedGroups===b.GROUPS)r.push((0,G.possibleElisions)(b.GROUPS));else{let n=s.address.split("::");n[0].length&&r.push((0,G.simpleRegularExpression)(n[0].split(":"))),be(typeof s.elidedGroups=="number"),r.push((0,G.possibleElisions)(s.elidedGroups,n[0].length!==0,n[1].length!==0)),n[1].length&&r.push((0,G.simpleRegularExpression)(n[1].split(":"))),r=[r.join(":")]}return e||(r=["(?=^|",G.ADDRESS_BOUNDARY,"|[^\\w\\:])(",...r,")(?=[^\\w\\:]|",G.ADDRESS_BOUNDARY,"|$)"]),r.join("")}regularExpression(e=!1){return new RegExp(this.regularExpressionString(e),"i")}};k.Address6=qe});var Xt=F(I=>{"use strict";var qs=I&&I.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),Ws=I&&I.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Gs=I&&I.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&qs(e,t,r);return Ws(e,t),e};Object.defineProperty(I,"__esModule",{value:!0});I.v6=I.AddressError=I.Address6=I.Address4=void 0;var Xs=Fe();Object.defineProperty(I,"Address4",{enumerable:!0,get:function(){return Xs.Address4}});var Ks=Gt();Object.defineProperty(I,"Address6",{enumerable:!0,get:function(){return Ks.Address6}});var Ys=fe();Object.defineProperty(I,"AddressError",{enumerable:!0,get:function(){return Ys.AddressError}});var Vs=Gs($e());I.v6={helpers:Vs}});var pr={};Nt(pr,{getObservationsByIds:()=>nt,getProjectStats:()=>it,getStaleObservations:()=>Bn,getTimeline:()=>ot,markObservationsStale:()=>$n,searchObservationsFTS:()=>rt,searchObservationsFTSWithRank:()=>Fn,searchObservationsLIKE:()=>tt,searchSummariesFiltered:()=>st});import{existsSync as Pn,statSync as kn}from"fs";function lr(t){return t.replace(/[%_\\]/g,"\\$&")}function dr(t){return(t.length>1e4?t.substring(0,1e4):t).replace(/[""\u0022]/g,"").split(/\s+/).filter(s=>s.length>0).slice(0,100).map(s=>`"${s}"`).join(" ")}function rt(t,e,r={}){let s=r.limit||50;try{let n=dr(e);if(!n)return tt(t,e,r);let o=`
|
|
2
|
+
var xn=Object.create;var kt=Object.defineProperty;var kn=Object.getOwnPropertyDescriptor;var Ln=Object.getOwnPropertyNames;var Pn=Object.getPrototypeOf,Mn=Object.prototype.hasOwnProperty;var $n=(t=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(t,{get:(e,r)=>(typeof require<"u"?require:e)[r]}):t)(function(t){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+t+'" is not supported')});var Be=(t,e)=>()=>(t&&(e=t(t=0)),e);var G=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),xr=(t,e)=>{for(var r in e)kt(t,r,{get:e[r],enumerable:!0})},Bn=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of Ln(e))!Mn.call(t,n)&&n!==r&&kt(t,n,{get:()=>e[n],enumerable:!(s=kn(e,n))||s.enumerable});return t};var Fn=(t,e,r)=>(r=t!=null?xn(Pn(t)):{},Bn(e||!t||!t.__esModule?kt(r,"default",{value:t,enumerable:!0}):r,t));var Ye=G(oe=>{"use strict";Object.defineProperty(oe,"__esModule",{value:!0});oe.isInSubnet=io;oe.isCorrect=ao;oe.numberToPaddedHex=Br;oe.stringToPaddedHex=co;oe.testBit=uo;function io(t){return this.subnetMask<t.subnetMask?!1:this.mask(t.subnetMask)===t.mask()}function ao(t){return function(){return this.addressMinusSuffix!==this.correctForm()?!1:this.subnetMask===t&&!this.parsedSubnet?!0:this.parsedSubnet===String(this.subnetMask)}}function Br(t){return t.toString(16).padStart(2,"0")}function co(t){return Br(parseInt(t,10))}function uo(t,e){let{length:r}=t;if(e>r)return!1;let s=r-e;return t.substring(s,s+1)==="1"}});var Ft=G(H=>{"use strict";Object.defineProperty(H,"__esModule",{value:!0});H.RE_SUBNET_STRING=H.RE_ADDRESS=H.GROUPS=H.BITS=void 0;H.BITS=32;H.GROUPS=4;H.RE_ADDRESS=/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/g;H.RE_SUBNET_STRING=/\/\d{1,2}$/});var Ve=G(ze=>{"use strict";Object.defineProperty(ze,"__esModule",{value:!0});ze.AddressError=void 0;var Ht=class extends Error{constructor(e,r){super(e),this.name="AddressError",this.parseMessage=r}};ze.AddressError=Ht});var Wt=G(q=>{"use strict";var po=q&&q.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),lo=q&&q.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Hr=q&&q.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&po(e,t,r);return lo(e,t),e};Object.defineProperty(q,"__esModule",{value:!0});q.Address4=void 0;var de=Hr(Ye()),F=Hr(Ft()),Fr=Ve(),qt=class t{constructor(e){this.groups=F.GROUPS,this.parsedAddress=[],this.parsedSubnet="",this.subnet="/32",this.subnetMask=32,this.v4=!0,this.isCorrect=de.isCorrect(F.BITS),this.isInSubnet=de.isInSubnet,this.address=e;let r=F.RE_SUBNET_STRING.exec(e);if(r){if(this.parsedSubnet=r[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,this.subnetMask<0||this.subnetMask>F.BITS)throw new Fr.AddressError("Invalid subnet mask.");e=e.replace(F.RE_SUBNET_STRING,"")}this.addressMinusSuffix=e,this.parsedAddress=this.parse(e)}static isValid(e){try{return new t(e),!0}catch{return!1}}parse(e){let r=e.split(".");if(!e.match(F.RE_ADDRESS))throw new Fr.AddressError("Invalid IPv4 address.");return r}correctForm(){return this.parsedAddress.map(e=>parseInt(e,10)).join(".")}static fromHex(e){let r=e.replace(/:/g,"").padStart(8,"0"),s=[],n;for(n=0;n<8;n+=2){let o=r.slice(n,n+2);s.push(parseInt(o,16))}return new t(s.join("."))}static fromInteger(e){return t.fromHex(e.toString(16))}static fromArpa(e){let s=e.replace(/(\.in-addr\.arpa)?\.$/,"").split(".").reverse().join(".");return new t(s)}toHex(){return this.parsedAddress.map(e=>de.stringToPaddedHex(e)).join(":")}toArray(){return this.parsedAddress.map(e=>parseInt(e,10))}toGroup6(){let e=[],r;for(r=0;r<F.GROUPS;r+=2)e.push(`${de.stringToPaddedHex(this.parsedAddress[r])}${de.stringToPaddedHex(this.parsedAddress[r+1])}`);return e.join(":")}bigInt(){return BigInt(`0x${this.parsedAddress.map(e=>de.stringToPaddedHex(e)).join("")}`)}_startAddress(){return BigInt(`0b${this.mask()+"0".repeat(F.BITS-this.subnetMask)}`)}startAddress(){return t.fromBigInt(this._startAddress())}startAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._startAddress()+e)}_endAddress(){return BigInt(`0b${this.mask()+"1".repeat(F.BITS-this.subnetMask)}`)}endAddress(){return t.fromBigInt(this._endAddress())}endAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._endAddress()-e)}static fromBigInt(e){return t.fromHex(e.toString(16))}mask(e){return e===void 0&&(e=this.subnetMask),this.getBitsBase2(0,e)}getBitsBase2(e,r){return this.binaryZeroPad().slice(e,r)}reverseForm(e){e||(e={});let r=this.correctForm().split(".").reverse().join(".");return e.omitSuffix?r:`${r}.in-addr.arpa.`}isMulticast(){return this.isInSubnet(new t("224.0.0.0/4"))}binaryZeroPad(){return this.bigInt().toString(2).padStart(F.BITS,"0")}groupForV6(){let e=this.parsedAddress;return this.address.replace(F.RE_ADDRESS,`<span class="hover-group group-v4 group-6">${e.slice(0,2).join(".")}</span>.<span class="hover-group group-v4 group-7">${e.slice(2,4).join(".")}</span>`)}};q.Address4=qt});var Ut=G(T=>{"use strict";Object.defineProperty(T,"__esModule",{value:!0});T.RE_URL_WITH_PORT=T.RE_URL=T.RE_ZONE_STRING=T.RE_SUBNET_STRING=T.RE_BAD_ADDRESS=T.RE_BAD_CHARACTERS=T.TYPES=T.SCOPES=T.GROUPS=T.BITS=void 0;T.BITS=128;T.GROUPS=8;T.SCOPES={0:"Reserved",1:"Interface local",2:"Link local",4:"Admin local",5:"Site local",8:"Organization local",14:"Global",15:"Reserved"};T.TYPES={"ff01::1/128":"Multicast (All nodes on this interface)","ff01::2/128":"Multicast (All routers on this interface)","ff02::1/128":"Multicast (All nodes on this link)","ff02::2/128":"Multicast (All routers on this link)","ff05::2/128":"Multicast (All routers in this site)","ff02::5/128":"Multicast (OSPFv3 AllSPF routers)","ff02::6/128":"Multicast (OSPFv3 AllDR routers)","ff02::9/128":"Multicast (RIP routers)","ff02::a/128":"Multicast (EIGRP routers)","ff02::d/128":"Multicast (PIM routers)","ff02::16/128":"Multicast (MLDv2 reports)","ff01::fb/128":"Multicast (mDNSv6)","ff02::fb/128":"Multicast (mDNSv6)","ff05::fb/128":"Multicast (mDNSv6)","ff02::1:2/128":"Multicast (All DHCP servers and relay agents on this link)","ff05::1:2/128":"Multicast (All DHCP servers and relay agents in this site)","ff02::1:3/128":"Multicast (All DHCP servers on this link)","ff05::1:3/128":"Multicast (All DHCP servers in this site)","::/128":"Unspecified","::1/128":"Loopback","ff00::/8":"Multicast","fe80::/10":"Link-local unicast"};T.RE_BAD_CHARACTERS=/([^0-9a-f:/%])/gi;T.RE_BAD_ADDRESS=/([0-9a-f]{5,}|:{3,}|[^:]:$|^:[^:]|\/$)/gi;T.RE_SUBNET_STRING=/\/\d{1,3}(?=%|$)/;T.RE_ZONE_STRING=/%.*$/;T.RE_URL=/^\[{0,1}([0-9a-f:]+)\]{0,1}/;T.RE_URL_WITH_PORT=/\[([0-9a-f:]+)\]:([0-9]{1,5})/});var Kt=G(me=>{"use strict";Object.defineProperty(me,"__esModule",{value:!0});me.spanAllZeroes=qr;me.spanAll=mo;me.spanLeadingZeroes=go;me.simpleGroup=fo;function qr(t){return t.replace(/(0+)/g,'<span class="zero">$1</span>')}function mo(t,e=0){return t.split("").map((s,n)=>`<span class="digit value-${s} position-${n+e}">${qr(s)}</span>`).join("")}function Wr(t){return t.replace(/^(0+)/,'<span class="zero">$1</span>')}function go(t){return t.split(":").map(r=>Wr(r)).join(":")}function fo(t,e=0){return t.split(":").map((s,n)=>/group-v4/.test(s)?s:`<span class="hover-group group-${n+e}">${Wr(s)}</span>`)}});var Ur=G(x=>{"use strict";var ho=x&&x.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),yo=x&&x.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Eo=x&&x.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&ho(e,t,r);return yo(e,t),e};Object.defineProperty(x,"__esModule",{value:!0});x.ADDRESS_BOUNDARY=void 0;x.groupPossibilities=Qe;x.padGroup=Je;x.simpleRegularExpression=_o;x.possibleElisions=So;var bo=Eo(Ut());function Qe(t){return`(${t.join("|")})`}function Je(t){return t.length<4?`0{0,${4-t.length}}${t}`:t}x.ADDRESS_BOUNDARY="[^A-Fa-f0-9:]";function _o(t){let e=[];t.forEach((s,n)=>{parseInt(s,16)===0&&e.push(n)});let r=e.map(s=>t.map((n,o)=>{if(o===s){let i=o===0||o===bo.GROUPS-1?":":"";return Qe([Je(n),i])}return Je(n)}).join(":"));return r.push(t.map(Je).join(":")),Qe(r)}function So(t,e,r){let s=e?"":":",n=r?"":":",o=[];!e&&!r&&o.push("::"),e&&r&&o.push(""),(r&&!e||!r&&e)&&o.push(":"),o.push(`${s}(:0{1,4}){1,${t-1}}`),o.push(`(0{1,4}:){1,${t-1}}${n}`),o.push(`(0{1,4}:){${t-1}}0{1,4}`);for(let i=1;i<t-1;i++)for(let a=1;a<t-i;a++)o.push(`(0{1,4}:){${a}}:(0{1,4}:){${t-a-i-1}}0{1,4}`);return Qe(o)}});var Yr=G(W=>{"use strict";var vo=W&&W.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),Ro=W&&W.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),tt=W&&W.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&vo(e,t,r);return Ro(e,t),e};Object.defineProperty(W,"__esModule",{value:!0});W.Address6=void 0;var Kr=tt(Ye()),Gt=tt(Ft()),b=tt(Ut()),Xt=tt(Kt()),ie=Wt(),ae=Ur(),X=Ve(),Ze=Ye();function et(t){if(!t)throw new Error("Assertion failed.")}function To(t){let e=/(\d+)(\d{3})/;for(;e.test(t);)t=t.replace(e,"$1,$2");return t}function Oo(t){return t=t.replace(/^(0{1,})([1-9]+)$/,'<span class="parse-error">$1</span>$2'),t=t.replace(/^(0{1,})(0)$/,'<span class="parse-error">$1</span>$2'),t}function wo(t,e){let r=[],s=[],n;for(n=0;n<t.length;n++)n<e[0]?r.push(t[n]):n>e[1]&&s.push(t[n]);return r.concat(["compact"]).concat(s)}function Gr(t){return parseInt(t,16).toString(16).padStart(4,"0")}function Xr(t){return t&255}var Yt=class t{constructor(e,r){this.addressMinusSuffix="",this.parsedSubnet="",this.subnet="/128",this.subnetMask=128,this.v4=!1,this.zone="",this.isInSubnet=Kr.isInSubnet,this.isCorrect=Kr.isCorrect(b.BITS),r===void 0?this.groups=b.GROUPS:this.groups=r,this.address=e;let s=b.RE_SUBNET_STRING.exec(e);if(s){if(this.parsedSubnet=s[0].replace("/",""),this.subnetMask=parseInt(this.parsedSubnet,10),this.subnet=`/${this.subnetMask}`,Number.isNaN(this.subnetMask)||this.subnetMask<0||this.subnetMask>b.BITS)throw new X.AddressError("Invalid subnet mask.");e=e.replace(b.RE_SUBNET_STRING,"")}else if(/\//.test(e))throw new X.AddressError("Invalid subnet mask.");let n=b.RE_ZONE_STRING.exec(e);n&&(this.zone=n[0],e=e.replace(b.RE_ZONE_STRING,"")),this.addressMinusSuffix=e,this.parsedAddress=this.parse(this.addressMinusSuffix)}static isValid(e){try{return new t(e),!0}catch{return!1}}static fromBigInt(e){let r=e.toString(16).padStart(32,"0"),s=[],n;for(n=0;n<b.GROUPS;n++)s.push(r.slice(n*4,(n+1)*4));return new t(s.join(":"))}static fromURL(e){let r,s=null,n;if(e.indexOf("[")!==-1&&e.indexOf("]:")!==-1){if(n=b.RE_URL_WITH_PORT.exec(e),n===null)return{error:"failed to parse address with port",address:null,port:null};r=n[1],s=n[2]}else if(e.indexOf("/")!==-1){if(e=e.replace(/^[a-z0-9]+:\/\//,""),n=b.RE_URL.exec(e),n===null)return{error:"failed to parse address from URL",address:null,port:null};r=n[1]}else r=e;return s?(s=parseInt(s,10),(s<0||s>65536)&&(s=null)):s=null,{address:new t(r),port:s}}static fromAddress4(e){let r=new ie.Address4(e),s=b.BITS-(Gt.BITS-r.subnetMask);return new t(`::ffff:${r.correctForm()}/${s}`)}static fromArpa(e){let r=e.replace(/(\.ip6\.arpa)?\.$/,""),s=7;if(r.length!==63)throw new X.AddressError("Invalid 'ip6.arpa' form.");let n=r.split(".").reverse();for(let o=s;o>0;o--){let i=o*4;n.splice(i,0,":")}return r=n.join(""),new t(r)}microsoftTranscription(){return`${this.correctForm().replace(/:/g,"-")}.ipv6-literal.net`}mask(e=this.subnetMask){return this.getBitsBase2(0,e)}possibleSubnets(e=128){let r=b.BITS-this.subnetMask,s=Math.abs(e-b.BITS),n=r-s;return n<0?"0":To((BigInt("2")**BigInt(n)).toString(10))}_startAddress(){return BigInt(`0b${this.mask()+"0".repeat(b.BITS-this.subnetMask)}`)}startAddress(){return t.fromBigInt(this._startAddress())}startAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._startAddress()+e)}_endAddress(){return BigInt(`0b${this.mask()+"1".repeat(b.BITS-this.subnetMask)}`)}endAddress(){return t.fromBigInt(this._endAddress())}endAddressExclusive(){let e=BigInt("1");return t.fromBigInt(this._endAddress()-e)}getScope(){let e=b.SCOPES[parseInt(this.getBits(12,16).toString(10),10)];return this.getType()==="Global unicast"&&e!=="Link local"&&(e="Global"),e||"Unknown"}getType(){for(let e of Object.keys(b.TYPES))if(this.isInSubnet(new t(e)))return b.TYPES[e];return"Global unicast"}getBits(e,r){return BigInt(`0b${this.getBitsBase2(e,r)}`)}getBitsBase2(e,r){return this.binaryZeroPad().slice(e,r)}getBitsBase16(e,r){let s=r-e;if(s%4!==0)throw new Error("Length of bits to retrieve must be divisible by four");return this.getBits(e,r).toString(16).padStart(s/4,"0")}getBitsPastSubnet(){return this.getBitsBase2(this.subnetMask,b.BITS)}reverseForm(e){e||(e={});let r=Math.floor(this.subnetMask/4),s=this.canonicalForm().replace(/:/g,"").split("").slice(0,r).reverse().join(".");return r>0?e.omitSuffix?s:`${s}.ip6.arpa.`:e.omitSuffix?"":"ip6.arpa."}correctForm(){let e,r=[],s=0,n=[];for(e=0;e<this.parsedAddress.length;e++){let a=parseInt(this.parsedAddress[e],16);a===0&&s++,a!==0&&s>0&&(s>1&&n.push([e-s,e-1]),s=0)}s>1&&n.push([this.parsedAddress.length-s,this.parsedAddress.length-1]);let o=n.map(a=>a[1]-a[0]+1);if(n.length>0){let a=o.indexOf(Math.max(...o));r=wo(this.parsedAddress,n[a])}else r=this.parsedAddress;for(e=0;e<r.length;e++)r[e]!=="compact"&&(r[e]=parseInt(r[e],16).toString(16));let i=r.join(":");return i=i.replace(/^compact$/,"::"),i=i.replace(/(^compact)|(compact$)/,":"),i=i.replace(/compact/,""),i}binaryZeroPad(){return this.bigInt().toString(2).padStart(b.BITS,"0")}parse4in6(e){let r=e.split(":"),n=r.slice(-1)[0].match(Gt.RE_ADDRESS);if(n){this.parsedAddress4=n[0],this.address4=new ie.Address4(this.parsedAddress4);for(let o=0;o<this.address4.groups;o++)if(/^0[0-9]+/.test(this.address4.parsedAddress[o]))throw new X.AddressError("IPv4 addresses can't have leading zeroes.",e.replace(Gt.RE_ADDRESS,this.address4.parsedAddress.map(Oo).join(".")));this.v4=!0,r[r.length-1]=this.address4.toGroup6(),e=r.join(":")}return e}parse(e){e=this.parse4in6(e);let r=e.match(b.RE_BAD_CHARACTERS);if(r)throw new X.AddressError(`Bad character${r.length>1?"s":""} detected in address: ${r.join("")}`,e.replace(b.RE_BAD_CHARACTERS,'<span class="parse-error">$1</span>'));let s=e.match(b.RE_BAD_ADDRESS);if(s)throw new X.AddressError(`Address failed regex: ${s.join("")}`,e.replace(b.RE_BAD_ADDRESS,'<span class="parse-error">$1</span>'));let n=[],o=e.split("::");if(o.length===2){let i=o[0].split(":"),a=o[1].split(":");i.length===1&&i[0]===""&&(i=[]),a.length===1&&a[0]===""&&(a=[]);let c=this.groups-(i.length+a.length);if(!c)throw new X.AddressError("Error parsing groups");this.elidedGroups=c,this.elisionBegin=i.length,this.elisionEnd=i.length+this.elidedGroups,n=n.concat(i);for(let u=0;u<c;u++)n.push("0");n=n.concat(a)}else if(o.length===1)n=e.split(":"),this.elidedGroups=0;else throw new X.AddressError("Too many :: groups found");if(n=n.map(i=>parseInt(i,16).toString(16)),n.length!==this.groups)throw new X.AddressError("Incorrect number of groups found");return n}canonicalForm(){return this.parsedAddress.map(Gr).join(":")}decimal(){return this.parsedAddress.map(e=>parseInt(e,16).toString(10).padStart(5,"0")).join(":")}bigInt(){return BigInt(`0x${this.parsedAddress.map(Gr).join("")}`)}to4(){let e=this.binaryZeroPad().split("");return ie.Address4.fromHex(BigInt(`0b${e.slice(96,128).join("")}`).toString(16))}to4in6(){let e=this.to4(),s=new t(this.parsedAddress.slice(0,6).join(":"),6).correctForm(),n="";return/:$/.test(s)||(n=":"),s+n+e.address}inspectTeredo(){let e=this.getBitsBase16(0,32),s=(this.getBits(80,96)^BigInt("0xffff")).toString(),n=ie.Address4.fromHex(this.getBitsBase16(32,64)),o=this.getBits(96,128),i=ie.Address4.fromHex((o^BigInt("0xffffffff")).toString(16)),a=this.getBitsBase2(64,80),c=(0,Ze.testBit)(a,15),u=(0,Ze.testBit)(a,14),l=(0,Ze.testBit)(a,8),d=(0,Ze.testBit)(a,9),m=BigInt(`0b${a.slice(2,6)+a.slice(8,16)}`).toString(10);return{prefix:`${e.slice(0,4)}:${e.slice(4,8)}`,server4:n.address,client4:i.address,flags:a,coneNat:c,microsoft:{reserved:u,universalLocal:d,groupIndividual:l,nonce:m},udpPort:s}}inspect6to4(){let e=this.getBitsBase16(0,16),r=ie.Address4.fromHex(this.getBitsBase16(16,48));return{prefix:e.slice(0,4),gateway:r.address}}to6to4(){if(!this.is4())return null;let e=["2002",this.getBitsBase16(96,112),this.getBitsBase16(112,128),"","/16"].join(":");return new t(e)}toByteArray(){let e=this.bigInt().toString(16),s=`${"0".repeat(e.length%2)}${e}`,n=[];for(let o=0,i=s.length;o<i;o+=2)n.push(parseInt(s.substring(o,o+2),16));return n}toUnsignedByteArray(){return this.toByteArray().map(Xr)}static fromByteArray(e){return this.fromUnsignedByteArray(e.map(Xr))}static fromUnsignedByteArray(e){let r=BigInt("256"),s=BigInt("0"),n=BigInt("1");for(let o=e.length-1;o>=0;o--)s+=n*BigInt(e[o].toString(10)),n*=r;return t.fromBigInt(s)}isCanonical(){return this.addressMinusSuffix===this.canonicalForm()}isLinkLocal(){return this.getBitsBase2(0,64)==="1111111010000000000000000000000000000000000000000000000000000000"}isMulticast(){return this.getType()==="Multicast"}is4(){return this.v4}isTeredo(){return this.isInSubnet(new t("2001::/32"))}is6to4(){return this.isInSubnet(new t("2002::/16"))}isLoopback(){return this.getType()==="Loopback"}href(e){return e===void 0?e="":e=`:${e}`,`http://[${this.correctForm()}]${e}/`}link(e){e||(e={}),e.className===void 0&&(e.className=""),e.prefix===void 0&&(e.prefix="/#address="),e.v4===void 0&&(e.v4=!1);let r=this.correctForm;e.v4&&(r=this.to4in6);let s=r.call(this);return e.className?`<a href="${e.prefix}${s}" class="${e.className}">${s}</a>`:`<a href="${e.prefix}${s}">${s}</a>`}group(){if(this.elidedGroups===0)return Xt.simpleGroup(this.address).join(":");et(typeof this.elidedGroups=="number"),et(typeof this.elisionBegin=="number");let e=[],[r,s]=this.address.split("::");r.length?e.push(...Xt.simpleGroup(r)):e.push("");let n=["hover-group"];for(let o=this.elisionBegin;o<this.elisionBegin+this.elidedGroups;o++)n.push(`group-${o}`);return e.push(`<span class="${n.join(" ")}"></span>`),s.length?e.push(...Xt.simpleGroup(s,this.elisionEnd)):e.push(""),this.is4()&&(et(this.address4 instanceof ie.Address4),e.pop(),e.push(this.address4.groupForV6())),e.join(":")}regularExpressionString(e=!1){let r=[],s=new t(this.correctForm());if(s.elidedGroups===0)r.push((0,ae.simpleRegularExpression)(s.parsedAddress));else if(s.elidedGroups===b.GROUPS)r.push((0,ae.possibleElisions)(b.GROUPS));else{let n=s.address.split("::");n[0].length&&r.push((0,ae.simpleRegularExpression)(n[0].split(":"))),et(typeof s.elidedGroups=="number"),r.push((0,ae.possibleElisions)(s.elidedGroups,n[0].length!==0,n[1].length!==0)),n[1].length&&r.push((0,ae.simpleRegularExpression)(n[1].split(":"))),r=[r.join(":")]}return e||(r=["(?=^|",ae.ADDRESS_BOUNDARY,"|[^\\w\\:])(",...r,")(?=[^\\w\\:]|",ae.ADDRESS_BOUNDARY,"|$)"]),r.join("")}regularExpression(e=!1){return new RegExp(this.regularExpressionString(e),"i")}};W.Address6=Yt});var zr=G(j=>{"use strict";var Do=j&&j.__createBinding||(Object.create?(function(t,e,r,s){s===void 0&&(s=r);var n=Object.getOwnPropertyDescriptor(e,r);(!n||("get"in n?!e.__esModule:n.writable||n.configurable))&&(n={enumerable:!0,get:function(){return e[r]}}),Object.defineProperty(t,s,n)}):(function(t,e,r,s){s===void 0&&(s=r),t[s]=e[r]})),Io=j&&j.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:!0,value:e})}):function(t,e){t.default=e}),Co=j&&j.__importStar||function(t){if(t&&t.__esModule)return t;var e={};if(t!=null)for(var r in t)r!=="default"&&Object.prototype.hasOwnProperty.call(t,r)&&Do(e,t,r);return Io(e,t),e};Object.defineProperty(j,"__esModule",{value:!0});j.v6=j.AddressError=j.Address6=j.Address4=void 0;var jo=Wt();Object.defineProperty(j,"Address4",{enumerable:!0,get:function(){return jo.Address4}});var No=Yr();Object.defineProperty(j,"Address6",{enumerable:!0,get:function(){return No.Address6}});var Ao=Ve();Object.defineProperty(j,"AddressError",{enumerable:!0,get:function(){return Ao.AddressError}});var xo=Co(Kt());j.v6={helpers:xo}});var ls={};xr(ls,{getObservationsByIds:()=>ye,getProjectStats:()=>pt,getStaleObservations:()=>ir,getTimeline:()=>Ee,markObservationsStale:()=>ar,searchObservationsFTS:()=>fe,searchObservationsFTSWithRank:()=>vi,searchObservationsLIKE:()=>ut,searchSummariesFiltered:()=>he});import{existsSync as _i,statSync as Si}from"fs";function us(t){return t.replace(/[%_\\]/g,"\\$&")}function ps(t){return(t.length>1e4?t.substring(0,1e4):t).replace(/[""\u0022]/g,"").split(/\s+/).filter(s=>s.length>0).slice(0,100).map(s=>`"${s}"`).join(" ")}function fe(t,e,r={}){let s=r.limit||50;try{let n=ps(e);if(!n)return ut(t,e,r);let o=`
|
|
3
3
|
SELECT o.* FROM observations o
|
|
4
4
|
JOIN observations_fts fts ON o.id = fts.rowid
|
|
5
5
|
WHERE observations_fts MATCH ?
|
|
6
|
-
`,i=[n];return r.project&&(o+=" AND o.project = ?",i.push(r.project)),r.type&&(o+=" AND o.type = ?",i.push(r.type)),r.dateStart&&(o+=" AND o.created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND o.created_at_epoch <= ?",i.push(r.dateEnd)),o+=` ORDER BY bm25(observations_fts, ${
|
|
7
|
-
SELECT o.*, bm25(observations_fts, ${
|
|
6
|
+
`,i=[n];return r.project&&(o+=" AND o.project = ?",i.push(r.project)),r.type&&(o+=" AND o.type = ?",i.push(r.type)),r.dateStart&&(o+=" AND o.created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND o.created_at_epoch <= ?",i.push(r.dateEnd)),o+=` ORDER BY bm25(observations_fts, ${or}) LIMIT ?`,i.push(s),t.query(o).all(...i)}catch{return ut(t,e,r)}}function vi(t,e,r={}){let s=r.limit||50;try{let n=ps(e);if(!n)return[];let o=`
|
|
7
|
+
SELECT o.*, bm25(observations_fts, ${or}) as fts5_rank FROM observations o
|
|
8
8
|
JOIN observations_fts fts ON o.id = fts.rowid
|
|
9
9
|
WHERE observations_fts MATCH ?
|
|
10
|
-
`,i=[n];return r.project&&(o+=" AND o.project = ?",i.push(r.project)),r.type&&(o+=" AND o.type = ?",i.push(r.type)),r.dateStart&&(o+=" AND o.created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND o.created_at_epoch <= ?",i.push(r.dateEnd)),o+=` ORDER BY bm25(observations_fts, ${
|
|
10
|
+
`,i=[n];return r.project&&(o+=" AND o.project = ?",i.push(r.project)),r.type&&(o+=" AND o.type = ?",i.push(r.type)),r.dateStart&&(o+=" AND o.created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND o.created_at_epoch <= ?",i.push(r.dateEnd)),o+=` ORDER BY bm25(observations_fts, ${or}) LIMIT ?`,i.push(s),t.query(o).all(...i)}catch{return[]}}function ut(t,e,r={}){let s=r.limit||50,n=`%${us(e)}%`,o=`
|
|
11
11
|
SELECT * FROM observations
|
|
12
12
|
WHERE (title LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\' OR narrative LIKE ? ESCAPE '\\' OR concepts LIKE ? ESCAPE '\\')
|
|
13
|
-
`,i=[n,n,n,n];return r.project&&(o+=" AND project = ?",i.push(r.project)),r.type&&(o+=" AND type = ?",i.push(r.type)),r.dateStart&&(o+=" AND created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND created_at_epoch <= ?",i.push(r.dateEnd)),o+=" ORDER BY created_at_epoch DESC LIMIT ?",i.push(s),t.query(o).all(...i)}function
|
|
13
|
+
`,i=[n,n,n,n];return r.project&&(o+=" AND project = ?",i.push(r.project)),r.type&&(o+=" AND type = ?",i.push(r.type)),r.dateStart&&(o+=" AND created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND created_at_epoch <= ?",i.push(r.dateEnd)),o+=" ORDER BY created_at_epoch DESC, id DESC LIMIT ?",i.push(s),t.query(o).all(...i)}function he(t,e,r={}){let s=r.limit||20,n=`%${us(e)}%`,o=`
|
|
14
14
|
SELECT * FROM summaries
|
|
15
15
|
WHERE (request LIKE ? ESCAPE '\\' OR learned LIKE ? ESCAPE '\\' OR completed LIKE ? ESCAPE '\\' OR notes LIKE ? ESCAPE '\\' OR next_steps LIKE ? ESCAPE '\\')
|
|
16
|
-
`,i=[n,n,n,n,n];return r.project&&(o+=" AND project = ?",i.push(r.project)),r.dateStart&&(o+=" AND created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND created_at_epoch <= ?",i.push(r.dateEnd)),o+=" ORDER BY created_at_epoch DESC LIMIT ?",i.push(s),t.query(o).all(...i)}function
|
|
16
|
+
`,i=[n,n,n,n,n];return r.project&&(o+=" AND project = ?",i.push(r.project)),r.dateStart&&(o+=" AND created_at_epoch >= ?",i.push(r.dateStart)),r.dateEnd&&(o+=" AND created_at_epoch <= ?",i.push(r.dateEnd)),o+=" ORDER BY created_at_epoch DESC, id DESC LIMIT ?",i.push(s),t.query(o).all(...i)}function ye(t,e){if(!Array.isArray(e)||e.length===0)return[];let r=e.filter(i=>typeof i=="number"&&Number.isInteger(i)&&i>0).slice(0,500);if(r.length===0)return[];let n=`SELECT * FROM observations WHERE id IN (${r.map(()=>"?").join(",")}) ORDER BY created_at_epoch DESC, id DESC`;return t.query(n).all(...r)}function Ee(t,e,r=5,s=5){let o=t.query("SELECT created_at_epoch FROM observations WHERE id = ?").get(e);if(!o)return[];let i=o.created_at_epoch,c=t.query(`
|
|
17
17
|
SELECT id, 'observation' as type, title, text as content, project, created_at, created_at_epoch
|
|
18
18
|
FROM observations
|
|
19
|
-
WHERE created_at_epoch < ?
|
|
20
|
-
ORDER BY created_at_epoch DESC
|
|
19
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
20
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
21
21
|
LIMIT ?
|
|
22
|
-
`).all(i,r).reverse(),
|
|
22
|
+
`).all(i,i,e,r).reverse(),l=t.query(`
|
|
23
23
|
SELECT id, 'observation' as type, title, text as content, project, created_at, created_at_epoch
|
|
24
24
|
FROM observations WHERE id = ?
|
|
25
25
|
`).all(e),m=t.query(`
|
|
26
26
|
SELECT id, 'observation' as type, title, text as content, project, created_at, created_at_epoch
|
|
27
27
|
FROM observations
|
|
28
|
-
WHERE created_at_epoch > ?
|
|
29
|
-
ORDER BY created_at_epoch ASC
|
|
28
|
+
WHERE (created_at_epoch > ? OR (created_at_epoch = ? AND id > ?))
|
|
29
|
+
ORDER BY created_at_epoch ASC, id ASC
|
|
30
30
|
LIMIT ?
|
|
31
|
-
`).all(i,s);return[...c,...
|
|
31
|
+
`).all(i,i,e,s);return[...c,...l,...m]}function pt(t,e){let s=t.query(`
|
|
32
32
|
WITH
|
|
33
33
|
obs_stats AS (
|
|
34
34
|
SELECT
|
|
@@ -50,35 +50,35 @@ var Jr=Object.create;var Ae=Object.defineProperty;var Qr=Object.getOwnPropertyDe
|
|
|
50
50
|
ses_count.count as sessions,
|
|
51
51
|
prm_count.count as prompts
|
|
52
52
|
FROM obs_stats, sum_count, ses_count, prm_count
|
|
53
|
-
`).get(e,e,e,e),n=s?.discovery_tokens||0,o=s?.read_tokens||0,i=Math.max(0,n-o);return{observations:s?.observations||0,summaries:s?.summaries||0,sessions:s?.sessions||0,prompts:s?.prompts||0,tokenEconomics:{discoveryTokens:n,readTokens:o,savings:i}}}function
|
|
53
|
+
`).get(e,e,e,e),n=s?.discovery_tokens||0,o=s?.read_tokens||0,i=Math.max(0,n-o);return{observations:s?.observations||0,summaries:s?.summaries||0,sessions:s?.sessions||0,prompts:s?.prompts||0,tokenEconomics:{discoveryTokens:n,readTokens:o,savings:i}}}function ir(t,e){let r=t.query(`
|
|
54
54
|
SELECT * FROM observations
|
|
55
55
|
WHERE project = ? AND files_modified IS NOT NULL AND files_modified != ''
|
|
56
|
-
ORDER BY created_at_epoch DESC
|
|
56
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
57
57
|
LIMIT 500
|
|
58
|
-
`).all(e),s=[];for(let n of r){if(!n.files_modified)continue;let o=n.files_modified.split(",").map(a=>a.trim()).filter(Boolean),i=!1;for(let a of o)try{if(!
|
|
59
|
-
(memory_session_id, project, type, title, subtitle, text, narrative, facts, concepts, files_read, files_modified, prompt_number, created_at, created_at_epoch, content_hash, discovery_tokens)
|
|
60
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e,r,s,
|
|
58
|
+
`).all(e),s=[];for(let n of r){if(!n.files_modified)continue;let o=n.files_modified.split(",").map(a=>a.trim()).filter(Boolean),i=!1;for(let a of o)try{if(!_i(a))continue;if(Si(a).mtimeMs>n.created_at_epoch){i=!0;break}}catch{}i&&s.push(n)}return s}function ar(t,e,r){if(!Array.isArray(e)||e.length===0)return;let s=e.filter(o=>typeof o=="number"&&Number.isInteger(o)&&o>0).slice(0,500);if(s.length===0)return;let n=s.map(()=>"?").join(",");t.run(`UPDATE observations SET is_stale = ? WHERE id IN (${n})`,[r?1:0,...s])}var or,J=Be(()=>{"use strict";or="10.0, 1.0, 5.0, 3.0"});function lt(t){if(!t)return t;let e=t;for(let{pattern:r}of Ri)r.lastIndex=0,e=e.replace(r,s=>`${s.substring(0,Math.min(4,s.length))}***REDACTED***`);return e}var Ri,ds=Be(()=>{"use strict";Ri=[{name:"aws-key",pattern:/(?:AKIA|ABIA|ACCA|ASIA)[A-Z0-9]{16}/g},{name:"jwt",pattern:/eyJ[a-zA-Z0-9_-]{10,}\.eyJ[a-zA-Z0-9_-]{10,}\.[a-zA-Z0-9_-]{10,}/g},{name:"api-key",pattern:/(?:api[_-]?key|apikey|api[_-]?secret)\s*[:=]\s*['"]?([a-zA-Z0-9_\-]{20,})['"]?/gi},{name:"credential",pattern:/(?:password|passwd|pwd|secret|token|auth[_-]?token|access[_-]?token|bearer)\s*[:=]\s*['"]?([^\s'"]{8,})['"]?/gi},{name:"url-credential",pattern:/(?:https?:\/\/)([^:]+):([^@]+)@/g},{name:"private-key",pattern:/-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g},{name:"github-token",pattern:/gh[pousr]_[a-zA-Z0-9]{36,}/g},{name:"slack-token",pattern:/xox[bpoas]-[a-zA-Z0-9-]{10,}/g},{name:"bearer-header",pattern:/\bBearer\s+([a-zA-Z0-9_\-\.]{20,})/g},{name:"hex-secret",pattern:/(?:key|secret|token|password)\s*[:=]\s*['"]?([0-9a-f]{32,})['"]?/gi}]});function ms(t){let e=new Map,r=[t.title,t.text||"",t.narrative||"",t.concepts||""].join(" ").toLowerCase(),s=[t.filesModified||"",t.filesRead||""].join(",");for(let i of Ti){let a=0;for(let c of i.keywords)r.includes(c.toLowerCase())&&(a+=i.weight);if(i.types&&i.types.includes(t.type)&&(a+=i.weight*2),i.filePatterns&&s)for(let c of i.filePatterns)c.test(s)&&(a+=i.weight);a>0&&e.set(i.category,(e.get(i.category)||0)+a)}let n="general",o=0;for(let[i,a]of e)a>o&&(o=a,n=i);return n}var Ti,gs=Be(()=>{"use strict";Ti=[{category:"security",keywords:["security","vulnerability","cve","xss","csrf","injection","sanitize","escape","auth","authentication","authorization","permission","helmet","cors","rate-limit","token","encrypt","decrypt","secret","redact","owasp"],filePatterns:[/security/i,/auth/i,/secrets?\.ts/i],weight:10},{category:"testing",keywords:["test","spec","expect","assert","mock","stub","fixture","coverage","jest","vitest","bun test","unit test","integration test","e2e"],types:["test"],filePatterns:[/\.test\./i,/\.spec\./i,/tests?\//i,/__tests__/i],weight:8},{category:"debugging",keywords:["debug","fix","bug","error","crash","stacktrace","stack trace","exception","breakpoint","investigate","root cause","troubleshoot","diagnose","bisect","regression"],types:["bugfix"],weight:8},{category:"architecture",keywords:["architect","design","pattern","modular","migration","schema","database","api design","abstract","dependency injection","singleton","factory","observer","middleware","pipeline","microservice","monolith"],types:["decision","constraint"],weight:7},{category:"refactoring",keywords:["refactor","rename","extract","inline","move","split","merge","simplify","cleanup","clean up","dead code","consolidate","reorganize","restructure","decouple"],weight:6},{category:"config",keywords:["config","configuration","env","environment","dotenv",".env","settings","tsconfig","eslint","prettier","webpack","vite","esbuild","docker","ci/cd","github actions","deploy","build","bundle","package.json"],filePatterns:[/\.config\./i,/\.env/i,/tsconfig/i,/\.ya?ml/i,/Dockerfile/i,/docker-compose/i],weight:5},{category:"docs",keywords:["document","readme","changelog","jsdoc","comment","explain","guide","tutorial","api doc","openapi","swagger"],types:["docs"],filePatterns:[/\.md$/i,/docs?\//i,/readme/i,/changelog/i],weight:5},{category:"feature-dev",keywords:["feature","implement","add","create","new","endpoint","component","module","service","handler","route","hook","plugin","integration"],types:["feature","file-write"],weight:3}]});var fs={};xr(fs,{consolidateObservations:()=>ur,createObservation:()=>Q,deleteObservation:()=>Di,getObservationsByProject:()=>Z,getObservationsBySession:()=>wi,isDuplicateObservation:()=>dt,searchObservations:()=>cr,updateLastAccessed:()=>Ii});function Oi(t){return t.replace(/[%_\\]/g,"\\$&")}function dt(t,e,r=3e4){if(!e)return!1;let s=Date.now()-r;return!!t.query("SELECT id FROM observations WHERE content_hash = ? AND created_at_epoch > ? LIMIT 1").get(e,s)}function Q(t,e,r,s,n,o,i,a,c,u,l,d,m,g=null,f=0){let h=new Date,E=lt(n),w=i&<(i),v=a&<(a),R=ms({type:s,title:E,text:w,narrative:v,concepts:u,filesModified:d,filesRead:l}),ne=t.run(`INSERT INTO observations
|
|
59
|
+
(memory_session_id, project, type, title, subtitle, text, narrative, facts, concepts, files_read, files_modified, prompt_number, created_at, created_at_epoch, content_hash, discovery_tokens, auto_category)
|
|
60
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e,r,s,E,o,w,v,c,u,l,d,m,h.toISOString(),h.getTime(),g,f,R]);return Number(ne.lastInsertRowid)}function wi(t,e){return t.query("SELECT * FROM observations WHERE memory_session_id = ? ORDER BY prompt_number ASC").all(e)}function Z(t,e,r=100){return t.query("SELECT * FROM observations WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?").all(e,r)}function cr(t,e,r){let s=r?`SELECT * FROM observations
|
|
61
61
|
WHERE project = ? AND (title LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\' OR narrative LIKE ? ESCAPE '\\')
|
|
62
|
-
ORDER BY created_at_epoch DESC`:`SELECT * FROM observations
|
|
62
|
+
ORDER BY created_at_epoch DESC, id DESC`:`SELECT * FROM observations
|
|
63
63
|
WHERE title LIKE ? ESCAPE '\\' OR text LIKE ? ESCAPE '\\' OR narrative LIKE ? ESCAPE '\\'
|
|
64
|
-
ORDER BY created_at_epoch DESC`,n=`%${
|
|
64
|
+
ORDER BY created_at_epoch DESC, id DESC`,n=`%${Oi(e)}%`,o=t.query(s);return r?o.all(r,n,n,n):o.all(n,n,n)}function Di(t,e){t.run("DELETE FROM observations WHERE id = ?",[e])}function Ii(t,e){if(!Array.isArray(e)||e.length===0)return;let r=e.filter(o=>typeof o=="number"&&Number.isInteger(o)&&o>0).slice(0,500);if(r.length===0)return;let s=Date.now(),n=r.map(()=>"?").join(",");t.run(`UPDATE observations SET last_accessed_epoch = ? WHERE id IN (${n})`,[s,...r])}function ur(t,e,r={}){let s=r.minGroupSize||3,n=t.query(`
|
|
65
65
|
SELECT type, files_modified, COUNT(*) as cnt, GROUP_CONCAT(id) as ids
|
|
66
66
|
FROM observations
|
|
67
67
|
WHERE project = ? AND files_modified IS NOT NULL AND files_modified != ''
|
|
68
68
|
GROUP BY type, files_modified
|
|
69
69
|
HAVING cnt >= ?
|
|
70
70
|
ORDER BY cnt DESC
|
|
71
|
-
`).all(e,s);if(n.length===0)return{merged:0,removed:0};if(r.dryRun){let i=0,a=0;for(let c of n){let u=c.ids.split(",").map(Number),
|
|
71
|
+
`).all(e,s);if(n.length===0)return{merged:0,removed:0};if(r.dryRun){let i=0,a=0;for(let c of n){let u=c.ids.split(",").map(Number),l=u.map(()=>"?").join(","),d=t.query(`SELECT COUNT(*) as cnt FROM observations WHERE id IN (${l})`).get(...u)?.cnt||0;d>=s&&(i+=1,a+=d-1)}return{merged:i,removed:a}}return t.transaction(()=>{let i=0,a=0;for(let c of n){let u=c.ids.split(",").map(Number),l=u.map(()=>"?").join(","),d=t.query(`SELECT * FROM observations WHERE id IN (${l}) ORDER BY created_at_epoch DESC, id DESC`).all(...u);if(d.length<s)continue;let m=d[0],g=d.slice(1),f=new Set;m.text&&f.add(m.text);for(let v of g)v.text&&!f.has(v.text)&&f.add(v.text);let h=Array.from(f).join(`
|
|
72
72
|
---
|
|
73
|
-
`).substring(0,1e5);t.run("UPDATE observations SET text = ?, title = ? WHERE id = ?",[E,`[consolidated x${l.length}] ${m.title}`,m.id]);let g=f.map(y=>y.id),O=g.map(()=>"?").join(",");t.run(`DELETE FROM observations WHERE id IN (${O})`,g),t.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${O})`,g),i+=1,a+=g.length}return{merged:i,removed:a}})()}var ct=At(()=>{"use strict"});import ht from"express";import io from"cors";var Ct=Symbol("dangerouslyDisableDefaultSrc"),ns=new Set(["none","self","strict-dynamic","report-sample","inline-speculation-rules","unsafe-inline","unsafe-eval","unsafe-hashes","wasm-unsafe-eval"]),Lt=()=>({"default-src":["'self'"],"base-uri":["'self'"],"font-src":["'self'","https:","data:"],"form-action":["'self'"],"frame-ancestors":["'self'"],"img-src":["'self'","data:"],"object-src":["'none'"],"script-src":["'self'"],"script-src-attr":["'none'"],"style-src":["'self'","https:","'unsafe-inline'"],"upgrade-insecure-requests":[]}),os=t=>t.replace(/[A-Z]/g,e=>"-"+e.toLowerCase()),xt=(t,e)=>{if(/;|,/.test(e))throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(t)}`)},jt=(t,e)=>{if(ns.has(e)||e.startsWith("nonce-")||e.startsWith("sha256-")||e.startsWith("sha384-")||e.startsWith("sha512-"))throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(t)}. ${JSON.stringify(e)} should be quoted`)};function is(t){let e=Lt(),{useDefaults:r=!0,directives:s=e}=t,n=new Map,o=new Set,i=new Set;for(let a in s){if(!Object.hasOwn(s,a))continue;if(a.length===0||/[^a-zA-Z0-9-]/.test(a))throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(a)}`);let c=os(a);if(o.has(c))throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(c)}`);o.add(c);let u=s[a],d;if(u===null){if(c==="default-src")throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.");i.add(c);continue}else if(typeof u=="string")d=[u];else if(u)if(u===Ct)if(c==="default-src"){i.add("default-src");continue}else throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(c)} as if it were default-src; simply omit the key`);else d=u;else throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(c)}`);for(let l of d)typeof l=="string"&&(xt(c,l),jt(c,l));n.set(c,d)}if(r&&Object.entries(e).forEach(([a,c])=>{!n.has(a)&&!i.has(a)&&n.set(a,c)}),!n.size)throw new Error("Content-Security-Policy has no directives. Either set some or disable the header");if(!n.has("default-src")&&!i.has("default-src"))throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.");return n}function as(t,e,r){let s=[];for(let[n,o]of r){let i="";for(let a of o)if(typeof a=="function"){let c=a(t,e);jt(n,c),i+=" "+c}else i+=" "+a;i?(xt(n,i),s.push(`${n}${i}`)):s.push(n)}return s.join(";")}var J=function(e={}){let r=e.reportOnly?"Content-Security-Policy-Report-Only":"Content-Security-Policy",s=is(e);return function(o,i,a){let c=as(o,i,s);c instanceof Error?a(c):(i.setHeader(r,c),a())}};J.getDefaultDirectives=Lt;J.dangerouslyDisableDefaultSrc=Ct;var cs=new Set(["require-corp","credentialless","unsafe-none"]);function us({policy:t="require-corp"}){if(cs.has(t))return t;throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(t)} policy`)}function Ne(t={}){let e=us(t);return function(s,n,o){n.setHeader("Cross-Origin-Embedder-Policy",e),o()}}var ls=new Set(["same-origin","same-origin-allow-popups","unsafe-none"]);function ds({policy:t="same-origin"}){if(ls.has(t))return t;throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(t)} policy`)}function Ce(t={}){let e=ds(t);return function(s,n,o){n.setHeader("Cross-Origin-Opener-Policy",e),o()}}var ps=new Set(["same-origin","same-site","cross-origin"]);function ms({policy:t="same-origin"}){if(ps.has(t))return t;throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(t)} policy`)}function Le(t={}){let e=ms(t);return function(s,n,o){n.setHeader("Cross-Origin-Resource-Policy",e),o()}}function xe(){return function(e,r,s){r.setHeader("Origin-Agent-Cluster","?1"),s()}}var fs=new Set(["no-referrer","no-referrer-when-downgrade","same-origin","origin","strict-origin","origin-when-cross-origin","strict-origin-when-cross-origin","unsafe-url",""]);function hs({policy:t=["no-referrer"]}){let e=typeof t=="string"?[t]:t;if(e.length===0)throw new Error("Referrer-Policy received no policy tokens");let r=new Set;return e.forEach(s=>{if(fs.has(s)){if(r.has(s))throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(s)}`)}else throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(s)}`);r.add(s)}),e.join(",")}function je(t={}){let e=hs(t);return function(s,n,o){n.setHeader("Referrer-Policy",e),o()}}var Es=365*24*60*60;function gs(t=Es){if(t>=0&&Number.isFinite(t))return Math.floor(t);throw new Error(`Strict-Transport-Security: ${JSON.stringify(t)} is not a valid value for maxAge. Please choose a positive integer.`)}function bs(t){if("maxage"in t)throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?");if("includeSubdomains"in t)throw new Error('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)');let e=[`max-age=${gs(t.maxAge)}`];return(t.includeSubDomains===void 0||t.includeSubDomains)&&e.push("includeSubDomains"),t.preload&&e.push("preload"),e.join("; ")}function ne(t={}){let e=bs(t);return function(s,n,o){n.setHeader("Strict-Transport-Security",e),o()}}function oe(){return function(e,r,s){r.setHeader("X-Content-Type-Options","nosniff"),s()}}function ie(t={}){let e=t.allow?"on":"off";return function(s,n,o){n.setHeader("X-DNS-Prefetch-Control",e),o()}}function ae(){return function(e,r,s){r.setHeader("X-Download-Options","noopen"),s()}}function _s({action:t="sameorigin"}){let e=typeof t=="string"?t.toUpperCase():t;switch(e){case"SAME-ORIGIN":return"SAMEORIGIN";case"DENY":case"SAMEORIGIN":return e;default:throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(t)}`)}}function ce(t={}){let e=_s(t);return function(s,n,o){n.setHeader("X-Frame-Options",e),o()}}var ys=new Set(["none","master-only","by-content-type","all"]);function Ss({permittedPolicies:t="none"}){if(ys.has(t))return t;throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(t)}`)}function ue(t={}){let e=Ss(t);return function(s,n,o){n.setHeader("X-Permitted-Cross-Domain-Policies",e),o()}}function le(){return function(e,r,s){r.removeHeader("X-Powered-By"),s()}}function de(){return function(e,r,s){r.setHeader("X-XSS-Protection","0"),s()}}function Rs(t){let e=[];switch(t.contentSecurityPolicy){case void 0:case!0:e.push(J());break;case!1:break;default:e.push(J(t.contentSecurityPolicy));break}switch(t.crossOriginEmbedderPolicy){case void 0:case!1:break;case!0:e.push(Ne());break;default:e.push(Ne(t.crossOriginEmbedderPolicy));break}switch(t.crossOriginOpenerPolicy){case void 0:case!0:e.push(Ce());break;case!1:break;default:e.push(Ce(t.crossOriginOpenerPolicy));break}switch(t.crossOriginResourcePolicy){case void 0:case!0:e.push(Le());break;case!1:break;default:e.push(Le(t.crossOriginResourcePolicy));break}switch(t.originAgentCluster){case void 0:case!0:e.push(xe());break;case!1:break;default:console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning."),e.push(xe());break}switch(t.referrerPolicy){case void 0:case!0:e.push(je());break;case!1:break;default:e.push(je(t.referrerPolicy));break}if("strictTransportSecurity"in t&&"hsts"in t)throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.");let r=t.strictTransportSecurity??t.hsts;switch(r){case void 0:case!0:e.push(ne());break;case!1:break;default:e.push(ne(r));break}if("xContentTypeOptions"in t&&"noSniff"in t)throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.");switch(t.xContentTypeOptions??t.noSniff){case void 0:case!0:e.push(oe());break;case!1:break;default:console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning."),e.push(oe());break}if("xDnsPrefetchControl"in t&&"dnsPrefetchControl"in t)throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.");let n=t.xDnsPrefetchControl??t.dnsPrefetchControl;switch(n){case void 0:case!0:e.push(ie());break;case!1:break;default:e.push(ie(n));break}if("xDownloadOptions"in t&&"ieNoOpen"in t)throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.");switch(t.xDownloadOptions??t.ieNoOpen){case void 0:case!0:e.push(ae());break;case!1:break;default:console.warn("X-Download-Options does not take options. Remove the property to silence this warning."),e.push(ae());break}if("xFrameOptions"in t&&"frameguard"in t)throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.");let i=t.xFrameOptions??t.frameguard;switch(i){case void 0:case!0:e.push(ce());break;case!1:break;default:e.push(ce(i));break}if("xPermittedCrossDomainPolicies"in t&&"permittedCrossDomainPolicies"in t)throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.");let a=t.xPermittedCrossDomainPolicies??t.permittedCrossDomainPolicies;switch(a){case void 0:case!0:e.push(ue());break;case!1:break;default:e.push(ue(a));break}if("xPoweredBy"in t&&"hidePoweredBy"in t)throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.");switch(t.xPoweredBy??t.hidePoweredBy){case void 0:case!0:e.push(le());break;case!1:break;default:console.warn("X-Powered-By does not take options. Remove the property to silence this warning."),e.push(le());break}if("xXssProtection"in t&&"xssFilter"in t)throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.");switch(t.xXssProtection??t.xssFilter){case void 0:case!0:e.push(de());break;case!1:break;default:console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning."),e.push(de());break}return e}var Mt=Object.assign(function(e={}){if(e.constructor?.name==="IncomingMessage")throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.");let r=Rs(e);return function(n,o,i){let a=0;(function c(u){if(u){i(u);return}let d=r[a];d?(a++,d(n,o,c)):i()})()}},{contentSecurityPolicy:J,crossOriginEmbedderPolicy:Ne,crossOriginOpenerPolicy:Ce,crossOriginResourcePolicy:Le,originAgentCluster:xe,referrerPolicy:je,strictTransportSecurity:ne,xContentTypeOptions:oe,xDnsPrefetchControl:ie,xDownloadOptions:ae,xFrameOptions:ce,xPermittedCrossDomainPolicies:ue,xPoweredBy:le,xXssProtection:de,dnsPrefetchControl:ie,xssFilter:de,permittedCrossDomainPolicies:ue,ieNoOpen:ae,noSniff:oe,frameguard:ce,hidePoweredBy:le,hsts:ne});var zt=ss(Xt(),1);import{isIPv6 as zs}from"node:net";import{isIPv6 as Zs}from"node:net";import{Buffer as en}from"node:buffer";import{createHash as tn}from"node:crypto";import{isIP as ln}from"node:net";function Js(t,e=56){return e&&zs(t)?`${new zt.Address6(`${t}/${e}`).startAddress().correctForm()}/${e}`:t}var Qs=class{constructor(t){this.validations=t,this.previous=new Map,this.current=new Map,this.localKeys=!0}init(t){this.windowMs=t.windowMs,this.validations?.windowMs(this.windowMs),this.interval&&clearInterval(this.interval),this.interval=setInterval(()=>{this.clearExpired()},this.windowMs),this.interval.unref?.()}async get(t){return this.current.get(t)??this.previous.get(t)}async increment(t){let e=this.getClient(t),r=Date.now();return e.resetTime.getTime()<=r&&this.resetClient(e,r),e.totalHits++,e}async decrement(t){let e=this.getClient(t);e.totalHits>0&&e.totalHits--}async resetKey(t){this.current.delete(t),this.previous.delete(t)}async resetAll(){this.current.clear(),this.previous.clear()}shutdown(){clearInterval(this.interval),this.resetAll()}resetClient(t,e=Date.now()){return t.totalHits=0,t.resetTime.setTime(e+this.windowMs),t}getClient(t){if(this.current.has(t))return this.current.get(t);let e;return this.previous.has(t)?(e=this.previous.get(t),this.previous.delete(t)):(e={totalHits:0,resetTime:new Date},this.resetClient(e)),this.current.set(t,e),e}clearExpired(){this.previous=this.current,this.current=new Map}},Kt=["draft-6","draft-7","draft-8"],Se=(t,e)=>{let r;if(e){let s=Math.ceil((e.getTime()-Date.now())/1e3);r=Math.max(0,s)}else r=Math.ceil(t/1e3);return r},rn=t=>{let e=tn("sha256");e.update(t);let r=e.digest("hex").slice(0,12);return en.from(r).toString("base64")},sn=(t,e)=>{t.headersSent||(t.setHeader("X-RateLimit-Limit",e.limit.toString()),t.setHeader("X-RateLimit-Remaining",e.remaining.toString()),e.resetTime instanceof Date&&(t.setHeader("Date",new Date().toUTCString()),t.setHeader("X-RateLimit-Reset",Math.ceil(e.resetTime.getTime()/1e3).toString())))},nn=(t,e,r)=>{if(t.headersSent)return;let s=Math.ceil(r/1e3),n=Se(r,e.resetTime);t.setHeader("RateLimit-Policy",`${e.limit};w=${s}`),t.setHeader("RateLimit-Limit",e.limit.toString()),t.setHeader("RateLimit-Remaining",e.remaining.toString()),typeof n=="number"&&t.setHeader("RateLimit-Reset",n.toString())},on=(t,e,r)=>{if(t.headersSent)return;let s=Math.ceil(r/1e3),n=Se(r,e.resetTime);t.setHeader("RateLimit-Policy",`${e.limit};w=${s}`),t.setHeader("RateLimit",`limit=${e.limit}, remaining=${e.remaining}, reset=${n}`)},an=(t,e,r,s,n)=>{if(t.headersSent)return;let o=Math.ceil(r/1e3),i=Se(r,e.resetTime),a=rn(n),c=`r=${e.remaining}; t=${i}`,u=`q=${e.limit}; w=${o}; pk=:${a}:`;t.append("RateLimit",`"${s}"; ${c}`),t.append("RateLimit-Policy",`"${s}"; ${u}`)},cn=(t,e,r)=>{if(t.headersSent)return;let s=Se(r,e.resetTime);t.setHeader("Retry-After",s.toString())},un=t=>{let e={};for(let r of Object.keys(t)){let s=r;t[s]!==void 0&&(e[s]=t[s])}return e},v=class extends Error{constructor(t,e){let r=`https://express-rate-limit.github.io/${t}/`;super(`${e} See ${r} for more information.`),this.name=this.constructor.name,this.code=t,this.help=r}},ye=class extends v{},Yt=new Set,Vt=new WeakMap,dn={enabled:{default:!0},disable(){for(let t of Object.keys(this.enabled))this.enabled[t]=!1},ip(t){if(t===void 0)throw new v("ERR_ERL_UNDEFINED_IP_ADDRESS","An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.");if(!ln(t))throw new v("ERR_ERL_INVALID_IP_ADDRESS",`An invalid 'request.ip' (${t}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`)},trustProxy(t){if(t.app.get("trust proxy")===!0)throw new v("ERR_ERL_PERMISSIVE_TRUST_PROXY","The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.")},xForwardedForHeader(t){if(t.headers["x-forwarded-for"]&&t.app.get("trust proxy")===!1)throw new v("ERR_ERL_UNEXPECTED_X_FORWARDED_FOR","The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.")},forwardedHeader(t){if(t.headers.forwarded&&t.ip===t.socket?.remoteAddress)throw new v("ERR_ERL_FORWARDED_HEADER","The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.")},positiveHits(t){if(typeof t!="number"||t<1||t!==Math.round(t))throw new v("ERR_ERL_INVALID_HITS",`The totalHits value returned from the store must be a positive integer, got ${t}`)},unsharedStore(t){if(Yt.has(t)){let e=t?.localKeys?"":" (with a unique prefix)";throw new v("ERR_ERL_STORE_REUSE",`A Store instance must not be shared across multiple rate limiters. Create a new instance of ${t.constructor.name}${e} for each limiter instead.`)}Yt.add(t)},singleCount(t,e,r){let s=Vt.get(t);s||(s=new Map,Vt.set(t,s));let n=e.localKeys?e:e.constructor.name,o=s.get(n);o||(o=[],s.set(n,o));let i=`${e.prefix??""}${r}`;if(o.includes(i))throw new v("ERR_ERL_DOUBLE_COUNT",`The hit count for ${r} was incremented more than once for a single request.`);o.push(i)},limit(t){if(t===0)throw new ye("WRN_ERL_MAX_ZERO","Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7")},draftPolliHeaders(t){if(t)throw new ye("WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS","The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.")},onLimitReached(t){if(t)throw new ye("WRN_ERL_DEPRECATED_ON_LIMIT_REACHED","The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.")},headersDraftVersion(t){if(typeof t!="string"||!Kt.includes(t)){let e=Kt.join(", ");throw new v("ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",`standardHeaders: only the following versions of the IETF draft specification are supported: ${e}.`)}},headersResetTime(t){if(!t)throw new v("ERR_ERL_HEADERS_NO_RESET","standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.")},knownOptions(t){if(!t)return;let r=Object.keys({windowMs:!0,limit:!0,message:!0,statusCode:!0,legacyHeaders:!0,standardHeaders:!0,identifier:!0,requestPropertyName:!0,skipFailedRequests:!0,skipSuccessfulRequests:!0,keyGenerator:!0,ipv6Subnet:!0,handler:!0,skip:!0,requestWasSuccessful:!0,store:!0,validate:!0,headers:!0,max:!0,passOnStoreError:!0}).concat("draft_polli_ratelimit_headers","delayAfter","delayMs","maxDelayMs");for(let s of Object.keys(t))if(!r.includes(s))throw new v("ERR_ERL_UNKNOWN_OPTION",`Unexpected configuration option: ${s}`)},validationsConfig(){let t=Object.keys(this).filter(e=>!["enabled","disable"].includes(e));t.push("default");for(let e of Object.keys(this.enabled))if(!t.includes(e))throw new v("ERR_ERL_UNKNOWN_VALIDATION",`options.validate.${e} is not recognized. Supported validate options are: ${t.join(", ")}.`)},creationStack(t){let{stack:e}=new Error("express-rate-limit validation check (set options.validate.creationStack=false to disable)");if(e?.includes("Layer.handle [as handle_request]")||e?.includes("Layer.handleRequest"))throw t.localKeys?new v("ERR_ERL_CREATED_IN_REQUEST_HANDLER","express-rate-limit instance should be created at app initialization, not when responding to a request."):new v("ERR_ERL_CREATED_IN_REQUEST_HANDLER","express-rate-limit instance should *usually* be created at app initialization, not when responding to a request.")},ipv6Subnet(t){if(t!==!1&&(!Number.isInteger(t)||t<32||t>64))throw new v("ERR_ERL_IPV6_SUBNET",`Unexpected ipv6Subnet value: ${t}. Expected an integer between 32 and 64 (usually 48-64).`)},ipv6SubnetOrKeyGenerator(t){if(t.ipv6Subnet!==void 0&&t.keyGenerator)throw new v("ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR","Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.")},keyGeneratorIpFallback(t){if(!t)return;let e=t.toString();if((e.includes("req.ip")||e.includes("request.ip"))&&!e.includes("ipKeyGenerator"))throw new v("ERR_ERL_KEY_GEN_IPV6","Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.")},windowMs(t){if(typeof t!="number"||Number.isNaN(t)||t<1||t>2147483647)throw new v("ERR_ERL_WINDOW_MS",`Invalid windowMs value: ${t}${typeof t!="number"?` (${typeof t})`:""}, must be a number between 1 and 2147483647 when using the default MemoryStore`)}},pn=t=>{let e;typeof t=="boolean"?e={default:t}:e={default:!0,...t};let r={enabled:e};for(let[s,n]of Object.entries(dn))typeof n=="function"&&(r[s]=(...o)=>{if(e[s]??e.default)try{n.apply(r,o)}catch(i){i instanceof ye?console.warn(i):console.error(i)}});return r},mn=t=>typeof t.incr=="function"&&typeof t.increment!="function",fn=t=>{if(!mn(t))return t;let e=t;class r{async increment(n){return new Promise((o,i)=>{e.incr(n,(a,c,u)=>{a&&i(a),o({totalHits:c,resetTime:u})})})}async decrement(n){return e.decrement(n)}async resetKey(n){return e.resetKey(n)}async resetAll(){if(typeof e.resetAll=="function")return e.resetAll()}}return new r},hn=t=>{let{validations:e,...r}=t;return{...r,validate:e.enabled}},En=t=>{let e=un(t),r=pn(e?.validate??!0);r.validationsConfig(),r.knownOptions(t),r.draftPolliHeaders(e.draft_polli_ratelimit_headers),r.onLimitReached(e.onLimitReached),e.ipv6Subnet!==void 0&&typeof e.ipv6Subnet!="function"&&r.ipv6Subnet(e.ipv6Subnet),r.keyGeneratorIpFallback(e.keyGenerator),r.ipv6SubnetOrKeyGenerator(e);let s=e.standardHeaders??!1;s===!0&&(s="draft-6");let n={windowMs:60*1e3,limit:t.max??5,message:"Too many requests, please try again later.",statusCode:429,legacyHeaders:t.headers??!0,identifier(o,i){let a="",c=n.requestPropertyName,{limit:u}=o[c],d=n.windowMs/1e3,l=n.windowMs/(1e3*60),m=n.windowMs/(1e3*60*60),f=n.windowMs/(1e3*60*60*24);return d<60?a=`${d}sec`:l<60?a=`${l}min`:m<24?a=`${m}hr${m>1?"s":""}`:a=`${f}day${f>1?"s":""}`,`${u}-in-${a}`},requestPropertyName:"rateLimit",skipFailedRequests:!1,skipSuccessfulRequests:!1,requestWasSuccessful:(o,i)=>i.statusCode<400,skip:(o,i)=>!1,async keyGenerator(o,i){r.ip(o.ip),r.trustProxy(o),r.xForwardedForHeader(o),r.forwardedHeader(o);let a=o.ip,c=56;return Zs(a)&&(c=typeof n.ipv6Subnet=="function"?await n.ipv6Subnet(o,i):n.ipv6Subnet,typeof n.ipv6Subnet=="function"&&r.ipv6Subnet(c)),Js(a,c)},ipv6Subnet:56,async handler(o,i,a,c){i.status(n.statusCode);let u=typeof n.message=="function"?await n.message(o,i):n.message;i.writableEnded||i.send(u)},passOnStoreError:!1,...e,standardHeaders:s,store:fn(e.store??new Qs(r)),validations:r};if(typeof n.store.increment!="function"||typeof n.store.decrement!="function"||typeof n.store.resetKey!="function"||n.store.resetAll!==void 0&&typeof n.store.resetAll!="function"||n.store.init!==void 0&&typeof n.store.init!="function")throw new TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");return n},gn=t=>async(e,r,s)=>{try{await Promise.resolve(t(e,r,s)).catch(s)}catch(n){s(n)}},bn=t=>{let e=En(t??{}),r=hn(e);e.validations.creationStack(e.store),e.validations.unsharedStore(e.store),typeof e.store.init=="function"&&e.store.init(r);let s=gn(async(o,i,a)=>{if(await e.skip(o,i)){a();return}let u=o,d=await e.keyGenerator(o,i),l=0,m;try{let g=await e.store.increment(d);l=g.totalHits,m=g.resetTime}catch(g){if(e.passOnStoreError){console.error("express-rate-limit: error from store, allowing request without rate-limiting.",g),a();return}throw g}e.validations.positiveHits(l),e.validations.singleCount(o,e.store,d);let h=await(typeof e.limit=="function"?e.limit(o,i):e.limit);e.validations.limit(h);let E={limit:h,used:l,remaining:Math.max(h-l,0),resetTime:m,key:d};if(Object.defineProperty(E,"current",{configurable:!1,enumerable:!1,value:l}),u[e.requestPropertyName]=E,e.legacyHeaders&&!i.headersSent&&sn(i,E),e.standardHeaders&&!i.headersSent)switch(e.standardHeaders){case"draft-6":{nn(i,E,e.windowMs);break}case"draft-7":{e.validations.headersResetTime(E.resetTime),on(i,E,e.windowMs);break}case"draft-8":{let O=await(typeof e.identifier=="function"?e.identifier(o,i):e.identifier);e.validations.headersResetTime(E.resetTime),an(i,E,e.windowMs,O,d);break}default:{e.validations.headersDraftVersion(e.standardHeaders);break}}if(e.skipFailedRequests||e.skipSuccessfulRequests){let g=!1,O=async()=>{g||(await e.store.decrement(d),g=!0)};e.skipFailedRequests&&(i.on("finish",async()=>{await e.requestWasSuccessful(o,i)||await O()}),i.on("close",async()=>{i.writableEnded||await O()}),i.on("error",async()=>{await O()})),e.skipSuccessfulRequests&&i.on("finish",async()=>{await e.requestWasSuccessful(o,i)&&await O()})}if(e.validations.disable(),l>h){(e.legacyHeaders||e.standardHeaders)&&cn(i,E,e.windowMs),e.handler(o,i,a,r);return}a()}),n=()=>{throw new Error("The current store does not support the get/getKey method")};return s.resetKey=e.store.resetKey.bind(e.store),s.getKey=typeof e.store.get=="function"?e.store.get.bind(e.store):n,s},Re=bn;import ao from"crypto";import{join as Et,dirname as co}from"path";import{existsSync as De,mkdirSync as uo,writeFileSync as Hr,unlinkSync as $r,chmodSync as lo}from"fs";import{fileURLToPath as po}from"url";import _n from"better-sqlite3";var Te=class{_db;_stmtCache=new Map;constructor(e,r){this._db=new _n(e,{readonly:r?.readwrite===!1})}run(e,r){let s=this._db.prepare(e);return r?s.run(...r):s.run()}query(e){let r=this._stmtCache.get(e);return r||(r=new We(this._db,e),this._stmtCache.set(e,r)),r}transaction(e){return this._db.transaction(e)}close(){this._stmtCache.clear(),this._db.close()}},We=class{_stmt;constructor(e,r){this._stmt=e.prepare(r)}all(...e){return e.length>0?this._stmt.all(...e):this._stmt.all()}get(...e){return e.length>0?this._stmt.get(...e):this._stmt.get()}run(...e){return e.length>0?this._stmt.run(...e):this._stmt.run()}};import{join as A,dirname as vn,basename as Uo}from"path";import{homedir as Ke}from"os";import{existsSync as tr,mkdirSync as On}from"fs";import{fileURLToPath as wn}from"url";import{appendFileSync as yn,existsSync as Jt,mkdirSync as Sn,readFileSync as Rn}from"fs";import{join as ve}from"path";import{homedir as Tn}from"os";var Ge=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(Ge||{}),Qt=ve(Tn(),".contextkit"),Xe=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=ve(Qt,"logs");Jt(e)||Sn(e,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=ve(e,`kiro-memory-${r}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=ve(Qt,"settings.json");if(Jt(e)){let r=Rn(e,"utf-8"),s=JSON.parse(r),n=(s.KIRO_MEMORY_LOG_LEVEL||s.CONTEXTKIT_LOG_LEVEL||"INFO").toUpperCase();this.level=Ge[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(e,r){return`obs-${e}-${r}`}sessionId(e){return`session-${e}`}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
|
|
74
|
-
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Object.keys(e);return r.length===0?"{}":r.length<=3?JSON.stringify(e):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(e)}formatTimestamp(e){let r=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),c=String(e.getMilliseconds()).padStart(3,"0");return`${r}-${s}-${n} ${o}:${i}:${a}.${c}`}log(e,r,s,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=
|
|
73
|
+
`).substring(0,1e5);t.run("UPDATE observations SET text = ?, title = ? WHERE id = ?",[h,`[consolidated x${d.length}] ${m.title}`,m.id]);let E=g.map(v=>v.id),w=E.map(()=>"?").join(",");t.run(`DELETE FROM observations WHERE id IN (${w})`,E),t.run(`DELETE FROM observation_embeddings WHERE observation_id IN (${w})`,E),i+=1,a+=E.length}return{merged:i,removed:a}})()}var we=Be(()=>{"use strict";ds();gs()});import Nt from"express";import xa from"cors";var kr=Symbol("dangerouslyDisableDefaultSrc"),Hn=new Set(["none","self","strict-dynamic","report-sample","inline-speculation-rules","unsafe-inline","unsafe-eval","unsafe-hashes","wasm-unsafe-eval"]),Lr=()=>({"default-src":["'self'"],"base-uri":["'self'"],"font-src":["'self'","https:","data:"],"form-action":["'self'"],"frame-ancestors":["'self'"],"img-src":["'self'","data:"],"object-src":["'none'"],"script-src":["'self'"],"script-src-attr":["'none'"],"style-src":["'self'","https:","'unsafe-inline'"],"upgrade-insecure-requests":[]}),qn=t=>t.replace(/[A-Z]/g,e=>"-"+e.toLowerCase()),Pr=(t,e)=>{if(/;|,/.test(e))throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(t)}`)},Mr=(t,e)=>{if(Hn.has(e)||e.startsWith("nonce-")||e.startsWith("sha256-")||e.startsWith("sha384-")||e.startsWith("sha512-"))throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(t)}. ${JSON.stringify(e)} should be quoted`)};function Wn(t){let e=Lr(),{useDefaults:r=!0,directives:s=e}=t,n=new Map,o=new Set,i=new Set;for(let a in s){if(!Object.hasOwn(s,a))continue;if(a.length===0||/[^a-zA-Z0-9-]/.test(a))throw new Error(`Content-Security-Policy received an invalid directive name ${JSON.stringify(a)}`);let c=qn(a);if(o.has(c))throw new Error(`Content-Security-Policy received a duplicate directive ${JSON.stringify(c)}`);o.add(c);let u=s[a],l;if(u===null){if(c==="default-src")throw new Error("Content-Security-Policy needs a default-src but it was set to `null`. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.");i.add(c);continue}else if(typeof u=="string")l=[u];else if(u)if(u===kr)if(c==="default-src"){i.add("default-src");continue}else throw new Error(`Content-Security-Policy: tried to disable ${JSON.stringify(c)} as if it were default-src; simply omit the key`);else l=u;else throw new Error(`Content-Security-Policy received an invalid directive value for ${JSON.stringify(c)}`);for(let d of l)typeof d=="string"&&(Pr(c,d),Mr(c,d));n.set(c,l)}if(r&&Object.entries(e).forEach(([a,c])=>{!n.has(a)&&!i.has(a)&&n.set(a,c)}),!n.size)throw new Error("Content-Security-Policy has no directives. Either set some or disable the header");if(!n.has("default-src")&&!i.has("default-src"))throw new Error("Content-Security-Policy needs a default-src but none was provided. If you really want to disable it, set it to `contentSecurityPolicy.dangerouslyDisableDefaultSrc`.");return n}function Un(t,e,r){let s=[];for(let[n,o]of r){let i="";for(let a of o)if(typeof a=="function"){let c=a(t,e);Mr(n,c),i+=" "+c}else i+=" "+a;i?(Pr(n,i),s.push(`${n}${i}`)):s.push(n)}return s.join(";")}var Re=function(e={}){let r=e.reportOnly?"Content-Security-Policy-Report-Only":"Content-Security-Policy",s=Wn(e);return function(o,i,a){let c=Un(o,i,s);c instanceof Error?a(c):(i.setHeader(r,c),a())}};Re.getDefaultDirectives=Lr;Re.dangerouslyDisableDefaultSrc=kr;var Kn=new Set(["require-corp","credentialless","unsafe-none"]);function Gn({policy:t="require-corp"}){if(Kn.has(t))return t;throw new Error(`Cross-Origin-Embedder-Policy does not support the ${JSON.stringify(t)} policy`)}function Lt(t={}){let e=Gn(t);return function(s,n,o){n.setHeader("Cross-Origin-Embedder-Policy",e),o()}}var Xn=new Set(["same-origin","same-origin-allow-popups","unsafe-none"]);function Yn({policy:t="same-origin"}){if(Xn.has(t))return t;throw new Error(`Cross-Origin-Opener-Policy does not support the ${JSON.stringify(t)} policy`)}function Pt(t={}){let e=Yn(t);return function(s,n,o){n.setHeader("Cross-Origin-Opener-Policy",e),o()}}var zn=new Set(["same-origin","same-site","cross-origin"]);function Vn({policy:t="same-origin"}){if(zn.has(t))return t;throw new Error(`Cross-Origin-Resource-Policy does not support the ${JSON.stringify(t)} policy`)}function Mt(t={}){let e=Vn(t);return function(s,n,o){n.setHeader("Cross-Origin-Resource-Policy",e),o()}}function $t(){return function(e,r,s){r.setHeader("Origin-Agent-Cluster","?1"),s()}}var Jn=new Set(["no-referrer","no-referrer-when-downgrade","same-origin","origin","strict-origin","origin-when-cross-origin","strict-origin-when-cross-origin","unsafe-url",""]);function Qn({policy:t=["no-referrer"]}){let e=typeof t=="string"?[t]:t;if(e.length===0)throw new Error("Referrer-Policy received no policy tokens");let r=new Set;return e.forEach(s=>{if(Jn.has(s)){if(r.has(s))throw new Error(`Referrer-Policy received a duplicate policy token ${JSON.stringify(s)}`)}else throw new Error(`Referrer-Policy received an unexpected policy token ${JSON.stringify(s)}`);r.add(s)}),e.join(",")}function Bt(t={}){let e=Qn(t);return function(s,n,o){n.setHeader("Referrer-Policy",e),o()}}var Zn=365*24*60*60;function eo(t=Zn){if(t>=0&&Number.isFinite(t))return Math.floor(t);throw new Error(`Strict-Transport-Security: ${JSON.stringify(t)} is not a valid value for maxAge. Please choose a positive integer.`)}function to(t){if("maxage"in t)throw new Error("Strict-Transport-Security received an unsupported property, `maxage`. Did you mean to pass `maxAge`?");if("includeSubdomains"in t)throw new Error('Strict-Transport-Security middleware should use `includeSubDomains` instead of `includeSubdomains`. (The correct one has an uppercase "D".)');let e=[`max-age=${eo(t.maxAge)}`];return(t.includeSubDomains===void 0||t.includeSubDomains)&&e.push("includeSubDomains"),t.preload&&e.push("preload"),e.join("; ")}function Fe(t={}){let e=to(t);return function(s,n,o){n.setHeader("Strict-Transport-Security",e),o()}}function He(){return function(e,r,s){r.setHeader("X-Content-Type-Options","nosniff"),s()}}function qe(t={}){let e=t.allow?"on":"off";return function(s,n,o){n.setHeader("X-DNS-Prefetch-Control",e),o()}}function We(){return function(e,r,s){r.setHeader("X-Download-Options","noopen"),s()}}function ro({action:t="sameorigin"}){let e=typeof t=="string"?t.toUpperCase():t;switch(e){case"SAME-ORIGIN":return"SAMEORIGIN";case"DENY":case"SAMEORIGIN":return e;default:throw new Error(`X-Frame-Options received an invalid action ${JSON.stringify(t)}`)}}function Ue(t={}){let e=ro(t);return function(s,n,o){n.setHeader("X-Frame-Options",e),o()}}var so=new Set(["none","master-only","by-content-type","all"]);function no({permittedPolicies:t="none"}){if(so.has(t))return t;throw new Error(`X-Permitted-Cross-Domain-Policies does not support ${JSON.stringify(t)}`)}function Ke(t={}){let e=no(t);return function(s,n,o){n.setHeader("X-Permitted-Cross-Domain-Policies",e),o()}}function Ge(){return function(e,r,s){r.removeHeader("X-Powered-By"),s()}}function Xe(){return function(e,r,s){r.setHeader("X-XSS-Protection","0"),s()}}function oo(t){let e=[];switch(t.contentSecurityPolicy){case void 0:case!0:e.push(Re());break;case!1:break;default:e.push(Re(t.contentSecurityPolicy));break}switch(t.crossOriginEmbedderPolicy){case void 0:case!1:break;case!0:e.push(Lt());break;default:e.push(Lt(t.crossOriginEmbedderPolicy));break}switch(t.crossOriginOpenerPolicy){case void 0:case!0:e.push(Pt());break;case!1:break;default:e.push(Pt(t.crossOriginOpenerPolicy));break}switch(t.crossOriginResourcePolicy){case void 0:case!0:e.push(Mt());break;case!1:break;default:e.push(Mt(t.crossOriginResourcePolicy));break}switch(t.originAgentCluster){case void 0:case!0:e.push($t());break;case!1:break;default:console.warn("Origin-Agent-Cluster does not take options. Remove the property to silence this warning."),e.push($t());break}switch(t.referrerPolicy){case void 0:case!0:e.push(Bt());break;case!1:break;default:e.push(Bt(t.referrerPolicy));break}if("strictTransportSecurity"in t&&"hsts"in t)throw new Error("Strict-Transport-Security option was specified twice. Remove `hsts` to silence this warning.");let r=t.strictTransportSecurity??t.hsts;switch(r){case void 0:case!0:e.push(Fe());break;case!1:break;default:e.push(Fe(r));break}if("xContentTypeOptions"in t&&"noSniff"in t)throw new Error("X-Content-Type-Options option was specified twice. Remove `noSniff` to silence this warning.");switch(t.xContentTypeOptions??t.noSniff){case void 0:case!0:e.push(He());break;case!1:break;default:console.warn("X-Content-Type-Options does not take options. Remove the property to silence this warning."),e.push(He());break}if("xDnsPrefetchControl"in t&&"dnsPrefetchControl"in t)throw new Error("X-DNS-Prefetch-Control option was specified twice. Remove `dnsPrefetchControl` to silence this warning.");let n=t.xDnsPrefetchControl??t.dnsPrefetchControl;switch(n){case void 0:case!0:e.push(qe());break;case!1:break;default:e.push(qe(n));break}if("xDownloadOptions"in t&&"ieNoOpen"in t)throw new Error("X-Download-Options option was specified twice. Remove `ieNoOpen` to silence this warning.");switch(t.xDownloadOptions??t.ieNoOpen){case void 0:case!0:e.push(We());break;case!1:break;default:console.warn("X-Download-Options does not take options. Remove the property to silence this warning."),e.push(We());break}if("xFrameOptions"in t&&"frameguard"in t)throw new Error("X-Frame-Options option was specified twice. Remove `frameguard` to silence this warning.");let i=t.xFrameOptions??t.frameguard;switch(i){case void 0:case!0:e.push(Ue());break;case!1:break;default:e.push(Ue(i));break}if("xPermittedCrossDomainPolicies"in t&&"permittedCrossDomainPolicies"in t)throw new Error("X-Permitted-Cross-Domain-Policies option was specified twice. Remove `permittedCrossDomainPolicies` to silence this warning.");let a=t.xPermittedCrossDomainPolicies??t.permittedCrossDomainPolicies;switch(a){case void 0:case!0:e.push(Ke());break;case!1:break;default:e.push(Ke(a));break}if("xPoweredBy"in t&&"hidePoweredBy"in t)throw new Error("X-Powered-By option was specified twice. Remove `hidePoweredBy` to silence this warning.");switch(t.xPoweredBy??t.hidePoweredBy){case void 0:case!0:e.push(Ge());break;case!1:break;default:console.warn("X-Powered-By does not take options. Remove the property to silence this warning."),e.push(Ge());break}if("xXssProtection"in t&&"xssFilter"in t)throw new Error("X-XSS-Protection option was specified twice. Remove `xssFilter` to silence this warning.");switch(t.xXssProtection??t.xssFilter){case void 0:case!0:e.push(Xe());break;case!1:break;default:console.warn("X-XSS-Protection does not take options. Remove the property to silence this warning."),e.push(Xe());break}return e}var $r=Object.assign(function(e={}){if(e.constructor?.name==="IncomingMessage")throw new Error("It appears you have done something like `app.use(helmet)`, but it should be `app.use(helmet())`.");let r=oo(e);return function(n,o,i){let a=0;(function c(u){if(u){i(u);return}let l=r[a];l?(a++,l(n,o,c)):i()})()}},{contentSecurityPolicy:Re,crossOriginEmbedderPolicy:Lt,crossOriginOpenerPolicy:Pt,crossOriginResourcePolicy:Mt,originAgentCluster:$t,referrerPolicy:Bt,strictTransportSecurity:Fe,xContentTypeOptions:He,xDnsPrefetchControl:qe,xDownloadOptions:We,xFrameOptions:Ue,xPermittedCrossDomainPolicies:Ke,xPoweredBy:Ge,xXssProtection:Xe,dnsPrefetchControl:qe,xssFilter:Xe,permittedCrossDomainPolicies:Ke,ieNoOpen:We,noSniff:He,frameguard:Ue,hidePoweredBy:Ge,hsts:Fe});var Zr=Fn(zr(),1);import{isIPv6 as ko}from"node:net";import{isIPv6 as Mo}from"node:net";import{Buffer as $o}from"node:buffer";import{createHash as Bo}from"node:crypto";import{isIP as Xo}from"node:net";function Lo(t,e=56){return e&&ko(t)?`${new Zr.Address6(`${t}/${e}`).startAddress().correctForm()}/${e}`:t}var Po=class{constructor(t){this.validations=t,this.previous=new Map,this.current=new Map,this.localKeys=!0}init(t){this.windowMs=t.windowMs,this.validations?.windowMs(this.windowMs),this.interval&&clearInterval(this.interval),this.interval=setInterval(()=>{this.clearExpired()},this.windowMs),this.interval.unref?.()}async get(t){return this.current.get(t)??this.previous.get(t)}async increment(t){let e=this.getClient(t),r=Date.now();return e.resetTime.getTime()<=r&&this.resetClient(e,r),e.totalHits++,e}async decrement(t){let e=this.getClient(t);e.totalHits>0&&e.totalHits--}async resetKey(t){this.current.delete(t),this.previous.delete(t)}async resetAll(){this.current.clear(),this.previous.clear()}shutdown(){clearInterval(this.interval),this.resetAll()}resetClient(t,e=Date.now()){return t.totalHits=0,t.resetTime.setTime(e+this.windowMs),t}getClient(t){if(this.current.has(t))return this.current.get(t);let e;return this.previous.has(t)?(e=this.previous.get(t),this.previous.delete(t)):(e={totalHits:0,resetTime:new Date},this.resetClient(e)),this.current.set(t,e),e}clearExpired(){this.previous=this.current,this.current=new Map}},Vr=["draft-6","draft-7","draft-8"],st=(t,e)=>{let r;if(e){let s=Math.ceil((e.getTime()-Date.now())/1e3);r=Math.max(0,s)}else r=Math.ceil(t/1e3);return r},Fo=t=>{let e=Bo("sha256");e.update(t);let r=e.digest("hex").slice(0,12);return $o.from(r).toString("base64")},Ho=(t,e)=>{t.headersSent||(t.setHeader("X-RateLimit-Limit",e.limit.toString()),t.setHeader("X-RateLimit-Remaining",e.remaining.toString()),e.resetTime instanceof Date&&(t.setHeader("Date",new Date().toUTCString()),t.setHeader("X-RateLimit-Reset",Math.ceil(e.resetTime.getTime()/1e3).toString())))},qo=(t,e,r)=>{if(t.headersSent)return;let s=Math.ceil(r/1e3),n=st(r,e.resetTime);t.setHeader("RateLimit-Policy",`${e.limit};w=${s}`),t.setHeader("RateLimit-Limit",e.limit.toString()),t.setHeader("RateLimit-Remaining",e.remaining.toString()),typeof n=="number"&&t.setHeader("RateLimit-Reset",n.toString())},Wo=(t,e,r)=>{if(t.headersSent)return;let s=Math.ceil(r/1e3),n=st(r,e.resetTime);t.setHeader("RateLimit-Policy",`${e.limit};w=${s}`),t.setHeader("RateLimit",`limit=${e.limit}, remaining=${e.remaining}, reset=${n}`)},Uo=(t,e,r,s,n)=>{if(t.headersSent)return;let o=Math.ceil(r/1e3),i=st(r,e.resetTime),a=Fo(n),c=`r=${e.remaining}; t=${i}`,u=`q=${e.limit}; w=${o}; pk=:${a}:`;t.append("RateLimit",`"${s}"; ${c}`),t.append("RateLimit-Policy",`"${s}"; ${u}`)},Ko=(t,e,r)=>{if(t.headersSent)return;let s=st(r,e.resetTime);t.setHeader("Retry-After",s.toString())},Go=t=>{let e={};for(let r of Object.keys(t)){let s=r;t[s]!==void 0&&(e[s]=t[s])}return e},D=class extends Error{constructor(t,e){let r=`https://express-rate-limit.github.io/${t}/`;super(`${e} See ${r} for more information.`),this.name=this.constructor.name,this.code=t,this.help=r}},rt=class extends D{},Jr=new Set,Qr=new WeakMap,Yo={enabled:{default:!0},disable(){for(let t of Object.keys(this.enabled))this.enabled[t]=!1},ip(t){if(t===void 0)throw new D("ERR_ERL_UNDEFINED_IP_ADDRESS","An undefined 'request.ip' was detected. This might indicate a misconfiguration or the connection being destroyed prematurely.");if(!Xo(t))throw new D("ERR_ERL_INVALID_IP_ADDRESS",`An invalid 'request.ip' (${t}) was detected. Consider passing a custom 'keyGenerator' function to the rate limiter.`)},trustProxy(t){if(t.app.get("trust proxy")===!0)throw new D("ERR_ERL_PERMISSIVE_TRUST_PROXY","The Express 'trust proxy' setting is true, which allows anyone to trivially bypass IP-based rate limiting.")},xForwardedForHeader(t){if(t.headers["x-forwarded-for"]&&t.app.get("trust proxy")===!1)throw new D("ERR_ERL_UNEXPECTED_X_FORWARDED_FOR","The 'X-Forwarded-For' header is set but the Express 'trust proxy' setting is false (default). This could indicate a misconfiguration which would prevent express-rate-limit from accurately identifying users.")},forwardedHeader(t){if(t.headers.forwarded&&t.ip===t.socket?.remoteAddress)throw new D("ERR_ERL_FORWARDED_HEADER","The 'Forwarded' header (standardized X-Forwarded-For) is set but currently being ignored. Add a custom keyGenerator to use a value from this header.")},positiveHits(t){if(typeof t!="number"||t<1||t!==Math.round(t))throw new D("ERR_ERL_INVALID_HITS",`The totalHits value returned from the store must be a positive integer, got ${t}`)},unsharedStore(t){if(Jr.has(t)){let e=t?.localKeys?"":" (with a unique prefix)";throw new D("ERR_ERL_STORE_REUSE",`A Store instance must not be shared across multiple rate limiters. Create a new instance of ${t.constructor.name}${e} for each limiter instead.`)}Jr.add(t)},singleCount(t,e,r){let s=Qr.get(t);s||(s=new Map,Qr.set(t,s));let n=e.localKeys?e:e.constructor.name,o=s.get(n);o||(o=[],s.set(n,o));let i=`${e.prefix??""}${r}`;if(o.includes(i))throw new D("ERR_ERL_DOUBLE_COUNT",`The hit count for ${r} was incremented more than once for a single request.`);o.push(i)},limit(t){if(t===0)throw new rt("WRN_ERL_MAX_ZERO","Setting limit or max to 0 disables rate limiting in express-rate-limit v6 and older, but will cause all requests to be blocked in v7")},draftPolliHeaders(t){if(t)throw new rt("WRN_ERL_DEPRECATED_DRAFT_POLLI_HEADERS","The draft_polli_ratelimit_headers configuration option is deprecated and has been removed in express-rate-limit v7, please set standardHeaders: 'draft-6' instead.")},onLimitReached(t){if(t)throw new rt("WRN_ERL_DEPRECATED_ON_LIMIT_REACHED","The onLimitReached configuration option is deprecated and has been removed in express-rate-limit v7.")},headersDraftVersion(t){if(typeof t!="string"||!Vr.includes(t)){let e=Vr.join(", ");throw new D("ERR_ERL_HEADERS_UNSUPPORTED_DRAFT_VERSION",`standardHeaders: only the following versions of the IETF draft specification are supported: ${e}.`)}},headersResetTime(t){if(!t)throw new D("ERR_ERL_HEADERS_NO_RESET","standardHeaders: 'draft-7' requires a 'resetTime', but the store did not provide one. The 'windowMs' value will be used instead, which may cause clients to wait longer than necessary.")},knownOptions(t){if(!t)return;let r=Object.keys({windowMs:!0,limit:!0,message:!0,statusCode:!0,legacyHeaders:!0,standardHeaders:!0,identifier:!0,requestPropertyName:!0,skipFailedRequests:!0,skipSuccessfulRequests:!0,keyGenerator:!0,ipv6Subnet:!0,handler:!0,skip:!0,requestWasSuccessful:!0,store:!0,validate:!0,headers:!0,max:!0,passOnStoreError:!0}).concat("draft_polli_ratelimit_headers","delayAfter","delayMs","maxDelayMs");for(let s of Object.keys(t))if(!r.includes(s))throw new D("ERR_ERL_UNKNOWN_OPTION",`Unexpected configuration option: ${s}`)},validationsConfig(){let t=Object.keys(this).filter(e=>!["enabled","disable"].includes(e));t.push("default");for(let e of Object.keys(this.enabled))if(!t.includes(e))throw new D("ERR_ERL_UNKNOWN_VALIDATION",`options.validate.${e} is not recognized. Supported validate options are: ${t.join(", ")}.`)},creationStack(t){let{stack:e}=new Error("express-rate-limit validation check (set options.validate.creationStack=false to disable)");if(e?.includes("Layer.handle [as handle_request]")||e?.includes("Layer.handleRequest"))throw t.localKeys?new D("ERR_ERL_CREATED_IN_REQUEST_HANDLER","express-rate-limit instance should be created at app initialization, not when responding to a request."):new D("ERR_ERL_CREATED_IN_REQUEST_HANDLER","express-rate-limit instance should *usually* be created at app initialization, not when responding to a request.")},ipv6Subnet(t){if(t!==!1&&(!Number.isInteger(t)||t<32||t>64))throw new D("ERR_ERL_IPV6_SUBNET",`Unexpected ipv6Subnet value: ${t}. Expected an integer between 32 and 64 (usually 48-64).`)},ipv6SubnetOrKeyGenerator(t){if(t.ipv6Subnet!==void 0&&t.keyGenerator)throw new D("ERR_ERL_IPV6SUBNET_OR_KEYGENERATOR","Incompatible options: the 'ipv6Subnet' option is ignored when a custom 'keyGenerator' function is also set.")},keyGeneratorIpFallback(t){if(!t)return;let e=t.toString();if((e.includes("req.ip")||e.includes("request.ip"))&&!e.includes("ipKeyGenerator"))throw new D("ERR_ERL_KEY_GEN_IPV6","Custom keyGenerator appears to use request IP without calling the ipKeyGenerator helper function for IPv6 addresses. This could allow IPv6 users to bypass limits.")},windowMs(t){if(typeof t!="number"||Number.isNaN(t)||t<1||t>2147483647)throw new D("ERR_ERL_WINDOW_MS",`Invalid windowMs value: ${t}${typeof t!="number"?` (${typeof t})`:""}, must be a number between 1 and 2147483647 when using the default MemoryStore`)}},zo=t=>{let e;typeof t=="boolean"?e={default:t}:e={default:!0,...t};let r={enabled:e};for(let[s,n]of Object.entries(Yo))typeof n=="function"&&(r[s]=(...o)=>{if(e[s]??e.default)try{n.apply(r,o)}catch(i){i instanceof rt?console.warn(i):console.error(i)}});return r},Vo=t=>typeof t.incr=="function"&&typeof t.increment!="function",Jo=t=>{if(!Vo(t))return t;let e=t;class r{async increment(n){return new Promise((o,i)=>{e.incr(n,(a,c,u)=>{a&&i(a),o({totalHits:c,resetTime:u})})})}async decrement(n){return e.decrement(n)}async resetKey(n){return e.resetKey(n)}async resetAll(){if(typeof e.resetAll=="function")return e.resetAll()}}return new r},Qo=t=>{let{validations:e,...r}=t;return{...r,validate:e.enabled}},Zo=t=>{let e=Go(t),r=zo(e?.validate??!0);r.validationsConfig(),r.knownOptions(t),r.draftPolliHeaders(e.draft_polli_ratelimit_headers),r.onLimitReached(e.onLimitReached),e.ipv6Subnet!==void 0&&typeof e.ipv6Subnet!="function"&&r.ipv6Subnet(e.ipv6Subnet),r.keyGeneratorIpFallback(e.keyGenerator),r.ipv6SubnetOrKeyGenerator(e);let s=e.standardHeaders??!1;s===!0&&(s="draft-6");let n={windowMs:60*1e3,limit:t.max??5,message:"Too many requests, please try again later.",statusCode:429,legacyHeaders:t.headers??!0,identifier(o,i){let a="",c=n.requestPropertyName,{limit:u}=o[c],l=n.windowMs/1e3,d=n.windowMs/(1e3*60),m=n.windowMs/(1e3*60*60),g=n.windowMs/(1e3*60*60*24);return l<60?a=`${l}sec`:d<60?a=`${d}min`:m<24?a=`${m}hr${m>1?"s":""}`:a=`${g}day${g>1?"s":""}`,`${u}-in-${a}`},requestPropertyName:"rateLimit",skipFailedRequests:!1,skipSuccessfulRequests:!1,requestWasSuccessful:(o,i)=>i.statusCode<400,skip:(o,i)=>!1,async keyGenerator(o,i){r.ip(o.ip),r.trustProxy(o),r.xForwardedForHeader(o),r.forwardedHeader(o);let a=o.ip,c=56;return Mo(a)&&(c=typeof n.ipv6Subnet=="function"?await n.ipv6Subnet(o,i):n.ipv6Subnet,typeof n.ipv6Subnet=="function"&&r.ipv6Subnet(c)),Lo(a,c)},ipv6Subnet:56,async handler(o,i,a,c){i.status(n.statusCode);let u=typeof n.message=="function"?await n.message(o,i):n.message;i.writableEnded||i.send(u)},passOnStoreError:!1,...e,standardHeaders:s,store:Jo(e.store??new Po(r)),validations:r};if(typeof n.store.increment!="function"||typeof n.store.decrement!="function"||typeof n.store.resetKey!="function"||n.store.resetAll!==void 0&&typeof n.store.resetAll!="function"||n.store.init!==void 0&&typeof n.store.init!="function")throw new TypeError("An invalid store was passed. Please ensure that the store is a class that implements the `Store` interface.");return n},ei=t=>async(e,r,s)=>{try{await Promise.resolve(t(e,r,s)).catch(s)}catch(n){s(n)}},ti=t=>{let e=Zo(t??{}),r=Qo(e);e.validations.creationStack(e.store),e.validations.unsharedStore(e.store),typeof e.store.init=="function"&&e.store.init(r);let s=ei(async(o,i,a)=>{if(await e.skip(o,i)){a();return}let u=o,l=await e.keyGenerator(o,i),d=0,m;try{let E=await e.store.increment(l);d=E.totalHits,m=E.resetTime}catch(E){if(e.passOnStoreError){console.error("express-rate-limit: error from store, allowing request without rate-limiting.",E),a();return}throw E}e.validations.positiveHits(d),e.validations.singleCount(o,e.store,l);let f=await(typeof e.limit=="function"?e.limit(o,i):e.limit);e.validations.limit(f);let h={limit:f,used:d,remaining:Math.max(f-d,0),resetTime:m,key:l};if(Object.defineProperty(h,"current",{configurable:!1,enumerable:!1,value:d}),u[e.requestPropertyName]=h,e.legacyHeaders&&!i.headersSent&&Ho(i,h),e.standardHeaders&&!i.headersSent)switch(e.standardHeaders){case"draft-6":{qo(i,h,e.windowMs);break}case"draft-7":{e.validations.headersResetTime(h.resetTime),Wo(i,h,e.windowMs);break}case"draft-8":{let w=await(typeof e.identifier=="function"?e.identifier(o,i):e.identifier);e.validations.headersResetTime(h.resetTime),Uo(i,h,e.windowMs,w,l);break}default:{e.validations.headersDraftVersion(e.standardHeaders);break}}if(e.skipFailedRequests||e.skipSuccessfulRequests){let E=!1,w=async()=>{E||(await e.store.decrement(l),E=!0)};e.skipFailedRequests&&(i.on("finish",async()=>{await e.requestWasSuccessful(o,i)||await w()}),i.on("close",async()=>{i.writableEnded||await w()}),i.on("error",async()=>{await w()})),e.skipSuccessfulRequests&&i.on("finish",async()=>{await e.requestWasSuccessful(o,i)&&await w()})}if(e.validations.disable(),d>f){(e.legacyHeaders||e.standardHeaders)&&Ko(i,h,e.windowMs),e.handler(o,i,a,r);return}a()}),n=()=>{throw new Error("The current store does not support the get/getKey method")};return s.resetKey=e.store.resetKey.bind(e.store),s.getKey=typeof e.store.get=="function"?e.store.get.bind(e.store):n,s},ge=ti;import ka from"crypto";import{join as Sr,dirname as La}from"path";import{existsSync as jt,mkdirSync as Pa,writeFileSync as Rn,unlinkSync as vn,chmodSync as Ma}from"fs";import{fileURLToPath as $a}from"url";import ri from"better-sqlite3";var nt=class{_db;_stmtCache=new Map;constructor(e,r){this._db=new ri(e,{readonly:r?.readwrite===!1})}run(e,r){let s=this._db.prepare(e);return r?s.run(...r):s.run()}query(e){let r=this._stmtCache.get(e);return r||(r=new zt(this._db,e),this._stmtCache.set(e,r)),r}transaction(e){return this._db.transaction(e)}close(){this._stmtCache.clear(),this._db.close()}},zt=class{_stmt;constructor(e,r){this._stmt=e.prepare(r)}all(...e){return e.length>0?this._stmt.all(...e):this._stmt.all()}get(...e){return e.length>0?this._stmt.get(...e):this._stmt.get()}run(...e){return e.length>0?this._stmt.run(...e):this._stmt.run()}};import{join as N,dirname as ai,basename as yc}from"path";import{homedir as Jt}from"os";import{existsSync as ns,mkdirSync as ci}from"fs";import{fileURLToPath as ui}from"url";import{appendFileSync as si,existsSync as es,mkdirSync as ni,readFileSync as oi}from"fs";import{join as ot}from"path";import{homedir as ii}from"os";var it=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(it||{}),ts=ot(ii(),".contextkit"),Vt=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=ot(ts,"logs");es(e)||ni(e,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=ot(e,`kiro-memory-${r}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=ot(ts,"settings.json");if(es(e)){let r=oi(e,"utf-8"),s=JSON.parse(r),n=(s.KIRO_MEMORY_LOG_LEVEL||s.CONTEXTKIT_LOG_LEVEL||"INFO").toUpperCase();this.level=it[n]??1}else this.level=1}catch{this.level=1}return this.level}correlationId(e,r){return`obs-${e}-${r}`}sessionId(e){return`session-${e}`}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
|
|
74
|
+
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Object.keys(e);return r.length===0?"{}":r.length<=3?JSON.stringify(e):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(e)}formatTimestamp(e){let r=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),n=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),c=String(e.getMilliseconds()).padStart(3,"0");return`${r}-${s}-${n} ${o}:${i}:${a}.${c}`}log(e,r,s,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=it[e].padEnd(5),c=r.padEnd(6),u="";n?.correlationId?u=`[${n.correlationId}] `:n?.sessionId&&(u=`[session-${n.sessionId}] `);let l="";o!=null&&(o instanceof Error?l=this.getLevel()===0?`
|
|
75
75
|
${o.message}
|
|
76
|
-
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?
|
|
77
|
-
`+JSON.stringify(o,null,2):
|
|
78
|
-
`,"utf8")}catch(
|
|
76
|
+
${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?l=`
|
|
77
|
+
`+JSON.stringify(o,null,2):l=" "+this.formatData(o));let d="";if(n){let{sessionId:g,memorySessionId:f,correlationId:h,...E}=n;Object.keys(E).length>0&&(d=` {${Object.entries(E).map(([v,R])=>`${v}=${R}`).join(", ")}}`)}let m=`[${i}] [${a}] [${c}] ${u}${s}${d}${l}`;if(this.logFilePath)try{si(this.logFilePath,m+`
|
|
78
|
+
`,"utf8")}catch(g){process.stderr.write(`[LOGGER] Failed to write to log file: ${g}
|
|
79
79
|
`)}else process.stderr.write(m+`
|
|
80
80
|
`)}debug(e,r,s,n){this.log(0,e,r,s,n)}info(e,r,s,n){this.log(1,e,r,s,n)}warn(e,r,s,n){this.log(2,e,r,s,n)}error(e,r,s,n){this.log(3,e,r,s,n)}dataIn(e,r,s,n){this.info(e,`\u2192 ${r}`,s,n)}dataOut(e,r,s,n){this.info(e,`\u2190 ${r}`,s,n)}success(e,r,s,n){this.info(e,`\u2713 ${r}`,s,n)}failure(e,r,s,n){this.error(e,`\u2717 ${r}`,s,n)}timing(e,r,s,n){this.info(e,`\u23F1 ${r}`,n,{duration:`${s}ms`})}happyPathError(e,r,s,n,o=""){let u=((new Error().stack||"").split(`
|
|
81
|
-
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),
|
|
81
|
+
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),l=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",d={...s,location:l};return this.warn(e,`[HAPPY-PATH] ${r}`,d,n),o}},p=new Vt;function pi(){return typeof __dirname<"u"?__dirname:ai(ui(import.meta.url))}var vc=pi(),rs=N(Jt(),".contextkit"),li=ns(rs)?rs:N(Jt(),".kiro-memory"),I=process.env.KIRO_MEMORY_DATA_DIR||process.env.CONTEXTKIT_DATA_DIR||li,Qt=process.env.KIRO_CONFIG_DIR||N(Jt(),".kiro"),Rc=N(Qt,"plugins","kiro-memory"),Tc=N(I,"archives"),Oc=N(I,"logs"),wc=N(I,"trash"),Y=N(I,"backups"),Dc=N(I,"modes"),Ic=N(I,"settings.json"),ss=N(I,"contextkit.db"),ce=ns(ss)?ss:N(I,"kiro-memory.db"),Cc=N(I,"vector-db"),jc=N(I,"observer-sessions"),Nc=N(Qt,"settings.json"),Ac=N(Qt,"context.md");function os(t){ci(t,{recursive:!0})}var di=256*1024*1024,mi=1e4,V=class{_db;get db(){return this._db}constructor(e=ce,r=!1){e!==":memory:"&&os(I),this._db=new nt(e,{create:!0,readwrite:!0}),this._db.run("PRAGMA journal_mode = WAL"),this._db.run("PRAGMA busy_timeout = 5000"),this._db.run("PRAGMA synchronous = NORMAL"),this._db.run("PRAGMA foreign_keys = ON"),this._db.run("PRAGMA temp_store = memory"),this._db.run(`PRAGMA mmap_size = ${di}`),this._db.run(`PRAGMA cache_size = ${mi}`),r||new Zt(this._db).runAllMigrations()}query(e){return this._db.query(e)}run(e,r){return this._db.run(e,r)}withTransaction(e){return this._db.transaction(e)(this._db)}close(){this._db.close()}},Zt=class{db;constructor(e){this.db=e}runAllMigrations(){this.db.run(`
|
|
82
82
|
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
83
83
|
id INTEGER PRIMARY KEY,
|
|
84
84
|
version INTEGER UNIQUE NOT NULL,
|
|
@@ -206,7 +206,40 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?d=`
|
|
|
206
206
|
created_at_epoch INTEGER NOT NULL,
|
|
207
207
|
FOREIGN KEY (session_id) REFERENCES sessions(id)
|
|
208
208
|
)
|
|
209
|
-
`),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_session ON checkpoints(session_id)"),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_project ON checkpoints(project)"),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_epoch ON checkpoints(created_at_epoch)")}},{version:7,up:e=>{e.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_hash ON observations(content_hash)")}},{version:8,up:e=>{e.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),e.run("ALTER TABLE summaries ADD COLUMN discovery_tokens INTEGER DEFAULT 0")}},{version:9,up:e=>{e.run("CREATE INDEX IF NOT EXISTS idx_observations_project_epoch ON observations(project, created_at_epoch DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_project_type ON observations(project, type)"),e.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_epoch ON summaries(project, created_at_epoch DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_prompts_project_epoch ON prompts(project, created_at_epoch DESC)")}}
|
|
209
|
+
`),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_session ON checkpoints(session_id)"),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_project ON checkpoints(project)"),e.run("CREATE INDEX IF NOT EXISTS idx_checkpoints_epoch ON checkpoints(created_at_epoch)")}},{version:7,up:e=>{e.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_hash ON observations(content_hash)")}},{version:8,up:e=>{e.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),e.run("ALTER TABLE summaries ADD COLUMN discovery_tokens INTEGER DEFAULT 0")}},{version:9,up:e=>{e.run("CREATE INDEX IF NOT EXISTS idx_observations_project_epoch ON observations(project, created_at_epoch DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_project_type ON observations(project, type)"),e.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_epoch ON summaries(project, created_at_epoch DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_prompts_project_epoch ON prompts(project, created_at_epoch DESC)")}},{version:10,up:e=>{e.run(`
|
|
210
|
+
CREATE TABLE IF NOT EXISTS job_queue (
|
|
211
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
212
|
+
type TEXT NOT NULL,
|
|
213
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
214
|
+
payload TEXT,
|
|
215
|
+
result TEXT,
|
|
216
|
+
error TEXT,
|
|
217
|
+
retry_count INTEGER DEFAULT 0,
|
|
218
|
+
max_retries INTEGER DEFAULT 3,
|
|
219
|
+
priority INTEGER DEFAULT 0,
|
|
220
|
+
created_at TEXT NOT NULL,
|
|
221
|
+
created_at_epoch INTEGER NOT NULL,
|
|
222
|
+
started_at_epoch INTEGER,
|
|
223
|
+
completed_at_epoch INTEGER
|
|
224
|
+
)
|
|
225
|
+
`),e.run("CREATE INDEX IF NOT EXISTS idx_jobs_status ON job_queue(status)"),e.run("CREATE INDEX IF NOT EXISTS idx_jobs_type ON job_queue(type)"),e.run("CREATE INDEX IF NOT EXISTS idx_jobs_priority ON job_queue(status, priority DESC, created_at_epoch ASC)")}},{version:11,up:e=>{e.run("ALTER TABLE observations ADD COLUMN auto_category TEXT"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_category ON observations(auto_category)")}},{version:12,up:e=>{e.run(`
|
|
226
|
+
CREATE TABLE IF NOT EXISTS github_links (
|
|
227
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
228
|
+
observation_id INTEGER,
|
|
229
|
+
session_id TEXT,
|
|
230
|
+
repo TEXT NOT NULL,
|
|
231
|
+
issue_number INTEGER,
|
|
232
|
+
pr_number INTEGER,
|
|
233
|
+
event_type TEXT NOT NULL,
|
|
234
|
+
action TEXT,
|
|
235
|
+
title TEXT,
|
|
236
|
+
url TEXT,
|
|
237
|
+
author TEXT,
|
|
238
|
+
created_at TEXT NOT NULL,
|
|
239
|
+
created_at_epoch INTEGER NOT NULL,
|
|
240
|
+
FOREIGN KEY (observation_id) REFERENCES observations(id)
|
|
241
|
+
)
|
|
242
|
+
`),e.run("CREATE INDEX IF NOT EXISTS idx_github_links_repo ON github_links(repo)"),e.run("CREATE INDEX IF NOT EXISTS idx_github_links_obs ON github_links(observation_id)"),e.run("CREATE INDEX IF NOT EXISTS idx_github_links_event ON github_links(event_type)"),e.run("CREATE INDEX IF NOT EXISTS idx_github_links_repo_issue ON github_links(repo, issue_number)"),e.run("CREATE INDEX IF NOT EXISTS idx_github_links_repo_pr ON github_links(repo, pr_number)")}},{version:13,up:e=>{e.run("CREATE INDEX IF NOT EXISTS idx_observations_keyset ON observations(created_at_epoch DESC, id DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_observations_project_keyset ON observations(project, created_at_epoch DESC, id DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_summaries_keyset ON summaries(created_at_epoch DESC, id DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_summaries_project_keyset ON summaries(project, created_at_epoch DESC, id DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_prompts_keyset ON prompts(created_at_epoch DESC, id DESC)"),e.run("CREATE INDEX IF NOT EXISTS idx_prompts_project_keyset ON prompts(project, created_at_epoch DESC, id DESC)")}}]}};var er={"all-MiniLM-L6-v2":{modelId:"Xenova/all-MiniLM-L6-v2",dimensions:384},"jina-code-v2":{modelId:"jinaai/jina-embeddings-v2-base-code",dimensions:768},"bge-small-en":{modelId:"BAAI/bge-small-en-v1.5",dimensions:384}},gi=new Set(["all-MiniLM-L6-v2","bge-small-en"]),rr=class{provider=null;model=null;initialized=!1;initializing=null;config;configName;constructor(){let e=process.env.KIRO_MEMORY_EMBEDDING_MODEL||"all-MiniLM-L6-v2";if(this.configName=e,er[e])this.config=er[e];else if(e.includes("/")){let r=parseInt(process.env.KIRO_MEMORY_EMBEDDING_DIMENSIONS||"384",10);this.config={modelId:e,dimensions:isNaN(r)?384:r}}else p.warn("EMBEDDING",`Unknown model name '${e}', falling back to 'all-MiniLM-L6-v2'`),this.configName="all-MiniLM-L6-v2",this.config=er["all-MiniLM-L6-v2"]}async initialize(){if(this.initialized)return this.provider!==null;if(this.initializing)return this.initializing;this.initializing=this._doInitialize();let e=await this.initializing;return this.initializing=null,e}async _doInitialize(){if(gi.has(this.configName))try{let r=await import("fastembed"),s=r.EmbeddingModel||r.default?.EmbeddingModel,n=r.FlagEmbedding||r.default?.FlagEmbedding;if(n&&s)return this.model=await n.init({model:s.BGESmallENV15}),this.provider="fastembed",this.initialized=!0,p.info("EMBEDDING",`Initialized with fastembed (BGE-small-en-v1.5) for model '${this.configName}'`),!0}catch(r){p.debug("EMBEDDING",`fastembed not available: ${r}`)}try{let r=await import("@huggingface/transformers"),s=r.pipeline||r.default?.pipeline;if(s)return this.model=await s("feature-extraction",this.config.modelId,{quantized:!0}),this.provider="transformers",this.initialized=!0,p.info("EMBEDDING",`Initialized with @huggingface/transformers (${this.config.modelId})`),!0}catch(r){p.debug("EMBEDDING",`@huggingface/transformers not available: ${r}`)}return this.provider=null,this.initialized=!0,p.warn("EMBEDDING","No embedding provider available, semantic search disabled"),!1}async embed(e){if(this.initialized||await this.initialize(),!this.provider||!this.model)return null;try{let r=e.substring(0,2e3);if(this.provider==="fastembed")return await this._embedFastembed(r);if(this.provider==="transformers")return await this._embedTransformers(r)}catch(r){p.error("EMBEDDING",`Error generating embedding: ${r}`)}return null}async embedBatch(e){if(this.initialized||await this.initialize(),!this.provider||!this.model)return e.map(()=>null);if(e.length===0)return[];let r=e.map(s=>s.substring(0,2e3));try{if(this.provider==="fastembed")return await this._embedBatchFastembed(r);if(this.provider==="transformers")return await this._embedBatchTransformers(r)}catch(s){p.warn("EMBEDDING",`Batch embedding failed, falling back to serial: ${s}`)}return this._embedBatchSerial(r)}isAvailable(){return this.initialized&&this.provider!==null}getProvider(){return this.provider}getDimensions(){return this.config.dimensions}getModelName(){return this.configName}async _embedBatchFastembed(e){let r=[],s=this.model.embed(e,e.length);for await(let n of s)if(n)for(let o of n)r.push(o instanceof Float32Array?o:new Float32Array(o));for(;r.length<e.length;)r.push(null);return r}async _embedBatchTransformers(e){let r=await this.model(e,{pooling:"mean",normalize:!0});if(!r?.data)return e.map(()=>null);let s=this.getDimensions(),n=r.data instanceof Float32Array?r.data:new Float32Array(r.data),o=[];for(let i=0;i<e.length;i++){let a=i*s;a+s<=n.length?o.push(n.slice(a,a+s)):o.push(null)}return o}async _embedBatchSerial(e){let r=[];for(let s of e)try{let n=await this.embed(s);r.push(n)}catch{r.push(null)}return r}async _embedFastembed(e){let r=this.model.embed([e],1);for await(let s of r)if(s&&s.length>0){let n=s[0];return n instanceof Float32Array?n:new Float32Array(n)}return null}async _embedTransformers(e){let r=await this.model(e,{pooling:"mean",normalize:!0});return r?.data?r.data instanceof Float32Array?r.data:new Float32Array(r.data):null}},tr=null;function L(){return tr||(tr=new rr),tr}var fi=2e3;function hi(t,e){let r=t.length;if(r!==e.length)return 0;let s=0,n=0,o=0;for(let a=0;a<r;a++){let c=t[a],u=e[a];s+=c*u,n+=c*c,o+=u*u}let i=Math.sqrt(n*o);return i===0?0:s/i}function yi(t){return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}function Ei(t){let e=t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength);return new Float32Array(e)}var nr=class{async search(e,r,s={}){let n=s.limit||10,o=s.threshold||.3,i=s.maxCandidates||fi;try{let a=[],c=[];s.project&&(a.push("o.project = ?"),c.push(s.project));let l=`
|
|
210
243
|
SELECT e.observation_id, e.embedding,
|
|
211
244
|
o.title, o.text, o.type, o.project, o.created_at, o.created_at_epoch
|
|
212
245
|
FROM observation_embeddings e
|
|
@@ -214,28 +247,155 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?d=`
|
|
|
214
247
|
${a.length>0?`WHERE ${a.join(" AND ")}`:""}
|
|
215
248
|
ORDER BY o.created_at_epoch DESC
|
|
216
249
|
LIMIT ?
|
|
217
|
-
`;c.push(i);let
|
|
250
|
+
`;c.push(i);let d=e.query(l).all(...c),m=[];for(let g of d){let f=Ei(g.embedding),h=hi(r,f);h>=o&&m.push({id:g.observation_id,observationId:g.observation_id,similarity:h,title:g.title,text:g.text,type:g.type,project:g.project,created_at:g.created_at,created_at_epoch:g.created_at_epoch})}return m.sort((g,f)=>f.similarity-g.similarity),p.debug("VECTOR",`Search: ${d.length} candidates \u2192 ${m.length} above threshold \u2192 ${Math.min(m.length,n)} results`),m.slice(0,n)}catch(a){return p.error("VECTOR",`Vector search error: ${a}`),[]}}async storeEmbedding(e,r,s,n){try{let o=yi(s);e.query(`
|
|
218
251
|
INSERT OR REPLACE INTO observation_embeddings
|
|
219
252
|
(observation_id, embedding, model, dimensions, created_at)
|
|
220
253
|
VALUES (?, ?, ?, ?, ?)
|
|
221
|
-
`).run(r,o,n,s.length,new Date().toISOString()),p.debug("VECTOR",`Embedding saved for observation ${r}`)}catch(o){p.error("VECTOR",`Error saving embedding: ${o}`)}}async backfillEmbeddings(e,r=50){let s
|
|
254
|
+
`).run(r,o,n,s.length,new Date().toISOString()),p.debug("VECTOR",`Embedding saved for observation ${r}`)}catch(o){p.error("VECTOR",`Error saving embedding: ${o}`)}}async backfillEmbeddings(e,r=50){let s=L();if(!await s.initialize())return p.warn("VECTOR","Embedding service not available, backfill skipped"),0;let n=e.query(`
|
|
222
255
|
SELECT o.id, o.title, o.text, o.narrative, o.concepts
|
|
223
256
|
FROM observations o
|
|
224
257
|
LEFT JOIN observation_embeddings e ON e.observation_id = o.id
|
|
225
258
|
WHERE e.observation_id IS NULL
|
|
226
259
|
ORDER BY o.created_at_epoch DESC
|
|
227
260
|
LIMIT ?
|
|
228
|
-
`).all(r);if(n.length===0)return 0;let o=0,i=s.
|
|
261
|
+
`).all(r);if(n.length===0)return 0;let o=0,i=s.getModelName();for(let a of n){let c=[a.title];a.text&&c.push(a.text),a.narrative&&c.push(a.narrative),a.concepts&&c.push(a.concepts);let u=c.join(" ").substring(0,2e3),l=await s.embed(u);l&&(await this.storeEmbedding(e,a.id,l,i),o++)}return p.info("VECTOR",`Backfill completed: ${o}/${n.length} embeddings generated`),o}getStats(e){try{let r=e.query("SELECT COUNT(*) as count FROM observations").get(),s=e.query("SELECT COUNT(*) as count FROM observation_embeddings").get(),n=r?.count||0,o=s?.count||0,i=n>0?Math.round(o/n*100):0;return{total:n,embedded:o,percentage:i}}catch{return{total:0,embedded:0,percentage:0}}}},sr=null;function M(){return sr||(sr=new nr),sr}var is={semantic:.4,fts5:.3,recency:.2,projectMatch:.1},as={semantic:0,fts5:0,recency:.7,projectMatch:.3};function Te(t,e=168){if(!t||t<=0)return 0;let s=Date.now()-t;if(s<=0)return 1;let n=s/(1e3*60*60);return Math.exp(-n*Math.LN2/e)}function cs(t,e){if(e.length===0)return 0;if(e.length===1)return 1;let r=Math.min(...e),s=Math.max(...e);return r===s?1:(s-t)/(s-r)}function Oe(t,e){return!t||!e?0:t.toLowerCase()===e.toLowerCase()?1:0}function at(t,e){return t.semantic*e.semantic+t.fts5*e.fts5+t.recency*e.recency+t.projectMatch*e.projectMatch}var bi={constraint:1.3,decision:1.25,heuristic:1.15,rejected:1.1};function ct(t){return bi[t]??1}var lr=class{embeddingInitialized=!1;async initialize(){try{let e=L();await e.initialize(),this.embeddingInitialized=e.isAvailable(),p.info("SEARCH",`HybridSearch initialized (embedding: ${this.embeddingInitialized?"active":"disabled"})`)}catch(e){p.warn("SEARCH","Embedding initialization failed, using only FTS5",{},e),this.embeddingInitialized=!1}}async search(e,r,s={}){let n=s.limit||10,o=s.weights||is,i=s.project||"",a=new Map;if(this.embeddingInitialized)try{let m=await L().embed(r);if(m){let f=await M().search(e,m,{project:s.project,limit:n*2,threshold:.3});for(let h of f)a.set(String(h.observationId),{id:String(h.observationId),title:h.title,content:h.text||"",type:h.type,project:h.project,created_at:h.created_at,created_at_epoch:h.created_at_epoch,semanticScore:h.similarity,fts5Rank:null,source:"vector"});p.debug("SEARCH",`Vector search: ${f.length} results`)}}catch(d){p.warn("SEARCH","Vector search failed, using only keyword",{},d)}try{let{searchObservationsFTSWithRank:d}=await Promise.resolve().then(()=>(J(),ls)),m=d(e,r,{project:s.project,limit:n*2});for(let g of m){let f=String(g.id),h=a.get(f);h?(h.fts5Rank=g.fts5_rank,h.source="vector"):a.set(f,{id:f,title:g.title,content:g.text||g.narrative||"",type:g.type,project:g.project,created_at:g.created_at,created_at_epoch:g.created_at_epoch,semanticScore:0,fts5Rank:g.fts5_rank,source:"keyword"})}p.debug("SEARCH",`Keyword search: ${m.length} results`)}catch(d){p.error("SEARCH","Keyword search failed",{},d)}if(a.size===0)return[];let c=Array.from(a.values()).filter(d=>d.fts5Rank!==null).map(d=>d.fts5Rank),u=[];for(let d of a.values()){let m={semantic:d.semanticScore,fts5:d.fts5Rank!==null?cs(d.fts5Rank,c):0,recency:Te(d.created_at_epoch),projectMatch:i?Oe(d.project,i):0},g=at(m,o),f=d.semanticScore>0&&d.fts5Rank!==null,E=Math.min(1,g*(f?1.15:1)*ct(d.type));u.push({id:d.id,title:d.title,content:d.content,type:d.type,project:d.project,created_at:d.created_at,created_at_epoch:d.created_at_epoch,score:E,source:f?"hybrid":d.source,signals:m})}u.sort((d,m)=>m.score-d.score);let l=u.slice(0,n);if(l.length>0)try{let{updateLastAccessed:d}=await Promise.resolve().then(()=>(we(),fs)),m=l.map(g=>parseInt(g.id,10)).filter(g=>g>0);m.length>0&&d(e,m)}catch{}return l}},pr=null;function ee(){return pr||(pr=new lr),pr}var Ci=50,De=[];function Ie(){return De}function hs(){return Ci}function ys(t){De.push(t)}function Es(t){let e=De.indexOf(t);e>-1&&De.splice(e,1)}function ji(t,e){let r=`event: ${t}
|
|
229
262
|
data: ${JSON.stringify(e)}
|
|
230
263
|
|
|
231
|
-
`;
|
|
264
|
+
`;De.forEach(s=>{try{s.write(r)}catch(n){p.warn("WORKER","Broadcast failed to client",{},n)}})}var te={data:[],ts:0},bs=6e4;function Ni(){te.ts=0}function _(t,e,r,s){if(!t)return e;let n=parseInt(t,10);return isNaN(n)||n<r||n>s?e:n}function S(t){return typeof t=="string"&&t.length>0&&t.length<=200&&/^[\w\-\.\/@ ]+$/.test(t)&&!t.includes("..")}function $(t,e){return typeof t=="string"&&t.length>0&&t.length<=e}async function Ai(t,e,r,s,n){try{let o=L();if(!o.isAvailable())return;let i=[r];s&&i.push(s),n?.length&&i.push(n.join(", "));let a=i.join(" ").substring(0,2e3),c=await o.embed(a);c&&await M().storeEmbedding(t.db,e,c,o.getProvider()||"unknown")}catch(o){p.debug("WORKER",`Embedding generation failed for obs ${e}: ${o}`)}}function _s(t){return{db:t,broadcast:ji,invalidateProjectsCache:Ni,generateEmbeddingForObservation:(e,r,s,n)=>Ai(t,e,r,s,n)}}var U=["constraint","decision","heuristic","rejected"];var Ce=U,gt=Ce.map(()=>"?").join(", ");function re(t){return t<=0?null:Date.now()-t*864e5}function Ss(){return`AND NOT (
|
|
265
|
+
facts IS NOT NULL AND (
|
|
266
|
+
facts LIKE '%"importance":4%'
|
|
267
|
+
OR facts LIKE '%"importance": 4%'
|
|
268
|
+
OR facts LIKE '%"importance":5%'
|
|
269
|
+
OR facts LIKE '%"importance": 5%'
|
|
270
|
+
)
|
|
271
|
+
)`}function vs(t,e){let r=re(e.observationsMaxAgeDays),s=re(e.summariesMaxAgeDays),n=re(e.promptsMaxAgeDays),o=re(e.knowledgeMaxAgeDays),i=Ss(),a=0;r!==null&&(a=t.query(`SELECT COUNT(*) as c FROM observations
|
|
272
|
+
WHERE created_at_epoch < ?
|
|
273
|
+
AND type NOT IN (${gt})`).get(r,...Ce)?.c??0);let c=0;s!==null&&(c=t.query("SELECT COUNT(*) as c FROM summaries WHERE created_at_epoch < ?").get(s)?.c??0);let u=0;n!==null&&(u=t.query("SELECT COUNT(*) as c FROM prompts WHERE created_at_epoch < ?").get(n)?.c??0);let l=0;o!==null&&(l=t.query(`SELECT COUNT(*) as c FROM observations
|
|
274
|
+
WHERE created_at_epoch < ?
|
|
275
|
+
AND type IN (${gt})
|
|
276
|
+
${i}`).get(o,...Ce)?.c??0);let d=a+c+u+l;return{observations:a,summaries:c,prompts:u,knowledge:l,total:d}}function mt(t,e,r){return t.query(e).get(...r)?.c??0}function ft(t,e){let r=re(e.observationsMaxAgeDays),s=re(e.summariesMaxAgeDays),n=re(e.promptsMaxAgeDays),o=re(e.knowledgeMaxAgeDays),i=Ss(),c=t.transaction(()=>{let l=0,d=0,m=0,g=0;if(r!==null){let f=[r,...Ce],h=`WHERE created_at_epoch < ? AND type NOT IN (${gt})`;l=mt(t,`SELECT COUNT(*) as c FROM observations ${h}`,f),l>0&&(t.run(`DELETE FROM observation_embeddings
|
|
277
|
+
WHERE observation_id IN (
|
|
278
|
+
SELECT id FROM observations ${h}
|
|
279
|
+
)`,f),t.run(`DELETE FROM observations ${h}`,f))}if(s!==null&&(d=mt(t,"SELECT COUNT(*) as c FROM summaries WHERE created_at_epoch < ?",[s]),d>0&&t.run("DELETE FROM summaries WHERE created_at_epoch < ?",[s])),n!==null&&(m=mt(t,"SELECT COUNT(*) as c FROM prompts WHERE created_at_epoch < ?",[n]),m>0&&t.run("DELETE FROM prompts WHERE created_at_epoch < ?",[n])),o!==null){let f=[o,...Ce],h=`WHERE created_at_epoch < ? AND type IN (${gt}) ${i}`;g=mt(t,`SELECT COUNT(*) as c FROM observations ${h}`,f),g>0&&(t.run(`DELETE FROM observation_embeddings
|
|
280
|
+
WHERE observation_id IN (
|
|
281
|
+
SELECT id FROM observations ${h}
|
|
282
|
+
)`,f),t.run(`DELETE FROM observations ${h}`,f))}return{observations:l,summaries:d,prompts:m,knowledge:g}})(),u=c.observations+c.summaries+c.prompts+c.knowledge;return{...c,total:u,executedAt:new Date().toISOString()}}function je(t){function e(r,s){let n=t[r];if(n==null)return s;let o=Number(n);return isNaN(o)?s:o}return{observationsMaxAgeDays:e("retention.observations.maxAgeDays",90),summariesMaxAgeDays:e("retention.summaries.maxAgeDays",365),promptsMaxAgeDays:e("retention.prompts.maxAgeDays",30),knowledgeMaxAgeDays:e("retention.knowledge.maxAgeDays",0)}}import{existsSync as k,mkdirSync as xi,copyFileSync as be,readdirSync as ki,statSync as Li,unlinkSync as Ne,readFileSync as Pi,writeFileSync as Mi}from"fs";import{join as ht,basename as $i}from"path";function Bi(t){let e=(u,l=2)=>String(u).padStart(l,"0"),r=t.getFullYear(),s=e(t.getMonth()+1),n=e(t.getDate()),o=e(t.getHours()),i=e(t.getMinutes()),a=e(t.getSeconds()),c=e(t.getMilliseconds(),3);return`${r}-${s}-${n}-${o}${i}${a}-${c}`}function Fi(t,e){let r=n=>{try{return t.query(`SELECT COUNT(*) as c FROM ${n}`).get()?.c??0}catch{return 0}},s=k(e)?Li(e).size:0;return{observations:r("observations"),sessions:r("sessions"),summaries:r("summaries"),prompts:r("prompts"),dbSizeBytes:s}}function Hi(t){try{return t.query("SELECT MAX(version) as v FROM schema_versions").get()?.v??0}catch{return 0}}function yt(t,e,r){xi(e,{recursive:!0});let s=new Date,n=Bi(s),o=`backup-${n}.db`,i=ht(e,o),a=`backup-${n}.meta.json`,c=ht(e,a);if(!k(t))throw new Error(`Database non trovato: ${t}`);be(t,i),p.info("BACKUP",`File DB copiato: ${t} \u2192 ${i}`);let u=`${t}-wal`,l=`${t}-shm`;k(u)&&(be(u,`${i}-wal`),p.debug("BACKUP","File WAL copiato")),k(l)&&(be(l,`${i}-shm`),p.debug("BACKUP","File SHM copiato"));let d=Fi(r,t),m=Hi(r),g={timestamp:s.toISOString(),timestampEpoch:s.getTime(),schemaVersion:m,stats:d,sourcePath:t,filename:o};return Mi(c,JSON.stringify(g,null,2),"utf8"),p.info("BACKUP",`Metadata scritto: ${c}`),{filePath:i,metaPath:c,metadata:g}}function Et(t){if(!k(t))return[];let e=[],r;try{r=ki(t)}catch(n){return p.warn("BACKUP",`Impossibile leggere la directory backup: ${t}`,{},n),[]}let s=r.filter(n=>n.startsWith("backup-")&&n.endsWith(".meta.json"));for(let n of s){let o=ht(t,n),i=n.replace(/\.meta\.json$/,".db"),a=ht(t,i),c;try{let u=Pi(o,"utf8");c=JSON.parse(u)}catch(u){p.warn("BACKUP",`Metadata non leggibile: ${o}`,{},u);continue}if(!k(a)){p.warn("BACKUP",`File backup mancante per metadata: ${a}`);continue}e.push({filePath:a,metaPath:o,metadata:c})}return e.sort((n,o)=>o.metadata.timestampEpoch-n.metadata.timestampEpoch),e}function Rs(t,e){if(!k(t))throw new Error(`File backup non trovato: ${t}`);be(t,e),p.info("BACKUP",`Database ripristinato: ${t} \u2192 ${e}`);let r=`${t}-wal`,s=`${t}-shm`,n=`${e}-wal`,o=`${e}-shm`;k(r)?(be(r,n),p.debug("BACKUP","File WAL ripristinato")):k(n)&&(Ne(n),p.debug("BACKUP","File WAL corrente rimosso (non presente nel backup)")),k(s)?(be(s,o),p.debug("BACKUP","File SHM ripristinato")):k(o)&&(Ne(o),p.debug("BACKUP","File SHM corrente rimosso (non presente nel backup)"))}function bt(t,e){if(e<=0)throw new Error(`maxKeep deve essere > 0, ricevuto: ${e}`);let r=Et(t);if(r.length<=e)return p.debug("BACKUP",`Rotazione non necessaria: ${r.length}/${e} backup presenti`),0;let s=r.slice(e),n=0;for(let o of s){try{k(o.filePath)&&Ne(o.filePath)}catch(i){p.warn("BACKUP",`Impossibile eliminare: ${o.filePath}`,{},i)}for(let i of[`${o.filePath}-wal`,`${o.filePath}-shm`])try{k(i)&&Ne(i)}catch{}try{k(o.metaPath)&&Ne(o.metaPath)}catch(i){p.warn("BACKUP",`Impossibile eliminare metadata: ${o.metaPath}`,{},i)}p.info("BACKUP",`Backup rimosso (rotazione): ${$i(o.filePath)}`),n++}return p.info("BACKUP",`Rotazione completata: ${n} backup eliminati, ${e} mantenuti`),n}import{existsSync as qi,statSync as du,readFileSync as Wi,writeFileSync as mu,mkdirSync as gu}from"fs";import{join as Ts}from"path";import{homedir as Ui}from"os";function Ki(){let t=process.env.KIRO_MEMORY_DATA_DIR||process.env.CONTEXTKIT_DATA_DIR||Ts(Ui(),".contextkit");return Ts(t,"config.json")}var dr={"worker.port":3001,"worker.host":"127.0.0.1","log.level":"INFO","search.limit":20,"embeddings.enabled":!1,"decay.staleThresholdDays":30,"retention.observations.maxAgeDays":90,"retention.summaries.maxAgeDays":365,"retention.prompts.maxAgeDays":30,"retention.knowledge.maxAgeDays":0,"retention.autoCleanupEnabled":!0,"retention.autoCleanupIntervalHours":24,"backup.enabled":!0,"backup.intervalHours":24,"backup.maxKeep":7,"backup.compress":!1};function Ae(t){let e=t||Ki();if(!qi(e))return{};try{let r=Wi(e,"utf8"),s=JSON.parse(r);return typeof s=="object"&&s!==null?s:{}}catch{return{}}}function se(t,e){let r=Ae(e);return t in r?r[t]:t in dr?dr[t]:null}function xe(t){let e=Ae(t),r={...dr};for(let[s,n]of Object.entries(e))r[s]=n;return r}import{existsSync as z,readdirSync as mr,readFileSync as gr}from"fs";import{join as P,resolve as fr}from"path";var Os="3.0.0";async function Gi(t){return import(t)}var _t=class{constructor(e,r={}){this.registry=e;this.localPluginsDir=r.localPluginsDir??P(I,"plugins"),this.projectRoot=r.projectRoot??process.cwd()}localPluginsDir;projectRoot;loadedModulePaths=new Map;async _loadModule(e){return Gi(e)}async discoverPlugins(){let e=P(this.projectRoot,"node_modules");if(!z(e))return p.debug("SYSTEM",`PluginLoader: node_modules non trovato in ${e}`),[];let r=[];try{let s=mr(e,{withFileTypes:!0});for(let n of s){if(n.isDirectory()&&n.name.startsWith("@")){let o=P(e,n.name);try{let i=mr(o,{withFileTypes:!0});for(let a of i)if(a.isDirectory()&&a.name.startsWith("kiro-memory-plugin-")){let c=P(o,a.name);this.hasValidPackageJson(c)&&r.push(c)}}catch{}continue}if(n.isDirectory()&&n.name.startsWith("kiro-memory-plugin-")){let o=P(e,n.name);this.hasValidPackageJson(o)&&r.push(o)}}}catch(s){p.warn("SYSTEM","PluginLoader: errore durante la scansione di node_modules",{},s)}return p.debug("SYSTEM",`PluginLoader: trovati ${r.length} plugin in node_modules`),r}hasValidPackageJson(e){let r=P(e,"package.json");if(!z(r))return!1;try{let s=gr(r,"utf-8"),n=JSON.parse(s);return!!(n.main||n.exports)}catch{return!1}}async loadFromPath(e){let r=fr(e);if(!z(r))throw new Error(`Percorso plugin non trovato: ${r}`);let s=this.resolveEntryPoint(r);p.debug("SYSTEM",`PluginLoader: caricamento modulo da ${s}`);let n=await this._loadModule(s),o=this.extractPlugin(n);return this.validatePlugin(o),o}resolveEntryPoint(e){let r=P(e,"package.json");if(z(r))try{let n=gr(r,"utf-8"),o=JSON.parse(n);if(typeof o.main=="string")return fr(e,o.main)}catch{}let s=P(e,"index.js");return z(s)?s:e}extractPlugin(e){if(!e||typeof e!="object")throw new Error("Il modulo non ha un export valido");let s=e.default??e;return typeof s=="function"&&(s=s()),s}async loadFromConfig(){let r=Ae().plugins;if(!r){p.debug("SYSTEM","PluginLoader: nessun plugin configurato in config.json");return}let s;try{if(s=typeof r=="string"?JSON.parse(r):r,!Array.isArray(s)){p.warn("SYSTEM",'PluginLoader: "plugins" in config.json deve essere un array');return}}catch(n){p.warn("SYSTEM",'PluginLoader: errore parsing "plugins" in config.json',{},n);return}for(let n of s){if(n.enabled===!1){p.debug("SYSTEM",`PluginLoader: plugin "${n.name}" disabilitato, skip`);continue}try{let o=n.path??n.name;await this.loadPlugin(o,n.name)}catch(o){let i=o instanceof Error?o.message:String(o);p.warn("SYSTEM",`PluginLoader: plugin "${n.name}" non caricato da config: ${i}`)}}}async loadPlugin(e,r){let s=r??e,n=await this._loadRawPluginByName(e),o=this.extractPlugin(n);this.validatePlugin(o);let i=o;this.loadedModulePaths.set(i.name,e),this.registry.register(i),p.info("SYSTEM",`PluginLoader: plugin "${s}" (v${i.version}) caricato`)}async _loadRawPluginByName(e){if(e.startsWith("/")||e.startsWith("./")||e.startsWith("../"))return{default:await this.loadFromPath(e)};let r=this.resolveModulePath(e);return this._loadModule(r)}resolveModulePath(e){if(e.startsWith("/"))return e;if(e.startsWith("./")||e.startsWith("../"))return fr(this.projectRoot,e);let r=P(this.projectRoot,"node_modules",e);if(z(r))return r;let s=P(this.localPluginsDir,e);return z(s)?s:r}async reloadPlugin(e){let r=this.loadedModulePaths.get(e);if(!r)throw new Error(`Plugin "${e}" non trovato \u2014 non \xE8 stato caricato da questo PluginLoader`);let s=this.registry.get(e);if(s){try{await s.destroy()}catch(n){p.warn("SYSTEM",`PluginLoader: errore durante destroy() di "${e}"`,{},n)}this.registry.unregister(e)}this.loadedModulePaths.delete(e),p.info("SYSTEM",`PluginLoader: hot reload di "${e}" da ${r}`),await this.loadPlugin(r,e)}async loadAll(){let e=[],r=[],s=await this.discoverPlugins();for(let a of s){let c=this.readPackageName(a)??this.basename(a);if(this.registry.get(c)){p.debug("SYSTEM",`PluginLoader: "${c}" gi\xE0 registrato, skip`);continue}try{await this.loadPlugin(a,c),e.push(c)}catch(u){let l=u instanceof Error?u.message:String(u);p.warn("SYSTEM",`PluginLoader: plugin "${c}" fallito (node_modules): ${l}`),r.push({name:c,error:l})}}let n=this.discoverLocalPlugins();for(let{name:a,path:c}of n){if(this.registry.get(a)){p.debug("SYSTEM",`PluginLoader: "${a}" gi\xE0 registrato, skip`);continue}try{await this.loadPlugin(c,a),e.push(a)}catch(u){let l=u instanceof Error?u.message:String(u);p.warn("SYSTEM",`PluginLoader: plugin locale "${a}" fallito: ${l}`),r.push({name:a,error:l})}}let i=Ae().plugins;if(i){let a=[];try{a=typeof i=="string"?JSON.parse(i):i}catch{}for(let c of Array.isArray(a)?a:[]){if(c.enabled===!1)continue;let u=c.name;if(this.registry.get(u)){p.debug("SYSTEM",`PluginLoader: "${u}" gi\xE0 registrato da config, skip`);continue}try{let l=c.path??c.name;await this.loadPlugin(l,u),e.push(u)}catch(l){let d=l instanceof Error?l.message:String(l);p.warn("SYSTEM",`PluginLoader: plugin da config "${u}" fallito: ${d}`),r.push({name:u,error:d})}}}return p.info("SYSTEM",`PluginLoader: loadAll completato \u2014 caricati=${e.length} falliti=${r.length}`),{loaded:e,failed:r}}readPackageName(e){let r=P(e,"package.json");try{let s=gr(r,"utf-8"),n=JSON.parse(s);return typeof n.name=="string"?n.name:null}catch{return null}}discoverLocalPlugins(){if(!z(this.localPluginsDir))return[];let e=[];try{let r=mr(this.localPluginsDir,{withFileTypes:!0});for(let s of r){if(!s.isDirectory())continue;let n=P(this.localPluginsDir,s.name),o=P(n,"index.js");z(o)&&e.push({name:s.name,path:n})}}catch(r){p.warn("SYSTEM",`PluginLoader: errore durante la scansione di ${this.localPluginsDir}`,{},r)}return e}basename(e){return e.split("/").filter(Boolean).pop()??e}validatePlugin(e){if(!e||typeof e!="object")throw new Error("Il plugin deve essere un oggetto non-null");let r=e;if(!r.name||typeof r.name!="string")throw new Error('Il plugin deve avere un campo "name" di tipo stringa');if(!r.version||typeof r.version!="string")throw new Error(`Plugin "${r.name}": campo "version" mancante o non stringa`);if(typeof r.init!="function")throw new Error(`Plugin "${r.name}": campo "init" deve essere una funzione`);if(typeof r.destroy!="function")throw new Error(`Plugin "${r.name}": campo "destroy" deve essere una funzione`);if(r.minKiroVersion&&typeof r.minKiroVersion=="string"&&!this.isVersionCompatible(Os,r.minKiroVersion))throw new Error(`Plugin "${r.name}": richiede kiro-memory >= ${r.minKiroVersion}, versione corrente: ${Os}`)}isVersionCompatible(e,r){let s=l=>l.split(".").map(d=>parseInt(d.replace(/[^0-9]/g,""),10)||0),[n,o,i]=s(e),[a,c,u]=s(r);return n!==a?n>a:o!==c?o>c:i>=u}};var Xi=5e3,Yi=5e3,zi=1e4;function hr(t,e,r){return new Promise((s,n)=>{let o=setTimeout(()=>{n(new Error(`Timeout dopo ${e}ms: ${r}`))},e);t.then(i=>{clearTimeout(o),s(i)},i=>{clearTimeout(o),n(i)})})}var _e=class t{static _instance=null;entries=new Map;constructor(){}static getInstance(){return t._instance||(t._instance=new t),t._instance}static _resetForTests(){t._instance=null}register(e){if(this.entries.has(e.name))throw new Error(`Plugin gi\xE0 registrato: "${e.name}"`);this.entries.set(e.name,{plugin:e,state:"registered"}),p.info("SYSTEM",`[PluginRegistry] Plugin registrato: ${e.name}@${e.version}`)}async unregister(e){let r=this.entries.get(e);r&&(r.state==="active"&&await this._runDestroy(r),this.entries.delete(e),p.info("SYSTEM",`[PluginRegistry] Plugin rimosso: ${e}`))}getAll(){return Array.from(this.entries.values()).map(e=>({name:e.plugin.name,version:e.plugin.version,description:e.plugin.description,state:e.state,error:e.error}))}get(e){return this.entries.get(e)?.plugin}async enable(e,r){let s=this.entries.get(e);if(!s)throw new Error(`Plugin non trovato: "${e}"`);if(s.state==="active"){p.info("SYSTEM",`[PluginRegistry] Plugin gi\xE0 attivo: ${e}`);return}s.state="initializing",s.error=void 0;try{await hr(s.plugin.init(r),Xi,`${e}.init()`),s.state="active",p.info("SYSTEM",`[PluginRegistry] Plugin attivato: ${e}`)}catch(n){s.state="error",s.error=n instanceof Error?n.message:String(n),p.error("SYSTEM",`[PluginRegistry] init() fallito per "${e}": ${s.error}`)}}async disable(e){let r=this.entries.get(e);if(!r)throw new Error(`Plugin non trovato: "${e}"`);if(r.state!=="active"){p.info("SYSTEM",`[PluginRegistry] Plugin non attivo, skip destroy: ${e}`);return}await this._runDestroy(r)}async emitHook(e,r){let s=Array.from(this.entries.values()).filter(n=>n.state==="active"&&n.plugin.hooks?.[e]);s.length!==0&&await Promise.allSettled(s.map(n=>{let o=n.plugin.hooks[e];if(!o)return Promise.resolve();let i=o(r);return hr(i,zi,`${n.plugin.name}.hooks.${e}()`).catch(a=>{let c=a instanceof Error?a.message:String(a);p.warn("SYSTEM",`[PluginRegistry] Hook ${e} fallito in "${n.plugin.name}": ${c}`)})}))}async _runDestroy(e){try{await hr(e.plugin.destroy(),Yi,`${e.plugin.name}.destroy()`),e.state="destroyed",p.info("SYSTEM",`[PluginRegistry] Plugin disabilitato: ${e.plugin.name}`)}catch(r){e.state="error",e.error=r instanceof Error?r.message:String(r),p.error("SYSTEM",`[PluginRegistry] destroy() fallito per "${e.plugin.name}": ${e.error}`)}}};function ws(t){let e=`[PLUGIN:${t}]`;return{info:(r,...s)=>p.info("SYSTEM",`${e} ${r}`,{},...s),warn:(r,...s)=>p.warn("SYSTEM",`${e} ${r}`,{},...s),error:(r,...s)=>p.error("SYSTEM",`${e} ${r}`,{},...s)}}import{Router as ia}from"express";function ke(t,e){let r=`${e}:${t}`;return Buffer.from(r,"utf8").toString("base64url")}function K(t){try{let e=Buffer.from(t,"base64url").toString("utf8"),r=e.indexOf(":");if(r===-1)return null;let s=e.substring(0,r),n=e.substring(r+1),o=parseInt(s,10),i=parseInt(n,10);return!Number.isInteger(o)||o<=0||!Number.isInteger(i)||i<=0?null:{epoch:o,id:i}}catch{return null}}function ue(t,e){if(t.length<e)return null;let r=t[t.length-1];return r?ke(r.id,r.created_at_epoch):null}function Ds(t,e,r,s){let n=new Date,o=t.run(`INSERT INTO sessions (content_session_id, project, user_prompt, status, started_at, started_at_epoch)
|
|
283
|
+
VALUES (?, ?, ?, 'active', ?, ?)`,[e,r,s,n.toISOString(),n.getTime()]);return Number(o.lastInsertRowid)}function Is(t,e){return t.query("SELECT * FROM sessions WHERE content_session_id = ?").get(e)}function Cs(t,e){let r=new Date;t.run(`UPDATE sessions
|
|
284
|
+
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
|
285
|
+
WHERE id = ?`,[r.toISOString(),r.getTime(),e])}function js(t,e=100){return t.query("SELECT * FROM sessions ORDER BY started_at_epoch DESC LIMIT ?").all(e)}function Ns(t,e,r=100){return t.query("SELECT * FROM sessions WHERE project = ? ORDER BY started_at_epoch DESC LIMIT ?").all(e,r)}we();function Vi(t){return t.replace(/[%_\\]/g,"\\$&")}function St(t,e,r,s,n,o,i,a,c){let u=new Date,l=t.run(`INSERT INTO summaries
|
|
286
|
+
(session_id, project, request, investigated, learned, completed, next_steps, notes, created_at, created_at_epoch)
|
|
287
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e,r,s,n,o,i,a,c,u.toISOString(),u.getTime()]);return Number(l.lastInsertRowid)}function Se(t,e,r=50){return t.query("SELECT * FROM summaries WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?").all(e,r)}function As(t,e,r){let s=r?`SELECT * FROM summaries
|
|
288
|
+
WHERE project = ? AND (request LIKE ? ESCAPE '\\' OR learned LIKE ? ESCAPE '\\' OR completed LIKE ? ESCAPE '\\' OR notes LIKE ? ESCAPE '\\')
|
|
289
|
+
ORDER BY created_at_epoch DESC, id DESC`:`SELECT * FROM summaries
|
|
290
|
+
WHERE request LIKE ? ESCAPE '\\' OR learned LIKE ? ESCAPE '\\' OR completed LIKE ? ESCAPE '\\' OR notes LIKE ? ESCAPE '\\'
|
|
291
|
+
ORDER BY created_at_epoch DESC, id DESC`,n=`%${Vi(e)}%`,o=t.query(s);return r?o.all(r,n,n,n,n):o.all(n,n,n,n)}function xs(t,e,r,s,n){let o=new Date,i=t.run(`INSERT INTO prompts
|
|
292
|
+
(content_session_id, project, prompt_number, prompt_text, created_at, created_at_epoch)
|
|
293
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[e,r,s,n,o.toISOString(),o.getTime()]);return Number(i.lastInsertRowid)}function ks(t,e,r=100){return t.query("SELECT * FROM prompts WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?").all(e,r)}function Ls(t,e,r,s){let n=new Date,o=t.run(`INSERT INTO checkpoints (session_id, project, task, progress, next_steps, open_questions, relevant_files, context_snapshot, created_at, created_at_epoch)
|
|
294
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e,r,s.task,s.progress||null,s.nextSteps||null,s.openQuestions||null,s.relevantFiles||null,s.contextSnapshot||null,n.toISOString(),n.getTime()]);return Number(o.lastInsertRowid)}function vt(t,e){return t.query("SELECT * FROM checkpoints WHERE session_id = ? ORDER BY created_at_epoch DESC, id DESC LIMIT 1").get(e)}function Rt(t,e){return t.query("SELECT * FROM checkpoints WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT 1").get(e)}function Tt(t,e,r,s){let n=new Date(r),o=new Date(s),i=Math.ceil((s-r)/(1440*60*1e3)),a=i<=7?"Weekly":i<=31?"Monthly":"Custom",c=(A,C="created_at_epoch")=>{let le=e?`SELECT COUNT(*) as count FROM ${A} WHERE project = ? AND ${C} >= ? AND ${C} <= ?`:`SELECT COUNT(*) as count FROM ${A} WHERE ${C} >= ? AND ${C} <= ?`,Ar=t.query(le);return(e?Ar.get(e,r,s):Ar.get(r,s))?.count||0},u=c("observations"),l=c("summaries"),d=c("prompts"),m=c("sessions","started_at_epoch"),g=e?`SELECT DATE(datetime(created_at_epoch / 1000, 'unixepoch')) as day, COUNT(*) as count
|
|
295
|
+
FROM observations
|
|
296
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
297
|
+
GROUP BY day ORDER BY day ASC`:`SELECT DATE(datetime(created_at_epoch / 1000, 'unixepoch')) as day, COUNT(*) as count
|
|
298
|
+
FROM observations
|
|
299
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ?
|
|
300
|
+
GROUP BY day ORDER BY day ASC`,f=t.query(g),h=e?f.all(e,r,s):f.all(r,s),E=e?`SELECT type, COUNT(*) as count FROM observations
|
|
301
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
302
|
+
GROUP BY type ORDER BY count DESC`:`SELECT type, COUNT(*) as count FROM observations
|
|
303
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ?
|
|
304
|
+
GROUP BY type ORDER BY count DESC`,w=t.query(E),v=e?w.all(e,r,s):w.all(r,s),R=e?"SELECT COUNT(*) as count FROM sessions WHERE project = ? AND started_at_epoch >= ? AND started_at_epoch <= ?":"SELECT COUNT(*) as count FROM sessions WHERE started_at_epoch >= ? AND started_at_epoch <= ?",ne=(e?t.query(R).get(e,r,s)?.count:t.query(R).get(r,s)?.count)||0,Rr=e?"SELECT COUNT(*) as count FROM sessions WHERE project = ? AND started_at_epoch >= ? AND started_at_epoch <= ? AND status = 'completed'":"SELECT COUNT(*) as count FROM sessions WHERE started_at_epoch >= ? AND started_at_epoch <= ? AND status = 'completed'",On=(e?t.query(Rr).get(e,r,s)?.count:t.query(Rr).get(r,s)?.count)||0,Tr=e?`SELECT AVG((completed_at_epoch - started_at_epoch) / 1000.0 / 60.0) as avg_min
|
|
305
|
+
FROM sessions
|
|
306
|
+
WHERE project = ? AND started_at_epoch >= ? AND started_at_epoch <= ?
|
|
307
|
+
AND status = 'completed' AND completed_at_epoch IS NOT NULL AND completed_at_epoch > started_at_epoch`:`SELECT AVG((completed_at_epoch - started_at_epoch) / 1000.0 / 60.0) as avg_min
|
|
308
|
+
FROM sessions
|
|
309
|
+
WHERE started_at_epoch >= ? AND started_at_epoch <= ?
|
|
310
|
+
AND status = 'completed' AND completed_at_epoch IS NOT NULL AND completed_at_epoch > started_at_epoch`,wn=e?t.query(Tr).get(e,r,s):t.query(Tr).get(r,s),Dn=Math.round((wn?.avg_min||0)*10)/10,Or=e?`SELECT COUNT(*) as count FROM observations
|
|
311
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
312
|
+
AND type IN ('constraint', 'decision', 'heuristic', 'rejected')`:`SELECT COUNT(*) as count FROM observations
|
|
313
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ?
|
|
314
|
+
AND type IN ('constraint', 'decision', 'heuristic', 'rejected')`,In=(e?t.query(Or).get(e,r,s)?.count:t.query(Or).get(r,s)?.count)||0,wr=e?`SELECT COUNT(*) as count FROM observations
|
|
315
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ? AND is_stale = 1`:`SELECT COUNT(*) as count FROM observations
|
|
316
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ? AND is_stale = 1`,Cn=(e?t.query(wr).get(e,r,s)?.count:t.query(wr).get(r,s)?.count)||0,Dr=e?`SELECT learned, completed, next_steps FROM summaries
|
|
317
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
318
|
+
ORDER BY created_at_epoch DESC, id DESC`:`SELECT learned, completed, next_steps FROM summaries
|
|
319
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ?
|
|
320
|
+
ORDER BY created_at_epoch DESC, id DESC`,jn=e?t.query(Dr).all(e,r,s):t.query(Dr).all(r,s),Ir=[],Cr=[],jr=[];for(let A of jn){if(A.learned){let C=A.learned.split("; ").filter(Boolean);Ir.push(...C)}if(A.completed){let C=A.completed.split("; ").filter(Boolean);Cr.push(...C)}if(A.next_steps){let C=A.next_steps.split("; ").filter(Boolean);jr.push(...C)}}let Nr=e?`SELECT files_modified FROM observations
|
|
321
|
+
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
322
|
+
AND files_modified IS NOT NULL AND files_modified != ''`:`SELECT files_modified FROM observations
|
|
323
|
+
WHERE created_at_epoch >= ? AND created_at_epoch <= ?
|
|
324
|
+
AND files_modified IS NOT NULL AND files_modified != ''`,Nn=e?t.query(Nr).all(e,r,s):t.query(Nr).all(r,s),xt=new Map;for(let A of Nn){let C=A.files_modified.split(",").map(le=>le.trim()).filter(Boolean);for(let le of C)xt.set(le,(xt.get(le)||0)+1)}let An=Array.from(xt.entries()).map(([A,C])=>({file:A,count:C})).sort((A,C)=>C.count-A.count).slice(0,15);return{period:{start:n.toISOString().split("T")[0],end:o.toISOString().split("T")[0],days:i,label:a},overview:{observations:u,summaries:l,sessions:m,prompts:d,knowledgeCount:In,staleCount:Cn},timeline:h,typeDistribution:v,sessionStats:{total:ne,completed:On,avgDurationMinutes:Dn},topLearnings:[...new Set(Ir)].slice(0,10),completedTasks:[...new Set(Cr)].slice(0,10),nextSteps:[...new Set(jr)].slice(0,10),fileHotspots:An}}J();function Ot(t,e){let r=new Date,s=t.run(`INSERT INTO github_links
|
|
325
|
+
(observation_id, session_id, repo, issue_number, pr_number, event_type,
|
|
326
|
+
action, title, url, author, created_at, created_at_epoch)
|
|
327
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[e.observation_id??null,e.session_id??null,e.repo,e.issue_number??null,e.pr_number??null,e.event_type,e.action??null,e.title??null,e.url??null,e.author??null,r.toISOString(),r.getTime()]);return Number(s.lastInsertRowid)}function Ps(t,e){return t.query(`SELECT * FROM github_links
|
|
328
|
+
WHERE observation_id = ?
|
|
329
|
+
ORDER BY created_at_epoch DESC, id DESC`).all(e)}function Ms(t,e,r=50){return t.query(`SELECT * FROM github_links
|
|
330
|
+
WHERE repo = ?
|
|
331
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
332
|
+
LIMIT ?`).all(e,r)}function $s(t,e,r){return t.query(`SELECT * FROM github_links
|
|
333
|
+
WHERE repo = ? AND issue_number = ?
|
|
334
|
+
ORDER BY created_at_epoch DESC, id DESC`).all(e,r)}function Bs(t,e,r){return t.query(`SELECT * FROM github_links
|
|
335
|
+
WHERE repo = ? AND pr_number = ?
|
|
336
|
+
ORDER BY created_at_epoch DESC, id DESC`).all(e,r)}function Fs(t,e,r={}){let{repo:s,event_type:n,limit:o=50}=r,i=Math.min(Math.max(1,o),200),a=[],c=[];if(e&&e.trim().length>0){let l=`%${e.replace(/[%_\\]/g,"\\$&")}%`;a.push("(title LIKE ? ESCAPE '\\' OR url LIKE ? ESCAPE '\\')"),c.push(l,l)}s&&(a.push("repo = ?"),c.push(s)),n&&(a.push("event_type = ?"),c.push(n));let u=a.length>0?`WHERE ${a.join(" AND ")}`:"";return c.push(i),t.query(`SELECT * FROM github_links
|
|
337
|
+
${u}
|
|
338
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
339
|
+
LIMIT ?`).all(...c)}function Hs(t){return t.query(`SELECT repo,
|
|
340
|
+
COUNT(*) as count,
|
|
341
|
+
MAX(created_at) as last_event_at
|
|
342
|
+
FROM github_links
|
|
343
|
+
GROUP BY repo
|
|
344
|
+
ORDER BY count DESC, repo ASC`).all()}import{createHash as Ji}from"crypto";var Qi="2.5.0",pe=100;function Zi(t,e){let{fromEpoch:r,toEpoch:s}=wt(e),n=ve({project:e.project,type:e.type,fromEpoch:r,toEpoch:s}),o=ve({project:e.project,fromEpoch:r,toEpoch:s}),i=ve({project:e.project,fromEpoch:r,toEpoch:s}),a=t.query(`SELECT COUNT(*) as c FROM observations WHERE ${n.where}`).get(...n.params).c,c=t.query(`SELECT COUNT(*) as c FROM summaries WHERE ${o.where}`).get(...o.params).c,u=t.query(`SELECT COUNT(*) as c FROM prompts WHERE ${i.where}`).get(...i.params).c;return{observations:a,summaries:c,prompts:u}}function Us(t,e){let r=Zi(t,e),s={_meta:{version:Qi,exported_at:new Date().toISOString(),counts:r,filters:Object.keys(e).length>0?e:void 0}};return JSON.stringify(s)}function Ks(t,e,r,s=200){let{fromEpoch:n,toEpoch:o}=wt(e),i=ve({project:e.project,type:e.type,fromEpoch:n,toEpoch:o}),a=0,c=0;for(;;){let u=t.query(`SELECT id, memory_session_id, project, type, title, subtitle, text, narrative, facts, concepts,
|
|
345
|
+
files_read, files_modified, prompt_number, content_hash, discovery_tokens, auto_category,
|
|
346
|
+
created_at, created_at_epoch
|
|
347
|
+
FROM observations
|
|
348
|
+
WHERE ${i.where}
|
|
349
|
+
ORDER BY created_at_epoch ASC, id ASC
|
|
350
|
+
LIMIT ? OFFSET ?`).all(...i.params,s,a);if(u.length===0)break;for(let l of u){let d={_type:"observation",id:l.id,memory_session_id:l.memory_session_id,project:l.project,type:l.type,title:l.title,subtitle:l.subtitle,text:l.text,narrative:l.narrative,facts:l.facts,concepts:l.concepts,files_read:l.files_read,files_modified:l.files_modified,prompt_number:l.prompt_number,content_hash:l.content_hash,discovery_tokens:l.discovery_tokens??0,auto_category:l.auto_category,created_at:l.created_at,created_at_epoch:l.created_at_epoch};r(JSON.stringify(d)),c++}if(a+=u.length,u.length<s)break}return c}function Gs(t,e,r,s=200){let{fromEpoch:n,toEpoch:o}=wt(e),i=ve({project:e.project,fromEpoch:n,toEpoch:o}),a=0,c=0;for(;;){let u=t.query(`SELECT id, session_id, project, request, investigated, learned, completed, next_steps, notes,
|
|
351
|
+
discovery_tokens, created_at, created_at_epoch
|
|
352
|
+
FROM summaries
|
|
353
|
+
WHERE ${i.where}
|
|
354
|
+
ORDER BY created_at_epoch ASC, id ASC
|
|
355
|
+
LIMIT ? OFFSET ?`).all(...i.params,s,a);if(u.length===0)break;for(let l of u){let d={_type:"summary",id:l.id,session_id:l.session_id,project:l.project,request:l.request,investigated:l.investigated,learned:l.learned,completed:l.completed,next_steps:l.next_steps,notes:l.notes,discovery_tokens:l.discovery_tokens??0,created_at:l.created_at,created_at_epoch:l.created_at_epoch};r(JSON.stringify(d)),c++}if(a+=u.length,u.length<s)break}return c}function Xs(t,e,r,s=200){let{fromEpoch:n,toEpoch:o}=wt(e),i=ve({project:e.project,fromEpoch:n,toEpoch:o}),a=0,c=0;for(;;){let u=t.query(`SELECT id, content_session_id, project, prompt_number, prompt_text, created_at, created_at_epoch
|
|
356
|
+
FROM prompts
|
|
357
|
+
WHERE ${i.where}
|
|
358
|
+
ORDER BY created_at_epoch ASC, id ASC
|
|
359
|
+
LIMIT ? OFFSET ?`).all(...i.params,s,a);if(u.length===0)break;for(let l of u){let d={_type:"prompt",id:l.id,content_session_id:l.content_session_id,project:l.project,prompt_number:l.prompt_number,prompt_text:l.prompt_text,created_at:l.created_at,created_at_epoch:l.created_at_epoch};r(JSON.stringify(d)),c++}if(a+=u.length,u.length<s)break}return c}function ea(t){if(!t||typeof t!="object")return"Il record non \xE8 un oggetto JSON valido";let e=t;if("_meta"in e)return null;let r=["observation","summary","prompt"];if(!e._type||typeof e._type!="string"||!r.includes(e._type))return`Campo "_type" obbligatorio, uno di: ${r.join(", ")}`;if(e._type==="observation"){if(!e.project||typeof e.project!="string")return'observation: campo "project" obbligatorio';if(!e.type||typeof e.type!="string")return'observation: campo "type" obbligatorio';if(!e.title||typeof e.title!="string")return'observation: campo "title" obbligatorio';if(e.project.length>200)return'observation: "project" troppo lungo (max 200)';if(e.title.length>500)return'observation: "title" troppo lungo (max 500)'}else if(e._type==="summary"){if(!e.project||typeof e.project!="string")return'summary: campo "project" obbligatorio';if(!e.session_id||typeof e.session_id!="string")return'summary: campo "session_id" obbligatorio'}else if(e._type==="prompt"){if(!e.project||typeof e.project!="string")return'prompt: campo "project" obbligatorio';if(!e.content_session_id||typeof e.content_session_id!="string")return'prompt: campo "content_session_id" obbligatorio';if(!e.prompt_text||typeof e.prompt_text!="string")return'prompt: campo "prompt_text" obbligatorio'}return null}function qs(t){let e=[t.project??"",t.type??"",t.title??"",t.narrative??""].join("|");return Ji("sha256").update(e).digest("hex")}function Ws(t,e){return!!t.query("SELECT id FROM observations WHERE content_hash = ? LIMIT 1").get(e)}function ta(t,e,r){let s=0,n=0;for(let o=0;o<e.length;o+=pe){let i=e.slice(o,o+pe);if(r){for(let c of i){let u=c.content_hash||qs(c);Ws(t,u)?n++:s++}continue}t.transaction(()=>{for(let c of i){let u=c.content_hash||qs(c);if(Ws(t,u)){n++;continue}let l=new Date().toISOString();t.run(`INSERT INTO observations
|
|
360
|
+
(memory_session_id, project, type, title, subtitle, text, narrative, facts, concepts,
|
|
361
|
+
files_read, files_modified, prompt_number, content_hash, discovery_tokens, auto_category,
|
|
362
|
+
created_at, created_at_epoch)
|
|
363
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[c.memory_session_id||"imported",c.project,c.type,c.title,c.subtitle??null,c.text??null,c.narrative??null,c.facts??null,c.concepts??null,c.files_read??null,c.files_modified??null,c.prompt_number??0,u,c.discovery_tokens??0,c.auto_category??null,c.created_at||l,c.created_at_epoch||Date.now()]),s++}})()}return{imported:s,skipped:n}}function ra(t,e,r){let s=0,n=0;for(let o=0;o<e.length;o+=pe){let i=e.slice(o,o+pe);if(r){for(let c of i)t.query("SELECT id FROM summaries WHERE session_id = ? AND project = ? AND created_at_epoch = ? LIMIT 1").get(c.session_id,c.project,c.created_at_epoch??0)?n++:s++;continue}t.transaction(()=>{for(let c of i){if(t.query("SELECT id FROM summaries WHERE session_id = ? AND project = ? AND created_at_epoch = ? LIMIT 1").get(c.session_id,c.project,c.created_at_epoch??0)){n++;continue}let l=new Date().toISOString();t.run(`INSERT INTO summaries
|
|
364
|
+
(session_id, project, request, investigated, learned, completed, next_steps, notes,
|
|
365
|
+
discovery_tokens, created_at, created_at_epoch)
|
|
366
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[c.session_id,c.project,c.request??null,c.investigated??null,c.learned??null,c.completed??null,c.next_steps??null,c.notes??null,c.discovery_tokens??0,c.created_at||l,c.created_at_epoch||Date.now()]),s++}})()}return{imported:s,skipped:n}}function sa(t,e,r){let s=0,n=0;for(let o=0;o<e.length;o+=pe){let i=e.slice(o,o+pe);if(r){for(let c of i)t.query("SELECT id FROM prompts WHERE content_session_id = ? AND prompt_number = ? LIMIT 1").get(c.content_session_id,c.prompt_number??0)?n++:s++;continue}t.transaction(()=>{for(let c of i){if(t.query("SELECT id FROM prompts WHERE content_session_id = ? AND prompt_number = ? LIMIT 1").get(c.content_session_id,c.prompt_number??0)){n++;continue}let l=new Date().toISOString();t.run(`INSERT INTO prompts
|
|
367
|
+
(content_session_id, project, prompt_number, prompt_text, created_at, created_at_epoch)
|
|
368
|
+
VALUES (?, ?, ?, ?, ?, ?)`,[c.content_session_id,c.project,c.prompt_number??0,c.prompt_text,c.created_at||l,c.created_at_epoch||Date.now()]),s++}})()}return{imported:s,skipped:n}}function Ys(t,e,r=!1){let s=e.split(`
|
|
369
|
+
`),n={imported:0,skipped:0,errors:0,total:0,errorDetails:[]},o=[],i=[],a=[],c=()=>{if(o.length>0){let u=ta(t,o.splice(0),r);n.imported+=u.imported,n.skipped+=u.skipped}if(i.length>0){let u=ra(t,i.splice(0),r);n.imported+=u.imported,n.skipped+=u.skipped}if(a.length>0){let u=sa(t,a.splice(0),r);n.imported+=u.imported,n.skipped+=u.skipped}};for(let u=0;u<s.length;u++){let l=s[u].trim();if(!l||l.startsWith("#"))continue;n.total++;let d;try{d=JSON.parse(l)}catch{n.errors++,n.errorDetails.push({line:u+1,error:`JSON non valido: ${l.substring(0,60)}`});continue}if(d&&typeof d=="object"&&"_meta"in d){n.total--;continue}let m=ea(d);if(m){n.errors++,n.errorDetails.push({line:u+1,error:m});continue}let g=d;g._type==="observation"?o.push(g):g._type==="summary"?i.push(g):g._type==="prompt"&&a.push(g),o.length+i.length+a.length>=pe&&c()}return c(),n}function wt(t){return{fromEpoch:t.from?new Date(t.from).getTime():void 0,toEpoch:t.to?new Date(t.to).getTime():void 0}}function ve(t){let e=["1=1"],r=[];return t.project&&(e.push("project = ?"),r.push(t.project)),t.type&&(e.push("type = ?"),r.push(t.type)),t.fromEpoch!==void 0&&(e.push("created_at_epoch >= ?"),r.push(t.fromEpoch)),t.toEpoch!==void 0&&(e.push("created_at_epoch <= ?"),r.push(t.toEpoch)),{where:e.join(" AND "),params:r}}we();import{createHash as na}from"crypto";J();var Le=class{db;project;constructor(e={}){this.db=new V(e.dataDir,e.skipMigrations||!1),this.project=e.project||this.detectProject()}detectProject(){try{let{execSync:e}=$n("child_process");return e("git rev-parse --show-toplevel",{cwd:process.cwd(),encoding:"utf8",stdio:["pipe","pipe","ignore"]}).trim().split("/").pop()||"default"}catch{return"default"}}async getContext(){return{project:this.project,relevantObservations:Z(this.db.db,this.project,20),relevantSummaries:Se(this.db.db,this.project,5),recentPrompts:ks(this.db.db,this.project,10)}}validateObservationInput(e){if(!e.type||typeof e.type!="string"||e.type.length>100)throw new Error("type is required (string, max 100 chars)");if(!e.title||typeof e.title!="string"||e.title.length>500)throw new Error("title is required (string, max 500 chars)");if(!e.content||typeof e.content!="string"||e.content.length>1e5)throw new Error("content is required (string, max 100KB)")}validateSummaryInput(e){for(let[s,n]of Object.entries(e))if(n!=null){if(typeof n!="string")throw new Error(`${s} must be a string`);if(n.length>5e4)throw new Error(`${s} too large (max 50KB)`)}}async generateEmbeddingAsync(e,r,s,n){try{let o=L();if(!o.isAvailable())return;let i=[r,s];n?.length&&i.push(n.join(", "));let a=i.join(" ").substring(0,2e3),c=await o.embed(a);c&&await M().storeEmbedding(this.db.db,e,c,o.getProvider()||"unknown")}catch(o){p.debug("SDK",`Embedding generation failed for obs ${e}: ${o}`)}}generateContentHash(e,r,s){let n=`${this.project}|${e}|${r}|${s||""}`;return na("sha256").update(n).digest("hex")}getDeduplicationWindow(e){switch(e){case"file-read":return 6e4;case"file-write":return 1e4;case"command":return 3e4;case"research":return 12e4;case"delegation":return 6e4;default:return 3e4}}async storeObservation(e){this.validateObservationInput(e);let r="sdk-"+Date.now(),s=this.generateContentHash(e.type,e.title,e.narrative),n=this.getDeduplicationWindow(e.type);if(dt(this.db.db,s,n))return p.debug("SDK",`Duplicate observation discarded (${e.type}, ${n}ms): ${e.title}`),-1;let o=e.filesRead||(e.type==="file-read"?e.files:void 0),i=e.filesModified||(e.type==="file-write"?e.files:void 0),a=Math.ceil(e.content.length/4),c=Q(this.db.db,r,this.project,e.type,e.title,e.subtitle||null,e.content,e.narrative||null,e.facts||null,e.concepts?.join(", ")||null,o?.join(", ")||null,i?.join(", ")||null,0,s,a);return this.generateEmbeddingAsync(c,e.title,e.content,e.concepts).catch(()=>{}),c}async storeKnowledge(e){if(!U.includes(e.knowledgeType))throw new Error(`Invalid knowledgeType: ${e.knowledgeType}. Allowed values: ${U.join(", ")}`);this.validateObservationInput({type:e.knowledgeType,title:e.title,content:e.content});let r=(()=>{switch(e.knowledgeType){case"constraint":return{knowledgeType:"constraint",severity:e.metadata?.severity||"soft",reason:e.metadata?.reason};case"decision":return{knowledgeType:"decision",alternatives:e.metadata?.alternatives,reason:e.metadata?.reason};case"heuristic":return{knowledgeType:"heuristic",context:e.metadata?.context,confidence:e.metadata?.confidence};case"rejected":return{knowledgeType:"rejected",reason:e.metadata?.reason||"",alternatives:e.metadata?.alternatives}}})(),s="sdk-"+Date.now(),n=this.generateContentHash(e.knowledgeType,e.title);if(dt(this.db.db,n))return p.debug("SDK",`Duplicate knowledge discarded: ${e.title}`),-1;let o=Math.ceil(e.content.length/4),i=Q(this.db.db,s,e.project||this.project,e.knowledgeType,e.title,null,e.content,null,JSON.stringify(r),e.concepts?.join(", ")||null,e.files?.join(", ")||null,null,0,n,o);return this.generateEmbeddingAsync(i,e.title,e.content,e.concepts).catch(()=>{}),i}async storeSummary(e){return this.validateSummaryInput(e),St(this.db.db,"sdk-"+Date.now(),this.project,e.request||null,e.investigated||null,e.learned||null,e.completed||null,e.nextSteps||null,e.notes||null)}async search(e){return{observations:cr(this.db.db,e,this.project),summaries:As(this.db.db,e,this.project)}}async getRecentObservations(e=10){return Z(this.db.db,this.project,e)}async getRecentSummaries(e=5){return Se(this.db.db,this.project,e)}async searchAdvanced(e,r={}){let s={...r,project:r.project||this.project};return{observations:fe(this.db.db,e,s),summaries:he(this.db.db,e,s)}}async getObservationsByIds(e){return ye(this.db.db,e)}async getTimeline(e,r=5,s=5){return Ee(this.db.db,e,r,s)}async getOrCreateSession(e){let r=Is(this.db.db,e);return r||(r={id:Ds(this.db.db,e,this.project,""),content_session_id:e,project:this.project,user_prompt:"",memory_session_id:null,status:"active",started_at:new Date().toISOString(),started_at_epoch:Date.now(),completed_at:null,completed_at_epoch:null}),r}async storePrompt(e,r,s){return xs(this.db.db,e,this.project,r,s)}async completeSession(e){Cs(this.db.db,e)}getProject(){return this.project}async hybridSearch(e,r={}){return ee().search(this.db.db,e,{project:this.project,limit:r.limit||10})}async semanticSearch(e,r={}){let s=L();if(s.isAvailable()||await s.initialize(),!s.isAvailable())return[];let n=await s.embed(e);return n?(await M().search(this.db.db,n,{project:this.project,limit:r.limit||10,threshold:r.threshold||.3})).map(a=>({id:String(a.observationId),title:a.title,content:a.text||"",type:a.type,project:a.project,created_at:a.created_at,created_at_epoch:a.created_at_epoch,score:a.similarity,source:"vector",signals:{semantic:a.similarity,fts5:0,recency:Te(a.created_at_epoch),projectMatch:Oe(a.project,this.project)}})):[]}async backfillEmbeddings(e=50){return M().backfillEmbeddings(this.db.db,e)}getEmbeddingStats(){return M().getStats(this.db.db)}async initializeEmbeddings(){return await ee().initialize(),L().isAvailable()}async getSmartContext(e={}){let r=e.tokenBudget||parseInt(process.env.KIRO_MEMORY_CONTEXT_TOKENS||"0",10)||2e3,s=Se(this.db.db,this.project,5),n;if(e.query)n=(await ee().search(this.db.db,e.query,{project:this.project,limit:30})).map(u=>({id:parseInt(u.id,10)||0,title:u.title,content:u.content,type:u.type,project:u.project,created_at:u.created_at,created_at_epoch:u.created_at_epoch,score:u.score,signals:u.signals}));else{let a=Z(this.db.db,this.project,30),c=new Set(U),u=[],l=[];for(let f of a)c.has(f.type)?u.push(f):l.push(f);let d=f=>{let h={semantic:0,fts5:0,recency:Te(f.created_at_epoch),projectMatch:Oe(f.project,this.project)},E=at(h,as);return{id:f.id,title:f.title,content:f.text||f.narrative||"",type:f.type,project:f.project,created_at:f.created_at,created_at_epoch:f.created_at_epoch,score:Math.min(1,E*ct(f.type)),signals:h}},m=u.map(d).sort((f,h)=>h.score-f.score),g=l.map(d).sort((f,h)=>h.score-f.score);n=[...m,...g]}let o=0,i=[];for(let a of n){let c=Math.ceil((a.title.length+a.content.length)/4);if(o+c>r)break;o+=c,i.push(a)}return n=i,{project:this.project,items:n,summaries:s,tokenBudget:r,tokensUsed:Math.min(o,r)}}async detectStaleObservations(){let e=ir(this.db.db,this.project);if(e.length>0){let r=e.map(s=>s.id);ar(this.db.db,r,!0)}return e.length}async consolidateObservations(e={}){return ur(this.db.db,this.project,e)}async getDecayStats(){let e=this.db.db.query("SELECT COUNT(*) as count FROM observations WHERE project = ?").get(this.project)?.count||0,r=this.db.db.query("SELECT COUNT(*) as count FROM observations WHERE project = ? AND is_stale = 1").get(this.project)?.count||0,s=this.db.db.query("SELECT COUNT(*) as count FROM observations WHERE project = ? AND last_accessed_epoch IS NULL").get(this.project)?.count||0,n=Date.now()-2880*60*1e3,o=this.db.db.query("SELECT COUNT(*) as count FROM observations WHERE project = ? AND last_accessed_epoch > ?").get(this.project,n)?.count||0;return{total:e,stale:r,neverAccessed:s,recentlyAccessed:o}}async createCheckpoint(e,r){let s=Z(this.db.db,this.project,10),n=JSON.stringify(s.map(o=>({id:o.id,type:o.type,title:o.title,text:o.text?.substring(0,200)})));return Ls(this.db.db,e,this.project,{task:r.task,progress:r.progress,nextSteps:r.nextSteps,openQuestions:r.openQuestions,relevantFiles:r.relevantFiles?.join(", "),contextSnapshot:n})}async getCheckpoint(e){return vt(this.db.db,e)}async getLatestProjectCheckpoint(){return Rt(this.db.db,this.project)}async generateReport(e){let r=new Date,s,n=r.getTime();if(e?.startDate&&e?.endDate)s=e.startDate.getTime(),n=e.endDate.getTime();else{let i=(e?.period||"weekly")==="monthly"?30:7;s=n-i*24*60*60*1e3}return Tt(this.db.db,this.project,s,n)}async listObservations(e={}){let r=Math.min(Math.max(e.limit??50,1),200),s=e.project??this.project,n;if(e.cursor){let i=K(e.cursor);if(!i)throw new Error("Cursor non valido");let a=s?`SELECT * FROM observations
|
|
370
|
+
WHERE project = ? AND (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
371
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
372
|
+
LIMIT ?`:`SELECT * FROM observations
|
|
373
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
374
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
375
|
+
LIMIT ?`;n=s?this.db.db.query(a).all(s,i.epoch,i.epoch,i.id,r):this.db.db.query(a).all(i.epoch,i.epoch,i.id,r)}else{let i=s?"SELECT * FROM observations WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?":"SELECT * FROM observations ORDER BY created_at_epoch DESC, id DESC LIMIT ?";n=s?this.db.db.query(i).all(s,r):this.db.db.query(i).all(r)}let o=n.length>=r?ke(n[n.length-1].id,n[n.length-1].created_at_epoch):null;return{data:n,next_cursor:o,has_more:o!==null}}async listSummaries(e={}){let r=Math.min(Math.max(e.limit??20,1),200),s=e.project??this.project,n;if(e.cursor){let i=K(e.cursor);if(!i)throw new Error("Cursor non valido");let a=s?`SELECT * FROM summaries
|
|
376
|
+
WHERE project = ? AND (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
377
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
378
|
+
LIMIT ?`:`SELECT * FROM summaries
|
|
379
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
380
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
381
|
+
LIMIT ?`;n=s?this.db.db.query(a).all(s,i.epoch,i.epoch,i.id,r):this.db.db.query(a).all(i.epoch,i.epoch,i.id,r)}else{let i=s?"SELECT * FROM summaries WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?":"SELECT * FROM summaries ORDER BY created_at_epoch DESC, id DESC LIMIT ?";n=s?this.db.db.query(i).all(s,r):this.db.db.query(i).all(r)}let o=n.length>=r?ke(n[n.length-1].id,n[n.length-1].created_at_epoch):null;return{data:n,next_cursor:o,has_more:o!==null}}getDb(){return this.db.db}close(){this.db.close()}};J();import{join as zs}from"path";var oa=process.env.KIRO_MEMORY_DATA_DIR||process.env.CONTEXTKIT_DATA_DIR||zs(process.env.HOME||"/tmp",".kiro-memory"),yp=zs(oa,"worker.token");var Vs="3.0.0";var Js=new Set(["observation-created","summary-created","prompt-created","session-created"]);function Qs(t,e){let r=ia(),s=ge({windowMs:6e4,max:60,standardHeaders:!0,legacyHeaders:!1});return r.post("/api/notify",s,(n,o)=>{if(n.headers["x-worker-token"]!==e){o.status(401).json({error:"Invalid or missing X-Worker-Token"});return}let{event:a,data:c}=n.body||{};if(!a||typeof a!="string"||!Js.has(a)){o.status(400).json({error:`Event must be one of: ${[...Js].join(", ")}`});return}t.broadcast(a,c||{}),o.json({ok:!0})}),r.get("/health",(n,o)=>{o.json({status:"ok",timestamp:Date.now(),version:Vs})}),r.get("/events",(n,o)=>{let i=Ie();if(i.length>=hs()){o.status(503).json({error:"Too many SSE connections"});return}o.setHeader("Content-Type","text/event-stream"),o.setHeader("Cache-Control","no-cache"),o.setHeader("Connection","keep-alive"),o.setHeader("X-Accel-Buffering","no"),o.flushHeaders(),ys(o),p.info("WORKER","SSE client connected",{clients:i.length}),o.write(`event: connected
|
|
232
382
|
data: ${JSON.stringify({timestamp:Date.now()})}
|
|
233
383
|
|
|
234
384
|
`);let a=setInterval(()=>{try{o.write(`:keepalive ${Date.now()}
|
|
235
385
|
|
|
236
|
-
`)}catch{clearInterval(a)}},15e3);n.on("close",()=>{clearInterval(a),
|
|
237
|
-
|
|
238
|
-
|
|
386
|
+
`)}catch{clearInterval(a)}},15e3);n.on("close",()=>{clearInterval(a),Es(o),p.info("WORKER","SSE client disconnected",{clients:Ie().length})})}),r}import{Router as aa}from"express";we();J();function Zs(t){let e=aa();return e.get("/api/observations",(r,s)=>{let{cursor:n,offset:o,limit:i,project:a}=r.query,c=_(i,50,1,200);try{let u;if(n){let m=K(n);if(!m){s.status(400).json({error:"Cursor non valido"});return}let g=a?`SELECT * FROM observations
|
|
387
|
+
WHERE project = ? AND (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
388
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
389
|
+
LIMIT ?`:`SELECT * FROM observations
|
|
390
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
391
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
392
|
+
LIMIT ?`;u=a?t.db.db.query(g).all(a,m.epoch,m.epoch,m.id,c):t.db.db.query(g).all(m.epoch,m.epoch,m.id,c)}else if(o!==void 0){let m=_(o,0,0,1e6),g=a?"SELECT * FROM observations WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?":"SELECT * FROM observations ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?";u=a?t.db.db.query(g).all(a,c,m):t.db.db.query(g).all(c,m)}else{let m=a?"SELECT * FROM observations WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?":"SELECT * FROM observations ORDER BY created_at_epoch DESC, id DESC LIMIT ?";u=a?t.db.db.query(m).all(a,c):t.db.db.query(m).all(c)}let d=ue(u,c);if(!n){let m=a?"SELECT COUNT(*) as total FROM observations WHERE project = ?":"SELECT COUNT(*) as total FROM observations",{total:g}=a?t.db.db.query(m).get(a):t.db.db.query(m).get();s.setHeader("X-Total-Count",g)}s.json({data:u,next_cursor:d,has_more:d!==null})}catch(u){p.error("WORKER","Observation list failed",{},u),s.status(500).json({error:"Failed to list observations"})}}),e.post("/api/observations",(r,s)=>{let{memorySessionId:n,project:o,type:i,title:a,content:c,concepts:u,files:l}=r.body;if(!S(o)){s.status(400).json({error:'Invalid or missing "project"'});return}if(!$(a,500)){s.status(400).json({error:'Invalid or missing "title" (max 500 chars)'});return}if(c&&!$(c,1e5)){s.status(400).json({error:'"content" too large (max 100KB)'});return}if(u&&!Array.isArray(u)){s.status(400).json({error:'"concepts" must be an array'});return}if(l&&!Array.isArray(l)){s.status(400).json({error:'"files" must be an array'});return}try{let d=Q(t.db.db,n||"api-"+Date.now(),o,i||"manual",a,null,c,null,null,u?.join(", ")||null,l?.join(", ")||null,null,0);t.broadcast("observation-created",{id:d,project:o,title:a}),t.invalidateProjectsCache(),t.generateEmbeddingForObservation(d,a,c,u).catch(()=>{}),s.json({id:d,success:!0})}catch(d){p.error("WORKER","Observation creation failed",{},d),s.status(500).json({error:"Failed to store observation"})}}),e.post("/api/observations/batch",(r,s)=>{let{ids:n}=r.body;if(!n||!Array.isArray(n)||n.length===0||n.length>100){s.status(400).json({error:'"ids" must be an array of 1-100 elements'});return}if(!n.every(o=>typeof o=="number"&&Number.isInteger(o)&&o>0)){s.status(400).json({error:"All IDs must be positive integers"});return}try{let o=ye(t.db.db,n);s.json({observations:o})}catch(o){p.error("WORKER","Batch fetch failed",{ids:n},o),s.status(500).json({error:"Batch fetch failed"})}}),e.post("/api/knowledge",(r,s)=>{let{project:n,knowledge_type:o,title:i,content:a,concepts:c,files:u,severity:l,alternatives:d,reason:m,context:g,confidence:f}=r.body;if(!S(n)){s.status(400).json({error:'Invalid or missing "project"'});return}if(!o||!U.includes(o)){s.status(400).json({error:`Invalid "knowledge_type". Must be one of: ${U.join(", ")}`});return}if(!$(i,500)){s.status(400).json({error:'Invalid or missing "title" (max 500 chars)'});return}if(!$(a,1e5)){s.status(400).json({error:'Invalid or missing "content" (max 100KB)'});return}if(c&&!Array.isArray(c)){s.status(400).json({error:'"concepts" must be an array'});return}if(u&&!Array.isArray(u)){s.status(400).json({error:'"files" must be an array'});return}try{let h;switch(o){case"constraint":h={knowledgeType:"constraint",severity:l==="hard"?"hard":"soft",reason:m};break;case"decision":h={knowledgeType:"decision",alternatives:d,reason:m};break;case"heuristic":h={knowledgeType:"heuristic",context:g,confidence:["high","medium","low"].includes(f)?f:void 0};break;case"rejected":h={knowledgeType:"rejected",reason:m||"",alternatives:d};break;default:s.status(400).json({error:"Invalid knowledge_type"});return}let E=Q(t.db.db,"api-"+Date.now(),n,o,i,null,a,null,JSON.stringify(h),c?.join(", ")||null,u?.join(", ")||null,null,0);t.broadcast("observation-created",{id:E,project:n,title:i,type:o}),t.generateEmbeddingForObservation(E,i,a,c).catch(()=>{}),s.json({id:E,success:!0,knowledge_type:o})}catch(h){p.error("WORKER","Knowledge save failed",{},h),s.status(500).json({error:"Failed to store knowledge"})}}),e.post("/api/memory/save",(r,s)=>{let{project:n,title:o,content:i,type:a,concepts:c}=r.body;if(!S(n)){s.status(400).json({error:'Invalid or missing "project"'});return}if(!$(o,500)){s.status(400).json({error:'Invalid or missing "title" (max 500 chars)'});return}if(!$(i,1e5)){s.status(400).json({error:'Invalid or missing "content" (max 100KB)'});return}let u=a||"research",l=Array.isArray(c)?c.join(", "):c||null;try{let d=Q(t.db.db,"memory-save-"+Date.now(),n,u,o,null,i,i,null,l,null,null,0);t.broadcast("observation-created",{id:d,project:n,title:o}),t.invalidateProjectsCache(),t.generateEmbeddingForObservation(d,o,i,Array.isArray(c)?c:void 0).catch(()=>{}),s.json({id:d,success:!0})}catch(d){p.error("WORKER","Memory save failed",{},d),s.status(500).json({error:"Failed to save memory"})}}),e.get("/api/context/:project",(r,s)=>{let{project:n}=r.params;if(!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o={project:n,observations:Z(t.db.db,n,20),summaries:Se(t.db.db,n,5)};s.json(o)}catch(o){p.error("WORKER","Context retrieval failed",{project:n},o),s.status(500).json({error:"Failed to get context"})}}),e}import{Router as ca}from"express";function en(t){let e=ca();return e.get("/api/summaries",(r,s)=>{let{cursor:n,offset:o,limit:i,project:a}=r.query,c=_(i,20,1,200);try{let u;if(n){let m=K(n);if(!m){s.status(400).json({error:"Cursor non valido"});return}let g=a?`SELECT * FROM summaries
|
|
393
|
+
WHERE project = ? AND (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
394
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
395
|
+
LIMIT ?`:`SELECT * FROM summaries
|
|
396
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
397
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
398
|
+
LIMIT ?`;u=a?t.db.db.query(g).all(a,m.epoch,m.epoch,m.id,c):t.db.db.query(g).all(m.epoch,m.epoch,m.id,c)}else if(o!==void 0){let m=_(o,0,0,1e6),g=a?"SELECT * FROM summaries WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?":"SELECT * FROM summaries ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?";u=a?t.db.db.query(g).all(a,c,m):t.db.db.query(g).all(c,m)}else{let m=a?"SELECT * FROM summaries WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?":"SELECT * FROM summaries ORDER BY created_at_epoch DESC, id DESC LIMIT ?";u=a?t.db.db.query(m).all(a,c):t.db.db.query(m).all(c)}let d=ue(u,c);if(!n){let m=a?"SELECT COUNT(*) as total FROM summaries WHERE project = ?":"SELECT COUNT(*) as total FROM summaries",{total:g}=a?t.db.db.query(m).get(a):t.db.db.query(m).get();s.setHeader("X-Total-Count",g)}s.json({data:u,next_cursor:d,has_more:d!==null})}catch(u){p.error("WORKER","Summary list failed",{},u),s.status(500).json({error:"Failed to list summaries"})}}),e.post("/api/summaries",(r,s)=>{let{sessionId:n,project:o,request:i,learned:a,completed:c,nextSteps:u}=r.body;if(!S(o)){s.status(400).json({error:'Invalid or missing "project"'});return}let l=5e4;if(i&&!$(i,l)){s.status(400).json({error:'"request" too large'});return}if(a&&!$(a,l)){s.status(400).json({error:'"learned" too large'});return}if(c&&!$(c,l)){s.status(400).json({error:'"completed" too large'});return}if(u&&!$(u,l)){s.status(400).json({error:'"nextSteps" too large'});return}try{let d=St(t.db.db,n||"api-"+Date.now(),o,i||null,null,a||null,c||null,u||null,null);t.broadcast("summary-created",{id:d,project:o}),s.json({id:d,success:!0})}catch(d){p.error("WORKER","Summary creation failed",{},d),s.status(500).json({error:"Failed to store summary"})}}),e}import{Router as ua}from"express";J();function tn(t){let e=ua();return e.get("/api/search",(r,s)=>{let{q:n,project:o,type:i,limit:a}=r.query;if(!n){s.status(400).json({error:'Query parameter "q" is required'});return}try{let c={project:o||void 0,type:i||void 0,limit:_(a,20,1,100)},u={observations:fe(t.db.db,n,c),summaries:he(t.db.db,n,c)};s.json(u)}catch(c){p.error("WORKER","Search failed",{query:n},c),s.status(500).json({error:"Search failed"})}}),e.get("/api/hybrid-search",async(r,s)=>{let{q:n,project:o,limit:i}=r.query;if(!n){s.status(400).json({error:'Query parameter "q" is required'});return}try{let c=await ee().search(t.db.db,n,{project:o||void 0,limit:_(i,10,1,100)});s.json({results:c,count:c.length})}catch(a){p.error("WORKER","Hybrid search failed",{query:n},a),s.status(500).json({error:"Hybrid search failed"})}}),e.get("/api/timeline",(r,s)=>{let{anchor:n,depth_before:o,depth_after:i}=r.query;if(!n){s.status(400).json({error:'Query parameter "anchor" is required'});return}let a=_(n,0,1,Number.MAX_SAFE_INTEGER);if(a===0){s.status(400).json({error:'Invalid "anchor" (must be positive integer)'});return}try{let c=Ee(t.db.db,a,_(o,5,1,50),_(i,5,1,50));s.json({timeline:c})}catch(c){p.error("WORKER","Timeline failed",{anchor:n},c),s.status(500).json({error:"Timeline failed"})}}),e}import{Router as pa}from"express";function rn(t,e,r=30){let s=Date.now()-r*24*60*60*1e3,n=e?`SELECT DATE(datetime(created_at_epoch / 1000, 'unixepoch')) as day, COUNT(*) as count
|
|
239
399
|
FROM observations
|
|
240
400
|
WHERE project = ? AND created_at_epoch >= ?
|
|
241
401
|
GROUP BY day
|
|
@@ -243,14 +403,14 @@ data: ${JSON.stringify({timestamp:Date.now()})}
|
|
|
243
403
|
FROM observations
|
|
244
404
|
WHERE created_at_epoch >= ?
|
|
245
405
|
GROUP BY day
|
|
246
|
-
ORDER BY day ASC`,o=t.query(n);return e?o.all(e,s):o.all(s)}function
|
|
406
|
+
ORDER BY day ASC`,o=t.query(n);return e?o.all(e,s):o.all(s)}function sn(t,e){let r=e?`SELECT type, COUNT(*) as count
|
|
247
407
|
FROM observations
|
|
248
408
|
WHERE project = ?
|
|
249
409
|
GROUP BY type
|
|
250
410
|
ORDER BY count DESC`:`SELECT type, COUNT(*) as count
|
|
251
411
|
FROM observations
|
|
252
412
|
GROUP BY type
|
|
253
|
-
ORDER BY count DESC`,s=t.query(r);return e?s.all(e):s.all()}function
|
|
413
|
+
ORDER BY count DESC`,s=t.query(r);return e?s.all(e):s.all()}function nn(t,e){let s=`
|
|
254
414
|
SELECT
|
|
255
415
|
COUNT(*) as total,
|
|
256
416
|
COUNT(CASE WHEN status = 'completed' THEN 1 END) as completed,
|
|
@@ -260,19 +420,19 @@ data: ${JSON.stringify({timestamp:Date.now()})}
|
|
|
260
420
|
END) as avg_min
|
|
261
421
|
FROM sessions
|
|
262
422
|
${e?"WHERE project = ?":""}
|
|
263
|
-
`,n=e?t.query(s).get(e):t.query(s).get();return{total:n?.total||0,completed:n?.completed||0,avgDurationMinutes:Math.round((n?.avg_min||0)*10)/10}}function
|
|
423
|
+
`,n=e?t.query(s).get(e):t.query(s).get();return{total:n?.total||0,completed:n?.completed||0,avgDurationMinutes:Math.round((n?.avg_min||0)*10)/10}}function on(t,e){let r=Date.now(),s=r-r%(1440*60*1e3),n=r-10080*60*1e3,o=e?"WHERE project = $project":"",a=`
|
|
264
424
|
WITH
|
|
265
425
|
obs_stats AS (
|
|
266
426
|
SELECT
|
|
267
427
|
COUNT(*) as total,
|
|
268
|
-
COUNT(CASE WHEN created_at_epoch >=
|
|
269
|
-
COUNT(CASE WHEN created_at_epoch >=
|
|
428
|
+
COUNT(CASE WHEN created_at_epoch >= $todayStart THEN 1 END) as today,
|
|
429
|
+
COUNT(CASE WHEN created_at_epoch >= $weekStart THEN 1 END) as this_week,
|
|
270
430
|
COUNT(CASE WHEN is_stale = 1 THEN 1 END) as stale,
|
|
271
431
|
COUNT(CASE WHEN type IN ('constraint', 'decision', 'heuristic', 'rejected') THEN 1 END) as knowledge,
|
|
272
432
|
COALESCE(SUM(discovery_tokens), 0) as discovery_tokens,
|
|
273
433
|
COALESCE(SUM(CAST((LENGTH(COALESCE(title, '')) + LENGTH(COALESCE(narrative, ''))) / 4 AS INTEGER)), 0) as read_tokens
|
|
274
434
|
FROM observations
|
|
275
|
-
${e?"WHERE project =
|
|
435
|
+
${e?"WHERE project = $project":""}
|
|
276
436
|
),
|
|
277
437
|
sum_count AS (
|
|
278
438
|
SELECT COUNT(*) as total FROM summaries ${o}
|
|
@@ -295,47 +455,138 @@ data: ${JSON.stringify({timestamp:Date.now()})}
|
|
|
295
455
|
sess_count.total as sessions,
|
|
296
456
|
prompt_count.total as prompts
|
|
297
457
|
FROM obs_stats, sum_count, sess_count, prompt_count
|
|
298
|
-
`,c={
|
|
458
|
+
`,c={$todayStart:s,$weekStart:n};e&&(c.$project=e);let u=t.query(a).get(c),l=u?.discovery_tokens||0,d=u?.read_tokens||0,m=Math.max(0,l-d),g=l>0?Math.round((1-d/l)*100):0;return{observations:u?.observations||0,summaries:u?.summaries||0,sessions:u?.sessions||0,prompts:u?.prompts||0,observationsToday:u?.observations_today||0,observationsThisWeek:u?.observations_this_week||0,staleCount:u?.stale_count||0,knowledgeCount:u?.knowledge_count||0,tokenEconomics:{discoveryTokens:l,readTokens:d,savings:m,reductionPct:g}}}function an(t,e,r=6){let s=Date.now()-r*30*24*60*60*1e3,n=e?`SELECT
|
|
459
|
+
DATE(datetime(created_at_epoch / 1000, 'unixepoch')) as date,
|
|
460
|
+
COUNT(*) as count,
|
|
461
|
+
GROUP_CONCAT(DISTINCT project) as projects_csv
|
|
462
|
+
FROM observations
|
|
463
|
+
WHERE project = ? AND created_at_epoch >= ?
|
|
464
|
+
GROUP BY date
|
|
465
|
+
ORDER BY date ASC`:`SELECT
|
|
466
|
+
DATE(datetime(created_at_epoch / 1000, 'unixepoch')) as date,
|
|
467
|
+
COUNT(*) as count,
|
|
468
|
+
GROUP_CONCAT(DISTINCT project) as projects_csv
|
|
469
|
+
FROM observations
|
|
470
|
+
WHERE created_at_epoch >= ?
|
|
471
|
+
GROUP BY date
|
|
472
|
+
ORDER BY date ASC`,o=t.query(n);return(e?o.all(e,s):o.all(s)).map(a=>({date:a.date,count:a.count,projects:a.projects_csv?a.projects_csv.split(",").filter(Boolean):[]}))}var It=class{db;windowSize;threshold;constructor(e,r=20,s=2){this.db=e,this.windowSize=r,this.threshold=s}getBaseline(e){let r=this.db.query(`
|
|
473
|
+
SELECT
|
|
474
|
+
s.id,
|
|
475
|
+
s.content_session_id,
|
|
476
|
+
s.started_at_epoch,
|
|
477
|
+
s.completed_at_epoch,
|
|
478
|
+
CASE
|
|
479
|
+
WHEN s.completed_at_epoch IS NOT NULL AND s.completed_at_epoch > s.started_at_epoch
|
|
480
|
+
THEN (s.completed_at_epoch - s.started_at_epoch) / 1000.0 / 60.0
|
|
481
|
+
ELSE NULL
|
|
482
|
+
END as duration_minutes,
|
|
483
|
+
(SELECT COUNT(*) FROM observations o WHERE o.memory_session_id = s.memory_session_id) as obs_count,
|
|
484
|
+
(SELECT COUNT(*) FROM observations o WHERE o.memory_session_id = s.memory_session_id AND o.type = 'command') as cmd_count
|
|
485
|
+
FROM sessions s
|
|
486
|
+
WHERE s.project = ? AND s.status = 'completed' AND s.completed_at_epoch IS NOT NULL
|
|
487
|
+
ORDER BY s.completed_at_epoch DESC, s.id DESC
|
|
488
|
+
LIMIT ?
|
|
489
|
+
`).all(e,this.windowSize);if(r.length<3)return p.debug("DB",`Baseline for "${e}": only ${r.length} sessions, skipping`),null;let s=r.filter(i=>i.duration_minutes!==null).map(i=>i.duration_minutes),n=r.map(i=>i.obs_count),o=r.map(i=>i.cmd_count);return{project:e,avgDurationMinutes:Dt(s),stdDurationMinutes:yr(s),avgObservations:Dt(n),stdObservations:yr(n),avgCommands:Dt(o),stdCommands:yr(o),sampleSize:r.length}}detectAnomalies(e){let r=this.getBaseline(e);if(!r)return[];let s=this.db.query(`
|
|
490
|
+
SELECT
|
|
491
|
+
s.id,
|
|
492
|
+
s.content_session_id,
|
|
493
|
+
s.project,
|
|
494
|
+
s.started_at_epoch,
|
|
495
|
+
s.completed_at_epoch,
|
|
496
|
+
CASE
|
|
497
|
+
WHEN s.completed_at_epoch IS NOT NULL AND s.completed_at_epoch > s.started_at_epoch
|
|
498
|
+
THEN (s.completed_at_epoch - s.started_at_epoch) / 1000.0 / 60.0
|
|
499
|
+
ELSE NULL
|
|
500
|
+
END as duration_minutes,
|
|
501
|
+
(SELECT COUNT(*) FROM observations o WHERE o.memory_session_id = s.memory_session_id) as obs_count,
|
|
502
|
+
(SELECT COUNT(*) FROM observations o WHERE o.memory_session_id = s.memory_session_id AND o.type = 'command') as cmd_count,
|
|
503
|
+
(SELECT COUNT(*) FROM observations o WHERE o.memory_session_id = s.memory_session_id AND o.type = 'file-write') as write_count
|
|
504
|
+
FROM sessions s
|
|
505
|
+
WHERE s.project = ? AND s.status = 'completed' AND s.completed_at_epoch IS NOT NULL
|
|
506
|
+
ORDER BY s.completed_at_epoch DESC, s.id DESC
|
|
507
|
+
LIMIT ?
|
|
508
|
+
`).all(e,this.windowSize),n=[];for(let o of s){if(o.duration_minutes!==null&&r.stdDurationMinutes>0){let i=(o.duration_minutes-r.avgDurationMinutes)/r.stdDurationMinutes;i>this.threshold&&n.push({sessionId:o.id,contentSessionId:o.content_session_id,project:o.project,type:"long-session",score:Math.round(i*100)/100,value:Math.round(o.duration_minutes*10)/10,mean:Math.round(r.avgDurationMinutes*10)/10,stdDev:Math.round(r.stdDurationMinutes*10)/10,description:`Session lasted ${Math.round(o.duration_minutes)} minutes (avg: ${Math.round(r.avgDurationMinutes)} min)`})}if(o.obs_count>0&&r.stdCommands>0){let i=o.cmd_count/o.obs_count,a=(o.cmd_count-r.avgCommands)/r.stdCommands;a>this.threshold&&i>.8&&n.push({sessionId:o.id,contentSessionId:o.content_session_id,project:o.project,type:"repetitive-commands",score:Math.round(a*100)/100,value:o.cmd_count,mean:Math.round(r.avgCommands*10)/10,stdDev:Math.round(r.stdCommands*10)/10,description:`${o.cmd_count} commands (${Math.round(i*100)}% of observations, avg: ${Math.round(r.avgCommands)})`})}o.obs_count>r.avgObservations&&o.write_count===0&&n.push({sessionId:o.id,contentSessionId:o.content_session_id,project:o.project,type:"no-progress",score:0,value:o.obs_count,mean:Math.round(r.avgObservations*10)/10,stdDev:Math.round(r.stdObservations*10)/10,description:`${o.obs_count} observations but no files written`})}return n}};function Dt(t){return t.length===0?0:t.reduce((e,r)=>e+r,0)/t.length}function yr(t){if(t.length<2)return 0;let e=Dt(t),r=t.map(s=>(s-e)**2);return Math.sqrt(r.reduce((s,n)=>s+n,0)/(t.length-1))}function cn(t){let e=pa();return e.get("/api/analytics/overview",(r,s)=>{let{project:n}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=on(t.db.db,n||void 0);s.json(o)}catch(o){p.error("WORKER","Analytics overview failed",{project:n},o),s.status(500).json({error:"Analytics overview failed"})}}),e.get("/api/analytics/timeline",(r,s)=>{let{project:n,days:o}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let i=rn(t.db.db,n||void 0,_(o,30,1,365));s.json(i)}catch(i){p.error("WORKER","Analytics timeline failed",{project:n},i),s.status(500).json({error:"Analytics timeline failed"})}}),e.get("/api/analytics/types",(r,s)=>{let{project:n}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=sn(t.db.db,n||void 0);s.json(o)}catch(o){p.error("WORKER","Analytics types failed",{project:n},o),s.status(500).json({error:"Analytics types failed"})}}),e.get("/api/analytics/sessions",(r,s)=>{let{project:n}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=nn(t.db.db,n||void 0);s.json(o)}catch(o){p.error("WORKER","Analytics sessions failed",{project:n},o),s.status(500).json({error:"Analytics sessions failed"})}}),e.get("/api/analytics/heatmap",(r,s)=>{let{project:n,months:o}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let i=an(t.db.db,n||void 0,_(o,6,1,24));s.json({days:i})}catch(i){p.error("WORKER","Heatmap data failed",{project:n},i),s.status(500).json({error:"Heatmap data fetch failed"})}}),e.get("/api/concepts",(r,s)=>{let{project:n,limit:o}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}let i=_(o,50,1,200);try{let a=n?"SELECT concepts FROM observations WHERE project = ? AND concepts IS NOT NULL AND concepts != ''":"SELECT concepts FROM observations WHERE concepts IS NOT NULL AND concepts != ''",c=t.db.db.query(a),u=n?c.all(n):c.all(),l=new Map;for(let m of u){let g=m.concepts.split(",").map(f=>f.trim()).filter(Boolean);for(let f of g)l.set(f,(l.get(f)??0)+1)}let d=Array.from(l.entries()).sort((m,g)=>g[1]-m[1]).slice(0,i).map(([m,g])=>({concept:m,count:g}));s.json(d)}catch(a){p.error("WORKER","Concepts fetch failed",{project:n},a),s.status(500).json({error:"Concepts fetch failed"})}}),e.get("/api/analytics/anomalies",(r,s)=>{let{project:n,window:o,threshold:i}=r.query;if(!n){s.status(400).json({error:"project parameter is required"});return}if(!S(n)){s.status(400).json({error:"Invalid project name"});return}let a=_(o,20,3,200),c=i!==void 0?parseFloat(i):2;if(isNaN(c)||c<=0||c>10){s.status(400).json({error:"threshold must be a number between 0 and 10"});return}try{let u=new It(t.db.db,a,c),l=u.detectAnomalies(n),d=u.getBaseline(n);s.json({anomalies:l,baseline:d,project:n})}catch(u){p.error("WORKER","Anomaly detection failed",{project:n},u),s.status(500).json({error:"Anomaly detection failed"})}}),e}import{Router as la}from"express";function un(t){let e=la();return e.get("/api/sessions",(r,s)=>{let{project:n}=r.query;if(n&&!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=n?Ns(t.db.db,n,50):js(t.db.db,50);s.json(o)}catch(o){p.error("WORKER","Session list failed",{project:n},o),s.status(500).json({error:"Sessions list failed"})}}),e.get("/api/sessions/:id/checkpoint",(r,s)=>{let n=parseInt(r.params.id,10);if(isNaN(n)||n<=0){s.status(400).json({error:"Invalid session ID"});return}try{let o=vt(t.db.db,n);if(!o){s.status(404).json({error:"No checkpoint found for this session"});return}s.json(o)}catch(o){p.error("WORKER","Checkpoint fetch failed",{sessionId:n},o),s.status(500).json({error:"Checkpoint fetch failed"})}}),e.get("/api/checkpoint",(r,s)=>{let{project:n}=r.query;if(!n){s.status(400).json({error:"Project parameter is required"});return}if(!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=Rt(t.db.db,n);if(!o){s.status(404).json({error:"No checkpoint found for this project"});return}s.json(o)}catch(o){p.error("WORKER","Project checkpoint fetch failed",{project:n},o),s.status(500).json({error:"Project checkpoint fetch failed"})}}),e.get("/api/prompts",(r,s)=>{let{cursor:n,offset:o,limit:i,project:a}=r.query,c=_(i,20,1,200);try{let u;if(n){let m=K(n);if(!m){s.status(400).json({error:"Cursor non valido"});return}let g=a?`SELECT * FROM prompts
|
|
509
|
+
WHERE project = ? AND (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
510
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
511
|
+
LIMIT ?`:`SELECT * FROM prompts
|
|
512
|
+
WHERE (created_at_epoch < ? OR (created_at_epoch = ? AND id < ?))
|
|
513
|
+
ORDER BY created_at_epoch DESC, id DESC
|
|
514
|
+
LIMIT ?`;u=a?t.db.db.query(g).all(a,m.epoch,m.epoch,m.id,c):t.db.db.query(g).all(m.epoch,m.epoch,m.id,c)}else if(o!==void 0){let m=_(o,0,0,1e6),g=a?"SELECT * FROM prompts WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?":"SELECT * FROM prompts ORDER BY created_at_epoch DESC, id DESC LIMIT ? OFFSET ?";u=a?t.db.db.query(g).all(a,c,m):t.db.db.query(g).all(c,m)}else{let m=a?"SELECT * FROM prompts WHERE project = ? ORDER BY created_at_epoch DESC, id DESC LIMIT ?":"SELECT * FROM prompts ORDER BY created_at_epoch DESC, id DESC LIMIT ?";u=a?t.db.db.query(m).all(a,c):t.db.db.query(m).all(c)}let d=ue(u,c);if(!n){let m=a?"SELECT COUNT(*) as total FROM prompts WHERE project = ?":"SELECT COUNT(*) as total FROM prompts",{total:g}=a?t.db.db.query(m).get(a):t.db.db.query(m).get();s.setHeader("X-Total-Count",g)}s.json({data:u,next_cursor:d,has_more:d!==null})}catch(u){p.error("WORKER","Prompt list failed",{},u),s.status(500).json({error:"Failed to list prompts"})}}),e}import{Router as da}from"express";J();function pn(t){let e=da();return e.get("/api/projects",(r,s)=>{try{let n=Date.now();if(n-te.ts<bs&&te.data.length>0){s.json(te.data);return}let i=t.db.db.query(`SELECT DISTINCT project FROM (
|
|
299
515
|
SELECT project FROM observations
|
|
300
516
|
UNION
|
|
301
517
|
SELECT project FROM summaries
|
|
302
518
|
UNION
|
|
303
519
|
SELECT project FROM prompts
|
|
304
|
-
) ORDER BY project ASC`).all();
|
|
520
|
+
) ORDER BY project ASC`).all();te.data=i.map(a=>a.project),te.ts=n,s.json(te.data)}catch(n){p.error("WORKER","Project list failed",{},n),s.status(500).json({error:"Failed to list projects"})}}),e.get("/api/project-aliases",(r,s)=>{try{let o=t.db.db.query("SELECT project_name, display_name FROM project_aliases").all(),i={};for(let a of o)i[a.project_name]=a.display_name;s.json(i)}catch(n){p.error("WORKER","Alias list failed",{},n),s.status(500).json({error:"Failed to list project aliases"})}}),e.put("/api/project-aliases/:project",(r,s)=>{let{project:n}=r.params,{displayName:o}=r.body;if(!S(n)){s.status(400).json({error:"Invalid project name"});return}if(!o||typeof o!="string"||o.trim().length===0||o.length>100){s.status(400).json({error:'Field "displayName" is required (string, max 100 chars)'});return}try{let i=new Date().toISOString();t.db.db.query(`
|
|
305
521
|
INSERT INTO project_aliases (project_name, display_name, created_at, updated_at)
|
|
306
522
|
VALUES (?, ?, ?, ?)
|
|
307
523
|
ON CONFLICT(project_name) DO UPDATE SET display_name = excluded.display_name, updated_at = excluded.updated_at
|
|
308
|
-
`).run(n,o.trim(),i,i),s.json({ok:!0,project_name:n,display_name:o.trim()})}catch(i){p.error("WORKER","Alias update failed",{project:n},i),s.status(500).json({error:"Failed to update project alias"})}}),e.get("/api/stats/:project",(r,s)=>{let{project:n}=r.params;if(!
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
WHERE project = ? AND created_at_epoch >= ? AND created_at_epoch <= ?
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
524
|
+
`).run(n,o.trim(),i,i),s.json({ok:!0,project_name:n,display_name:o.trim()})}catch(i){p.error("WORKER","Alias update failed",{project:n},i),s.status(500).json({error:"Failed to update project alias"})}}),e.get("/api/stats/:project",(r,s)=>{let{project:n}=r.params;if(!S(n)){s.status(400).json({error:"Invalid project name"});return}try{let o=pt(t.db.db,n);s.json(o)}catch(o){p.error("WORKER","Stats failed",{project:n},o),s.status(500).json({error:"Stats failed"})}}),e}import{Router as ma}from"express";function ln(t){let e=[];if(e.push(`# Kiro Memory Report \u2014 ${t.period.label}`),e.push(""),e.push(`**Period**: ${t.period.start} \u2192 ${t.period.end} (${t.period.days} days)`),e.push(""),e.push("## Overview"),e.push(""),e.push("| Metric | Count |"),e.push("|--------|------:|"),e.push(`| Observations | ${t.overview.observations} |`),e.push(`| Summaries | ${t.overview.summaries} |`),e.push(`| Sessions | ${t.overview.sessions} |`),e.push(`| Prompts | ${t.overview.prompts} |`),e.push(`| Knowledge items | ${t.overview.knowledgeCount} |`),t.overview.staleCount>0&&e.push(`| Stale observations | ${t.overview.staleCount} |`),e.push(""),t.sessionStats.total>0){let r=Math.round(t.sessionStats.completed/t.sessionStats.total*100);e.push("## Sessions"),e.push(""),e.push(`- **Total**: ${t.sessionStats.total}`),e.push(`- **Completed**: ${t.sessionStats.completed} (${r}%)`),t.sessionStats.avgDurationMinutes>0&&e.push(`- **Avg duration**: ${t.sessionStats.avgDurationMinutes} min`),e.push("")}if(t.timeline.length>0){e.push("## Activity Timeline"),e.push(""),e.push("| Date | Observations |"),e.push("|------|------------:|");for(let r of t.timeline)e.push(`| ${r.day} | ${r.count} |`);e.push("")}if(t.typeDistribution.length>0){e.push("## Observation Types"),e.push("");for(let r of t.typeDistribution)e.push(`- **${r.type}**: ${r.count}`);e.push("")}if(t.topLearnings.length>0){e.push("## Key Learnings"),e.push("");for(let r of t.topLearnings)e.push(`- ${r}`);e.push("")}if(t.completedTasks.length>0){e.push("## Completed"),e.push("");for(let r of t.completedTasks)e.push(`- ${r}`);e.push("")}if(t.nextSteps.length>0){e.push("## Next Steps"),e.push("");for(let r of t.nextSteps)e.push(`- ${r}`);e.push("")}if(t.fileHotspots.length>0){e.push("## File Hotspots"),e.push(""),e.push("| File | Modifications |"),e.push("|------|-------------:|");for(let r of t.fileHotspots.slice(0,10))e.push(`| \`${r.file}\` | ${r.count} |`);e.push("")}return e.join(`
|
|
525
|
+
`)}function dn(t,e){let r=ma();function s(n,o,i){if(!e){i();return}if(n.headers["x-worker-token"]!==e){o.status(401).json({error:"Invalid or missing X-Worker-Token"});return}i()}return r.post("/api/embeddings/backfill",s,async(n,o)=>{let{batchSize:i}=n.body||{};try{let c=await M().backfillEmbeddings(t.db.db,_(String(i),50,1,500));o.json({success:!0,generated:c})}catch(a){p.error("WORKER","Backfill embeddings failed",{},a),o.status(500).json({error:"Backfill failed"})}}),r.get("/api/embeddings/stats",(n,o)=>{try{let a=M().getStats(t.db.db),c=L();o.json({...a,provider:c.getProvider(),dimensions:c.getDimensions(),available:c.isAvailable()})}catch(i){p.error("WORKER","Embedding stats failed",{},i),o.status(500).json({error:"Stats failed"})}}),r.get("/api/retention/preview",(n,o)=>{try{let i=je(xe()),a=vs(t.db.db,i);o.json({dryRun:!0,config:i,wouldDelete:a})}catch(i){p.error("WORKER","Retention preview failed",{},i),o.status(500).json({error:"Retention preview failed"})}}),r.post("/api/retention/apply",s,(n,o)=>{try{let i=je(xe()),a=ft(t.db.db,i);t.invalidateProjectsCache(),p.info("WORKER",`Retention apply: ${a.observations} obs, ${a.summaries} sum, ${a.prompts} prompts, ${a.knowledge} knowledge eliminati`),o.json({success:!0,config:i,deleted:a})}catch(i){p.error("WORKER","Retention apply failed",{},i),o.status(500).json({error:"Retention apply failed"})}}),r.post("/api/retention/cleanup",s,(n,o)=>{let{maxAgeDays:i,dryRun:a}=n.body||{},c=_(String(i),90,7,730),u=Date.now()-c*864e5;try{if(a){let m=t.db.db.query("SELECT COUNT(*) as c FROM observations WHERE created_at_epoch < ?").get(u).c,g=t.db.db.query("SELECT COUNT(*) as c FROM summaries WHERE created_at_epoch < ?").get(u).c,f=t.db.db.query("SELECT COUNT(*) as c FROM prompts WHERE created_at_epoch < ?").get(u).c;o.json({dryRun:!0,maxAgeDays:c,wouldDelete:{observations:m,summaries:g,prompts:f}});return}let d=t.db.db.transaction(()=>{t.db.db.run("DELETE FROM observation_embeddings WHERE observation_id IN (SELECT id FROM observations WHERE created_at_epoch < ?)",[u]);let m=t.db.db.run("DELETE FROM observations WHERE created_at_epoch < ?",[u]),g=t.db.db.run("DELETE FROM summaries WHERE created_at_epoch < ?",[u]),f=t.db.db.run("DELETE FROM prompts WHERE created_at_epoch < ?",[u]);return{observations:m.changes,summaries:g.changes,prompts:f.changes}})();t.invalidateProjectsCache(),p.info("WORKER",`Retention cleanup (legacy): deleted ${d.observations} obs, ${d.summaries} sum, ${d.prompts} prompts (> ${c}d)`),o.json({success:!0,maxAgeDays:c,deleted:d})}catch(l){p.error("WORKER","Retention cleanup failed",{maxAgeDays:c},l),o.status(500).json({error:"Retention cleanup failed"})}}),r.get("/api/export",(n,o)=>{let{project:i,format:a,type:c,days:u}=n.query;if(i&&!S(i)){o.status(400).json({error:"Invalid project name"});return}let l=_(u,30,1,365),d=Date.now()-l*864e5;try{let m="SELECT * FROM observations WHERE created_at_epoch > ?",g=[d];i&&(m+=" AND project = ?",g.push(i)),c&&(m+=" AND type = ?",g.push(c)),m+=" ORDER BY created_at_epoch DESC LIMIT 1000";let f=t.db.db.query(m).all(...g),h="SELECT * FROM summaries WHERE created_at_epoch > ?",E=[d];i&&(h+=" AND project = ?",E.push(i)),h+=" ORDER BY created_at_epoch DESC LIMIT 100";let w=t.db.db.query(h).all(...E);if(a==="markdown"||a==="md"){let v=["# Kiro Memory Export",`> Project: ${i||"All"} | Period: ${l} days | Generated: ${new Date().toISOString()}`,"",`## Observations (${f.length})`,""];for(let R of f){let ne=new Date(R.created_at_epoch).toISOString().split("T")[0];v.push(`### [${R.type}] ${R.title}`),v.push(`- **Date**: ${ne} | **Project**: ${R.project} | **ID**: #${R.id}`),R.narrative&&v.push(`- ${R.narrative}`),R.concepts&&v.push(`- **Concepts**: ${R.concepts}`),v.push("")}v.push(`## Summaries (${w.length})`,"");for(let R of w){let ne=new Date(R.created_at_epoch).toISOString().split("T")[0];v.push(`### Session ${R.session_id} (${ne})`),R.request&&v.push(`- **Request**: ${R.request}`),R.completed&&v.push(`- **Completed**: ${R.completed}`),R.next_steps&&v.push(`- **Next steps**: ${R.next_steps}`),v.push("")}o.type("text/markdown").send(v.join(`
|
|
526
|
+
`))}else o.json({meta:{project:i||"all",daysBack:l,exportedAt:new Date().toISOString()},observations:f,summaries:w})}catch(m){p.error("WORKER","Export failed",{project:i,fmt:a},m),o.status(500).json({error:"Export failed"})}}),r.get("/api/report",(n,o)=>{let{project:i,period:a,format:c}=n.query;if(i&&!S(i)){o.status(400).json({error:"Invalid project name"});return}let d=(["weekly","monthly"].includes(a||"")?a:"weekly")==="monthly"?30:7,m=Date.now(),g=m-d*24*60*60*1e3;try{let f=Tt(t.db.db,i||void 0,g,m),h=c||"json";h==="markdown"||h==="md"?o.type("text/markdown").send(ln(f)):h==="text"?o.type("text/plain").send(JSON.stringify(f,null,2)):o.json(f)}catch(f){p.error("WORKER","Report generation failed",{project:i,period:a},f),o.status(500).json({error:"Report generation failed"})}}),r}import{Router as ga}from"express";import mn from"crypto";var fa=new Set(["issues","pull_request","push"]),ha=new Set(["opened","closed","reopened","labeled"]),ya=new Set(["opened","closed","reopened","review_requested","merged"]);function Ea(t){try{let e=t.getConfig?.("github.webhook_secret");if(e&&typeof e=="string"&&e.trim().length>0)return e.trim()}catch{}return process.env.KIRO_MEMORY_GITHUB_WEBHOOK_SECRET||null}function ba(t,e,r){if(!e||!e.startsWith("sha256="))return!1;let s="sha256="+mn.createHmac("sha256",r).update(t).digest("hex");try{return mn.timingSafeEqual(Buffer.from(e,"utf-8"),Buffer.from(s,"utf-8"))}catch{return!1}}function _a(t){let e=new Set,r=/#(\d+)/g,s;for(;(s=r.exec(t))!==null;){let n=parseInt(s[1],10);n>0&&n<1e6&&e.add(n)}return Array.from(e)}function Sa(t,e,r){let{action:s,issue:n}=e;if(!(!ha.has(s)||!n))try{Ot(t.db.db,{repo:r,issue_number:n.number,event_type:"issues",action:s,title:n.title||null,url:n.html_url||null,author:n.user?.login||null}),p.debug("WEBHOOK",`Issue #${n.number} (${s}) salvato per ${r}`)}catch(o){p.error("WEBHOOK",`Errore salvataggio issue event per ${r}`,{},o)}}function va(t,e,r){let{action:s,pull_request:n}=e;if(!n)return;let o=s==="closed"&&n.merged?"merged":s;if(ya.has(o))try{Ot(t.db.db,{repo:r,pr_number:n.number,event_type:"pull_request",action:o,title:n.title||null,url:n.html_url||null,author:n.user?.login||null}),p.debug("WEBHOOK",`PR #${n.number} (${o}) salvato per ${r}`)}catch(i){p.error("WEBHOOK",`Errore salvataggio PR event per ${r}`,{},i)}}function Ra(t,e,r){let{commits:s,pusher:n,ref:o}=e;if(!Array.isArray(s)||s.length===0)return;let i=typeof o=="string"?o.replace("refs/heads/",""):null,a=n?.name||null;for(let c of s){let u=c.message||"",l=c.url||null,d=_a(u);for(let m of d)try{Ot(t.db.db,{repo:r,issue_number:m,event_type:"push",action:i?`push:${i}`:"push",title:u.split(`
|
|
527
|
+
`)[0].substring(0,500)||null,url:l,author:a}),p.debug("WEBHOOK",`Riferimento issue #${m} trovato nel commit di ${r}`)}catch(g){p.error("WEBHOOK",`Errore salvataggio push ref per ${r}`,{},g)}}}function Ta(t,e,r){let s=[];t.on("data",n=>{s.push(n)}),t.on("end",()=>{let n=Buffer.concat(s);if(t.rawBody=n,(t.headers["content-type"]||"").includes("application/json")&&n.length>0)try{t.body=JSON.parse(n.toString("utf-8"))}catch{t.body={}}r()}),t.on("error",()=>{t.rawBody=Buffer.alloc(0),r()})}function gn(t){let e=ga(),r=ge({windowMs:6e4,max:30,standardHeaders:!0,legacyHeaders:!1,message:{error:"Troppo molte richieste al webhook, riprova tra poco"}});return e.post("/api/webhooks/github",r,Ta,(s,n)=>{let o=Ea(t);if(o){let a=s.headers["x-hub-signature-256"],c=s.rawBody;if(!c){n.status(400).json({error:"Payload non leggibile"});return}if(!ba(c,a,o)){p.warn("WEBHOOK","Firma GitHub non valida",{hasSignature:!!a}),n.status(401).json({error:"Firma non valida o mancante"});return}}let i=s.headers["x-github-event"];if(!i||!fa.has(i)){n.json({ok:!0,processed:!1,reason:"Evento non gestito"});return}n.json({ok:!0,processed:!0}),setImmediate(()=>{try{let a=s.body;if(!a||typeof a!="object")return;let c=a.repository?.full_name||a.repository?.name||"unknown";switch(i){case"issues":Sa(t,a,c);break;case"pull_request":va(t,a,c);break;case"push":Ra(t,a,c);break}}catch(a){p.error("WEBHOOK","Errore elaborazione evento webhook",{},a)}})}),e.get("/api/github/links",(s,n)=>{let{repo:o,issue:i,pr:a,observation_id:c,query:u}=s.query,l=_(s.query.limit,20,1,200);try{let d;if(c){let m=parseInt(c,10);if(isNaN(m)||m<=0){n.status(400).json({error:'"observation_id" deve essere un intero positivo'});return}d=Ps(t.db.db,m)}else if(o&&i){let m=parseInt(i,10);if(isNaN(m)||m<=0){n.status(400).json({error:'"issue" deve essere un intero positivo'});return}d=$s(t.db.db,o,m)}else if(o&&a){let m=parseInt(a,10);if(isNaN(m)||m<=0){n.status(400).json({error:'"pr" deve essere un intero positivo'});return}d=Bs(t.db.db,o,m)}else o?d=Ms(t.db.db,o,l):d=Fs(t.db.db,u||"",{limit:l});n.json({links:d,total:d.length})}catch(d){p.error("WORKER","Errore query github links",{},d),n.status(500).json({error:"Errore nel recupero dei link GitHub"})}}),e.get("/api/github/repos",(s,n)=>{try{let o=Hs(t.db.db);n.json({repos:o})}catch(o){p.error("WORKER","Errore query github repos",{},o),n.status(500).json({error:"Errore nel recupero dei repository"})}}),e}import{Router as Oa}from"express";function fn(t){let e=Oa();return e.get("/api/export",(r,s)=>{let{project:n,type:o,from:i,to:a}=r.query;if(n&&!S(n)){s.status(400).json({error:"Nome progetto non valido"});return}if(i&&isNaN(new Date(i).getTime())){s.status(400).json({error:'Parametro "from" non \xE8 una data ISO valida'});return}if(a&&isNaN(new Date(a).getTime())){s.status(400).json({error:'Parametro "to" non \xE8 una data ISO valida'});return}let c={};n&&(c.project=n),o&&(c.type=o),i&&(c.from=i),a&&(c.to=a);let u=new Date().toISOString().replace(/[:.]/g,"-").substring(0,19),d=`kiro-memory${n?`_${n.replace(/[^a-z0-9]/gi,"_")}`:""}_${u}.jsonl`;try{s.setHeader("Content-Type","text/plain; charset=utf-8"),s.setHeader("Content-Disposition",`attachment; filename="${d}"`),s.setHeader("Transfer-Encoding","chunked"),s.setHeader("X-Content-Type-Options","nosniff");let m=t.db.db;s.write(Us(m,c)+`
|
|
528
|
+
`),Ks(m,c,g=>{s.write(g+`
|
|
529
|
+
`)}),Gs(m,c,g=>{s.write(g+`
|
|
530
|
+
`)}),Xs(m,c,g=>{s.write(g+`
|
|
531
|
+
`)}),s.end(),p.info("WORKER",`Export JSONL completato: project=${n||"all"}, from=${i||"-"}, to=${a||"-"}`)}catch(m){p.error("WORKER","Export JSONL fallito",{project:n,from:i,to:a},m),s.headersSent?s.end():s.status(500).json({error:"Export JSONL fallito"})}}),e.post("/api/import",wa,(r,s)=>{let n=r.query.dry_run==="true"||r.query.dry_run==="1",o;if(typeof r.body=="string")o=r.body;else if(r.body&&typeof r.body=="object"&&typeof r.body.content=="string")o=r.body.content;else{s.status(400).json({error:'Body deve essere testo JSONL (text/plain) o JSON con campo "content"'});return}if(!o||o.trim().length===0){s.status(400).json({error:"Body vuoto: nessun dato da importare"});return}let i=50*1024*1024;if(o.length>i){s.status(413).json({error:`File troppo grande: max ${i/1024/1024}MB`});return}try{let a=Ys(t.db.db,o,n);p.info("WORKER",`Import JSONL: ${a.imported} importati, ${a.skipped} saltati, ${a.errors} errori (dryRun=${n})`),!n&&a.imported>0&&t.invalidateProjectsCache(),s.json({success:!0,dryRun:n,imported:a.imported,skipped:a.skipped,errors:a.errors,total:a.total,errorDetails:a.errorDetails.slice(0,50)})}catch(a){p.error("WORKER","Import JSONL fallito",{dryRun:n},a),s.status(500).json({error:"Import JSONL fallito"})}}),e}function wa(t,e,r){let s=t.headers["content-type"]||"";if(typeof t.body=="object"&&t.body!==null){r();return}if(s.includes("text/plain")||s.includes("application/octet-stream")||!s){let n=[];t.on("data",o=>n.push(o)),t.on("end",()=>{t.body=Buffer.concat(n).toString("utf-8"),r()}),t.on("error",o=>{e.status(400).json({error:`Errore lettura body: ${o.message}`})})}else r()}import{Router as Ca}from"express";var En={type:"object",properties:{error:{type:"string",description:"Messaggio di errore leggibile"}},required:["error"]},hn={type:"object",properties:{id:{type:"integer"},session_id:{type:"string"},project:{type:"string"},type:{type:"string"},title:{type:"string"},narrative:{type:["string","null"]},content:{type:["string","null"]},summary:{type:["string","null"]},metadata:{type:["string","null"]},concepts:{type:["string","null"]},files:{type:["string","null"]},raw_payload:{type:["string","null"]},discovery_tokens:{type:"integer"},created_at_epoch:{type:"integer"}}},yn={type:"object",properties:{id:{type:"integer"},session_id:{type:"string"},project:{type:"string"},request:{type:["string","null"]},learned:{type:["string","null"]},completed:{type:["string","null"]},next_steps:{type:["string","null"]},raw_payload:{type:["string","null"]},created_at_epoch:{type:"integer"}}},Da={type:"object",properties:{id:{type:"integer"},session_id:{type:"string"},project:{type:"string"},started_at_epoch:{type:"integer"},ended_at_epoch:{type:["integer","null"]}}},Ia={type:"object",properties:{id:{type:"integer"},session_id:{type:"string"},project:{type:"string"},prompt:{type:"string"},created_at_epoch:{type:"integer"}}};function Er(t){return{description:"Lista paginata. Il totale \xE8 incluso nell'header X-Total-Count.",headers:{"X-Total-Count":{schema:{type:"integer"},description:"Numero totale di record nel database"}},content:{"application/json":{schema:{type:"array",items:t}}}}}function y(t){return{description:t,content:{"application/json":{schema:En}}}}var Ct={openapi:"3.1.0",info:{title:"Kiro Memory REST API",version:"3.0.0",description:["API REST del worker Kiro Memory (porta 3001).","Fornisce accesso a osservazioni, sommari, sessioni, ricerca,","analytics, export, embeddings vettoriali e gestione progetti."].join(" "),license:{name:"MIT"},contact:{name:"Auriti-Labs",url:"https://github.com/Auriti-Labs/kiro-memory"}},servers:[{url:"http://127.0.0.1:3001",description:"Worker locale (default)"}],components:{schemas:{Error:En,Observation:hn,Summary:yn,Session:Da,Prompt:Ia,Checkpoint:{type:"object",properties:{id:{type:"integer"},session_id:{type:"integer"},project:{type:"string"},content:{type:"string"},created_at_epoch:{type:"integer"}}},AnalyticsOverview:{type:"object",properties:{totalObservations:{type:"integer"},totalSummaries:{type:"integer"},totalPrompts:{type:"integer"},totalSessions:{type:"integer"},projects:{type:"array",items:{type:"string"}}}},TimelineEntry:{type:"object",properties:{date:{type:"string",format:"date"},count:{type:"integer"}}},TypeDistributionEntry:{type:"object",properties:{type:{type:"string"},count:{type:"integer"}}},SessionStats:{type:"object",properties:{totalSessions:{type:"integer"},avgObsPerSession:{type:"number"},avgDurationMs:{type:"number"}}},AnomalyEntry:{type:"object",properties:{sessionId:{type:"integer"},project:{type:"string"},obsCount:{type:"integer"},zScore:{type:"number"},isAnomaly:{type:"boolean"}}},EmbeddingStats:{type:"object",properties:{total:{type:"integer"},withEmbed:{type:"integer"},provider:{type:"string"},dimensions:{type:"integer"},available:{type:"boolean"}}},HybridSearchResult:{type:"object",properties:{id:{type:"integer"},project:{type:"string"},type:{type:"string"},title:{type:"string"},score:{type:"number"},source:{type:"string",enum:["vector","fts","hybrid"]}}},ProjectAlias:{type:"object",properties:{project_name:{type:"string"},display_name:{type:"string"}}},ProjectStats:{type:"object",properties:{project:{type:"string"},observations:{type:"integer"},summaries:{type:"integer"},prompts:{type:"integer"},sessions:{type:"integer"},lastActivity:{type:"integer",description:"epoch ms"}}},ExportData:{type:"object",properties:{meta:{type:"object",properties:{project:{type:"string"},daysBack:{type:"integer"},exportedAt:{type:"string",format:"date-time"}}},observations:{type:"array",items:hn},summaries:{type:"array",items:yn}}}},securitySchemes:{workerToken:{type:"apiKey",in:"header",name:"X-Worker-Token",description:"Token segreto per endpoint riservati (notify, backfill, cleanup)"}},parameters:{projectQuery:{name:"project",in:"query",schema:{type:"string"},description:"Filtra per nome progetto"},offsetQuery:{name:"offset",in:"query",schema:{type:"integer",default:0,minimum:0},description:"Offset paginazione"},limitQuery:{name:"limit",in:"query",schema:{type:"integer",default:20,minimum:1,maximum:200},description:"Numero massimo di risultati"}}},paths:{"/health":{get:{tags:["Core"],summary:"Health check",description:"Verifica che il worker sia attivo e restituisce la versione.",operationId:"getHealth",responses:{200:{description:"Worker attivo",content:{"application/json":{schema:{type:"object",properties:{status:{type:"string",example:"ok"},timestamp:{type:"integer",description:"epoch ms"},version:{type:"string",example:"2.1.0"}}}}}}}}},"/events":{get:{tags:["Core"],summary:"Server-Sent Events (SSE)",description:["Stream SSE per aggiornamenti in tempo reale alla dashboard.","Emette eventi: `connected`, `observation-created`, `summary-created`,","`prompt-created`, `session-created`. Keepalive ogni 15s.","Limite: 50 connessioni simultanee."].join(" "),operationId:"getEvents",responses:{200:{description:"Stream SSE attivo",content:{"text/event-stream":{schema:{type:"string"}}}},503:y("Troppi client SSE connessi")}}},"/api/notify":{post:{tags:["Core"],summary:"Notifica interna hook \u2192 SSE",description:["Endpoint riservato agli hook Kiro. Riceve un evento e lo broadcast","a tutti i client SSE connessi. Richiede `X-Worker-Token`.","Rate limit: 60 richieste/minuto."].join(" "),operationId:"postNotify",security:[{workerToken:[]}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["event"],properties:{event:{type:"string",enum:["observation-created","summary-created","prompt-created","session-created"]},data:{type:"object",additionalProperties:!0}}}}}},responses:{200:{description:"Evento broadcast con successo",content:{"application/json":{schema:{type:"object",properties:{ok:{type:"boolean"}}}}}},400:y("Evento non valido o non consentito"),401:y("Token mancante o non valido")}}},"/api/observations":{get:{tags:["Observations"],summary:"Lista osservazioni paginate",operationId:"listObservations",parameters:[{$ref:"#/components/parameters/offsetQuery"},{$ref:"#/components/parameters/limitQuery"},{$ref:"#/components/parameters/projectQuery"}],responses:{200:Er({$ref:"#/components/schemas/Observation"}),500:y("Errore interno")}},post:{tags:["Observations"],summary:"Crea una nuova osservazione",operationId:"createObservation",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["project","title"],properties:{memorySessionId:{type:"string"},project:{type:"string"},type:{type:"string",default:"manual"},title:{type:"string",maxLength:500},content:{type:"string",maxLength:1e5},concepts:{type:"array",items:{type:"string"}},files:{type:"array",items:{type:"string"}}}}}}},responses:{200:{description:"Osservazione creata",content:{"application/json":{schema:{type:"object",properties:{id:{type:"integer"},success:{type:"boolean"}}}}}},400:y("Payload non valido"),500:y("Errore di persistenza")}}},"/api/observations/batch":{post:{tags:["Observations"],summary:"Recupero batch per ID (max 100)",operationId:"batchGetObservations",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["ids"],properties:{ids:{type:"array",items:{type:"integer",minimum:1},minItems:1,maxItems:100}}}}}},responses:{200:{description:"Osservazioni trovate",content:{"application/json":{schema:{type:"object",properties:{observations:{type:"array",items:{$ref:"#/components/schemas/Observation"}}}}}}},400:y("Array ids non valido"),500:y("Errore interno")}}},"/api/knowledge":{post:{tags:["Observations"],summary:"Salva conoscenza strutturata",description:["Crea un'osservazione di tipo knowledge con metadati tipizzati.","Tipi supportati: `constraint`, `decision`, `heuristic`, `rejected`."].join(" "),operationId:"createKnowledge",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["project","knowledge_type","title","content"],properties:{project:{type:"string"},knowledge_type:{type:"string",enum:["constraint","decision","heuristic","rejected"]},title:{type:"string",maxLength:500},content:{type:"string",maxLength:1e5},concepts:{type:"array",items:{type:"string"}},files:{type:"array",items:{type:"string"}},severity:{type:"string",enum:["hard","soft"],description:"Solo per constraint"},alternatives:{type:"array",items:{type:"string"},description:"Solo per decision/rejected"},reason:{type:"string",description:"Motivazione (constraint, decision, rejected)"},context:{type:"string",description:"Contesto applicativo (heuristic)"},confidence:{type:"string",enum:["high","medium","low"],description:"Solo per heuristic"}}}}}},responses:{200:{description:"Conoscenza salvata",content:{"application/json":{schema:{type:"object",properties:{id:{type:"integer"},success:{type:"boolean"},knowledge_type:{type:"string"}}}}}},400:y("Payload non valido o knowledge_type sconosciuto"),500:y("Errore di persistenza")}}},"/api/memory/save":{post:{tags:["Observations"],summary:"Salva una memoria (endpoint programmabile)",operationId:"saveMemory",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["project","title","content"],properties:{project:{type:"string"},title:{type:"string",maxLength:500},content:{type:"string",maxLength:1e5},type:{type:"string",default:"research"},concepts:{type:["array","string"],items:{type:"string"}}}}}}},responses:{200:{description:"Memoria salvata",content:{"application/json":{schema:{type:"object",properties:{id:{type:"integer"},success:{type:"boolean"}}}}}},400:y("Campo obbligatorio mancante o non valido"),500:y("Errore di persistenza")}}},"/api/context/{project}":{get:{tags:["Observations"],summary:"Contesto progetto (ultime osservazioni + sommari)",operationId:"getProjectContext",parameters:[{name:"project",in:"path",required:!0,schema:{type:"string"},description:"Nome del progetto"}],responses:{200:{description:"Contesto del progetto",content:{"application/json":{schema:{type:"object",properties:{project:{type:"string"},observations:{type:"array",items:{$ref:"#/components/schemas/Observation"}},summaries:{type:"array",items:{$ref:"#/components/schemas/Summary"}}}}}}},400:y("Nome progetto non valido"),500:y("Errore interno")}}},"/api/summaries":{get:{tags:["Summaries"],summary:"Lista sommari paginata",operationId:"listSummaries",parameters:[{$ref:"#/components/parameters/offsetQuery"},{$ref:"#/components/parameters/limitQuery"},{$ref:"#/components/parameters/projectQuery"}],responses:{200:Er({$ref:"#/components/schemas/Summary"}),500:y("Errore interno")}},post:{tags:["Summaries"],summary:"Crea un nuovo sommario di sessione",operationId:"createSummary",requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["project"],properties:{sessionId:{type:"string"},project:{type:"string"},request:{type:"string",maxLength:5e4},learned:{type:"string",maxLength:5e4},completed:{type:"string",maxLength:5e4},nextSteps:{type:"string",maxLength:5e4}}}}}},responses:{200:{description:"Sommario creato",content:{"application/json":{schema:{type:"object",properties:{id:{type:"integer"},success:{type:"boolean"}}}}}},400:y("Payload non valido o campo troppo grande"),500:y("Errore di persistenza")}}},"/api/search":{get:{tags:["Search"],summary:"Ricerca full-text FTS5",operationId:"searchFTS",parameters:[{name:"q",in:"query",required:!0,schema:{type:"string"},description:"Testo da cercare (SQLite FTS5)"},{$ref:"#/components/parameters/projectQuery"},{name:"type",in:"query",schema:{type:"string"},description:"Filtra per tipo osservazione"},{name:"limit",in:"query",schema:{type:"integer",default:20,minimum:1,maximum:100}}],responses:{200:{description:"Risultati ricerca FTS5",content:{"application/json":{schema:{type:"object",properties:{observations:{type:"array",items:{$ref:"#/components/schemas/Observation"}},summaries:{type:"array",items:{$ref:"#/components/schemas/Summary"}}}}}}},400:y('Parametro "q" obbligatorio'),500:y("Ricerca fallita")}}},"/api/hybrid-search":{get:{tags:["Search"],summary:"Ricerca ibrida (vettoriale + keyword)",description:"Combina embedding vettoriali e FTS5 per una ricerca semantica avanzata.",operationId:"searchHybrid",parameters:[{name:"q",in:"query",required:!0,schema:{type:"string"},description:"Testo da cercare"},{$ref:"#/components/parameters/projectQuery"},{name:"limit",in:"query",schema:{type:"integer",default:10,minimum:1,maximum:100}}],responses:{200:{description:"Risultati ibridi con score di rilevanza",content:{"application/json":{schema:{type:"object",properties:{results:{type:"array",items:{$ref:"#/components/schemas/HybridSearchResult"}},count:{type:"integer"}}}}}},400:y('Parametro "q" obbligatorio'),500:y("Ricerca ibrida fallita")}}},"/api/timeline":{get:{tags:["Search"],summary:"Timeline cronologica intorno a un'osservazione",operationId:"getTimeline",parameters:[{name:"anchor",in:"query",required:!0,schema:{type:"integer",minimum:1},description:"ID dell'osservazione centrale"},{name:"depth_before",in:"query",schema:{type:"integer",default:5,minimum:1,maximum:50},description:"Numero di osservazioni precedenti"},{name:"depth_after",in:"query",schema:{type:"integer",default:5,minimum:1,maximum:50},description:"Numero di osservazioni successive"}],responses:{200:{description:"Timeline restituita",content:{"application/json":{schema:{type:"object",properties:{timeline:{type:"array",items:{$ref:"#/components/schemas/Observation"}}}}}}},400:y('Parametro "anchor" mancante o non valido'),500:y("Timeline fallita")}}},"/api/analytics/overview":{get:{tags:["Analytics"],summary:"Panoramica aggregata delle statistiche",operationId:"getAnalyticsOverview",parameters:[{$ref:"#/components/parameters/projectQuery"}],responses:{200:{description:"Overview aggregata",content:{"application/json":{schema:{$ref:"#/components/schemas/AnalyticsOverview"}}}},400:y("Nome progetto non valido"),500:y("Analytics overview fallita")}}},"/api/analytics/timeline":{get:{tags:["Analytics"],summary:"Distribuzione temporale osservazioni per giorno",operationId:"getAnalyticsTimeline",parameters:[{$ref:"#/components/parameters/projectQuery"},{name:"days",in:"query",schema:{type:"integer",default:30,minimum:1,maximum:365},description:"Finestra temporale in giorni"}],responses:{200:{description:"Serie temporale giornaliera",content:{"application/json":{schema:{type:"array",items:{$ref:"#/components/schemas/TimelineEntry"}}}}},400:y("Nome progetto non valido"),500:y("Analytics timeline fallita")}}},"/api/analytics/types":{get:{tags:["Analytics"],summary:"Distribuzione per tipo osservazione",operationId:"getAnalyticsTypes",parameters:[{$ref:"#/components/parameters/projectQuery"}],responses:{200:{description:"Distribuzione dei tipi",content:{"application/json":{schema:{type:"array",items:{$ref:"#/components/schemas/TypeDistributionEntry"}}}}},400:y("Nome progetto non valido"),500:y("Analytics types fallita")}}},"/api/analytics/sessions":{get:{tags:["Analytics"],summary:"Statistiche aggregate delle sessioni",operationId:"getAnalyticsSessions",parameters:[{$ref:"#/components/parameters/projectQuery"}],responses:{200:{description:"Statistiche sessioni",content:{"application/json":{schema:{$ref:"#/components/schemas/SessionStats"}}}},400:y("Nome progetto non valido"),500:y("Analytics sessions fallita")}}},"/api/analytics/anomalies":{get:{tags:["Analytics"],summary:"Rilevamento anomalie sessioni tramite z-score",operationId:"getAnomalies",parameters:[{name:"project",in:"query",required:!0,schema:{type:"string"},description:"Nome progetto (obbligatorio)"},{name:"window",in:"query",schema:{type:"integer",default:20,minimum:3,maximum:200},description:"Dimensione finestra rolling"},{name:"threshold",in:"query",schema:{type:"number",default:2,minimum:.1,maximum:10},description:"Soglia z-score per segnalare anomalia"}],responses:{200:{description:"Anomalie rilevate",content:{"application/json":{schema:{type:"object",properties:{anomalies:{type:"array",items:{$ref:"#/components/schemas/AnomalyEntry"}},baseline:{type:"number"},project:{type:"string"}}}}}},400:y("Parametro project obbligatorio o threshold non valida"),500:y("Rilevamento anomalie fallito")}}},"/api/sessions":{get:{tags:["Sessions"],summary:"Lista sessioni (max 50)",operationId:"listSessions",parameters:[{$ref:"#/components/parameters/projectQuery"}],responses:{200:{description:"Lista sessioni",content:{"application/json":{schema:{type:"array",items:{$ref:"#/components/schemas/Session"}}}}},400:y("Nome progetto non valido"),500:y("Errore interno")}}},"/api/sessions/{id}/checkpoint":{get:{tags:["Sessions"],summary:"Ultimo checkpoint di una sessione",operationId:"getSessionCheckpoint",parameters:[{name:"id",in:"path",required:!0,schema:{type:"integer",minimum:1},description:"ID numerico della sessione"}],responses:{200:{description:"Checkpoint trovato",content:{"application/json":{schema:{$ref:"#/components/schemas/Checkpoint"}}}},400:y("ID sessione non valido"),404:y("Nessun checkpoint trovato per questa sessione"),500:y("Errore interno")}}},"/api/checkpoint":{get:{tags:["Sessions"],summary:"Ultimo checkpoint del progetto",operationId:"getProjectCheckpoint",parameters:[{name:"project",in:"query",required:!0,schema:{type:"string"},description:"Nome progetto (obbligatorio)"}],responses:{200:{description:"Checkpoint trovato",content:{"application/json":{schema:{$ref:"#/components/schemas/Checkpoint"}}}},400:y("Parametro project mancante o non valido"),404:y("Nessun checkpoint trovato per questo progetto"),500:y("Errore interno")}}},"/api/prompts":{get:{tags:["Sessions"],summary:"Lista prompt utente paginata",operationId:"listPrompts",parameters:[{$ref:"#/components/parameters/offsetQuery"},{name:"limit",in:"query",schema:{type:"integer",default:20,minimum:1,maximum:200}},{$ref:"#/components/parameters/projectQuery"}],responses:{200:Er({$ref:"#/components/schemas/Prompt"}),500:y("Errore interno")}}},"/api/projects":{get:{tags:["Projects"],summary:"Lista nomi progetto distinti (cache 60s)",operationId:"listProjects",responses:{200:{description:"Array di nomi progetto",content:{"application/json":{schema:{type:"array",items:{type:"string"}}}}},500:y("Errore interno")}}},"/api/project-aliases":{get:{tags:["Projects"],summary:"Mappa alias \u2192 display name",operationId:"getProjectAliases",responses:{200:{description:"Oggetto `{ project_name: display_name }`",content:{"application/json":{schema:{type:"object",additionalProperties:{type:"string"}}}}},500:y("Errore interno")}}},"/api/project-aliases/{project}":{put:{tags:["Projects"],summary:"Crea o aggiorna display name di un progetto",operationId:"upsertProjectAlias",parameters:[{name:"project",in:"path",required:!0,schema:{type:"string"},description:"Nome tecnico del progetto"}],requestBody:{required:!0,content:{"application/json":{schema:{type:"object",required:["displayName"],properties:{displayName:{type:"string",maxLength:100}}}}}},responses:{200:{description:"Alias aggiornato",content:{"application/json":{schema:{type:"object",properties:{ok:{type:"boolean"},project_name:{type:"string"},display_name:{type:"string"}}}}}},400:y("Payload non valido o nome progetto non valido"),500:y("Errore interno")}}},"/api/stats/{project}":{get:{tags:["Projects"],summary:"Statistiche aggregate per progetto",operationId:"getProjectStats",parameters:[{name:"project",in:"path",required:!0,schema:{type:"string"},description:"Nome del progetto"}],responses:{200:{description:"Statistiche progetto",content:{"application/json":{schema:{$ref:"#/components/schemas/ProjectStats"}}}},400:y("Nome progetto non valido"),500:y("Errore interno")}}},"/api/embeddings/backfill":{post:{tags:["Data"],summary:"Backfill embedding per osservazioni senza vettore",operationId:"backfillEmbeddings",security:[{workerToken:[]}],requestBody:{content:{"application/json":{schema:{type:"object",properties:{batchSize:{type:"integer",default:50,minimum:1,maximum:500}}}}}},responses:{200:{description:"Backfill completato",content:{"application/json":{schema:{type:"object",properties:{success:{type:"boolean"},generated:{type:"integer",description:"Embedding generati"}}}}}},401:y("Token non valido"),500:y("Backfill fallito")}}},"/api/embeddings/stats":{get:{tags:["Data"],summary:"Statistiche embedding vettoriali",operationId:"getEmbeddingStats",responses:{200:{description:"Statistiche embedding",content:{"application/json":{schema:{$ref:"#/components/schemas/EmbeddingStats"}}}},500:y("Errore interno")}}},"/api/retention/cleanup":{post:{tags:["Data"],summary:"Pulizia dati secondo policy di retention",description:"Elimina osservazioni, sommari e prompt pi\xF9 vecchi di `maxAgeDays` giorni. Supporta modalit\xE0 dry-run.",operationId:"runRetentionCleanup",security:[{workerToken:[]}],requestBody:{content:{"application/json":{schema:{type:"object",properties:{maxAgeDays:{type:"integer",default:90,minimum:7,maximum:730,description:"Et\xE0 massima in giorni"},dryRun:{type:"boolean",default:!1,description:"Se true, simula senza eliminare"}}}}}},responses:{200:{description:"Cleanup eseguito o simulato",content:{"application/json":{schema:{oneOf:[{description:"Risultato dry-run",type:"object",properties:{dryRun:{type:"boolean"},maxAgeDays:{type:"integer"},wouldDelete:{type:"object",properties:{observations:{type:"integer"},summaries:{type:"integer"},prompts:{type:"integer"}}}}},{description:"Risultato cleanup reale",type:"object",properties:{success:{type:"boolean"},maxAgeDays:{type:"integer"},deleted:{type:"object",properties:{observations:{type:"integer"},summaries:{type:"integer"},prompts:{type:"integer"}}}}}]}}}},401:y("Token non valido"),500:y("Cleanup fallito")}}},"/api/export":{get:{tags:["Data"],summary:"Esporta osservazioni e sommari",description:"Esporta i dati in formato JSON (default) o Markdown.",operationId:"exportData",parameters:[{$ref:"#/components/parameters/projectQuery"},{name:"format",in:"query",schema:{type:"string",enum:["json","markdown","md"],default:"json"},description:"Formato di output"},{name:"type",in:"query",schema:{type:"string"},description:"Filtra per tipo osservazione"},{name:"days",in:"query",schema:{type:"integer",default:30,minimum:1,maximum:365},description:"Finestra temporale in giorni"}],responses:{200:{description:"Export in formato selezionato",content:{"application/json":{schema:{$ref:"#/components/schemas/ExportData"}},"text/markdown":{schema:{type:"string"}}}},400:y("Nome progetto non valido"),500:y("Export fallito")}}},"/api/report":{get:{tags:["Data"],summary:"Report attivit\xE0 (weekly/monthly)",operationId:"getReport",parameters:[{$ref:"#/components/parameters/projectQuery"},{name:"period",in:"query",schema:{type:"string",enum:["weekly","monthly"],default:"weekly"},description:"Periodo del report"},{name:"format",in:"query",schema:{type:"string",enum:["json","markdown","md","text"],default:"json"},description:"Formato di output"}],responses:{200:{description:"Report generato",content:{"application/json":{schema:{type:"object",additionalProperties:!0}},"text/markdown":{schema:{type:"string"}},"text/plain":{schema:{type:"string"}}}},400:y("Nome progetto non valido"),500:y("Generazione report fallita")}}},"/api/docs":{get:{tags:["Docs"],summary:"Swagger UI interattiva",operationId:"getSwaggerUI",responses:{200:{description:"Pagina HTML Swagger UI",content:{"text/html":{schema:{type:"string"}}}}}}},"/api/docs/openapi.json":{get:{tags:["Docs"],summary:"Specifica OpenAPI 3.1 in formato JSON",operationId:"getOpenApiSpec",responses:{200:{description:"Specifica OpenAPI 3.1",content:{"application/json":{schema:{type:"object",additionalProperties:!0}}}}}}}},tags:[{name:"Core",description:"Health check, SSE, notifiche interne"},{name:"Observations",description:"CRUD osservazioni, knowledge, memoria"},{name:"Summaries",description:"Sommari di sessione"},{name:"Search",description:"Ricerca FTS5, vettoriale ibrida, timeline"},{name:"Analytics",description:"Overview, distribuzione, anomalie"},{name:"Sessions",description:"Sessioni, checkpoint, prompt"},{name:"Projects",description:"Lista progetti, alias, statistiche"},{name:"Data",description:"Embedding, retention, export, report"},{name:"Docs",description:"Documentazione API interattiva"}]};function ja(t){return`<!DOCTYPE html>
|
|
532
|
+
<html lang="it">
|
|
533
|
+
<head>
|
|
534
|
+
<meta charset="UTF-8" />
|
|
535
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
536
|
+
<title>Kiro Memory API \u2014 Documentazione</title>
|
|
537
|
+
<meta name="description" content="Documentazione interattiva dell'API REST di Kiro Memory" />
|
|
538
|
+
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css" />
|
|
539
|
+
<style>
|
|
540
|
+
/* Stile minimo per rimuovere il banner Swagger */
|
|
541
|
+
.swagger-ui .topbar { display: none; }
|
|
542
|
+
body { margin: 0; background: #fafafa; }
|
|
543
|
+
#kiro-header {
|
|
544
|
+
background: #1a1a2e;
|
|
545
|
+
color: #e0e0e0;
|
|
546
|
+
padding: 14px 24px;
|
|
547
|
+
font-family: system-ui, sans-serif;
|
|
548
|
+
display: flex;
|
|
549
|
+
align-items: center;
|
|
550
|
+
gap: 12px;
|
|
551
|
+
}
|
|
552
|
+
#kiro-header h1 { margin: 0; font-size: 1.1rem; font-weight: 600; }
|
|
553
|
+
#kiro-header .badge {
|
|
554
|
+
background: #16213e;
|
|
555
|
+
border: 1px solid #0f3460;
|
|
556
|
+
border-radius: 4px;
|
|
557
|
+
padding: 2px 8px;
|
|
558
|
+
font-size: 0.75rem;
|
|
559
|
+
color: #94a3b8;
|
|
560
|
+
}
|
|
561
|
+
</style>
|
|
562
|
+
</head>
|
|
563
|
+
<body>
|
|
564
|
+
<div id="kiro-header">
|
|
565
|
+
<h1>Kiro Memory REST API</h1>
|
|
566
|
+
<span class="badge">v${Ct.info.version}</span>
|
|
567
|
+
<span class="badge">OpenAPI 3.1</span>
|
|
568
|
+
</div>
|
|
569
|
+
<div id="swagger-ui"></div>
|
|
570
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js"></script>
|
|
571
|
+
<script src="https://unpkg.com/swagger-ui-dist@5/swagger-ui-standalone-preset.js"></script>
|
|
572
|
+
<script>
|
|
573
|
+
window.onload = function () {
|
|
574
|
+
SwaggerUIBundle({
|
|
575
|
+
url: '${t}',
|
|
576
|
+
dom_id: '#swagger-ui',
|
|
577
|
+
deepLinking: true,
|
|
578
|
+
presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset],
|
|
579
|
+
layout: 'StandaloneLayout',
|
|
580
|
+
tryItOutEnabled: true,
|
|
581
|
+
requestSnippetsEnabled: true,
|
|
582
|
+
displayRequestDuration: true,
|
|
583
|
+
filter: true,
|
|
584
|
+
defaultModelsExpandDepth: 1,
|
|
585
|
+
defaultModelExpandDepth: 2,
|
|
586
|
+
docExpansion: 'list'
|
|
587
|
+
});
|
|
588
|
+
};
|
|
589
|
+
</script>
|
|
590
|
+
</body>
|
|
591
|
+
</html>`}function bn(){let t=Ca();return t.get("/api/docs/openapi.json",(e,r)=>{r.setHeader("Cache-Control","public, max-age=300"),r.json(Ct)}),t.get("/api/docs",(e,r)=>{let s=ja("/api/docs/openapi.json");r.setHeader("Content-Type","text/html; charset=utf-8"),r.setHeader("Cache-Control","public, max-age=300"),r.send(s)}),t}import{Router as Na}from"express";function _n(t,e){let r=Na();function s(n,o,i){if(!e){i();return}if(n.headers["x-worker-token"]!==e){o.status(401).json({error:"X-Worker-Token non valido o mancante"});return}i()}return r.get("/api/backup/list",(n,o)=>{try{let a=Et(Y).map(c=>({filename:c.metadata.filename,timestamp:c.metadata.timestamp,timestampEpoch:c.metadata.timestampEpoch,schemaVersion:c.metadata.schemaVersion,stats:c.metadata.stats,filePath:c.filePath}));o.json({backups:a,total:a.length,backupDir:Y})}catch(i){p.error("BACKUP","Elenco backup fallito",{},i),o.status(500).json({error:"Impossibile elencare i backup"})}}),r.post("/api/backup/create",(n,o)=>{try{let i=Number(se("backup.maxKeep"))||7,a=yt(ce,Y,t.db.db),c=bt(Y,i);p.info("BACKUP",`Backup manuale creato: ${a.metadata.filename}`),o.json({success:!0,filename:a.metadata.filename,timestamp:a.metadata.timestamp,stats:a.metadata.stats,rotated:c})}catch(i){p.error("BACKUP","Creazione backup fallita",{},i),o.status(500).json({error:"Creazione backup fallita"})}}),r.post("/api/backup/restore",s,(n,o)=>{let{file:i}=n.body;if(!i||typeof i!="string"){o.status(400).json({error:'Campo "file" obbligatorio'});return}let a=/^backup-\d{4}-\d{2}-\d{2}-\d{6}(-\d{3})?\.db$/;if(i.includes("/")||i.includes("..")||!a.test(i)){o.status(400).json({error:'Nome file non valido (deve essere "backup-YYYY-MM-DD-HHmmss[-mmm].db")'});return}try{let u=Et(Y).find(l=>l.metadata.filename===i);if(!u){o.status(404).json({error:`Backup non trovato: ${i}`});return}Rs(u.filePath,ce),p.info("BACKUP",`Database ripristinato da: ${i}`),o.json({success:!0,restoredFrom:i,timestamp:u.metadata.timestamp,message:"Database ripristinato. Riavviare il worker per applicare le modifiche."})}catch(c){p.error("BACKUP",`Ripristino backup fallito: ${i}`,{},c),o.status(500).json({error:"Ripristino backup fallito"})}}),r}import{Router as Aa}from"express";function Sn(t){let e=Aa(),r=_e.getInstance(),s=new Le({skipMigrations:!0});return e.get("/api/plugins",(n,o)=>{try{let i=r.getAll();o.json({plugins:i,total:i.length})}catch(i){p.error("WORKER","Recupero lista plugin fallito",{},i),o.status(500).json({error:"Impossibile recuperare la lista plugin"})}}),e.post("/api/plugins/:name/enable",async(n,o)=>{let{name:i}=n.params;if(!i||typeof i!="string"||i.trim().length===0){o.status(400).json({error:"Nome plugin non valido"});return}if(!r.get(i)){o.status(404).json({error:`Plugin non trovato: "${i}"`});return}try{let c={sdk:s,logger:ws(i),config:{}};await r.enable(i,c);let u=r.getAll().find(l=>l.name===i);o.json({success:!0,plugin:u})}catch(c){p.error("WORKER",`Abilitazione plugin "${i}" fallita`,{},c),o.status(500).json({error:`Impossibile abilitare il plugin "${i}"`})}}),e.post("/api/plugins/:name/disable",async(n,o)=>{let{name:i}=n.params;if(!i||typeof i!="string"||i.trim().length===0){o.status(400).json({error:"Nome plugin non valido"});return}if(!r.get(i)){o.status(404).json({error:`Plugin non trovato: "${i}"`});return}try{await r.disable(i);let c=r.getAll().find(u=>u.name===i);o.json({success:!0,plugin:c})}catch(c){p.error("WORKER",`Disabilitazione plugin "${i}" fallita`,{},c),o.status(500).json({error:`Impossibile disabilitare il plugin "${i}"`})}}),e}var Tn=La($a(import.meta.url)),Me=process.env.KIRO_MEMORY_WORKER_PORT||process.env.CONTEXTKIT_WORKER_PORT||3001,br=process.env.KIRO_MEMORY_WORKER_HOST||process.env.CONTEXTKIT_WORKER_HOST||"127.0.0.1",Pe=Sr(I,"worker.pid"),_r=Sr(I,"worker.token");jt(I)||Pa(I,{recursive:!0});var At=ka.randomBytes(32).toString("hex");Rn(_r,At,"utf-8");try{Ma(_r,384)}catch(t){process.platform!=="win32"&&p.warn("WORKER",`chmod 600 failed on ${_r}`,{},t)}var $e=new V;p.info("WORKER","Database initialized");ee().initialize().catch(t=>{p.warn("WORKER","Embedding initialization failed, FTS5 search only",{},t)});var B=_s($e),O=Nt();O.use($r({contentSecurityPolicy:{directives:{defaultSrc:["'self'"],scriptSrc:["'self'","'unsafe-inline'"],styleSrc:["'self'","'unsafe-inline'","https://fonts.googleapis.com"],imgSrc:["'self'","data:"],connectSrc:["'self'"],fontSrc:["'self'","https://fonts.gstatic.com"],frameSrc:["'none'"]}}}));O.use(xa({origin:[`http://localhost:${Me}`,`http://127.0.0.1:${Me}`,`http://${br}:${Me}`],credentials:!0,maxAge:86400}));O.use(Nt.json({limit:"50mb"}));O.use(Nt.text({limit:"50mb",type:"text/plain"}));O.use("/api/",ge({windowMs:6e4,max:200,standardHeaders:!0,legacyHeaders:!1,message:{error:"Too many requests, retry later"}}));O.use(Qs(B,At));O.use(Zs(B));O.use(en(B));O.use(tn(B));O.use(cn(B));O.use(un(B));O.use(pn(B));O.use(dn(B,At));O.use(gn(B));O.use(fn(B));O.use(bn());O.use(_n(B,At));O.use(Sn(B));O.use(Nt.static(Tn,{index:!1,maxAge:"1h"}));O.get("/",(t,e)=>{let r=Sr(Tn,"viewer.html");jt(r)?e.sendFile(r):e.status(404).json({error:"Viewer not found. Run npm run build first."})});function Ba(){if(!se("retention.autoCleanupEnabled")){p.info("WORKER","Retention automatico disabilitato (retention.autoCleanupEnabled=false)");return}let e=Number(se("retention.autoCleanupIntervalHours")??24),r=e*36e5;function s(){try{let i=je(xe()),a=ft($e.db,i);a.total>0?p.info("WORKER",`Retention schedulata: ${a.total} record eliminati (obs=${a.observations}, sum=${a.summaries}, prompts=${a.prompts}, knowledge=${a.knowledge})`):p.debug("WORKER","Retention schedulata: nessun record da eliminare")}catch(i){p.error("WORKER","Retention schedulata fallita",{},i)}}p.info("WORKER",`Retention automatica attiva (ogni ${e}h)`);let n=setTimeout(s,3e4),o=setInterval(s,r);process.once("beforeExit",()=>{clearTimeout(n),clearInterval(o)})}Ba();function Fa(){if(!se("backup.enabled")){p.info("WORKER","Backup automatico disabilitato (backup.enabled=false)");return}let e=Number(se("backup.intervalHours")??24),r=Number(se("backup.maxKeep")??7),s=e*36e5;function n(){try{let a=yt(ce,Y,$e.db);p.info("WORKER",`Backup schedulato creato: ${a.metadata.filename} (obs=${a.metadata.stats.observations})`);let c=bt(Y,r);c>0&&p.info("WORKER",`Rotazione backup: ${c} file rimossi, ${r} mantenuti`)}catch(a){p.error("WORKER","Backup schedulato fallito",{},a)}}p.info("WORKER",`Backup automatico attivo (ogni ${e}h, max ${r} backup)`);let o=setTimeout(n,6e4),i=setInterval(n,s);process.once("beforeExit",()=>{clearTimeout(o),clearInterval(i)})}Fa();async function Ha(){try{let t=_e.getInstance(),e={register:n=>{try{t.register(n)}catch{}},unregister:n=>{t.unregister(n).catch(()=>{})},get:n=>t.get(n)},s=await new _t(e).loadAll();if(s.loaded.length>0&&p.info("WORKER",`Plugin caricati: ${s.loaded.join(", ")}`),s.failed.length>0)for(let{name:n,error:o}of s.failed)p.warn("WORKER",`Plugin "${n}" non caricato: ${o}`)}catch(t){p.warn("WORKER","Inizializzazione plugin system fallita",{},t)}}var qa=O.listen(Number(Me),br,()=>{p.info("WORKER",`Kiro Memory worker started on http://${br}:${Me}`),Rn(Pe,String(process.pid),"utf-8"),Ha().catch(t=>{p.warn("WORKER","Plugin system: errore non gestito",{},t)})});function vr(t){p.info("WORKER",`Received ${t}, shutting down...`);let e=Ie();for(let s of e)try{s.end()}catch{}let r=setTimeout(()=>{p.warn("WORKER","Forced shutdown after 5s timeout"),jt(Pe)&&vn(Pe),$e.close(),process.exit(1)},5e3);qa.close(()=>{clearTimeout(r),p.info("WORKER","Server closed"),jt(Pe)&&vn(Pe),$e.close(),process.exit(0)})}process.on("SIGTERM",()=>vr("SIGTERM"));process.on("SIGINT",()=>vr("SIGINT"));process.on("uncaughtException",t=>{p.error("WORKER","Uncaught exception",{},t),vr("uncaughtException")});process.on("unhandledRejection",t=>{p.error("WORKER","Unhandled promise rejection",{reason:t},t)});
|
|
341
592
|
//# sourceMappingURL=worker-service.js.map
|