@hasna/knowledge 0.2.28 → 0.2.29

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- var A=import.meta.require;import{readFileSync as ke,writeFileSync as Ee,existsSync as ye,renameSync as cr,unlinkSync as Ot}from"fs";import{randomUUID as Nt}from"crypto";import{existsSync as rr,mkdirSync as Je,readFileSync as ir,writeFileSync as bt}from"fs";import{homedir as vt}from"os";import{dirname as sr,join as D,resolve as or}from"path";var ne=D(".hasna","apps","knowledge"),O={division:"xyz",app_type:"opensource",app:"knowledge",env:"prod",local_path:ne,s3:{bucket:"hasna-xyz-opensource-knowledge-prod",region:"us-east-1",profile:"hasna-xyz-infra",prefix:".hasna/apps/knowledge",server_side_encryption:"AES256"},secrets:{env:"hasna/xyz/opensource/knowledge/prod/env",aws:"hasna/xyz/opensource/knowledge/prod/aws",s3:"hasna/xyz/opensource/knowledge/prod/s3",rds:null,future_rds:"hasna/xyz/opensource/knowledge/prod/rds"},source_owner:"open-files",evidence_doc:"docs/canonical-secrets-bootstrap-2026-06-08.md"};function wt(){return{type:"s3",artifacts_root:"artifacts",s3:{bucket:O.s3.bucket,prefix:O.s3.prefix,region:O.s3.region,profile:O.s3.profile,server_side_encryption:O.s3.server_side_encryption}}}function Ge(){return D(vt(),".open-knowledge","db.json")}function ze(){return D(vt(),".hasna","apps","knowledge")}function ar(e=process.cwd()){return or(e,ne)}function ce(e){return{home:e,configPath:D(e,"config.json"),jsonStorePath:D(e,"db.json"),knowledgeDbPath:D(e,"knowledge.db"),artifactsDir:D(e,"artifacts"),cacheDir:D(e,"cache"),exportsDir:D(e,"exports"),indexesDir:D(e,"indexes"),logsDir:D(e,"logs"),runsDir:D(e,"runs"),schemasDir:D(e,"schemas"),wikiDir:D(e,"wiki")}}function ur(){return{version:1,mode:"local",hosted:{api_url:"https://knowledge.hasna.xyz"},storage:{type:"local",artifacts_root:"artifacts"},sources:{preferred_ref:"open-files",allowed_schemes:["open-files","s3","file","https","http"]},providers:{default_model:"openai:gpt-5.2",aliases:{fast:"openai:gpt-5-mini",reasoning:"anthropic:claude-opus-4-6",sonnet:"anthropic:claude-sonnet-4-6",deepseek:"deepseek:deepseek-chat","deepseek-reasoning":"deepseek:deepseek-reasoner"},openai:{api_key_env:"OPENAI_API_KEY",default_model:"gpt-5.2"},anthropic:{api_key_env:"ANTHROPIC_API_KEY",default_model:"claude-sonnet-4-6"},deepseek:{api_key_env:"DEEPSEEK_API_KEY",default_model:"deepseek-chat"}},embeddings:{default_model:"openai:text-embedding-3-small",dimensions:1536,batch_size:64,max_parallel_calls:4},safety:{network:{web_search_enabled:!1,s3_reads_enabled:!1,allowed_s3_buckets:[]},redaction:{enabled:!0},approvals:{generated_writes_require_approval:!0}}}}function Tt(e){let t=ce(e);Je(t.home,{recursive:!0});for(let n of[t.artifactsDir,t.cacheDir,t.exportsDir,t.indexesDir,t.logsDir,t.runsDir,t.schemasDir,t.wikiDir])Je(n,{recursive:!0});if(!rr(t.configPath))bt(t.configPath,`${JSON.stringify(ur(),null,2)}
3
+ var A=import.meta.require;import{readFileSync as ke,writeFileSync as Ee,existsSync as ye,renameSync as cr,unlinkSync as Ot}from"fs";import{randomUUID as Nt}from"crypto";import{existsSync as rr,mkdirSync as Je,readFileSync as ir,writeFileSync as bt}from"fs";import{homedir as vt}from"os";import{dirname as sr,join as D,resolve as or}from"path";var ne=D(".hasna","apps","knowledge"),O={division:"xyz",app_type:"opensource",app:"knowledge",env:"prod",local_path:ne,s3:{bucket:"hasna-xyz-opensource-knowledge-prod",region:"us-east-1",profile:"hasna-xyz-infra",prefix:".hasna/apps/knowledge",server_side_encryption:"AES256"},secrets:{env:"hasna/xyz/opensource/knowledge/prod/env",aws:"hasna/xyz/opensource/knowledge/prod/aws",s3:"hasna/xyz/opensource/knowledge/prod/s3",rds:null,future_rds:"hasna/xyz/opensource/knowledge/prod/rds"},source_owner:"open-files",evidence_doc:"docs/canonical-secrets-bootstrap-2026-06-08.md"};function Tt(){return{type:"s3",artifacts_root:"artifacts",s3:{bucket:O.s3.bucket,prefix:O.s3.prefix,region:O.s3.region,profile:O.s3.profile,server_side_encryption:O.s3.server_side_encryption}}}function Ge(){return D(vt(),".open-knowledge","db.json")}function ze(){return D(vt(),".hasna","apps","knowledge")}function ar(e=process.cwd()){return or(e,ne)}function ce(e){return{home:e,configPath:D(e,"config.json"),jsonStorePath:D(e,"db.json"),knowledgeDbPath:D(e,"knowledge.db"),artifactsDir:D(e,"artifacts"),cacheDir:D(e,"cache"),exportsDir:D(e,"exports"),indexesDir:D(e,"indexes"),logsDir:D(e,"logs"),runsDir:D(e,"runs"),schemasDir:D(e,"schemas"),wikiDir:D(e,"wiki")}}function ur(){return{version:1,mode:"local",hosted:{api_url:"https://knowledge.hasna.xyz"},storage:{type:"local",artifacts_root:"artifacts"},sources:{preferred_ref:"open-files",allowed_schemes:["open-files","s3","file","https","http"]},providers:{default_model:"openai:gpt-5.2",aliases:{fast:"openai:gpt-5-mini",reasoning:"anthropic:claude-opus-4-6",sonnet:"anthropic:claude-sonnet-4-6",deepseek:"deepseek:deepseek-chat","deepseek-reasoning":"deepseek:deepseek-reasoner"},openai:{api_key_env:"OPENAI_API_KEY",default_model:"gpt-5.2"},anthropic:{api_key_env:"ANTHROPIC_API_KEY",default_model:"claude-sonnet-4-6"},deepseek:{api_key_env:"DEEPSEEK_API_KEY",default_model:"deepseek-chat"}},embeddings:{default_model:"openai:text-embedding-3-small",dimensions:1536,batch_size:64,max_parallel_calls:4},safety:{network:{web_search_enabled:!1,s3_reads_enabled:!1,allowed_s3_buckets:[]},redaction:{enabled:!0},approvals:{generated_writes_require_approval:!0}}}}function wt(e){let t=ce(e);Je(t.home,{recursive:!0});for(let n of[t.artifactsDir,t.cacheDir,t.exportsDir,t.indexesDir,t.logsDir,t.runsDir,t.schemasDir,t.wikiDir])Je(n,{recursive:!0});if(!rr(t.configPath))bt(t.configPath,`${JSON.stringify(ur(),null,2)}
4
4
  `);return t}function Rt(e,t=process.cwd()){if(e==="project"||e==="local")return ce(ar(t));return ce(ze())}function de(e){Je(sr(e),{recursive:!0})}function St(e){let t=ir(e,"utf8");return JSON.parse(t)}function xt(e,t){de(e),bt(e,`${JSON.stringify(t,null,2)}
5
5
  `)}function Ye(){return ce(ze()).jsonStorePath}function Ve(e){if(!ye(e))if(de(e),e===Ye()&&ye(Ge()))Ee(e,ke(Ge(),"utf8"));else Ee(e,JSON.stringify({items:[]},null,2))}function dr(e){return`${e}.lock`}function lr(e,t){let i=Date.now();while(Date.now()-i<5000){try{if(!ye(e)){Ee(e,JSON.stringify({owner:t,ts:Date.now()}));return}let c=JSON.parse(ke(e,"utf8"));if(Date.now()-c.ts>1e4)Ot(e)}catch{}let s=Date.now();while(Date.now()-s<50);}throw Error(`Could not acquire lock on ${e} after 5000ms`)}function _r(e,t){try{if(ye(e)){if(JSON.parse(ke(e,"utf8")).owner===t)Ot(e)}}catch{}}function U(e){Ve(e);let t=ke(e,"utf8"),n=JSON.parse(t);if(!n||!Array.isArray(n.items))return{items:[]};return n}function $(e,t){let n=`${e}.tmp.${Nt()}`;Ee(n,JSON.stringify(t,null,2)),cr(n,e)}function P(e,t){let n=Nt(),r=dr(e);lr(r,n);try{return t()}finally{_r(r,n)}}function Qe(){return`k_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}function At(e){return e.replace(/^k_/,"").slice(0,12)}import{Database as fr}from"bun:sqlite";var gr=`
6
6
  PRAGMA journal_mode = WAL;
@@ -265,8 +265,8 @@ CREATE INDEX IF NOT EXISTS idx_reindex_queue_source_uri ON reindex_queue(source_
265
265
 
266
266
  INSERT OR IGNORE INTO schema_versions(version, applied_at)
267
267
  VALUES (5, datetime('now'));
268
- `;function b(e){de(e);let t=new fr(e);return t.exec("PRAGMA foreign_keys = ON;"),t.exec("PRAGMA busy_timeout = 5000;"),t}function x(e){let t=b(e);try{if(t.exec(gr),re(t)<2)t.exec(mr);if(re(t)<3)t.exec(pr);if(re(t)<4)t.exec(hr);if(re(t)<5)t.exec(Er);return{path:e,schema_version:re(t)}}finally{t.close()}}function re(e){return e.query("SELECT MAX(version) AS version FROM schema_versions").get()?.version??0}function L(e,t){return e.query(`SELECT COUNT(*) AS n FROM ${t}`).get()?.n??0}function It(e){let t=b(e);try{return{schema_version:re(t),sources:L(t,"sources"),source_revisions:L(t,"source_revisions"),chunks:L(t,"chunks"),wiki_pages:L(t,"wiki_pages"),citations:L(t,"citations"),indexes:L(t,"knowledge_indexes"),runs:L(t,"runs"),run_events:L(t,"run_events"),redaction_findings:L(t,"redaction_findings"),audit_events:L(t,"audit_events"),approval_gates:L(t,"approval_gates"),storage_objects:L(t,"storage_objects"),embeddings:L(t,"chunk_embeddings"),vector_entries:L(t,"vector_index_entries"),reindex_queue:L(t,"reindex_queue")}}finally{t.close()}}import{existsSync as yr,mkdirSync as Lt,readFileSync as kr,writeFileSync as br}from"fs";import{dirname as vr,join as Ze,relative as wr,sep as Tr}from"path";function le(e){let t=e.replace(/\\/g,"/").trim();if(!t||t.startsWith("/"))throw Error(`Invalid artifact key: ${e}`);let n=t.split("/").filter(Boolean);if(n.length===0||n.some((r)=>r==="."||r===".."))throw Error(`Invalid artifact key: ${e}`);return n.join("/")}function et(e,t){let n=wr(e,t);if(n.startsWith("..")||n===".."||n.startsWith(`..${Tr}`))throw Error(`Artifact path escapes root: ${t}`)}class Ct{root;type="local";canRead=!0;canWrite=!0;constructor(e){this.root=e;Lt(e,{recursive:!0})}async put(e){let t=le(e.key),n=Ze(this.root,t);return et(this.root,n),Lt(vr(n),{recursive:!0}),br(n,e.body),{key:t,uri:`file://${n}`}}async getText(e){let t=le(e),n=Ze(this.root,t);return et(this.root,n),kr(n,"utf8")}async exists(e){let t=le(e),n=Ze(this.root,t);return et(this.root,n),yr(n)}}class Dt{options;type="s3";canRead=!0;canWrite=!0;client;constructor(e){this.options=e;this.client=e.client}async getClient(){if(this.client)return this.client;let[{S3Client:e},{fromIni:t}]=await Promise.all([import("@aws-sdk/client-s3"),import("@aws-sdk/credential-providers")]);return this.client=new e({region:this.options.region,credentials:this.options.profile?t({profile:this.options.profile}):void 0,maxAttempts:this.options.max_attempts}),this.client}objectKey(e){let t=le(e),n=this.options.prefix?le(this.options.prefix):"";return n?`${n}/${t}`:t}async put(e){let[{PutObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e.key);return await n.send(new t({Bucket:this.options.bucket,Key:r,Body:e.body,ContentType:e.content_type,Metadata:e.metadata,ServerSideEncryption:this.options.server_side_encryption,SSEKMSKeyId:this.options.kms_key_id})),{key:r,uri:`s3://${this.options.bucket}/${r}`}}async getText(e){let[{GetObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e),i=await n.send(new t({Bucket:this.options.bucket,Key:r}));if(!i.Body)return"";return await i.Body.transformToString()}async exists(e){let[{HeadObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e);try{return await n.send(new t({Bucket:this.options.bucket,Key:r})),!0}catch(i){let s=i instanceof Error?i.name:"";if(s==="NotFound"||s==="NoSuchKey"||s==="NotFoundError")return!1;throw i}}}function Ut(e,t){if(e.storage.type==="s3"){if(!e.storage.s3?.bucket)throw Error("S3 artifact storage requires storage.s3.bucket");return new Dt({bucket:e.storage.s3.bucket,prefix:e.storage.s3.prefix,region:e.storage.s3.region,profile:e.storage.s3.profile,max_attempts:e.storage.s3.max_attempts,server_side_encryption:e.storage.s3.server_side_encryption,kms_key_id:e.storage.s3.kms_key_id})}return new Ct(t.artifactsDir)}import{existsSync as Rr,mkdirSync as Sr,readFileSync as xr,unlinkSync as Or,writeFileSync as Nr}from"fs";import{homedir as Ar}from"os";import{dirname as Ir,join as Pt}from"path";var tt="https://knowledge.hasna.xyz";function X(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw Error("Knowledge API URL must use http or https.");let n=t.pathname.replace(/\/+$/,"");if(n==="/api"||n==="/api/v1")t.pathname="/";else if(n.endsWith("/api/v1"))t.pathname=n.slice(0,-7)||"/";else if(n.endsWith("/api"))t.pathname=n.slice(0,-4)||"/";return t.toString().replace(/\/+$/,"")}function ve(e=process.env){if(e.HASNA_KNOWLEDGE_AUTH_PATH)return e.HASNA_KNOWLEDGE_AUTH_PATH;let t=e.HASNA_KNOWLEDGE_AUTH_DIR??Pt(Ar(),".hasna","knowledge");return Pt(t,"auth.json")}function be(e,t=process.env){return X(t.KNOWLEDGE_API_URL??e?.hosted?.api_url??tt)}function Ft(e=process.env){try{let t=ve(e);if(!Rr(t))return null;let n=JSON.parse(xr(t,"utf8"));return typeof n.api_key==="string"&&n.api_key.length>0?n:null}catch{return null}}function Mt(e,t=process.env){let n=ve(t),r={...e,api_url:e.api_url?X(e.api_url):void 0,created_at:e.created_at??new Date().toISOString()};return Sr(Ir(n),{recursive:!0,mode:448}),Nr(n,`${JSON.stringify(r,null,2)}
269
- `,{mode:384}),r}function jt(e=process.env){try{return Or(ve(e)),!0}catch{return!1}}function nt(e=process.env){if(e.KNOWLEDGE_API_KEY)return{apiKey:e.KNOWLEDGE_API_KEY,source:"env"};if(e.HASNA_KNOWLEDGE_API_KEY)return{apiKey:e.HASNA_KNOWLEDGE_API_KEY,source:"env"};let t=Ft(e);return t?.api_key?{apiKey:t.api_key,source:"file"}:{apiKey:null,source:"none"}}function Kt(e,t=process.env){let n=Ft(t),r=nt(t),i=t.KNOWLEDGE_API_URL?be(e,t):n?.api_url?X(n.api_url):be(e,t);return{authenticated:Boolean(r.apiKey),source:r.source,api_url:i,auth_path:ve(t),email:r.source==="file"?n?.email??null:null,org_id:r.source==="file"?n?.org_id??null:null,org_slug:r.source==="file"?n?.org_slug??null:null,user_id:r.source==="file"?n?.user_id??null:null,api_key_present:Boolean(r.apiKey)}}import{randomUUID as ln}from"crypto";import{randomUUID as Lr}from"crypto";var rt={openai:{api_key_env:"OPENAI_API_KEY",default_model:"gpt-5.2"},anthropic:{api_key_env:"ANTHROPIC_API_KEY",default_model:"claude-sonnet-4-6"},deepseek:{api_key_env:"DEEPSEEK_API_KEY",default_model:"deepseek-chat"}},Cr={openai:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!0,native_web_search:!0,reasoning:!0,embeddings:!0},anthropic:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!0,native_web_search:!1,reasoning:!0,embeddings:!1},deepseek:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!1,native_web_search:!1,reasoning:!0,embeddings:!1}},Dr={default:"openai:gpt-5.2",fast:"openai:gpt-5-mini",reasoning:"anthropic:claude-opus-4-6",sonnet:"anthropic:claude-sonnet-4-6",deepseek:"deepseek:deepseek-chat","deepseek-reasoning":"deepseek:deepseek-reasoner"};function Wt(e){return e?.providers??{}}function q(e,t){let n=Wt(e)[t]??{};return{...rt[t],...n}}function Xt(e){let t=Wt(e);return{...Dr,...t.default_model?{default:t.default_model}:{},...t.aliases??{}}}function C(e){let[t,...n]=e.split(":"),r=n.join(":");if(t!=="openai"&&t!=="anthropic"&&t!=="deepseek")throw Error(`Unsupported AI provider: ${t}`);if(!r)throw Error(`Invalid model ref: ${e}. Expected provider:model.`);return{provider:t,model:r}}function H(e,t){return Xt(t)[e]??e}function it(e){let t=Xt(e);return Object.entries(t).map(([n,r])=>{let i=C(r);return{alias:n,model_ref:r,provider:i.provider,model:i.model,default:n==="default",capabilities:Cr[i.provider]}})}function qt(e,t=process.env){return Object.keys(rt).map((n)=>{let r=q(e,n),i=Boolean(t[r.api_key_env]);return{provider:n,api_key_env:r.api_key_env,configured:i,source:i?"env":"missing",base_url:r.base_url??null,default_model:r.default_model}})}function Ht(e,t=process.env){return{default_model:H("default",e),providers:qt(e,t),models:it(e)}}function z(e,t,n=process.env){let r=qt(t,n).find((i)=>i.provider===e);if(!r)throw Error(`Unsupported AI provider: ${e}`);if(!r.configured)throw Error(`Missing ${r.api_key_env} for ${e}. Set the env var to use this provider.`);return r}async function Ur(e){if(e==="openai"){let{createOpenAI:n}=await import("@ai-sdk/openai");return n}if(e==="anthropic"){let{createAnthropic:n}=await import("@ai-sdk/anthropic");return n}let{createDeepSeek:t}=await import("@ai-sdk/deepseek");return t}async function Pr(e={}){let{createProviderRegistry:t}=await import("ai"),n=e.env??process.env,r={};for(let i of Object.keys(rt)){let s=q(e.config,i),c=n[s.api_key_env];if(!c)continue;let d=e.factories?.[i]??await Ur(i);r[i]=d({apiKey:c,baseURL:s.base_url})}return t(r)}async function Bt(e,t={}){let n=H(e,t.config),r=C(n);return z(r.provider,t.config,t.env),(await Pr(t)).languageModel(n)}function $t(e,t){for(let n of t){let r=e[n];if(typeof r==="number"&&Number.isFinite(r))return r}return 0}function we(e){let t=e.usage??{};return{provider:e.provider,model:e.model,input_tokens:$t(t,["inputTokens","promptTokens","input_tokens","prompt_tokens"]),output_tokens:$t(t,["outputTokens","completionTokens","output_tokens","completion_tokens"]),cost_usd:e.costUsd??0,metadata:{usage:t,provider_metadata:e.providerMetadata??{}}}}function Te(e,t){let n=`usage_${Lr()}`;return e.run(`INSERT INTO provider_usage (id, run_id, provider, model, input_tokens, output_tokens, cost_usd, metadata_json, created_at)
268
+ `;function b(e){de(e);let t=new fr(e);return t.exec("PRAGMA foreign_keys = ON;"),t.exec("PRAGMA busy_timeout = 5000;"),t}function x(e){let t=b(e);try{if(t.exec(gr),re(t)<2)t.exec(mr);if(re(t)<3)t.exec(pr);if(re(t)<4)t.exec(hr);if(re(t)<5)t.exec(Er);return{path:e,schema_version:re(t)}}finally{t.close()}}function re(e){return e.query("SELECT MAX(version) AS version FROM schema_versions").get()?.version??0}function L(e,t){return e.query(`SELECT COUNT(*) AS n FROM ${t}`).get()?.n??0}function It(e){let t=b(e);try{return{schema_version:re(t),sources:L(t,"sources"),source_revisions:L(t,"source_revisions"),chunks:L(t,"chunks"),wiki_pages:L(t,"wiki_pages"),citations:L(t,"citations"),indexes:L(t,"knowledge_indexes"),runs:L(t,"runs"),run_events:L(t,"run_events"),redaction_findings:L(t,"redaction_findings"),audit_events:L(t,"audit_events"),approval_gates:L(t,"approval_gates"),storage_objects:L(t,"storage_objects"),embeddings:L(t,"chunk_embeddings"),vector_entries:L(t,"vector_index_entries"),reindex_queue:L(t,"reindex_queue")}}finally{t.close()}}import{existsSync as yr,mkdirSync as Lt,readFileSync as kr,writeFileSync as br}from"fs";import{dirname as vr,join as Ze,relative as Tr,sep as wr}from"path";function le(e){let t=e.replace(/\\/g,"/").trim();if(!t||t.startsWith("/"))throw Error(`Invalid artifact key: ${e}`);let n=t.split("/").filter(Boolean);if(n.length===0||n.some((r)=>r==="."||r===".."))throw Error(`Invalid artifact key: ${e}`);return n.join("/")}function et(e,t){let n=Tr(e,t);if(n.startsWith("..")||n===".."||n.startsWith(`..${wr}`))throw Error(`Artifact path escapes root: ${t}`)}class Ct{root;type="local";canRead=!0;canWrite=!0;constructor(e){this.root=e;Lt(e,{recursive:!0})}async put(e){let t=le(e.key),n=Ze(this.root,t);return et(this.root,n),Lt(vr(n),{recursive:!0}),br(n,e.body),{key:t,uri:`file://${n}`}}async getText(e){let t=le(e),n=Ze(this.root,t);return et(this.root,n),kr(n,"utf8")}async exists(e){let t=le(e),n=Ze(this.root,t);return et(this.root,n),yr(n)}}class Dt{options;type="s3";canRead=!0;canWrite=!0;client;constructor(e){this.options=e;this.client=e.client}async getClient(){if(this.client)return this.client;let[{S3Client:e},{fromIni:t}]=await Promise.all([import("@aws-sdk/client-s3"),import("@aws-sdk/credential-providers")]);return this.client=new e({region:this.options.region,credentials:this.options.profile?t({profile:this.options.profile}):void 0,maxAttempts:this.options.max_attempts}),this.client}objectKey(e){let t=le(e),n=this.options.prefix?le(this.options.prefix):"";return n?`${n}/${t}`:t}async put(e){let[{PutObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e.key);return await n.send(new t({Bucket:this.options.bucket,Key:r,Body:e.body,ContentType:e.content_type,Metadata:e.metadata,ServerSideEncryption:this.options.server_side_encryption,SSEKMSKeyId:this.options.kms_key_id})),{key:r,uri:`s3://${this.options.bucket}/${r}`}}async getText(e){let[{GetObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e),i=await n.send(new t({Bucket:this.options.bucket,Key:r}));if(!i.Body)return"";return await i.Body.transformToString()}async exists(e){let[{HeadObjectCommand:t},n]=await Promise.all([import("@aws-sdk/client-s3"),this.getClient()]),r=this.objectKey(e);try{return await n.send(new t({Bucket:this.options.bucket,Key:r})),!0}catch(i){let s=i instanceof Error?i.name:"";if(s==="NotFound"||s==="NoSuchKey"||s==="NotFoundError")return!1;throw i}}}function Ut(e,t){if(e.storage.type==="s3"){if(!e.storage.s3?.bucket)throw Error("S3 artifact storage requires storage.s3.bucket");return new Dt({bucket:e.storage.s3.bucket,prefix:e.storage.s3.prefix,region:e.storage.s3.region,profile:e.storage.s3.profile,max_attempts:e.storage.s3.max_attempts,server_side_encryption:e.storage.s3.server_side_encryption,kms_key_id:e.storage.s3.kms_key_id})}return new Ct(t.artifactsDir)}import{existsSync as Rr,mkdirSync as Sr,readFileSync as xr,unlinkSync as Or,writeFileSync as Nr}from"fs";import{homedir as Ar}from"os";import{dirname as Ir,join as Pt}from"path";var tt="https://knowledge.hasna.xyz";function X(e){let t=new URL(e);if(t.protocol!=="http:"&&t.protocol!=="https:")throw Error("Knowledge API URL must use http or https.");let n=t.pathname.replace(/\/+$/,"");if(n==="/api"||n==="/api/v1")t.pathname="/";else if(n.endsWith("/api/v1"))t.pathname=n.slice(0,-7)||"/";else if(n.endsWith("/api"))t.pathname=n.slice(0,-4)||"/";return t.toString().replace(/\/+$/,"")}function ve(e=process.env){if(e.HASNA_KNOWLEDGE_AUTH_PATH)return e.HASNA_KNOWLEDGE_AUTH_PATH;let t=e.HASNA_KNOWLEDGE_AUTH_DIR??Pt(Ar(),".hasna","knowledge");return Pt(t,"auth.json")}function be(e,t=process.env){return X(t.KNOWLEDGE_API_URL??e?.hosted?.api_url??tt)}function Ft(e=process.env){try{let t=ve(e);if(!Rr(t))return null;let n=JSON.parse(xr(t,"utf8"));return typeof n.api_key==="string"&&n.api_key.length>0?n:null}catch{return null}}function Mt(e,t=process.env){let n=ve(t),r={...e,api_url:e.api_url?X(e.api_url):void 0,created_at:e.created_at??new Date().toISOString()};return Sr(Ir(n),{recursive:!0,mode:448}),Nr(n,`${JSON.stringify(r,null,2)}
269
+ `,{mode:384}),r}function jt(e=process.env){try{return Or(ve(e)),!0}catch{return!1}}function nt(e=process.env){if(e.KNOWLEDGE_API_KEY)return{apiKey:e.KNOWLEDGE_API_KEY,source:"env"};if(e.HASNA_KNOWLEDGE_API_KEY)return{apiKey:e.HASNA_KNOWLEDGE_API_KEY,source:"env"};let t=Ft(e);return t?.api_key?{apiKey:t.api_key,source:"file"}:{apiKey:null,source:"none"}}function Kt(e,t=process.env){let n=Ft(t),r=nt(t),i=t.KNOWLEDGE_API_URL?be(e,t):n?.api_url?X(n.api_url):be(e,t);return{authenticated:Boolean(r.apiKey),source:r.source,api_url:i,auth_path:ve(t),email:r.source==="file"?n?.email??null:null,org_id:r.source==="file"?n?.org_id??null:null,org_slug:r.source==="file"?n?.org_slug??null:null,user_id:r.source==="file"?n?.user_id??null:null,api_key_present:Boolean(r.apiKey)}}import{randomUUID as ln}from"crypto";import{randomUUID as Lr}from"crypto";var rt={openai:{api_key_env:"OPENAI_API_KEY",default_model:"gpt-5.2"},anthropic:{api_key_env:"ANTHROPIC_API_KEY",default_model:"claude-sonnet-4-6"},deepseek:{api_key_env:"DEEPSEEK_API_KEY",default_model:"deepseek-chat"}},Cr={openai:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!0,native_web_search:!0,reasoning:!0,embeddings:!0},anthropic:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!0,native_web_search:!1,reasoning:!0,embeddings:!1},deepseek:{text_generation:!0,structured_output:!0,tool_usage:!0,tool_streaming:!0,image_input:!1,native_web_search:!1,reasoning:!0,embeddings:!1}},Dr={default:"openai:gpt-5.2",fast:"openai:gpt-5-mini",reasoning:"anthropic:claude-opus-4-6",sonnet:"anthropic:claude-sonnet-4-6",deepseek:"deepseek:deepseek-chat","deepseek-reasoning":"deepseek:deepseek-reasoner"};function Wt(e){return e?.providers??{}}function q(e,t){let n=Wt(e)[t]??{};return{...rt[t],...n}}function Xt(e){let t=Wt(e);return{...Dr,...t.default_model?{default:t.default_model}:{},...t.aliases??{}}}function C(e){let[t,...n]=e.split(":"),r=n.join(":");if(t!=="openai"&&t!=="anthropic"&&t!=="deepseek")throw Error(`Unsupported AI provider: ${t}`);if(!r)throw Error(`Invalid model ref: ${e}. Expected provider:model.`);return{provider:t,model:r}}function H(e,t){return Xt(t)[e]??e}function it(e){let t=Xt(e);return Object.entries(t).map(([n,r])=>{let i=C(r);return{alias:n,model_ref:r,provider:i.provider,model:i.model,default:n==="default",capabilities:Cr[i.provider]}})}function qt(e,t=process.env){return Object.keys(rt).map((n)=>{let r=q(e,n),i=Boolean(t[r.api_key_env]);return{provider:n,api_key_env:r.api_key_env,configured:i,source:i?"env":"missing",base_url:r.base_url??null,default_model:r.default_model}})}function Ht(e,t=process.env){return{default_model:H("default",e),providers:qt(e,t),models:it(e)}}function z(e,t,n=process.env){let r=qt(t,n).find((i)=>i.provider===e);if(!r)throw Error(`Unsupported AI provider: ${e}`);if(!r.configured)throw Error(`Missing ${r.api_key_env} for ${e}. Set the env var to use this provider.`);return r}async function Ur(e){if(e==="openai"){let{createOpenAI:n}=await import("@ai-sdk/openai");return n}if(e==="anthropic"){let{createAnthropic:n}=await import("@ai-sdk/anthropic");return n}let{createDeepSeek:t}=await import("@ai-sdk/deepseek");return t}async function Pr(e={}){let{createProviderRegistry:t}=await import("ai"),n=e.env??process.env,r={};for(let i of Object.keys(rt)){let s=q(e.config,i),c=n[s.api_key_env];if(!c)continue;let d=e.factories?.[i]??await Ur(i);r[i]=d({apiKey:c,baseURL:s.base_url})}return t(r)}async function Bt(e,t={}){let n=H(e,t.config),r=C(n);return z(r.provider,t.config,t.env),(await Pr(t)).languageModel(n)}function $t(e,t){for(let n of t){let r=e[n];if(typeof r==="number"&&Number.isFinite(r))return r}return 0}function Te(e){let t=e.usage??{};return{provider:e.provider,model:e.model,input_tokens:$t(t,["inputTokens","promptTokens","input_tokens","prompt_tokens"]),output_tokens:$t(t,["outputTokens","completionTokens","output_tokens","completion_tokens"]),cost_usd:e.costUsd??0,metadata:{usage:t,provider_metadata:e.providerMetadata??{}}}}function we(e,t){let n=`usage_${Lr()}`;return e.run(`INSERT INTO provider_usage (id, run_id, provider, model, input_tokens, output_tokens, cost_usd, metadata_json, created_at)
270
270
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,t.run_id??null,t.provider,t.model,t.input_tokens,t.output_tokens,t.cost_usd,JSON.stringify(t.metadata),t.created_at??new Date().toISOString()]),n}import{createHash as ri}from"crypto";function st(e){return["deleted","stale","invalidated","reindex_required"].includes((e??"").toLowerCase())}function B(e){let t=e.status??null;return{source_owner:"open-files",source_ref:e.source_ref??null,source_uri:e.source_uri??null,source_kind:e.source_kind??null,source_revision_id:e.source_revision_id??null,revision:e.revision??null,hash:e.hash??null,chunk_id:e.chunk_id??null,start_offset:e.start_offset??null,end_offset:e.end_offset??null,status:t,read_only:!0,citation_required:!0,resolver:e.resolver??null,stale:st(t)}}function Y(e){return{source_owner:"open-files",generated_from:e.generated_from,artifact_key:e.artifact_key,source_refs:e.source_refs??[],read_only_sources:!0,citation_required:e.citation_required??!0,raw_source_bytes_stored_in_open_knowledge:!1}}function Jt(e,t){return{...e,provenance:t}}import{createHash as Yt}from"crypto";var Fr="openai:text-embedding-3-small",Vt=1536;function Re(e){return e?.embeddings??{}}function Gt(e,t){return`${e}_${Yt("sha256").update(t).digest("hex").slice(0,20)}`}function at(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function j(e,t){for(let n of t){let r=e[n];if(typeof r==="string"&&r.length>0)return r}return null}function zt(e,t){for(let n of t){let r=e[n];if(typeof r==="number"&&Number.isFinite(r))return r}return null}function ot(e){return Math.sqrt(e.reduce((t,n)=>t+n*n,0))}function Mr(e,t,n=ot(t)){let r=ot(e);if(r===0||n===0)return 0;let i=Math.min(e.length,t.length),s=0;for(let c=0;c<i;c+=1)s+=e[c]*t[c];return s/(r*n)}function jr(e,t){let n=Yt("sha256").update(e).digest();return Array.from({length:t},(r,i)=>{let s=n[i%n.length]/255;return Number((s*2-1).toFixed(6))})}async function Kr(e,t,n=process.env){z("openai",t,n);let r=q(t,"openai"),{createOpenAI:i}=await import("@ai-sdk/openai"),s=i({apiKey:n[r.api_key_env],baseURL:r.base_url});if(s.embeddingModel)return s.embeddingModel(e);if(s.textEmbedding)return s.textEmbedding(e);if(s.textEmbeddingModel)return s.textEmbeddingModel(e);throw Error("OpenAI provider does not expose an embedding model factory.")}function V(e,t){if(!e||e==="default"||e==="embedding")return Re(t).default_model??Fr;return e}async function Qt(e,t={}){let n=V(t.modelRef,t.config),r=C(n);if(r.provider!=="openai")throw Error(`Embedding provider ${r.provider} is not supported yet. Use openai:text-embedding-3-small.`);let i=t.dimensions??Re(t.config).dimensions??Vt;if(t.fake)return{provider:r.provider,model:r.model,dimensions:i,vectors:e.map((a)=>jr(a,i)),usage:{input_tokens:e.reduce((a,u)=>a+Math.max(1,Math.ceil(u.split(/\s+/).filter(Boolean).length*1.25)),0)}};let{embedMany:s}=await import("ai"),c=await Kr(r.model,t.config,t.env),d=await s({model:c,values:e,maxParallelCalls:t.maxParallelCalls??Re(t.config).max_parallel_calls,providerOptions:{openai:{dimensions:i}}}),g=d.embeddings;return{provider:r.provider,model:r.model,dimensions:g[0]?.length??i,vectors:g,usage:{input_tokens:d.usage?.tokens??0}}}function $r(e,t){if(t.sourceRevisionId)return e.query(`SELECT
271
271
  c.id,
272
272
  c.text,
@@ -386,7 +386,7 @@ VALUES (5, datetime('now'));
386
386
  FROM knowledge_indexes
387
387
  WHERE ${sn(r,t)}
388
388
  ORDER BY updated_at DESC
389
- LIMIT ?`).all(...nn(t,r.length),n)}function Zr(e,t){let n=Ne(e.chunk_metadata_json),r=zr(e),i=F(n,["source_ref"]),s=e.source_uri??F(n,["source_uri"]),c=Boolean(e.wiki_page_id),d={kind:c?"wiki_chunk":"source_chunk",id:e.chunk_id,title:c?e.wiki_title:e.source_title,text:e.text,score:0,scores:{keyword:t},source:s||i?{uri:s,ref:i,kind:e.source_kind??F(n,["source_kind"]),revision:e.revision??F(n,["revision"]),hash:e.hash??F(n,["hash"])}:null,citation:{chunk_id:e.chunk_id,start_offset:e.start_offset,end_offset:e.end_offset},artifact:c?{uri:e.wiki_artifact_uri,path:e.wiki_path,hash:e.wiki_content_hash,shard_key:e.wiki_path}:null,provenance:r,reasons:["keyword_match"]};return d.score=_e(d.scores,d.citation),d}function ei(e,t){let n=Ne(e.metadata_json),r=rn(`${e.path} ${e.title} ${e.artifact_uri??""} ${e.metadata_json}`.toLowerCase(),t),i={kind:"wiki_page",id:e.id,title:e.title,text:null,score:0,scores:{catalog:r},source:null,citation:null,artifact:{uri:e.artifact_uri,path:e.path,hash:e.content_hash,shard_key:e.path},provenance:ut(n),reasons:["wiki_catalog_match"]};return i.score=_e(i.scores,i.citation),i}function ti(e,t){let n=Ne(e.metadata_json),r=rn(`${e.kind} ${e.name} ${e.shard_key??""} ${e.artifact_uri??""} ${e.metadata_json}`.toLowerCase(),t),i={kind:"knowledge_index",id:e.id,title:e.name,text:null,score:0,scores:{catalog:r},source:null,citation:null,artifact:{uri:e.artifact_uri,path:F(n,["artifact_key"]),hash:F(n,["content_hash"]),shard_key:e.shard_key},provenance:ut(n),reasons:["index_catalog_match"]};return i.score=_e(i.scores,i.citation),i}function Oe(e,t){let n=`${t.kind}:${t.id}`,r=e.get(n);if(!r){e.set(n,t);return}r.scores={keyword:Math.max(r.scores.keyword??0,t.scores.keyword??0)||void 0,semantic:Math.max(r.scores.semantic??0,t.scores.semantic??0)||void 0,catalog:Math.max(r.scores.catalog??0,t.scores.catalog??0)||void 0},r.reasons=tn([...r.reasons,...t.reasons]),r.text=r.text??t.text,r.title=r.title??t.title,r.source=r.source??t.source,r.citation=r.citation??t.citation,r.artifact=r.artifact??t.artifact,r.provenance=r.provenance??t.provenance,r.score=_e(r.scores,r.citation)}function ni(e){let t={source_chunk:0,wiki_chunk:1,wiki_page:2,knowledge_index:3};return e.sort((n,r)=>{if(r.score!==n.score)return r.score-n.score;return t[n.kind]-t[r.kind]||n.id.localeCompare(r.id)})}async function Ie(e){let t=e.query.trim();if(!t)throw Error("Search query is required.");let n=Math.max(1,Math.min(e.limit??10,100)),r=qr(t),i=Hr(r),s=e.semantic===!0||e.fake===!0||Boolean(e.modelRef),c=[],d=null,g=null,a=null,u=0,o=0,_=0,l=new Map;x(e.dbPath);let f=b(e.dbPath);try{let E=Yr(f,i,Math.max(n*3,20));u=E.length,E.forEach((k,p)=>Oe(l,Zr(k,Jr(k.rank,p))));let h=Vr(f,r,Math.max(n,10)),T=Qr(f,r,Math.max(n,10));o=h.length+T.length,h.forEach((k)=>Oe(l,ei(k,r))),T.forEach((k)=>Oe(l,ti(k,r)))}finally{f.close()}if(s)try{let E=await xe({dbPath:e.dbPath,query:t,limit:Math.max(n*3,20),config:e.config,env:e.env,modelRef:e.modelRef,dimensions:e.dimensions,fake:e.fake,batchSize:e.batchSize,maxParallelCalls:e.maxParallelCalls});d=E.provider,g=E.model,a=E.dimensions,_=E.results.length;for(let h of E.results){let T={kind:"source_chunk",id:h.chunk_id,title:null,text:h.text,score:0,scores:{semantic:Gr(h.score)},source:{uri:h.source_uri,ref:h.source_ref,kind:h.provenance?.source_kind??null,revision:h.revision,hash:h.hash},citation:{chunk_id:h.chunk_id,start_offset:h.provenance?.start_offset??null,end_offset:h.provenance?.end_offset??null},artifact:null,provenance:h.provenance,reasons:["semantic_match"]};T.score=_e(T.scores,T.citation),Oe(l,T)}}catch(E){c.push(`semantic_search_failed: ${E instanceof Error?E.message:String(E)}`)}let m=ni(Array.from(l.values())).slice(0,n);return{query:t,limit:n,mode:{keyword:!0,catalog:!0,semantic:s},semantic_provider:d,semantic_model:g,semantic_dimensions:a,counts:{keyword_results:u,catalog_results:o,semantic_results:_,merged_results:m.length},warnings:c,results:m}}function on(e,t){return`${e}_${ri("sha256").update(t).digest("hex").slice(0,20)}`}function an(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}function ii(e){return Array.from(new Set(an(e).match(/[\p{L}\p{N}_]+/gu)??[])).slice(0,16)}function si(e){return[e.title,e.text].filter(Boolean).join(" ").toLowerCase()}function oi(e,t){if(t.length===0)return 0;let n=si(e),r=t.filter((i)=>n.includes(i)).length;return Number((r/t.length).toFixed(6))}function ai(e){if(!e)return!0;if("read_only"in e)return e.read_only===!0;if("read_only_sources"in e)return e.read_only_sources===!0;return!0}function un(e){if(!e)return!1;if("stale"in e&&e.stale)return!0;if("status"in e)return st(e.status);return!1}function ui(e){if(un(e.provenance))return 0;if(e.source?.hash||e.source?.revision)return 1;if(e.artifact?.hash)return 0.85;if(e.provenance&&"source_refs"in e.provenance&&e.provenance.source_refs.length>0)return 0.75;return 0.55}function ci(e){if(e.citation?.chunk_id&&(e.source?.uri||e.artifact?.uri))return 1;if(e.provenance&&"citation_required"in e.provenance&&e.provenance.citation_required)return 0.75;if(e.artifact?.uri)return 0.65;return 0.35}function di(e){if(e.kind==="wiki_chunk")return 0.85;if(e.kind==="source_chunk")return 0.8;if(e.kind==="wiki_page")return 0.65;return 0.55}function li(e,t){let n={base_score:e.score,exact_score:oi(e,t),citation_score:ci(e),freshness_score:ui(e),authority_score:di(e)},r=Math.min(1,n.base_score*0.65+n.exact_score*0.1+n.citation_score*0.1+n.freshness_score*0.1+n.authority_score*0.05),i=new Set(e.reasons);if(n.exact_score>0.5)i.add("exact_term");if(n.citation_score>=0.75)i.add("cited_source");if(n.freshness_score>=0.85)i.add("fresh_source");return{...e,score:Number(r.toFixed(6)),reasons:Array.from(i),rerank:{...n,final_score:Number(r.toFixed(6))}}}function cn(e,t){let n=e.text??e.title;if(!n)return null;let r=n.replace(/\s+/g," ").trim();return r.length<=t?r:`${r.slice(0,Math.max(0,t-1)).trim()}...`}function _i(e){return{id:on("cite",`${e.kind}\x00${e.id}\x00${e.source?.uri??""}\x00${e.artifact?.uri??""}`),result_id:e.id,kind:e.kind,source_uri:e.source?.uri??null,source_ref:e.source?.ref??null,artifact_uri:e.artifact?.uri??null,artifact_path:e.artifact?.path??null,revision:e.source?.revision??null,hash:e.source?.hash??e.artifact?.hash??null,chunk_id:e.citation?.chunk_id??null,start_offset:e.citation?.start_offset??null,end_offset:e.citation?.end_offset??null,quote:cn(e,500),provenance:e.provenance}}function fi(e,t,n){let r=cn(e,n);if(!r)return null;return{id:on("excerpt",`${e.kind}\x00${e.id}`),result_id:e.id,citation_id:t.id,kind:e.kind,text:r,score:e.score}}function Le(e){return e.map(()=>"?").join(", ")}function gi(e,t){let n=t.map((d)=>d.citation?.chunk_id).filter((d)=>Boolean(d)),r=t.filter((d)=>d.kind==="wiki_page").map((d)=>d.id),i=[],s=[];if(n.length===0&&r.length===0)return{citations:i,backlinks:s};let c=b(e);try{if(n.length>0)i.push(...c.query(`SELECT id, wiki_page_id, chunk_id, source_uri, quote, start_offset, end_offset
389
+ LIMIT ?`).all(...nn(t,r.length),n)}function Zr(e,t){let n=Ne(e.chunk_metadata_json),r=zr(e),i=F(n,["source_ref"]),s=e.source_uri??F(n,["source_uri"]),c=Boolean(e.wiki_page_id),d={kind:c?"wiki_chunk":"source_chunk",id:e.chunk_id,title:c?e.wiki_title:e.source_title,text:e.text,score:0,scores:{keyword:t},source:s||i?{uri:s,ref:i,kind:e.source_kind??F(n,["source_kind"]),revision:e.revision??F(n,["revision"]),hash:e.hash??F(n,["hash"])}:null,citation:{chunk_id:e.chunk_id,start_offset:e.start_offset,end_offset:e.end_offset},artifact:c?{uri:e.wiki_artifact_uri,path:e.wiki_path,hash:e.wiki_content_hash,shard_key:e.wiki_path}:null,provenance:r,reasons:["keyword_match"]};return d.score=_e(d.scores,d.citation),d}function ei(e,t){let n=Ne(e.metadata_json),r=rn(`${e.path} ${e.title} ${e.artifact_uri??""} ${e.metadata_json}`.toLowerCase(),t),i={kind:"wiki_page",id:e.id,title:e.title,text:null,score:0,scores:{catalog:r},source:null,citation:null,artifact:{uri:e.artifact_uri,path:e.path,hash:e.content_hash,shard_key:e.path},provenance:ut(n),reasons:["wiki_catalog_match"]};return i.score=_e(i.scores,i.citation),i}function ti(e,t){let n=Ne(e.metadata_json),r=rn(`${e.kind} ${e.name} ${e.shard_key??""} ${e.artifact_uri??""} ${e.metadata_json}`.toLowerCase(),t),i={kind:"knowledge_index",id:e.id,title:e.name,text:null,score:0,scores:{catalog:r},source:null,citation:null,artifact:{uri:e.artifact_uri,path:F(n,["artifact_key"]),hash:F(n,["content_hash"]),shard_key:e.shard_key},provenance:ut(n),reasons:["index_catalog_match"]};return i.score=_e(i.scores,i.citation),i}function Oe(e,t){let n=`${t.kind}:${t.id}`,r=e.get(n);if(!r){e.set(n,t);return}r.scores={keyword:Math.max(r.scores.keyword??0,t.scores.keyword??0)||void 0,semantic:Math.max(r.scores.semantic??0,t.scores.semantic??0)||void 0,catalog:Math.max(r.scores.catalog??0,t.scores.catalog??0)||void 0},r.reasons=tn([...r.reasons,...t.reasons]),r.text=r.text??t.text,r.title=r.title??t.title,r.source=r.source??t.source,r.citation=r.citation??t.citation,r.artifact=r.artifact??t.artifact,r.provenance=r.provenance??t.provenance,r.score=_e(r.scores,r.citation)}function ni(e){let t={source_chunk:0,wiki_chunk:1,wiki_page:2,knowledge_index:3};return e.sort((n,r)=>{if(r.score!==n.score)return r.score-n.score;return t[n.kind]-t[r.kind]||n.id.localeCompare(r.id)})}async function Ie(e){let t=e.query.trim();if(!t)throw Error("Search query is required.");let n=Math.max(1,Math.min(e.limit??10,100)),r=qr(t),i=Hr(r),s=e.semantic===!0||e.fake===!0||Boolean(e.modelRef),c=[],d=null,g=null,a=null,u=0,o=0,_=0,l=new Map;x(e.dbPath);let f=b(e.dbPath);try{let E=Yr(f,i,Math.max(n*3,20));u=E.length,E.forEach((k,p)=>Oe(l,Zr(k,Jr(k.rank,p))));let h=Vr(f,r,Math.max(n,10)),w=Qr(f,r,Math.max(n,10));o=h.length+w.length,h.forEach((k)=>Oe(l,ei(k,r))),w.forEach((k)=>Oe(l,ti(k,r)))}finally{f.close()}if(s)try{let E=await xe({dbPath:e.dbPath,query:t,limit:Math.max(n*3,20),config:e.config,env:e.env,modelRef:e.modelRef,dimensions:e.dimensions,fake:e.fake,batchSize:e.batchSize,maxParallelCalls:e.maxParallelCalls});d=E.provider,g=E.model,a=E.dimensions,_=E.results.length;for(let h of E.results){let w={kind:"source_chunk",id:h.chunk_id,title:null,text:h.text,score:0,scores:{semantic:Gr(h.score)},source:{uri:h.source_uri,ref:h.source_ref,kind:h.provenance?.source_kind??null,revision:h.revision,hash:h.hash},citation:{chunk_id:h.chunk_id,start_offset:h.provenance?.start_offset??null,end_offset:h.provenance?.end_offset??null},artifact:null,provenance:h.provenance,reasons:["semantic_match"]};w.score=_e(w.scores,w.citation),Oe(l,w)}}catch(E){c.push(`semantic_search_failed: ${E instanceof Error?E.message:String(E)}`)}let m=ni(Array.from(l.values())).slice(0,n);return{query:t,limit:n,mode:{keyword:!0,catalog:!0,semantic:s},semantic_provider:d,semantic_model:g,semantic_dimensions:a,counts:{keyword_results:u,catalog_results:o,semantic_results:_,merged_results:m.length},warnings:c,results:m}}function on(e,t){return`${e}_${ri("sha256").update(t).digest("hex").slice(0,20)}`}function an(e){return e.normalize("NFKC").trim().replace(/\s+/g," ").toLowerCase()}function ii(e){return Array.from(new Set(an(e).match(/[\p{L}\p{N}_]+/gu)??[])).slice(0,16)}function si(e){return[e.title,e.text].filter(Boolean).join(" ").toLowerCase()}function oi(e,t){if(t.length===0)return 0;let n=si(e),r=t.filter((i)=>n.includes(i)).length;return Number((r/t.length).toFixed(6))}function ai(e){if(!e)return!0;if("read_only"in e)return e.read_only===!0;if("read_only_sources"in e)return e.read_only_sources===!0;return!0}function un(e){if(!e)return!1;if("stale"in e&&e.stale)return!0;if("status"in e)return st(e.status);return!1}function ui(e){if(un(e.provenance))return 0;if(e.source?.hash||e.source?.revision)return 1;if(e.artifact?.hash)return 0.85;if(e.provenance&&"source_refs"in e.provenance&&e.provenance.source_refs.length>0)return 0.75;return 0.55}function ci(e){if(e.citation?.chunk_id&&(e.source?.uri||e.artifact?.uri))return 1;if(e.provenance&&"citation_required"in e.provenance&&e.provenance.citation_required)return 0.75;if(e.artifact?.uri)return 0.65;return 0.35}function di(e){if(e.kind==="wiki_chunk")return 0.85;if(e.kind==="source_chunk")return 0.8;if(e.kind==="wiki_page")return 0.65;return 0.55}function li(e,t){let n={base_score:e.score,exact_score:oi(e,t),citation_score:ci(e),freshness_score:ui(e),authority_score:di(e)},r=Math.min(1,n.base_score*0.65+n.exact_score*0.1+n.citation_score*0.1+n.freshness_score*0.1+n.authority_score*0.05),i=new Set(e.reasons);if(n.exact_score>0.5)i.add("exact_term");if(n.citation_score>=0.75)i.add("cited_source");if(n.freshness_score>=0.85)i.add("fresh_source");return{...e,score:Number(r.toFixed(6)),reasons:Array.from(i),rerank:{...n,final_score:Number(r.toFixed(6))}}}function cn(e,t){let n=e.text??e.title;if(!n)return null;let r=n.replace(/\s+/g," ").trim();return r.length<=t?r:`${r.slice(0,Math.max(0,t-1)).trim()}...`}function _i(e){return{id:on("cite",`${e.kind}\x00${e.id}\x00${e.source?.uri??""}\x00${e.artifact?.uri??""}`),result_id:e.id,kind:e.kind,source_uri:e.source?.uri??null,source_ref:e.source?.ref??null,artifact_uri:e.artifact?.uri??null,artifact_path:e.artifact?.path??null,revision:e.source?.revision??null,hash:e.source?.hash??e.artifact?.hash??null,chunk_id:e.citation?.chunk_id??null,start_offset:e.citation?.start_offset??null,end_offset:e.citation?.end_offset??null,quote:cn(e,500),provenance:e.provenance}}function fi(e,t,n){let r=cn(e,n);if(!r)return null;return{id:on("excerpt",`${e.kind}\x00${e.id}`),result_id:e.id,citation_id:t.id,kind:e.kind,text:r,score:e.score}}function Le(e){return e.map(()=>"?").join(", ")}function gi(e,t){let n=t.map((d)=>d.citation?.chunk_id).filter((d)=>Boolean(d)),r=t.filter((d)=>d.kind==="wiki_page").map((d)=>d.id),i=[],s=[];if(n.length===0&&r.length===0)return{citations:i,backlinks:s};let c=b(e);try{if(n.length>0)i.push(...c.query(`SELECT id, wiki_page_id, chunk_id, source_uri, quote, start_offset, end_offset
390
390
  FROM citations
391
391
  WHERE chunk_id IN (${Le(n)})
392
392
  ORDER BY created_at DESC
@@ -405,9 +405,9 @@ ${JSON.stringify(n,null,2)}`].join(`
405
405
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[t.runId,"knowledge-prompt",t.prompt,t.status,t.provider,t.model,JSON.stringify(t.metadata),t.now,t.now])}finally{n.close()}}function dt(e,t){let n=b(e);try{n.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
406
406
  VALUES (?, ?, ?, ?, ?, ?)`,[`evt_${ln()}`,t.runId,t.level,t.event,JSON.stringify(t.metadata),t.now])}finally{n.close()}}function dn(e,t){let n=b(e);try{n.run(`UPDATE runs
407
407
  SET status = ?, provider = ?, model = ?, metadata_json = ?, updated_at = ?
408
- WHERE id = ?`,[t.status,t.provider,t.model,JSON.stringify(t.metadata),t.now,t.runId])}finally{n.close()}}function yi(e,t,n,r,i,s,c={}){let d=b(e);try{Te(d,{run_id:t,provider:r,model:i,input_tokens:n.input_tokens,output_tokens:n.output_tokens,cost_usd:n.cost_usd,metadata:c,created_at:s})}finally{d.close()}}async function _n(e){let t=e.prompt.trim();if(!t)throw Error("Knowledge prompt is required.");let n=(e.now??new Date).toISOString(),r=`run_${ln()}`,i=H(e.modelRef??"default",e.config),s=C(i);x(e.dbPath),Ei(e.dbPath,{runId:r,prompt:t,status:e.generate?"running":"dry_run",provider:e.generate?s.provider:"local",model:e.generate?s.model:"context-draft",metadata:{semantic:e.semantic===!0||e.fake===!0||Boolean(e.modelRef),approve_write:e.approveWrite===!0,generated:e.generate===!0},now:n});let{prompt:c,generate:d,approveWrite:g,now:a,...u}=e,o=await Ce({...u,query:t});dt(e.dbPath,{runId:r,level:"info",event:"context_retrieved",metadata:{results:o.results.length,citations:o.citations.length,warnings:o.warnings},now:n});let _=mi(t,o),l=!1,f="local",m="context-draft",E={input_tokens:ct(t)+o.excerpts.reduce((p,R)=>p+ct(R.text),0),output_tokens:ct(_),cost_usd:0},h=[...o.warnings];if(e.generate)try{if(e.fake)l=!0,f=s.provider,m=s.model,_=`Fake generated answer for: ${t}
408
+ WHERE id = ?`,[t.status,t.provider,t.model,JSON.stringify(t.metadata),t.now,t.runId])}finally{n.close()}}function yi(e,t,n,r,i,s,c={}){let d=b(e);try{we(d,{run_id:t,provider:r,model:i,input_tokens:n.input_tokens,output_tokens:n.output_tokens,cost_usd:n.cost_usd,metadata:c,created_at:s})}finally{d.close()}}async function _n(e){let t=e.prompt.trim();if(!t)throw Error("Knowledge prompt is required.");let n=(e.now??new Date).toISOString(),r=`run_${ln()}`,i=H(e.modelRef??"default",e.config),s=C(i);x(e.dbPath),Ei(e.dbPath,{runId:r,prompt:t,status:e.generate?"running":"dry_run",provider:e.generate?s.provider:"local",model:e.generate?s.model:"context-draft",metadata:{semantic:e.semantic===!0||e.fake===!0||Boolean(e.modelRef),approve_write:e.approveWrite===!0,generated:e.generate===!0},now:n});let{prompt:c,generate:d,approveWrite:g,now:a,...u}=e,o=await Ce({...u,query:t});dt(e.dbPath,{runId:r,level:"info",event:"context_retrieved",metadata:{results:o.results.length,citations:o.citations.length,warnings:o.warnings},now:n});let _=mi(t,o),l=!1,f="local",m="context-draft",E={input_tokens:ct(t)+o.excerpts.reduce((p,R)=>p+ct(R.text),0),output_tokens:ct(_),cost_usd:0},h=[...o.warnings];if(e.generate)try{if(e.fake)l=!0,f=s.provider,m=s.model,_=`Fake generated answer for: ${t}
409
409
 
410
- ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,env:e.env}),v=await p({model:R,system:"You answer company knowledge-base prompts using only provided context and citation ids.",prompt:pi(t,o)});l=!0,f=s.provider,m=s.model,_=v.text;let w=we({provider:f,model:m,usage:v.usage,providerMetadata:v.providerMetadata});E={input_tokens:w.input_tokens,output_tokens:w.output_tokens,cost_usd:w.cost_usd}}}catch(p){throw dt(e.dbPath,{runId:r,level:"error",event:"answer_generation_failed",metadata:{message:p instanceof Error?p.message:String(p)},now:n}),dn(e.dbPath,{runId:r,status:"failed",provider:s.provider,model:s.model,metadata:{generated:!1,error:p instanceof Error?p.message:String(p)},now:n}),p}let T=hi(t,o),k={approved:e.approveWrite===!0,durable_writes_performed:!1,reason:e.approveWrite?"Approval flag recorded; durable wiki writing is deferred to the wiki compile task.":"Dry-run mode: proposed wiki updates require approval before durable writes."};return dt(e.dbPath,{runId:r,level:"info",event:l?"answer_generated":"answer_drafted",metadata:{provider:f,model:m,proposed_updates:T.length,durable_writes_performed:!1},now:n}),yi(e.dbPath,r,E,f,m,n,{generated:l,citations:o.citations.length}),dn(e.dbPath,{runId:r,status:l?"completed":"dry_run",provider:f,model:m,metadata:{generated:l,citations:o.citations.length,proposed_updates:T.length,approve_write:e.approveWrite===!0},now:n}),{run_id:r,prompt:t,generated:l,provider:f,model:m,answer:_,context:o,citations:o.citations,proposed_wiki_updates:T,write_policy:k,usage:E,warnings:h}}import{createHash as Ii,randomUUID as Li}from"crypto";import{existsSync as Ci,readFileSync as Di}from"fs";import{basename as Ui}from"path";function fn(e,t){if(!e)throw Error(t);return e}function ki(e){let n=e.slice(13).split("/").filter(Boolean),r=n[0];if(r!=="file"&&r!=="source")throw Error("Invalid open-files ref. Expected open-files://file/<id>, open-files://file/<id>/revision/<revision_id>, or open-files://source/<id>/path/<path>.");let i=fn(n[1],"Invalid open-files ref. Missing id.");if(r==="file"){if(n.length===2)return{kind:"open-files",uri:e,entity:r,id:i};if(n[2]==="revision"&&n[3]&&n.length===4)return{kind:"open-files",uri:e,entity:r,id:i,revision_id:decodeURIComponent(n[3])};throw Error("Invalid open-files file ref. Expected open-files://file/<id>/revision/<revision_id>.")}let s=n.indexOf("path"),c=s>=0?decodeURIComponent(n.slice(s+1).join("/")):void 0;return{kind:"open-files",uri:e,entity:r,id:i,path:c}}function bi(e){let t=new URL(e),n=fn(t.hostname,"Invalid s3 ref. Missing bucket."),r=decodeURIComponent(t.pathname.replace(/^\/+/,""));if(!r)throw Error("Invalid s3 ref. Missing object key.");return{kind:"s3",uri:e,bucket:n,key:r}}function vi(e){let t=new URL(e);return{kind:"file",uri:e,path:decodeURIComponent(t.pathname)}}function wi(e){let t=new URL(e);return{kind:"web",uri:e,url:t.toString()}}function M(e){if(e.startsWith("open-files://"))return ki(e);if(e.startsWith("s3://"))return bi(e);if(e.startsWith("file://"))return vi(e);if(e.startsWith("https://")||e.startsWith("http://"))return wi(e);throw Error(`Unsupported source ref scheme: ${e}`)}function gn(e,t=M(e)){if(t.kind==="open-files"&&t.entity==="file"&&t.revision_id)return e.replace(/\/revision\/[^/]+$/,"");return e}function mn(e){let t=M(e);return t.kind==="open-files"&&t.entity==="file"?t.revision_id??null:null}import{createHash as Ti,randomUUID as _t}from"crypto";import{relative as Ri,resolve as hn,sep as Si}from"path";function pn(e){let t=process.env[e];return t==="1"||t==="true"||t==="yes"}function En(e,t){let n=e,r=new Set(n.safety?.network?.allowed_s3_buckets??[]);if(e.storage.type==="s3"&&e.storage.s3?.bucket)r.add(e.storage.s3.bucket);if(process.env.HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS)for(let i of process.env.HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS.split(",").map((s)=>s.trim()).filter(Boolean))r.add(i);return{mode:e.mode,allowWriteRoots:[t.home,t.artifactsDir,t.cacheDir,t.exportsDir,t.indexesDir,t.logsDir,t.runsDir,t.schemasDir,t.wikiDir].map((i)=>hn(i)),readOnlySourceAccess:!0,network:{webSearchEnabled:n.safety?.network?.web_search_enabled??pn("HASNA_KNOWLEDGE_WEB_SEARCH"),s3ReadsEnabled:n.safety?.network?.s3_reads_enabled??pn("HASNA_KNOWLEDGE_ALLOW_S3_READS"),allowedS3Buckets:[...r].sort()},redaction:{enabled:n.safety?.redaction?.enabled??!0},approvals:{generatedWritesRequireApproval:n.safety?.approvals?.generated_writes_require_approval??!0}}}function xi(e,t){let n=Ri(e,t);return n===""||!n.startsWith("..")&&n!==".."&&!n.startsWith(`..${Si}`)}function Q(e,t){let n=hn(e);if(!t.allowWriteRoots.some((r)=>xi(r,n)))throw Error(`Safety policy denied write outside .hasna/apps/knowledge: ${e}`)}function J(e,t){let r=new URL(e).hostname;if(!t.network.s3ReadsEnabled)throw Error("Safety policy denied S3 read. Set safety.network.s3_reads_enabled=true or HASNA_KNOWLEDGE_ALLOW_S3_READS=1.");if(!t.network.allowedS3Buckets.includes(r))throw Error(`Safety policy denied S3 bucket "${r}". Add it to safety.network.allowed_s3_buckets or HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS.`)}function ie(e){if(!e.network.webSearchEnabled)throw Error("Safety policy denied web search. Set safety.network.web_search_enabled=true or HASNA_KNOWLEDGE_WEB_SEARCH=1.")}var Oi=[{type:"private_key_block",severity:"high",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,replacement:"[REDACTED:private_key_block]"},{type:"secret_assignment",severity:"high",regex:/\b(?:api[_-]?key|secret|token|password)\s*[:=]\s*['"]?[^'"\s]{8,}/gi,replacement:"[REDACTED:secret_assignment]"},{type:"openai_api_key",severity:"high",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,replacement:"[REDACTED:openai_api_key]"},{type:"anthropic_api_key",severity:"high",regex:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,replacement:"[REDACTED:anthropic_api_key]"},{type:"aws_access_key_id",severity:"high",regex:/\bA(?:KIA|SIA)[A-Z0-9]{16}\b/g,replacement:"[REDACTED:aws_access_key_id]"}];function De(e,t){if(t&&!t.redaction.enabled)return{text:e,findings:[]};let n=e,r=[];for(let i of Oi)n=n.replace(i.regex,(s,...c)=>{let d=typeof c.at(-2)==="number"?c.at(-2):n.indexOf(s);return r.push({type:i.type,severity:i.severity,start:Math.max(0,d),end:Math.max(0,d+s.length)}),i.replacement});return{text:n,findings:r}}function Ni(e){return`audit_${Ti("sha256").update(`${e.event_type}\x00${e.action}\x00${e.target_uri??""}\x00${e.created_at??""}\x00${JSON.stringify(e.metadata??{})}\x00${_t()}`).digest("hex").slice(0,24)}`}function I(e,t){let n=t.created_at??new Date().toISOString(),r=Ni({...t,created_at:n});return e.run(`INSERT INTO audit_events (id, event_type, action, target_uri, decision, metadata_json, created_at)
410
+ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,env:e.env}),v=await p({model:R,system:"You answer company knowledge-base prompts using only provided context and citation ids.",prompt:pi(t,o)});l=!0,f=s.provider,m=s.model,_=v.text;let T=Te({provider:f,model:m,usage:v.usage,providerMetadata:v.providerMetadata});E={input_tokens:T.input_tokens,output_tokens:T.output_tokens,cost_usd:T.cost_usd}}}catch(p){throw dt(e.dbPath,{runId:r,level:"error",event:"answer_generation_failed",metadata:{message:p instanceof Error?p.message:String(p)},now:n}),dn(e.dbPath,{runId:r,status:"failed",provider:s.provider,model:s.model,metadata:{generated:!1,error:p instanceof Error?p.message:String(p)},now:n}),p}let w=hi(t,o),k={approved:e.approveWrite===!0,durable_writes_performed:!1,reason:e.approveWrite?"Approval flag recorded; durable wiki writing is deferred to the wiki compile task.":"Dry-run mode: proposed wiki updates require approval before durable writes."};return dt(e.dbPath,{runId:r,level:"info",event:l?"answer_generated":"answer_drafted",metadata:{provider:f,model:m,proposed_updates:w.length,durable_writes_performed:!1},now:n}),yi(e.dbPath,r,E,f,m,n,{generated:l,citations:o.citations.length}),dn(e.dbPath,{runId:r,status:l?"completed":"dry_run",provider:f,model:m,metadata:{generated:l,citations:o.citations.length,proposed_updates:w.length,approve_write:e.approveWrite===!0},now:n}),{run_id:r,prompt:t,generated:l,provider:f,model:m,answer:_,context:o,citations:o.citations,proposed_wiki_updates:w,write_policy:k,usage:E,warnings:h}}import{createHash as Ii,randomUUID as Li}from"crypto";import{existsSync as Ci,readFileSync as Di}from"fs";import{basename as Ui}from"path";function fn(e,t){if(!e)throw Error(t);return e}function ki(e){let n=e.slice(13).split("/").filter(Boolean),r=n[0];if(r!=="file"&&r!=="source")throw Error("Invalid open-files ref. Expected open-files://file/<id>, open-files://file/<id>/revision/<revision_id>, or open-files://source/<id>/path/<path>.");let i=fn(n[1],"Invalid open-files ref. Missing id.");if(r==="file"){if(n.length===2)return{kind:"open-files",uri:e,entity:r,id:i};if(n[2]==="revision"&&n[3]&&n.length===4)return{kind:"open-files",uri:e,entity:r,id:i,revision_id:decodeURIComponent(n[3])};throw Error("Invalid open-files file ref. Expected open-files://file/<id>/revision/<revision_id>.")}let s=n.indexOf("path"),c=s>=0?decodeURIComponent(n.slice(s+1).join("/")):void 0;return{kind:"open-files",uri:e,entity:r,id:i,path:c}}function bi(e){let t=new URL(e),n=fn(t.hostname,"Invalid s3 ref. Missing bucket."),r=decodeURIComponent(t.pathname.replace(/^\/+/,""));if(!r)throw Error("Invalid s3 ref. Missing object key.");return{kind:"s3",uri:e,bucket:n,key:r}}function vi(e){let t=new URL(e);return{kind:"file",uri:e,path:decodeURIComponent(t.pathname)}}function Ti(e){let t=new URL(e);return{kind:"web",uri:e,url:t.toString()}}function M(e){if(e.startsWith("open-files://"))return ki(e);if(e.startsWith("s3://"))return bi(e);if(e.startsWith("file://"))return vi(e);if(e.startsWith("https://")||e.startsWith("http://"))return Ti(e);throw Error(`Unsupported source ref scheme: ${e}`)}function gn(e,t=M(e)){if(t.kind==="open-files"&&t.entity==="file"&&t.revision_id)return e.replace(/\/revision\/[^/]+$/,"");return e}function mn(e){let t=M(e);return t.kind==="open-files"&&t.entity==="file"?t.revision_id??null:null}import{createHash as wi,randomUUID as _t}from"crypto";import{relative as Ri,resolve as hn,sep as Si}from"path";function pn(e){let t=process.env[e];return t==="1"||t==="true"||t==="yes"}function En(e,t){let n=e,r=new Set(n.safety?.network?.allowed_s3_buckets??[]);if(e.storage.type==="s3"&&e.storage.s3?.bucket)r.add(e.storage.s3.bucket);if(process.env.HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS)for(let i of process.env.HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS.split(",").map((s)=>s.trim()).filter(Boolean))r.add(i);return{mode:e.mode,allowWriteRoots:[t.home,t.artifactsDir,t.cacheDir,t.exportsDir,t.indexesDir,t.logsDir,t.runsDir,t.schemasDir,t.wikiDir].map((i)=>hn(i)),readOnlySourceAccess:!0,network:{webSearchEnabled:n.safety?.network?.web_search_enabled??pn("HASNA_KNOWLEDGE_WEB_SEARCH"),s3ReadsEnabled:n.safety?.network?.s3_reads_enabled??pn("HASNA_KNOWLEDGE_ALLOW_S3_READS"),allowedS3Buckets:[...r].sort()},redaction:{enabled:n.safety?.redaction?.enabled??!0},approvals:{generatedWritesRequireApproval:n.safety?.approvals?.generated_writes_require_approval??!0}}}function xi(e,t){let n=Ri(e,t);return n===""||!n.startsWith("..")&&n!==".."&&!n.startsWith(`..${Si}`)}function Q(e,t){let n=hn(e);if(!t.allowWriteRoots.some((r)=>xi(r,n)))throw Error(`Safety policy denied write outside .hasna/apps/knowledge: ${e}`)}function J(e,t){let r=new URL(e).hostname;if(!t.network.s3ReadsEnabled)throw Error("Safety policy denied S3 read. Set safety.network.s3_reads_enabled=true or HASNA_KNOWLEDGE_ALLOW_S3_READS=1.");if(!t.network.allowedS3Buckets.includes(r))throw Error(`Safety policy denied S3 bucket "${r}". Add it to safety.network.allowed_s3_buckets or HASNA_KNOWLEDGE_ALLOWED_S3_BUCKETS.`)}function ie(e){if(!e.network.webSearchEnabled)throw Error("Safety policy denied web search. Set safety.network.web_search_enabled=true or HASNA_KNOWLEDGE_WEB_SEARCH=1.")}var Oi=[{type:"private_key_block",severity:"high",regex:/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,replacement:"[REDACTED:private_key_block]"},{type:"secret_assignment",severity:"high",regex:/\b(?:api[_-]?key|secret|token|password)\s*[:=]\s*['"]?[^'"\s]{8,}/gi,replacement:"[REDACTED:secret_assignment]"},{type:"openai_api_key",severity:"high",regex:/\bsk-[A-Za-z0-9_-]{20,}\b/g,replacement:"[REDACTED:openai_api_key]"},{type:"anthropic_api_key",severity:"high",regex:/\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,replacement:"[REDACTED:anthropic_api_key]"},{type:"aws_access_key_id",severity:"high",regex:/\bA(?:KIA|SIA)[A-Z0-9]{16}\b/g,replacement:"[REDACTED:aws_access_key_id]"}];function De(e,t){if(t&&!t.redaction.enabled)return{text:e,findings:[]};let n=e,r=[];for(let i of Oi)n=n.replace(i.regex,(s,...c)=>{let d=typeof c.at(-2)==="number"?c.at(-2):n.indexOf(s);return r.push({type:i.type,severity:i.severity,start:Math.max(0,d),end:Math.max(0,d+s.length)}),i.replacement});return{text:n,findings:r}}function Ni(e){return`audit_${wi("sha256").update(`${e.event_type}\x00${e.action}\x00${e.target_uri??""}\x00${e.created_at??""}\x00${JSON.stringify(e.metadata??{})}\x00${_t()}`).digest("hex").slice(0,24)}`}function I(e,t){let n=t.created_at??new Date().toISOString(),r=Ni({...t,created_at:n});return e.run(`INSERT INTO audit_events (id, event_type, action, target_uri, decision, metadata_json, created_at)
411
411
  VALUES (?, ?, ?, ?, ?, ?, ?)`,[r,t.event_type,t.action,t.target_uri??null,t.decision,JSON.stringify(t.metadata??{}),n]),r}function Ue(e,t){let n=t.created_at??new Date().toISOString();for(let r of t.findings)e.run(`INSERT INTO redaction_findings (id, source_uri, run_id, severity, finding_type, metadata_json, created_at)
412
412
  VALUES (?, ?, ?, ?, ?, ?, ?)`,[`redact_${_t()}`,t.source_uri??null,t.run_id??null,r.severity,r.type,JSON.stringify({...t.metadata??{},start:r.start,end:r.end}),n]);return t.findings.length}function yn(e,t){let n=t.created_at??new Date().toISOString(),r=`approval_${_t()}`;return e.run(`INSERT INTO approval_gates (id, action, target_uri, status, reason, approved_by, metadata_json, created_at, updated_at)
413
413
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[r,t.action,t.target_uri??null,"approved",t.reason??null,t.approved_by??"local-cli",JSON.stringify(t.metadata??{}),n,n]),{id:r,status:"approved"}}function Ai(e,t,n){let r=e.query(`SELECT id FROM approval_gates
@@ -422,7 +422,7 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
422
422
  ON CONFLICT(source_id, revision) DO UPDATE SET
423
423
  hash = COALESCE(excluded.hash, source_revisions.hash),
424
424
  metadata_json = excluded.metadata_json`,[i,t,n.revision,n.hash,N(n.raw.extracted_text_ref)??null,JSON.stringify(s),r]),e.query("SELECT id FROM source_revisions WHERE source_id = ? AND revision = ?").get(t,n.revision)?.id??null}function Gi(e,t,n){if(n.revision)return e.query("SELECT id FROM source_revisions WHERE source_id = ? AND revision = ?").all(t,n.revision).map((r)=>r.id);if(n.hash)return e.query("SELECT id FROM source_revisions WHERE source_id = ? AND hash = ?").all(t,n.hash).map((r)=>r.id);return e.query("SELECT id FROM source_revisions WHERE source_id = ?").all(t).map((r)=>r.id)}function zi(e,t){let n=e.query("SELECT id FROM chunks WHERE source_revision_id = ?").all(t),r=0,i=0;for(let c of n){let d=e.query("SELECT COUNT(*) AS n FROM chunk_embeddings WHERE chunk_id = ?").get(c.id);r+=d?.n??0;let g=e.query("SELECT COUNT(*) AS n FROM vector_index_entries WHERE chunk_id = ?").get(c.id);i+=g?.n??0,e.run("DELETE FROM vector_index_entries WHERE chunk_id = ?",[c.id]),e.run("DELETE FROM chunk_embeddings WHERE chunk_id = ?",[c.id]),e.run("DELETE FROM chunks_fts WHERE chunk_id = ?",[c.id])}e.run("DELETE FROM chunks WHERE source_revision_id = ?",[t]);let s=e.query("SELECT metadata_json FROM source_revisions WHERE id = ?").get(t);return e.run("UPDATE source_revisions SET metadata_json = ? WHERE id = ?",[bn(s?.metadata_json,{reindex_required:!0,invalidated_at:new Date().toISOString()}),t]),{chunksDeleted:n.length,embeddingsDeleted:r,vectorEntriesDeleted:i}}function Yi(e,t){return t==="deleted"||["delete","deleted","remove","removed"].includes(e)}function Vi(e){return["move","moved","rename","renamed","path_changed"].includes(e)}function Qi(e){return["permission","permissions","permission_changed","acl_changed"].includes(e)}async function vn(e){let t=(e.now??new Date).toISOString();if(e.safetyPolicy)Q(e.dbPath,e.safetyPolicy);x(e.dbPath);let n=await Hi(e.input,e.config,e.safetyPolicy),r=Xi(n),i=b(e.dbPath),s=`run_${Li()}`;try{return i.transaction(()=>{i.run(`INSERT INTO runs (id, type, prompt, status, provider, model, metadata_json, created_at, updated_at)
425
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[s,"open-files-outbox",e.input,"completed","local","open-files-outbox",JSON.stringify({path:e.input,events:r.length}),t,t]);let c=new Set,d=new Set,g=0,a=0,u=0,o=0,_=0,l=0,f=0;return I(i,{event_type:"source_read",action:e.input.startsWith("s3://")?"s3_outbox_read":"local_outbox_read",target_uri:e.input,decision:"allow",metadata:{events:r.length,read_only:!0},created_at:t}),r.forEach((m,E)=>{let h=Wi(m,t),T=Bi(i,h,t);c.add(T);let k=Ji(i,T,h,t);if(k)d.add(k);let p=Gi(i,T,h);for(let R of p){d.add(R);let v=zi(i,R);g+=v.chunksDeleted,a+=v.embeddingsDeleted,u+=v.vectorEntriesDeleted,o+=1}if(Yi(h.eventType,h.status))_+=1;if(Vi(h.eventType))l+=1;if(Qi(h.eventType)||h.acl!==void 0)f+=1;i.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
425
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[s,"open-files-outbox",e.input,"completed","local","open-files-outbox",JSON.stringify({path:e.input,events:r.length}),t,t]);let c=new Set,d=new Set,g=0,a=0,u=0,o=0,_=0,l=0,f=0;return I(i,{event_type:"source_read",action:e.input.startsWith("s3://")?"s3_outbox_read":"local_outbox_read",target_uri:e.input,decision:"allow",metadata:{events:r.length,read_only:!0},created_at:t}),r.forEach((m,E)=>{let h=Wi(m,t),w=Bi(i,h,t);c.add(w);let k=Ji(i,w,h,t);if(k)d.add(k);let p=Gi(i,w,h);for(let R of p){d.add(R);let v=zi(i,R);g+=v.chunksDeleted,a+=v.embeddingsDeleted,u+=v.vectorEntriesDeleted,o+=1}if(Yi(h.eventType,h.status))_+=1;if(Vi(h.eventType))l+=1;if(Qi(h.eventType)||h.acl!==void 0)f+=1;i.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
426
426
  VALUES (?, ?, ?, ?, ?, ?)`,[Pe("evt",`${s}\x00${E}\x00${h.sourceRef}\x00${h.eventType}`),s,"info",h.eventType,JSON.stringify({source_ref:h.sourceRef,source_uri:h.sourceUri,revision:h.revision,hash:h.hash,status:h.status,affected_revisions:p.length}),h.updatedAt])}),i.run(`INSERT INTO provider_usage (id, run_id, provider, model, input_tokens, output_tokens, cost_usd, metadata_json, created_at)
427
427
  VALUES (?, ?, ?, ?, 0, 0, 0, ?, ?)`,[Pe("usage",s),s,"local","open-files-outbox",JSON.stringify({note:"No model provider used for outbox invalidation."}),t]),I(i,{event_type:"write",action:"knowledge_outbox_invalidation",target_uri:e.dbPath,decision:"allow",metadata:{run_id:s,events:r.length,sources:c.size,revisions:d.size,chunks_deleted:g,embeddings_deleted:a,vector_entries_deleted:u},created_at:t}),{path:e.input,db_path:e.dbPath,run_id:s,events_seen:r.length,sources_touched:c.size,revisions_touched:d.size,chunks_deleted:g,embeddings_deleted:a,vector_entries_deleted:u,stale_revisions:o,deleted_sources:_,moved_sources:l,permission_updates:f}})()}finally{i.close()}}import{createHash as Zi}from"crypto";import{existsSync as es,readFileSync as ts}from"fs";import{basename as ns}from"path";function ft(e,t){return`${e}_${Zi("sha256").update(t).digest("hex").slice(0,20)}`}function oe(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:void 0}function S(e){return typeof e==="string"&&e.length>0?e:void 0}function rs(e){return typeof e==="number"&&Number.isFinite(e)?e:void 0}function is(e){let t=S(e.source_ref)??S(e.source_uri)??S(e.uri);if(t)return t;let n=S(e.file_id);if(n){let s=S(e.revision_id)??S(e.revision),c=`open-files://file/${encodeURIComponent(n)}`;return s?`${c}/revision/${encodeURIComponent(s)}`:c}let r=S(e.source_id),i=S(e.path);if(r&&i)return`open-files://source/${encodeURIComponent(r)}/path/${encodeURIComponent(i)}`;throw Error("Manifest item is missing source_ref, file_id, or source_id/path.")}function ss(e,t){if(t.kind==="open-files"&&t.entity==="file"&&t.revision_id)return e.replace(/\/revision\/[^/]+$/,"");return e}function os(e){let t=S(e.extracted_text)??S(e.text)??S(e.content_text)??S(e.markdown);if(t!==void 0)return t;let n=e.content;return typeof n==="string"?n:null}function as(e){let t=S(e.extracted_text_ref)??S(e.extracted_text_uri)??S(e.text_ref);if(t)return t;let n=oe(e.content);return S(n?.extracted_text_ref)??S(n?.extracted_text_uri)??null}function us(e){let t=S(e.path);return S(e.title)??S(e.name)??(t?ns(t):null)}function cs(e){return S(e.hash)??S(e.checksum)??S(e.sha256)??null}function ds(e,t,n){return S(e.revision_id)??S(e.revision)??S(e.version_id)??(t.kind==="open-files"?t.revision_id:void 0)??n??S(e.updated_at)??"current"}function ls(e,t){let n={};for(let[r,i]of Object.entries(e)){if(["text","content","content_text","extracted_text","markdown"].includes(r))continue;n[r]=i}return n.source_ref=t.sourceRef,n.source_uri=t.sourceUri,n.status=t.status,n}function _s(e,t){let n=is(e),r=M(n),i=ss(n,r),s=cs(e),c=S(e.status)??"active";return{raw:e,sourceRef:n,sourceUri:i,kind:r.kind,title:us(e),revision:ds(e,r,s),hash:s,extractedTextUri:as(e),text:os(e),metadata:ls(e,{sourceRef:n,sourceUri:i,status:c}),acl:e.permissions??e.acl??{},status:c,updatedAt:S(e.updated_at)??t}}function fs(e){let t=e.trim();if(!t)return[];if(t.startsWith("[")){let n=JSON.parse(t);if(!Array.isArray(n))throw Error("Manifest array parse failed.");return n.map((r)=>{let i=oe(r);if(!i)throw Error("Manifest array entries must be objects.");return i})}if(t.startsWith("{"))try{let n=JSON.parse(t),r=oe(n);if(!r)throw Error("Manifest object parse failed.");if(Array.isArray(r.items))return r.items.map((i)=>{let s=oe(i);if(!s)throw Error("Manifest items entries must be objects.");return s});if("source_ref"in r||"source_uri"in r||"file_id"in r)return[r]}catch(n){let r=t.split(/\r?\n/).filter((i)=>i.trim().length>0);if(r.length<=1)throw n;return r.map((i)=>{let s=oe(JSON.parse(i));if(!s)throw Error("Manifest JSONL entries must be objects.");return s})}return t.split(/\r?\n/).filter((n)=>n.trim().length>0).map((n)=>{let r=oe(JSON.parse(n));if(!r)throw Error("Manifest JSONL entries must be objects.");return r})}async function gs(e,t,n){let r=new URL(e),i=r.hostname,s=decodeURIComponent(r.pathname.replace(/^\/+/,""));if(!i||!s)throw Error(`Invalid S3 manifest URI: ${e}`);if(n)J(e,n);let[{S3Client:c,GetObjectCommand:d},{fromIni:g}]=await Promise.all([import("@aws-sdk/client-s3"),import("@aws-sdk/credential-providers")]),a=t?.storage.type==="s3"&&t.storage.s3?.bucket===i?t.storage.s3:void 0,o=await new c({region:a?.region,credentials:a?.profile?g({profile:a.profile}):void 0,maxAttempts:a?.max_attempts}).send(new d({Bucket:i,Key:s}));if(!o.Body)return"";return await o.Body.transformToString()}async function ms(e,t,n){if(e.startsWith("s3://"))return gs(e,t,n);if(!es(e))throw Error(`Manifest not found: ${e}`);return ts(e,"utf8")}function ps(e,t,n){let r=e.replace(/\r\n/g,`
428
428
  `);if(!r.trim())return[];let i=[],s=0;while(s<r.length){let c=Math.min(r.length,s+t),d=c;if(c<r.length){let a=r.lastIndexOf(`
@@ -440,7 +440,7 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
440
440
  hash = excluded.hash,
441
441
  extracted_text_uri = excluded.extracted_text_uri,
442
442
  metadata_json = excluded.metadata_json`,[i,t,n.revision,n.hash,n.extractedTextUri,JSON.stringify(n.metadata),r]);let s=e.query("SELECT id FROM source_revisions WHERE source_id = ? AND revision = ?").get(t,n.revision);if(!s)throw Error(`Failed to upsert source revision: ${n.sourceRef}`);return s.id}function bs(e,t,n,r,i,s,c){if(!n.text||n.status.toLowerCase()==="deleted")return{chunksInserted:0,redactions:0};let d=De(n.text,c);if(d.findings.length>0)Ue(e,{source_uri:n.sourceUri,findings:d.findings,metadata:{source_ref:n.sourceRef,revision:n.revision},created_at:r}),I(e,{event_type:"redaction",action:"source_text_redact",target_uri:n.sourceUri,decision:"redacted",metadata:{findings:d.findings.length,source_ref:n.sourceRef,revision:n.revision},created_at:r});let g=ps(d.text,i,s);for(let a of g){let u=ft("chk",`${t}\x00${a.ordinal}\x00${a.text}`),o=B({source_ref:n.sourceRef,source_uri:n.sourceUri,source_kind:n.kind,source_revision_id:t,revision:n.revision,hash:n.hash,chunk_id:u,start_offset:a.startOffset,end_offset:a.endOffset,status:n.status,resolver:"open-files-read-only"}),_=Jt({source_ref:n.sourceRef,source_uri:n.sourceUri,source_kind:n.kind,source_revision_id:t,revision:n.revision,hash:n.hash,status:n.status,path:S(n.raw.path)??null,mime:S(n.raw.mime)??S(n.raw.content_type)??null,size:rs(n.raw.size)??null},o);e.run(`INSERT INTO chunks (id, source_revision_id, kind, ordinal, text, token_count, start_offset, end_offset, metadata_json, created_at)
443
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[u,t,"source",a.ordinal,a.text,hs(a.text),a.startOffset,a.endOffset,JSON.stringify(_),r]),e.run("INSERT INTO chunks_fts (chunk_id, text, title, source_uri) VALUES (?, ?, ?, ?)",[u,a.text,n.title??"",n.sourceUri])}return{chunksInserted:g.length,redactions:d.findings.length}}async function wn(e){let t=e.now??new Date;if(e.safetyPolicy)Q(e.dbPath,e.safetyPolicy);x(e.dbPath);let n=await ms(e.input,e.config,e.safetyPolicy),r=fs(n);return fe({dbPath:e.dbPath,items:r,sourceLabel:e.input,safetyPolicy:e.safetyPolicy,now:t,maxChunkChars:e.maxChunkChars,chunkOverlapChars:e.chunkOverlapChars})}async function fe(e){let t=(e.now??new Date).toISOString(),n=e.maxChunkChars??4000,r=e.chunkOverlapChars??200;if(n<500)throw Error("maxChunkChars must be at least 500.");if(r<0||r>=n)throw Error("chunkOverlapChars must be less than maxChunkChars.");if(e.safetyPolicy)Q(e.dbPath,e.safetyPolicy);x(e.dbPath);let i=b(e.dbPath);try{return i.transaction(()=>{let c=new Set,d=new Set,g=0,a=0,u=0,o=0;I(i,{event_type:"source_read",action:e.readAction??(e.sourceLabel.startsWith("s3://")?"s3_manifest_read":"local_manifest_read"),target_uri:e.sourceLabel,decision:"allow",metadata:{items:e.items.length,read_only:!0},created_at:t});for(let _ of e.items){let l=_s(_,t),f=ys(i,l,t),m=ks(i,f,l,t);if(c.add(f),d.add(m),l.text||l.status.toLowerCase()==="deleted")a+=Es(i,m);let E=bs(i,m,l,t,n,r,e.safetyPolicy);g+=E.chunksInserted,u+=E.redactions}return I(i,{event_type:"write",action:"knowledge_manifest_ingest",target_uri:e.dbPath,decision:"allow",metadata:{items:e.items.length,sources:c.size,revisions:d.size,chunks_inserted:g,redactions:u},created_at:t}),{path:e.sourceLabel,db_path:e.dbPath,items_seen:e.items.length,sources_upserted:c.size,revisions_upserted:d.size,chunks_inserted:g,chunks_deleted:a,redactions:u,skipped:o}})()}finally{i.close()}}import{createHash as Os}from"crypto";import{existsSync as Ns,readFileSync as As}from"fs";import{basename as je}from"path";function Fe(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function Z(e,t){for(let n of t){let r=e[n];if(typeof r==="string"&&r.length>0)return r}return null}function Tn(e,t){for(let n of t){let r=e[n];if(typeof r==="number"&&Number.isFinite(r))return r}return null}function vs(e,t){let n=e.mode;if(typeof n==="string"&&n!=="read_only")throw Error(`Source resolver denied ${t}. Permission mode is ${n}, expected read_only.`);let r=e.denied_purposes;if(Array.isArray(r)&&r.includes(t))throw Error(`Source resolver denied ${t}. Purpose is explicitly denied.`);let i=e.allowed_purposes;if(Array.isArray(i)&&i.length>0&&!i.includes(t))throw Error(`Source resolver denied ${t}. Allowed purposes: ${i.join(", ")}`)}function ws(e,t,n){if(!t)return n;try{let r=M(e);if(r.kind==="open-files"&&r.entity==="file")return`${e}/revision/${encodeURIComponent(t.revision)}`}catch{return n}return n}function Ts(e,t,n){return e.query(`SELECT id, uri, kind, title, metadata_json, acl_json, updated_at
443
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,[u,t,"source",a.ordinal,a.text,hs(a.text),a.startOffset,a.endOffset,JSON.stringify(_),r]),e.run("INSERT INTO chunks_fts (chunk_id, text, title, source_uri) VALUES (?, ?, ?, ?)",[u,a.text,n.title??"",n.sourceUri])}return{chunksInserted:g.length,redactions:d.findings.length}}async function Tn(e){let t=e.now??new Date;if(e.safetyPolicy)Q(e.dbPath,e.safetyPolicy);x(e.dbPath);let n=await ms(e.input,e.config,e.safetyPolicy),r=fs(n);return fe({dbPath:e.dbPath,items:r,sourceLabel:e.input,safetyPolicy:e.safetyPolicy,now:t,maxChunkChars:e.maxChunkChars,chunkOverlapChars:e.chunkOverlapChars})}async function fe(e){let t=(e.now??new Date).toISOString(),n=e.maxChunkChars??4000,r=e.chunkOverlapChars??200;if(n<500)throw Error("maxChunkChars must be at least 500.");if(r<0||r>=n)throw Error("chunkOverlapChars must be less than maxChunkChars.");if(e.safetyPolicy)Q(e.dbPath,e.safetyPolicy);x(e.dbPath);let i=b(e.dbPath);try{return i.transaction(()=>{let c=new Set,d=new Set,g=0,a=0,u=0,o=0;I(i,{event_type:"source_read",action:e.readAction??(e.sourceLabel.startsWith("s3://")?"s3_manifest_read":"local_manifest_read"),target_uri:e.sourceLabel,decision:"allow",metadata:{items:e.items.length,read_only:!0},created_at:t});for(let _ of e.items){let l=_s(_,t),f=ys(i,l,t),m=ks(i,f,l,t);if(c.add(f),d.add(m),l.text||l.status.toLowerCase()==="deleted")a+=Es(i,m);let E=bs(i,m,l,t,n,r,e.safetyPolicy);g+=E.chunksInserted,u+=E.redactions}return I(i,{event_type:"write",action:"knowledge_manifest_ingest",target_uri:e.dbPath,decision:"allow",metadata:{items:e.items.length,sources:c.size,revisions:d.size,chunks_inserted:g,redactions:u},created_at:t}),{path:e.sourceLabel,db_path:e.dbPath,items_seen:e.items.length,sources_upserted:c.size,revisions_upserted:d.size,chunks_inserted:g,chunks_deleted:a,redactions:u,skipped:o}})()}finally{i.close()}}import{createHash as Os}from"crypto";import{existsSync as Ns,readFileSync as As}from"fs";import{basename as je}from"path";function Fe(e){if(!e)return{};try{let t=JSON.parse(e);return t&&typeof t==="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function Z(e,t){for(let n of t){let r=e[n];if(typeof r==="string"&&r.length>0)return r}return null}function wn(e,t){for(let n of t){let r=e[n];if(typeof r==="number"&&Number.isFinite(r))return r}return null}function vs(e,t){let n=e.mode;if(typeof n==="string"&&n!=="read_only")throw Error(`Source resolver denied ${t}. Permission mode is ${n}, expected read_only.`);let r=e.denied_purposes;if(Array.isArray(r)&&r.includes(t))throw Error(`Source resolver denied ${t}. Purpose is explicitly denied.`);let i=e.allowed_purposes;if(Array.isArray(i)&&i.length>0&&!i.includes(t))throw Error(`Source resolver denied ${t}. Allowed purposes: ${i.join(", ")}`)}function Ts(e,t,n){if(!t)return n;try{let r=M(e);if(r.kind==="open-files"&&r.entity==="file")return`${e}/revision/${encodeURIComponent(t.revision)}`}catch{return n}return n}function ws(e,t,n){return e.query(`SELECT id, uri, kind, title, metadata_json, acl_json, updated_at
444
444
  FROM sources
445
445
  WHERE uri = ? OR uri = ?
446
446
  ORDER BY CASE WHEN uri = ? THEN 0 ELSE 1 END
@@ -455,7 +455,7 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
455
455
  FROM chunks
456
456
  WHERE source_revision_id = ?
457
457
  ORDER BY ordinal ASC
458
- LIMIT ?`).all(t,n)}async function Me(e){let t=e.purpose??"knowledge_answer",n=Math.max(0,Math.min(e.limit??10,100)),r=(e.now??new Date).toISOString(),i=M(e.sourceRef),s=gn(e.sourceRef,i),c=mn(e.sourceRef);if(e.safetyPolicy){if(!e.safetyPolicy.readOnlySourceAccess)throw Error("Safety policy denied source resolution.");Q(e.dbPath,e.safetyPolicy)}x(e.dbPath);let d=b(e.dbPath);try{return d.transaction(()=>{let g=Ts(d,s,e.sourceRef);if(!g)return I(d,{event_type:"source_read",action:"open_files_resolve_missing",target_uri:e.sourceRef,decision:"allow",metadata:{purpose:t,read_only:!0,source_uri:s},created_at:r}),{source_ref:e.sourceRef,source_uri:s,purpose:t,read_only:!0,resolved:!1,resolver:{name:"open-files-read-only",mode:"local_catalog",contract:"open-files-knowledge-source-v1"},source:null,revision:null,content:{mime:null,size:null,hash:null,text_available:!1,chunks_total:0,chunks_returned:0,char_count_returned:0,extracted_text_ref:null,bytes_available:!1,bytes_exposed:!1},chunks:[],citations:[]};let a=Fe(g.metadata_json),u=Fe(g.acl_json);try{vs(u,t)}catch(p){throw I(d,{event_type:"source_read",action:"open_files_resolve",target_uri:e.sourceRef,decision:"deny",metadata:{purpose:t,read_only:!0,source_uri:g.uri,error:p instanceof Error?p.message:String(p)},created_at:r}),p}let o=Rs(d,g.id,c),_=Fe(o?.metadata_json),l=Ss(d,o?.id??null),f=xs(d,o?.id??null,n),m=ws(g.uri,o,e.sourceRef),E=f.map((p)=>{let R=Fe(p.metadata_json),v={resolver:"open-files-read-only",mode:"local_catalog",purpose:t,read_only:!0,source_ref:Z(R,["source_ref"])??m,source_uri:g.uri,source_revision_id:o?.id??null,revision:o?.revision??null,hash:o?.hash??Z(R,["hash"]),chunk_id:p.id,start_offset:p.start_offset,end_offset:p.end_offset,resolved_at:r},w=B({source_ref:v.source_ref,source_uri:v.source_uri,source_kind:g.kind,source_revision_id:v.source_revision_id,revision:v.revision,hash:v.hash,chunk_id:p.id,start_offset:p.start_offset,end_offset:p.end_offset,status:Z(R,["status"]),resolver:v.resolver});return{id:p.id,kind:p.kind,ordinal:p.ordinal,text:p.text,token_count:p.token_count,start_offset:p.start_offset,end_offset:p.end_offset,metadata:R,evidence:v,provenance:w}}),h=E.map((p)=>({source_ref:p.evidence.source_ref,source_uri:g.uri,chunk_id:p.id,quote:p.text.slice(0,500),start_offset:p.start_offset,end_offset:p.end_offset,evidence:p.evidence,provenance:p.provenance}));I(d,{event_type:"source_read",action:"open_files_resolve",target_uri:e.sourceRef,decision:"allow",metadata:{purpose:t,read_only:!0,source_uri:g.uri,revision:o?.revision??null,chunks_returned:E.length,chunks_total:l},created_at:r});let T=Z(a,["mime","content_type"])??Z(_,["mime","content_type"]),k=Tn(a,["size","size_bytes"])??Tn(_,["size","size_bytes"]);return{source_ref:m,source_uri:g.uri,purpose:t,read_only:!0,resolved:!0,resolver:{name:"open-files-read-only",mode:"local_catalog",contract:"open-files-knowledge-source-v1"},source:{id:g.id,uri:g.uri,kind:g.kind,title:g.title,metadata:a,permissions:u,updated_at:g.updated_at},revision:o?{id:o.id,revision:o.revision,hash:o.hash,extracted_text_uri:o.extracted_text_uri,metadata:_,created_at:o.created_at,reindex_required:_.reindex_required===!0}:null,content:{mime:T,size:k,hash:o?.hash??Z(a,["hash","checksum","sha256"]),text_available:l>0,chunks_total:l,chunks_returned:E.length,char_count_returned:E.reduce((p,R)=>p+R.text.length,0),extracted_text_ref:o?.extracted_text_uri??Z(_,["extracted_text_ref","extracted_text_uri"]),bytes_available:!1,bytes_exposed:!1},chunks:E,citations:h}})()}finally{d.close()}}function ae(e){return`sha256:${Os("sha256").update(e).digest("hex")}`}function Is(e){return e.replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/\s+\n/g,`
458
+ LIMIT ?`).all(t,n)}async function Me(e){let t=e.purpose??"knowledge_answer",n=Math.max(0,Math.min(e.limit??10,100)),r=(e.now??new Date).toISOString(),i=M(e.sourceRef),s=gn(e.sourceRef,i),c=mn(e.sourceRef);if(e.safetyPolicy){if(!e.safetyPolicy.readOnlySourceAccess)throw Error("Safety policy denied source resolution.");Q(e.dbPath,e.safetyPolicy)}x(e.dbPath);let d=b(e.dbPath);try{return d.transaction(()=>{let g=ws(d,s,e.sourceRef);if(!g)return I(d,{event_type:"source_read",action:"open_files_resolve_missing",target_uri:e.sourceRef,decision:"allow",metadata:{purpose:t,read_only:!0,source_uri:s},created_at:r}),{source_ref:e.sourceRef,source_uri:s,purpose:t,read_only:!0,resolved:!1,resolver:{name:"open-files-read-only",mode:"local_catalog",contract:"open-files-knowledge-source-v1"},source:null,revision:null,content:{mime:null,size:null,hash:null,text_available:!1,chunks_total:0,chunks_returned:0,char_count_returned:0,extracted_text_ref:null,bytes_available:!1,bytes_exposed:!1},chunks:[],citations:[]};let a=Fe(g.metadata_json),u=Fe(g.acl_json);try{vs(u,t)}catch(p){throw I(d,{event_type:"source_read",action:"open_files_resolve",target_uri:e.sourceRef,decision:"deny",metadata:{purpose:t,read_only:!0,source_uri:g.uri,error:p instanceof Error?p.message:String(p)},created_at:r}),p}let o=Rs(d,g.id,c),_=Fe(o?.metadata_json),l=Ss(d,o?.id??null),f=xs(d,o?.id??null,n),m=Ts(g.uri,o,e.sourceRef),E=f.map((p)=>{let R=Fe(p.metadata_json),v={resolver:"open-files-read-only",mode:"local_catalog",purpose:t,read_only:!0,source_ref:Z(R,["source_ref"])??m,source_uri:g.uri,source_revision_id:o?.id??null,revision:o?.revision??null,hash:o?.hash??Z(R,["hash"]),chunk_id:p.id,start_offset:p.start_offset,end_offset:p.end_offset,resolved_at:r},T=B({source_ref:v.source_ref,source_uri:v.source_uri,source_kind:g.kind,source_revision_id:v.source_revision_id,revision:v.revision,hash:v.hash,chunk_id:p.id,start_offset:p.start_offset,end_offset:p.end_offset,status:Z(R,["status"]),resolver:v.resolver});return{id:p.id,kind:p.kind,ordinal:p.ordinal,text:p.text,token_count:p.token_count,start_offset:p.start_offset,end_offset:p.end_offset,metadata:R,evidence:v,provenance:T}}),h=E.map((p)=>({source_ref:p.evidence.source_ref,source_uri:g.uri,chunk_id:p.id,quote:p.text.slice(0,500),start_offset:p.start_offset,end_offset:p.end_offset,evidence:p.evidence,provenance:p.provenance}));I(d,{event_type:"source_read",action:"open_files_resolve",target_uri:e.sourceRef,decision:"allow",metadata:{purpose:t,read_only:!0,source_uri:g.uri,revision:o?.revision??null,chunks_returned:E.length,chunks_total:l},created_at:r});let w=Z(a,["mime","content_type"])??Z(_,["mime","content_type"]),k=wn(a,["size","size_bytes"])??wn(_,["size","size_bytes"]);return{source_ref:m,source_uri:g.uri,purpose:t,read_only:!0,resolved:!0,resolver:{name:"open-files-read-only",mode:"local_catalog",contract:"open-files-knowledge-source-v1"},source:{id:g.id,uri:g.uri,kind:g.kind,title:g.title,metadata:a,permissions:u,updated_at:g.updated_at},revision:o?{id:o.id,revision:o.revision,hash:o.hash,extracted_text_uri:o.extracted_text_uri,metadata:_,created_at:o.created_at,reindex_required:_.reindex_required===!0}:null,content:{mime:w,size:k,hash:o?.hash??Z(a,["hash","checksum","sha256"]),text_available:l>0,chunks_total:l,chunks_returned:E.length,char_count_returned:E.reduce((p,R)=>p+R.text.length,0),extracted_text_ref:o?.extracted_text_uri??Z(_,["extracted_text_ref","extracted_text_uri"]),bytes_available:!1,bytes_exposed:!1},chunks:E,citations:h}})()}finally{d.close()}}function ae(e){return`sha256:${Os("sha256").update(e).digest("hex")}`}function Is(e){return e.replace(/<script[\s\S]*?<\/script>/gi," ").replace(/<style[\s\S]*?<\/style>/gi," ").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/\s+\n/g,`
459
459
  `).replace(/\n\s+/g,`
460
460
  `).replace(/[ \t]{2,}/g," ").trim()}async function Ls(e,t,n){let r=new URL(e),i=r.hostname,s=decodeURIComponent(r.pathname.replace(/^\/+/,""));if(!i||!s)throw Error(`Invalid S3 source URI: ${e}`);if(n)J(e,n);let[{S3Client:c,GetObjectCommand:d},{fromIni:g}]=await Promise.all([import("@aws-sdk/client-s3"),import("@aws-sdk/credential-providers")]),a=t?.storage.type==="s3"&&t.storage.s3?.bucket===i?t.storage.s3:void 0,o=await new c({region:a?.region,credentials:a?.profile?g({profile:a.profile}):void 0,maxAttempts:a?.max_attempts}).send(new d({Bucket:i,Key:s}));if(!o.Body)return"";return await o.Body.transformToString()}async function Cs(e,t){if(t)ie(t);let n=await fetch(e,{headers:{accept:"text/markdown,text/plain,text/html,application/json;q=0.8,*/*;q=0.5","user-agent":"@hasna/knowledge source-ingest"}});if(!n.ok)throw Error(`Web source read failed ${n.status}: ${e}`);let r=n.headers.get("content-type"),i=await n.text();return{text:r?.includes("html")?Is(i):i,mime:r}}function Ke(e){if(e.kind==="file")return je(e.path);if(e.kind==="s3")return je(e.key);if(e.kind==="web")return je(new URL(e.url).pathname)||e.url;return e.path?je(e.path):e.id}async function Rn(e,t,n){if(e.kind==="file"){if(!Ns(e.path))throw Error(`Source file not found: ${e.path}`);let r=As(e.path,"utf8");return{text:r,contentSource:"file",title:Ke(e),mime:"text/plain",size:r.length,hash:ae(r),revision:null,extractedTextRef:null,metadata:{path:e.path},permissions:{mode:"read_only"}}}if(e.kind==="s3"){let r=await Ls(e.uri,t,n);return{text:r,contentSource:"s3",title:Ke(e),mime:"text/plain",size:r.length,hash:ae(r),revision:null,extractedTextRef:null,metadata:{bucket:e.bucket,key:e.key},permissions:{mode:"read_only"}}}if(e.kind==="web"){let r=await Cs(e.url,n);return{text:r.text,contentSource:"web",title:Ke(e),mime:r.mime,size:r.text.length,hash:ae(r.text),revision:null,extractedTextRef:null,metadata:{url:e.url},permissions:{mode:"read_only"}}}throw Error(`Direct source reading is not available for ${e.uri}`)}async function Ds(e,t,n){if(e.startsWith("open-files://"))throw Error("Open-files extracted text refs require an open-files resolver API. Ingest an open-files manifest with extracted_text or an extracted_text_ref using file://, s3://, or https://.");let r=M(e);return{text:(await Rn(r,t,n)).text,contentSource:"extracted_text_ref"}}async function Us(e){let t=await Me({dbPath:e.dbPath,sourceRef:e.sourceRef,purpose:e.purpose??"knowledge_index",limit:100,safetyPolicy:e.safetyPolicy,now:e.now});if(!t.resolved)throw Error("Open-files source is not in the local knowledge catalog. Ingest an open-files manifest first or use the open-files resolver API.");if(t.revision?.extracted_text_uri&&!t.content.text_available){let r=await Ds(t.revision.extracted_text_uri,e.config,e.safetyPolicy);return{text:r.text,contentSource:r.contentSource,title:t.source?.title??null,mime:t.content.mime,size:r.text.length,hash:t.revision.hash??ae(r.text),revision:t.revision.revision,extractedTextRef:t.revision.extracted_text_uri,metadata:t.source?.metadata??{},permissions:t.source?.permissions??{mode:"read_only"}}}if(t.chunks.length===0)throw Error("Open-files source has no extracted text chunks yet. Ingest an open-files manifest with extracted_text or extracted_text_ref first.");let n=t.chunks.map((r)=>r.text).join(`
461
461
 
@@ -480,8 +480,8 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
480
480
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[n,"embedding-refresh",e.full?"full":"incremental","running","local",V(e.modelRef,e.config),JSON.stringify({full:e.full===!0,queued:i}),t,t])}finally{s.close()}let c=await Se({dbPath:e.dbPath,config:e.config,env:e.env,modelRef:e.modelRef,dimensions:e.dimensions,fake:e.fake,limit:e.limit,now:e.now}),d=$s(e.dbPath,e,t),g=b(e.dbPath);try{g.run("UPDATE runs SET status = ?, metadata_json = ?, updated_at = ? WHERE id = ?",["completed",JSON.stringify({full:e.full===!0,queued:i,indexed:c,completed_queue_items:d}),t,n]),g.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
481
481
  VALUES (?, ?, ?, ?, ?, ?)`,[`evt_${xn()}`,n,"info","embedding_refresh_completed",JSON.stringify({queued:i,indexed:c,completed_queue_items:d}),t])}finally{g.close()}return{run_id:n,full:e.full===!0,deleted_embeddings:r.embeddings,deleted_vector_entries:r.vectorEntries,queued:i,indexed:c,completed_queue_items:d}}var $e=1;function In(e){return Boolean(e&&typeof e==="object"&&!Array.isArray(e))}function K(e,t){let n=e[t];return typeof n==="string"?n:void 0}function Ws(e,t){let n=e[t];return typeof n==="number"&&Number.isFinite(n)?n:void 0}function Ln(e,t){let n=e[t];return Array.isArray(n)?n:void 0}function ge(e,t){let n=In(e)?e:{};return{contract_version:$e,id:K(n,"id")??t?.id,type:K(n,"type")??t?.type,status:K(n,"status")??t?.status,query:K(n,"query")??t?.query,prompt:K(n,"prompt")??t?.prompt,output_preview:Object.prototype.hasOwnProperty.call(n,"output_preview")?n.output_preview:t?.output_preview,citations:Ln(n,"citations")??t?.citations,artifacts:Ln(n,"artifacts")??t?.artifacts,usage:In(n.usage)?n.usage:t?.usage,created_at:K(n,"created_at")??t?.created_at,started_at:K(n,"started_at")??t?.started_at,completed_at:K(n,"completed_at")??t?.completed_at,duration_ms:Ws(n,"duration_ms")??t?.duration_ms,error_code:K(n,"error_code")??t?.error_code,error_message:K(n,"error_message")??t?.error_message,error:K(n,"error")??t?.error,details:Object.prototype.hasOwnProperty.call(n,"details")?n.details:t?.details}}function Cn(e){return{contract_version:$e,service:"open-knowledge",mode:e.mode,capabilities:["registry","search","ask","build","sync","status","logs","artifacts","open-files-source-refs","s3-generated-artifacts"],endpoints:{registry:"/api/v1/knowledge/registry",search:"/api/v1/knowledge/search",ask:"/api/v1/knowledge/ask",build:"/api/v1/knowledge/build",sync:"/api/v1/knowledge/sync",run_status:"/api/v1/knowledge/runs/{run_id}",run_logs:"/api/v1/knowledge/runs/{run_id}/logs",run_artifacts:"/api/v1/knowledge/runs/{run_id}/artifacts"},source_contract:{owner:"open-files",preferred_ref:"open-files",allowed_schemes:e.sourceSchemes,raw_source_bytes_stored_in_open_knowledge:!1},artifact_contract:{storage_type:e.storageType,uri_prefix:e.artifactUriPrefix,generated_only:!0}}}class We{apiKey;apiUrl;constructor(e,t){this.apiKey=e;this.apiUrl=t}static fromConfig(e,t=process.env){let n=nt(t);if(!n.apiKey)return null;return new We(n.apiKey,be(e,t))}async request(e,t={}){return fetch(`${this.apiUrl}${e}`,{...t,headers:{Authorization:`Bearer ${this.apiKey}`,"Content-Type":"application/json",...t.headers}})}async registry(){return(await this.request("/api/v1/knowledge/registry")).json()}async search(e){let t=await this.request("/api/v1/knowledge/search",{method:"POST",body:JSON.stringify(e)});return ge(await t.json(),{type:"search",query:e.query})}async ask(e){let t=await this.request("/api/v1/knowledge/ask",{method:"POST",body:JSON.stringify(e)});return ge(await t.json(),{type:"ask",prompt:e.prompt})}async build(e){let t=await this.request("/api/v1/knowledge/build",{method:"POST",body:JSON.stringify(e)});return ge(await t.json(),{type:"build",prompt:e.prompt})}async sync(e={}){let t=await this.request("/api/v1/knowledge/sync",{method:"POST",body:JSON.stringify(e)});return ge(await t.json(),{type:"sync"})}async runStatus(e){let t=await this.request(`/api/v1/knowledge/runs/${encodeURIComponent(e)}`);if(!t.ok)return null;return ge(await t.json(),{id:e,type:"status"})}async runLogs(e){let t=await this.request(`/api/v1/knowledge/runs/${encodeURIComponent(e)}/logs`);if(!t.ok)return[];let n=await t.json();return Array.isArray(n)?n:[]}async runArtifacts(e){let t=await this.request(`/api/v1/knowledge/runs/${encodeURIComponent(e)}/artifacts`);if(!t.ok)return[];let n=await t.json();return Array.isArray(n)?n:[]}}import{createHash as Xs,randomUUID as Dn}from"crypto";function qs(e){return`sha256:${Xs("sha256").update(e).digest("hex")}`}function Un(e){let t=e.trim().split(/\s+/).filter(Boolean).length;return Math.max(1,Math.ceil(t*1.25))}function Pn(e){return e&&typeof e==="object"&&!Array.isArray(e)?e:{}}function G(e){return typeof e==="string"&&e.length>0?e:null}function Hs(e){let t=Pn(e),n=G(t.url)??G(t.uri)??G(t.sourceUrl);if(!n)return null;return{url:n,title:G(t.title)??G(t.name),snippet:G(t.snippet)??G(t.text)??G(t.description),provider_metadata:t}}function Xe(e,t){if(Array.isArray(e)){for(let i of e)Xe(i,t);return}let n=Hs(e);if(n)t.set(n.url,n);let r=Pn(e);for(let i of["sources","results","citations","annotations","output"])if(r[i])Xe(r[i],t)}function Bs(e,t){return Array.from({length:Math.min(t,3)},(n,r)=>({url:`https://example.com/knowledge-web-${r+1}`,title:`Fake web source ${r+1}`,snippet:`Deterministic web-search fixture for "${e}"`,provider_metadata:{fake:!0,rank:r+1}}))}async function Js(e){let{generateText:t}=await import("ai"),{createOpenAI:n}=await import("@ai-sdk/openai"),r=q(e.config,"openai"),i=n({apiKey:e.env[r.api_key_env],baseURL:r.base_url}),s=i.tools?.webSearch;if(!s)throw Error("OpenAI provider does not expose tools.webSearch.");return t({model:i(e.model),prompt:e.query,tools:{web_search:s({externalWebAccess:!0,searchContextSize:"medium",...e.domains.length>0?{allowedDomains:e.domains}:{}})},toolChoice:{type:"tool",toolName:"web_search"}})}async function Gs(e){let{generateText:t}=await import("ai"),{createAnthropic:n}=await import("@ai-sdk/anthropic"),r=q(e.config,"anthropic"),i=n({apiKey:e.env[r.api_key_env],baseURL:r.base_url}),s=i.tools?.webSearch_20250305??i.tools?.webSearch;if(!s)throw Error("Anthropic provider does not expose a web search tool.");return t({model:i(e.model),prompt:e.query,tools:{web_search:s({maxUses:e.maxUses,...e.domains.length>0?{allowedDomains:e.domains}:{}})}})}async function zs(e,t,n){if(!e.fileResults||t.length===0)return 0;let r=t.map((s)=>{let c=[s.title,s.snippet,s.url].filter(Boolean).join(`
482
482
  `),d=qs(c);return{source_ref:s.url,name:s.title??s.url,url:s.url,mime:"text/plain",hash:d,revision:d,status:"active",updated_at:n,permissions:{mode:"read_only",allowed_purposes:["knowledge_answer","knowledge_index"]},metadata:{source_ref:s.url,content_source:"provider_web_search",provider_metadata:s.provider_metadata},extracted_text:c}});return(await fe({dbPath:e.dbPath,items:r,sourceLabel:`web-search:${e.query}`,readAction:"provider_web_search_file_results",safetyPolicy:e.safetyPolicy,now:new Date(n)})).sources_upserted}async function Fn(e){let t=e.query.trim();if(!t)throw Error("Web search query is required.");let n=e.env??process.env,r=(e.now??new Date).toISOString(),i=Math.max(1,Math.min(e.limit??5,20)),s=Math.max(1,Math.min(e.maxUses??3,10)),c=e.domains??[],d=H(e.modelRef??(e.provider?`${e.provider}:${q(e.config,e.provider).default_model}`:"default"),e.config),g=C(d),a=e.provider??g.provider,u=g.provider===a?g.model:q(e.config,a).default_model,o=`run_${Dn()}`;if(!e.fake&&e.safetyPolicy)ie(e.safetyPolicy);if(!e.fake&&a!=="openai"&&a!=="anthropic")throw Error(`Provider ${a} does not expose native web search yet.`);if(!e.fake)z(a,e.config,n);x(e.dbPath);let _=b(e.dbPath);try{_.run(`INSERT INTO runs (id, type, prompt, status, provider, model, metadata_json, created_at, updated_at)
483
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[o,"provider-web-search",t,"running",a,u,JSON.stringify({domains:c,max_uses:s,fake:e.fake===!0}),r,r]),I(_,{event_type:"source_read",action:e.fake?"fake_provider_web_search":"provider_web_search",target_uri:t,decision:"allow",metadata:{provider:a,model:u,domains:c,max_uses:s},created_at:r})}finally{_.close()}let l="",f=[],m={input_tokens:Un(t),output_tokens:0,cost_usd:0},E=[];if(e.fake)f=Bs(t,i),l=`Fake web search answer for: ${t}`,m.output_tokens=Un(l);else{let k=a==="openai"?await Js({query:t,model:u,config:e.config,env:n,maxUses:s,domains:c}):await Gs({query:t,model:u,config:e.config,env:n,maxUses:s,domains:c});l=k.text;let p=new Map;Xe(k.sources,p),Xe(k.toolResults,p),f=Array.from(p.values()).slice(0,i);let R=we({provider:a,model:u,usage:k.usage,providerMetadata:k.providerMetadata});m={input_tokens:R.input_tokens,output_tokens:R.output_tokens,cost_usd:R.cost_usd}}let h=await zs(e,f,r),T=b(e.dbPath);try{T.run("UPDATE runs SET status = ?, metadata_json = ?, updated_at = ? WHERE id = ?",["completed",JSON.stringify({domains:c,max_uses:s,sources:f.length,filed_sources:h,fake:e.fake===!0}),r,o]),T.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
484
- VALUES (?, ?, ?, ?, ?, ?)`,[`evt_${Dn()}`,o,"info","provider_web_search_completed",JSON.stringify({sources:f.length,filed_sources:h}),r]),Te(T,{run_id:o,provider:a,model:u,input_tokens:m.input_tokens,output_tokens:m.output_tokens,cost_usd:m.cost_usd,metadata:{web_search:!0,sources:f.length,filed_sources:h},created_at:r})}finally{T.close()}if(f.length===0)E.push("no_web_sources_returned");return{run_id:o,query:t,provider:a,model:u,answer:l,sources:f,filed_sources:h,usage:m,warnings:E}}import{createHash as Qs,randomUUID as Zs}from"crypto";import{createHash as Ys,randomUUID as Vs}from"crypto";var Mn=[{kind:"schema",prefix:"schemas/",description:"Machine-readable agent schemas and source rules."},{kind:"index",prefix:"indexes/",description:"Small orientation indexes and future shard manifests."},{kind:"log",prefix:"logs/",description:"Append-only JSONL run and wiki-maintenance log partitions."},{kind:"run",prefix:"runs/",description:"Prompt/tool/cost ledgers and generated output records."},{kind:"wiki_page",prefix:"wiki/",description:"Generated cited Markdown pages, not raw source files."},{kind:"export",prefix:"exports/",description:"Portable exports and snapshots of derived knowledge state."}];function qe(e){let t=typeof e==="string"?Buffer.from(e):Buffer.from(e);return{hash:`sha256:${Ys("sha256").update(t).digest("hex")}`,size_bytes:t.byteLength}}function jn(e){return Mn.find((n)=>e.startsWith(n.prefix))?.kind??"artifact"}function mt(e,t,n="global"){let r=pt(e,t),i=e.storage.s3??null,s=i?.prefix?.replace(/^\/+|\/+$/g,"")??"",c=i?`s3://${i.bucket}/${s?`${s}/`:""}`:"",d=O.s3.prefix.replace(/^\/+|\/+$/g,""),g=`s3://${O.s3.bucket}/${d}/`,a=e.storage.type==="s3"&&i?.bucket===O.s3.bucket&&(i.region??null)===O.s3.region;return{scope:n,mode:e.mode,storage_type:e.storage.type,workspace_home:t.home,local_layout:{app_path:ne,config_path:t.configPath,json_store_path:t.jsonStorePath,knowledge_db_path:t.knowledgeDbPath,directories:{artifacts:t.artifactsDir,cache:t.cacheDir,exports:t.exportsDir,indexes:t.indexesDir,logs:t.logsDir,runs:t.runsDir,schemas:t.schemasDir,wiki:t.wikiDir}},artifact_store:{type:e.storage.type,artifacts_root:e.storage.artifacts_root,uri_prefix:e.storage.type==="s3"?c:`file://${t.artifactsDir}/`,s3:i?{bucket:i.bucket,prefix:s,region:i.region??null,profile:i.profile??null,server_side_encryption:i.server_side_encryption??null,kms_key_configured:Boolean(i.kms_key_id)}:null},canonical_hasna_xyz:{division:O.division,app_type:O.app_type,app:O.app,env:O.env,active:a,local_path:O.local_path,s3:{bucket:O.s3.bucket,region:O.s3.region,profile:O.s3.profile,prefix:d,uri_prefix:g,server_side_encryption:O.s3.server_side_encryption},secrets:{env:O.secrets.env,aws:O.secrets.aws,s3:O.secrets.s3,rds:O.secrets.rds,future_rds:O.secrets.future_rds},evidence_doc:O.evidence_doc},hosted:{enabled:e.mode==="hosted",api_url:X(e.hosted?.api_url??tt),api_url_env:"KNOWLEDGE_API_URL",api_key_env:"KNOWLEDGE_API_KEY",auth_storage:"~/.hasna/knowledge/auth.json",remote_contract_version:$e,requires_hosted_account_for_local_use:!1},source_ownership:{owner:"open-files",preferred_ref:e.sources.preferred_ref,allowed_schemes:e.sources.allowed_schemes,raw_source_bytes_stored_in_open_knowledge:!1,stores:["source refs","source revisions and hashes","citation spans","redacted extracted chunks","embeddings","generated wiki artifacts","indexes","run ledgers"],does_not_store:["raw open-files bytes","S3 object credentials","connector secrets","hosted tenant ownership state"]},generated_artifacts:Mn,scalability:{catalog:"knowledge.db tracks sources, revisions, chunks, citations, indexes, runs, and storage_objects.",indexes:"Indexes are cataloged DB rows plus sharded artifacts, not one giant index.md.",logs:"Logs use dated JSONL partitions under logs/yyyy/mm/dd.jsonl.",markdown:"Markdown pages are the readable wiki layer over DB/object-store state."},warnings:r.warnings}}function pt(e,t){let n=[],r=[];if(!t.home.endsWith(ne))r.push(`Workspace home does not end with ${ne}: ${t.home}`);if(e.storage.type==="s3"){if(!e.storage.s3?.bucket)n.push("storage.s3.bucket is required when storage.type is s3.");if(!e.storage.s3?.prefix)r.push("storage.s3.prefix is empty; generated knowledge artifacts will be written at the bucket root.");if(e.mode==="local")r.push("storage.type is s3 while mode is local; this is valid for BYO S3, but hosted wrappers should set mode to hosted.")}if(e.storage.type==="local"&&e.storage.s3)r.push("storage.s3 is configured but ignored while storage.type is local.");if(e.sources.preferred_ref!=="open-files")r.push("sources.preferred_ref should stay open-files for durable company knowledge.");if(!e.sources.allowed_schemes.includes("open-files"))n.push("sources.allowed_schemes must include open-files.");if(e.mode==="hosted"&&e.hosted?.api_url)try{X(e.hosted.api_url)}catch{n.push("hosted.api_url must be an http(s) URL when mode is hosted.")}return{ok:n.length===0,errors:n,warnings:r}}function me(e,t,n=new Date){let r=n.toISOString(),i=e.prepare(`
483
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,[o,"provider-web-search",t,"running",a,u,JSON.stringify({domains:c,max_uses:s,fake:e.fake===!0}),r,r]),I(_,{event_type:"source_read",action:e.fake?"fake_provider_web_search":"provider_web_search",target_uri:t,decision:"allow",metadata:{provider:a,model:u,domains:c,max_uses:s},created_at:r})}finally{_.close()}let l="",f=[],m={input_tokens:Un(t),output_tokens:0,cost_usd:0},E=[];if(e.fake)f=Bs(t,i),l=`Fake web search answer for: ${t}`,m.output_tokens=Un(l);else{let k=a==="openai"?await Js({query:t,model:u,config:e.config,env:n,maxUses:s,domains:c}):await Gs({query:t,model:u,config:e.config,env:n,maxUses:s,domains:c});l=k.text;let p=new Map;Xe(k.sources,p),Xe(k.toolResults,p),f=Array.from(p.values()).slice(0,i);let R=Te({provider:a,model:u,usage:k.usage,providerMetadata:k.providerMetadata});m={input_tokens:R.input_tokens,output_tokens:R.output_tokens,cost_usd:R.cost_usd}}let h=await zs(e,f,r),w=b(e.dbPath);try{w.run("UPDATE runs SET status = ?, metadata_json = ?, updated_at = ? WHERE id = ?",["completed",JSON.stringify({domains:c,max_uses:s,sources:f.length,filed_sources:h,fake:e.fake===!0}),r,o]),w.run(`INSERT INTO run_events (id, run_id, level, event, metadata_json, created_at)
484
+ VALUES (?, ?, ?, ?, ?, ?)`,[`evt_${Dn()}`,o,"info","provider_web_search_completed",JSON.stringify({sources:f.length,filed_sources:h}),r]),we(w,{run_id:o,provider:a,model:u,input_tokens:m.input_tokens,output_tokens:m.output_tokens,cost_usd:m.cost_usd,metadata:{web_search:!0,sources:f.length,filed_sources:h},created_at:r})}finally{w.close()}if(f.length===0)E.push("no_web_sources_returned");return{run_id:o,query:t,provider:a,model:u,answer:l,sources:f,filed_sources:h,usage:m,warnings:E}}import{createHash as Qs,randomUUID as Zs}from"crypto";import{createHash as Ys,randomUUID as Vs}from"crypto";var Mn=[{kind:"schema",prefix:"schemas/",description:"Machine-readable agent schemas and source rules."},{kind:"index",prefix:"indexes/",description:"Small orientation indexes and future shard manifests."},{kind:"log",prefix:"logs/",description:"Append-only JSONL run and wiki-maintenance log partitions."},{kind:"run",prefix:"runs/",description:"Prompt/tool/cost ledgers and generated output records."},{kind:"wiki_page",prefix:"wiki/",description:"Generated cited Markdown pages, not raw source files."},{kind:"export",prefix:"exports/",description:"Portable exports and snapshots of derived knowledge state."}];function qe(e){let t=typeof e==="string"?Buffer.from(e):Buffer.from(e);return{hash:`sha256:${Ys("sha256").update(t).digest("hex")}`,size_bytes:t.byteLength}}function jn(e){return Mn.find((n)=>e.startsWith(n.prefix))?.kind??"artifact"}function mt(e,t,n="global"){let r=pt(e,t),i=e.storage.s3??null,s=i?.prefix?.replace(/^\/+|\/+$/g,"")??"",c=i?`s3://${i.bucket}/${s?`${s}/`:""}`:"",d=O.s3.prefix.replace(/^\/+|\/+$/g,""),g=`s3://${O.s3.bucket}/${d}/`,a=e.storage.type==="s3"&&i?.bucket===O.s3.bucket&&(i.region??null)===O.s3.region;return{scope:n,mode:e.mode,storage_type:e.storage.type,workspace_home:t.home,local_layout:{app_path:ne,config_path:t.configPath,json_store_path:t.jsonStorePath,knowledge_db_path:t.knowledgeDbPath,directories:{artifacts:t.artifactsDir,cache:t.cacheDir,exports:t.exportsDir,indexes:t.indexesDir,logs:t.logsDir,runs:t.runsDir,schemas:t.schemasDir,wiki:t.wikiDir}},artifact_store:{type:e.storage.type,artifacts_root:e.storage.artifacts_root,uri_prefix:e.storage.type==="s3"?c:`file://${t.artifactsDir}/`,s3:i?{bucket:i.bucket,prefix:s,region:i.region??null,profile:i.profile??null,server_side_encryption:i.server_side_encryption??null,kms_key_configured:Boolean(i.kms_key_id)}:null},canonical_hasna_xyz:{division:O.division,app_type:O.app_type,app:O.app,env:O.env,active:a,local_path:O.local_path,s3:{bucket:O.s3.bucket,region:O.s3.region,profile:O.s3.profile,prefix:d,uri_prefix:g,server_side_encryption:O.s3.server_side_encryption},secrets:{env:O.secrets.env,aws:O.secrets.aws,s3:O.secrets.s3,rds:O.secrets.rds,future_rds:O.secrets.future_rds},evidence_doc:O.evidence_doc},hosted:{enabled:e.mode==="hosted",api_url:X(e.hosted?.api_url??tt),api_url_env:"KNOWLEDGE_API_URL",api_key_env:"KNOWLEDGE_API_KEY",auth_storage:"~/.hasna/knowledge/auth.json",remote_contract_version:$e,requires_hosted_account_for_local_use:!1},source_ownership:{owner:"open-files",preferred_ref:e.sources.preferred_ref,allowed_schemes:e.sources.allowed_schemes,raw_source_bytes_stored_in_open_knowledge:!1,stores:["source refs","source revisions and hashes","citation spans","redacted extracted chunks","embeddings","generated wiki artifacts","indexes","run ledgers"],does_not_store:["raw open-files bytes","S3 object credentials","connector secrets","hosted tenant ownership state"]},generated_artifacts:Mn,scalability:{catalog:"knowledge.db tracks sources, revisions, chunks, citations, indexes, runs, and storage_objects.",indexes:"Indexes are cataloged DB rows plus sharded artifacts, not one giant index.md.",logs:"Logs use dated JSONL partitions under logs/yyyy/mm/dd.jsonl.",markdown:"Markdown pages are the readable wiki layer over DB/object-store state."},warnings:r.warnings}}function pt(e,t){let n=[],r=[];if(!t.home.endsWith(ne))r.push(`Workspace home does not end with ${ne}: ${t.home}`);if(e.storage.type==="s3"){if(!e.storage.s3?.bucket)n.push("storage.s3.bucket is required when storage.type is s3.");if(!e.storage.s3?.prefix)r.push("storage.s3.prefix is empty; generated knowledge artifacts will be written at the bucket root.");if(e.mode==="local")r.push("storage.type is s3 while mode is local; this is valid for BYO S3, but hosted wrappers should set mode to hosted.")}if(e.storage.type==="local"&&e.storage.s3)r.push("storage.s3 is configured but ignored while storage.type is local.");if(e.sources.preferred_ref!=="open-files")r.push("sources.preferred_ref should stay open-files for durable company knowledge.");if(!e.sources.allowed_schemes.includes("open-files"))n.push("sources.allowed_schemes must include open-files.");if(e.mode==="hosted"&&e.hosted?.api_url)try{X(e.hosted.api_url)}catch{n.push("hosted.api_url must be an http(s) URL when mode is hosted.")}return{ok:n.length===0,errors:n,warnings:r}}function me(e,t,n=new Date){let r=n.toISOString(),i=e.prepare(`
485
485
  INSERT INTO storage_objects (
486
486
  id, artifact_uri, kind, content_type, hash, size_bytes, metadata_json, created_at, updated_at
487
487
  )
@@ -527,9 +527,9 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
527
527
  ON CONFLICT(kind, name, shard_key) DO UPDATE SET
528
528
  artifact_uri = excluded.artifact_uri,
529
529
  metadata_json = excluded.metadata_json,
530
- updated_at = excluded.updated_at`,[ue("idx",`wiki-topic\x00${t.path}`),"wiki_topic",t.title,t.artifactUri,t.path,JSON.stringify({artifact_key:t.path,content_hash:t.contentHash}),t.now,t.now]),1}function oo(e){return e.toLowerCase().match(/[a-z0-9][a-z0-9-]{2,}/)?.[0]??"knowledge"}async function Bn(e){let t=e.now??new Date,n=t.toISOString();x(e.dbPath);let r=b(e.dbPath),i;try{i=ro(r,e)}finally{r.close()}if(i.length===0)throw Error("No source chunks matched wiki compile input.");let s=io(e,i),d=`wiki/generated/${ht(s)}.md`,g=so(s,i,n),a=i.map((v)=>{let w=Kn(v.metadata_json);return typeof w.source_ref==="string"?w.source_ref:v.source_uri}).filter((v)=>Boolean(v)),u=Y({generated_from:"wiki_compile",artifact_key:d,source_refs:a}),o=await He(e.store,{key:d,body:g,content_type:"text/markdown",metadata:{generated_from:"wiki_compile"}}),_=ue("wiki",d),l=i.map((v)=>({chunk_id:v.chunk_id,source_uri:v.source_uri??"unknown",quote:Wn(v.text,240),start_offset:v.start_offset,end_offset:v.end_offset,metadata:{source_revision_id:v.source_revision_id,revision:v.revision,hash:v.hash,source_ref:Kn(v.metadata_json).source_ref??v.source_uri}})),f=oo(s),m=`wiki/concepts/${ht(f)}.md`,E=[`# ${f}`,"",`Related page: [[${d}]]`,""].join(`
531
- `),h=Y({generated_from:"wiki_compile_concept",artifact_key:m,source_refs:a}),T=await He(e.store,{key:m,body:E,content_type:"text/markdown",metadata:{generated_from:"wiki_compile_concept"}}),k=ue("wiki",m),p=await Xn(e.store,{ts:n,event:"wiki_compile_completed",page_key:d,source_refs:a,chunks_seen:i.length},t),R=b(e.dbPath);try{me(R,[o,T,p],t),Et(R,{pageId:_,path:d,title:s,artifactUri:o.uri,contentHash:o.hash??"",body:g,provenance:u,now:n}),Et(R,{pageId:k,path:m,title:f,artifactUri:T.uri,contentHash:T.hash??"",body:E,provenance:h,now:n}),R.run(`INSERT OR REPLACE INTO wiki_backlinks (from_page_id, to_page_id, label, created_at)
532
- VALUES (?, ?, ?, ?)`,[_,k,"concept",n]);let v=qn(R,_,l,n),w=Hn(R,{title:s,path:d,artifactUri:o.uri,contentHash:o.hash??"",now:n});return{page_id:_,path:d,artifact_uri:o.uri,content_hash:o.hash??"",chunks_seen:i.length,citations_written:v,concept_page_id:k,indexes_updated:w,log_key:p.key,warnings:[]}}finally{R.close()}}async function Jn(e){if(!e.approveWrite)return{approved:!1,durable_writes_performed:!1,page_id:null,path:null,artifact_uri:null,citations_written:0,log_key:null,message:"Dry-run: answer filing requires --approve-write."};let t=e.now??new Date,n=t.toISOString(),r=e.prompt.length>80?`${e.prompt.slice(0,77)}...`:e.prompt,s=`wiki/answers/${ht(r)}.md`,c=e.context.citations,d=[`# ${r}`,"",e.answer,"","## Citations","",...c.map((f,m)=>`- [C${m+1}] ${f.source_ref??f.source_uri??f.artifact_path??f.artifact_uri??"unknown"} ${f.hash?`(hash ${f.hash})`:""}`),""].join(`
530
+ updated_at = excluded.updated_at`,[ue("idx",`wiki-topic\x00${t.path}`),"wiki_topic",t.title,t.artifactUri,t.path,JSON.stringify({artifact_key:t.path,content_hash:t.contentHash}),t.now,t.now]),1}function oo(e){return e.toLowerCase().match(/[a-z0-9][a-z0-9-]{2,}/)?.[0]??"knowledge"}async function Bn(e){let t=e.now??new Date,n=t.toISOString();x(e.dbPath);let r=b(e.dbPath),i;try{i=ro(r,e)}finally{r.close()}if(i.length===0)throw Error("No source chunks matched wiki compile input.");let s=io(e,i),d=`wiki/generated/${ht(s)}.md`,g=so(s,i,n),a=i.map((v)=>{let T=Kn(v.metadata_json);return typeof T.source_ref==="string"?T.source_ref:v.source_uri}).filter((v)=>Boolean(v)),u=Y({generated_from:"wiki_compile",artifact_key:d,source_refs:a}),o=await He(e.store,{key:d,body:g,content_type:"text/markdown",metadata:{generated_from:"wiki_compile"}}),_=ue("wiki",d),l=i.map((v)=>({chunk_id:v.chunk_id,source_uri:v.source_uri??"unknown",quote:Wn(v.text,240),start_offset:v.start_offset,end_offset:v.end_offset,metadata:{source_revision_id:v.source_revision_id,revision:v.revision,hash:v.hash,source_ref:Kn(v.metadata_json).source_ref??v.source_uri}})),f=oo(s),m=`wiki/concepts/${ht(f)}.md`,E=[`# ${f}`,"",`Related page: [[${d}]]`,""].join(`
531
+ `),h=Y({generated_from:"wiki_compile_concept",artifact_key:m,source_refs:a}),w=await He(e.store,{key:m,body:E,content_type:"text/markdown",metadata:{generated_from:"wiki_compile_concept"}}),k=ue("wiki",m),p=await Xn(e.store,{ts:n,event:"wiki_compile_completed",page_key:d,source_refs:a,chunks_seen:i.length},t),R=b(e.dbPath);try{me(R,[o,w,p],t),Et(R,{pageId:_,path:d,title:s,artifactUri:o.uri,contentHash:o.hash??"",body:g,provenance:u,now:n}),Et(R,{pageId:k,path:m,title:f,artifactUri:w.uri,contentHash:w.hash??"",body:E,provenance:h,now:n}),R.run(`INSERT OR REPLACE INTO wiki_backlinks (from_page_id, to_page_id, label, created_at)
532
+ VALUES (?, ?, ?, ?)`,[_,k,"concept",n]);let v=qn(R,_,l,n),T=Hn(R,{title:s,path:d,artifactUri:o.uri,contentHash:o.hash??"",now:n});return{page_id:_,path:d,artifact_uri:o.uri,content_hash:o.hash??"",chunks_seen:i.length,citations_written:v,concept_page_id:k,indexes_updated:T,log_key:p.key,warnings:[]}}finally{R.close()}}async function Jn(e){if(!e.approveWrite)return{approved:!1,durable_writes_performed:!1,page_id:null,path:null,artifact_uri:null,citations_written:0,log_key:null,message:"Dry-run: answer filing requires --approve-write."};let t=e.now??new Date,n=t.toISOString(),r=e.prompt.length>80?`${e.prompt.slice(0,77)}...`:e.prompt,s=`wiki/answers/${ht(r)}.md`,c=e.context.citations,d=[`# ${r}`,"",e.answer,"","## Citations","",...c.map((f,m)=>`- [C${m+1}] ${f.source_ref??f.source_uri??f.artifact_path??f.artifact_uri??"unknown"} ${f.hash?`(hash ${f.hash})`:""}`),""].join(`
533
533
  `),g=c.map((f)=>f.source_ref??f.source_uri).filter((f)=>Boolean(f)),a=Y({generated_from:"knowledge_answer",artifact_key:s,source_refs:g}),u=await He(e.store,{key:s,body:d,content_type:"text/markdown",metadata:{generated_from:"knowledge_answer"}}),o=await Xn(e.store,{ts:n,event:"wiki_answer_filed",page_key:s,prompt:e.prompt,citations:c.length},t),_=ue("wiki",s),l=b(e.dbPath);try{me(l,[u,o],t),Et(l,{pageId:_,path:s,title:r,artifactUri:u.uri,contentHash:u.hash??"",body:d,provenance:a,now:n});let f=qn(l,_,c.map((m)=>({chunk_id:m.chunk_id,source_uri:m.source_uri??m.artifact_uri??"unknown",quote:m.quote,start_offset:m.start_offset,end_offset:m.end_offset,metadata:{source_ref:m.source_ref,artifact_path:m.artifact_path,revision:m.revision,hash:m.hash}})),n);return Hn(l,{title:r,path:s,artifactUri:u.uri,contentHash:u.hash??"",now:n}),{approved:!0,durable_writes_performed:!0,page_id:_,path:s,artifact_uri:u.uri,citations_written:f,log_key:o.key,message:`Filed answer to ${s}`}}finally{l.close()}}function ee(e,t){e.push(t)}function Gn(e){x(e.dbPath);let t=b(e.dbPath),n=[];try{let r=t.query("SELECT COUNT(*) AS n FROM wiki_pages WHERE status = 'active'").get()?.n??0,i=t.query("SELECT COUNT(*) AS n FROM citations").get()?.n??0,s=t.query("SELECT COUNT(*) AS n FROM wiki_backlinks").get()?.n??0,c=t.query(`SELECT wp.id, wp.path
534
534
  FROM wiki_pages wp
535
535
  LEFT JOIN citations c ON c.wiki_page_id = wp.id
@@ -567,7 +567,7 @@ ${_}`;else{let{generateText:p}=await import("ai"),R=await Bt(i,{config:e.config,
567
567
  ## Source Rules
568
568
 
569
569
  - Treat open-files source references as the preferred source of truth.
570
- - Do not copy raw source files into open-knowledge.
570
+ - Do not copy raw source files into knowledge.
571
571
  - Cite every durable fact with a source URI, revision/hash when available, and optional span.
572
572
  - Mark uncertainty explicitly when sources disagree or are incomplete.
573
573
 
@@ -622,10 +622,10 @@ Pages should be concise, cited, and organized for both humans and agents.
622
622
  content_hash = excluded.content_hash,
623
623
  status = excluded.status,
624
624
  metadata_json = excluded.metadata_json,
625
- updated_at = excluded.updated_at`,[c,"wiki/README.md","Wiki",s.uri,s.hash??null,"active",JSON.stringify({artifact_key:s.key,provenance:kt(s)}),r,r]),fo(e,c,"Wiki",s,zn(),r)}}function go(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="local"||t==="offline")return"local";if(t==="hosted"||t==="remote"||t==="knowledge.hasna.xyz")return"hosted";throw Error("Invalid setup mode. Use hosted or local.")}class Qn{options;ensuredWorkspace;cachedConfig;constructor(e={}){this.options=e}get scope(){return this.options.scope??"global"}get workspace(){return this.ensuredWorkspace??Rt(this.options.scope,this.options.cwd)}ensureWorkspace(){if(!this.ensuredWorkspace)this.ensuredWorkspace=Tt(this.workspace.home);return this.ensuredWorkspace}jsonStorePath(){return this.ensureWorkspace().jsonStorePath}config(){if(!this.cachedConfig){let e=this.ensureWorkspace();this.cachedConfig=St(e.configPath)}return this.cachedConfig}safetyPolicy(){return En(this.config(),this.ensureWorkspace())}artifactStore(){return Ut(this.config(),this.ensureWorkspace())}storageContract(){return mt(this.config(),this.ensureWorkspace(),this.scope)}validateStorage(){return pt(this.config(),this.ensureWorkspace())}setup(e={}){let t=this.ensureWorkspace(),n=this.config(),r=go(e.mode)??n.mode,i=e.apiUrl?X(e.apiUrl):n.hosted?.api_url?X(n.hosted.api_url):null,s={...n,mode:r,hosted:{...n.hosted??{},...i?{api_url:i}:{}},storage:e.canonicalHasnaXyz?wt():n.storage};xt(t.configPath,s),this.cachedConfig=s;let c=mt(s,t,this.scope);return{ok:!0,mode:r,api_url:s.hosted?.api_url??null,storage_type:s.storage.type,artifact_uri_prefix:c.artifact_store.uri_prefix,canonical_hasna_xyz:c.canonical_hasna_xyz,config_path:t.configPath,next:r==="hosted"?["open-knowledge auth login --api-key <key>","open-knowledge storage status --json","open-knowledge remote contracts --json"]:["open-knowledge search <query>","knowledge <prompt>"],message:`Set knowledge mode to ${r}`}}authStatus(e=process.env){return Kt(this.config(),e)}saveAuth(e,t=process.env){let n=e.apiUrl??this.config().hosted?.api_url;return Mt({api_key:e.apiKey,email:e.email,org_id:e.orgId,org_slug:e.orgSlug,user_id:e.userId,api_url:n},t)}clearAuth(e=process.env){return jt(e)}remoteContract(){let e=this.storageContract();return Cn({mode:this.config().mode,sourceSchemes:this.config().sources.allowed_schemes,storageType:e.artifact_store.type,artifactUriPrefix:e.artifact_store.uri_prefix})}remoteClient(e=process.env){return We.fromConfig(this.config(),e)}paths(){let e=this.ensureWorkspace();return{ok:!0,scope:this.scope,home:e.home,config_path:e.configPath,json_store_path:e.jsonStorePath,knowledge_db_path:e.knowledgeDbPath,artifacts_dir:e.artifactsDir,indexes_dir:e.indexesDir,logs_dir:e.logsDir,runs_dir:e.runsDir,schemas_dir:e.schemasDir,wiki_dir:e.wikiDir,config:this.config(),message:e.home}}initDb(){return x(this.ensureWorkspace().knowledgeDbPath)}dbStats(){let e=this.ensureWorkspace();return x(e.knowledgeDbPath),It(e.knowledgeDbPath)}async initWiki(){let e=this.ensureWorkspace();x(e.knowledgeDbPath);let t=await Yn(this.artifactStore()),n=b(e.knowledgeDbPath);try{me(n,t.artifacts),Vn(n,t.artifacts)}finally{n.close()}return t}async compileWiki(e={}){let t=this.ensureWorkspace();return Bn({...e,dbPath:t.knowledgeDbPath,store:this.artifactStore()})}async fileAnswer(e){let t=this.ensureWorkspace(),n=await this.retrieveContext({query:e.prompt,limit:e.limit,semantic:e.semantic,modelRef:e.modelRef,dimensions:e.dimensions,fake:e.fake});return Jn({dbPath:t.knowledgeDbPath,store:this.artifactStore(),prompt:e.prompt,answer:e.answer,context:n,approveWrite:e.approveWrite})}lintWiki(){let e=this.ensureWorkspace();return Gn({dbPath:e.knowledgeDbPath})}async ingestManifest(e){let t=this.ensureWorkspace();return wn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}async ingestSource(e,t){let n=this.ensureWorkspace();return Sn({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t,config:this.config(),safetyPolicy:this.safetyPolicy()})}async resolveSource(e,t={}){let n=this.ensureWorkspace();return Me({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t.purpose,limit:t.limit,safetyPolicy:this.safetyPolicy()})}async consumeOutbox(e){let t=this.ensureWorkspace();return vn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}reindexHealth(e={}){let t=this.ensureWorkspace();return Nn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}enqueueReindex(e={}){let t=this.ensureWorkspace();return gt({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async refreshEmbeddings(e={}){let t=this.ensureWorkspace();return An({...e,dbPath:t.knowledgeDbPath,config:this.config()})}providerStatus(e=process.env){return Ht(this.config(),e)}modelRegistry(){return it(this.config())}embeddingStatus(){let e=this.ensureWorkspace();return Zt(e.knowledgeDbPath)}async indexEmbeddings(e={}){let t=this.ensureWorkspace();return Se({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async semanticSearch(e){let t=this.ensureWorkspace();return xe({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async search(e){let t=this.ensureWorkspace();return Ie({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async retrieveContext(e){let t=this.ensureWorkspace();return Ce({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async runPrompt(e){let t=this.ensureWorkspace();return _n({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async webSearch(e){let t=this.ensureWorkspace();return Fn({...e,dbPath:t.knowledgeDbPath,config:this.config(),safetyPolicy:this.safetyPolicy()})}}function Zn(e={}){return new Qn(e)}import{basename as po}from"path";var pe={name:"@hasna/knowledge",version:"0.2.28",description:"Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",type:"module",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},main:"./dist/index.js",types:"./dist/index.d.ts",bin:{knowledge:"bin/open-knowledge.js","open-knowledge":"bin/open-knowledge.js","open-knowledge-mcp":"bin/open-knowledge-mcp.js"},files:["bin","dist","docs","LICENSE","README.md"],scripts:{test:"bun test","test:cli":"bun test tests/cli.test.ts",build:"rm -rf dist && bun build --target=bun --outfile=bin/open-knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/cli.ts && bun build --target=bun --outfile=bin/open-knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/mcp.js && bun build ./src/index.ts --outdir ./dist --target bun --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek && bunx tsc -p tsconfig.build.json",prepublishOnly:"bun run build"},keywords:["knowledge","cli","agents","json","notes","local","store"],license:"Apache-2.0",publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/hasna/knowledge.git"},bugs:{url:"https://github.com/hasna/knowledge/issues"},author:"Hasna Inc. <hasna@example.com>",engines:{bun:">=1.0",node:">=18"},dependencies:{"@ai-sdk/anthropic":"^3.0.81","@ai-sdk/deepseek":"^2.0.35","@ai-sdk/openai":"^3.0.68","@aws-sdk/client-s3":"^3.1063.0","@aws-sdk/credential-providers":"^3.1063.0","@modelcontextprotocol/sdk":"^1.29.0","@types/json-schema":"^7.0.15",ai:"^6.0.197",zod:"^4.3.6"},devDependencies:{"@types/bun":"^1.3.14"}};var er={debug:0,info:1,warn:2,error:3},ho=()=>{if(process.env.DEBUG)return"debug";if(process.env.LOG_LEVEL==="debug")return"debug";if(process.env.LOG_LEVEL==="warn")return"warn";if(process.env.LOG_LEVEL==="error")return"error";return"info"};function te(e,t,n){if(er[e]<er[ho()])return;let r={debug:"[DEBUG]",info:"[INFO]",warn:"[WARN]",error:"[ERROR]"}[e],i=n?`${r} ${t} ${JSON.stringify(n)}`:`${r} ${t}`;if(e==="error")console.error(i);else console.error(i)}var tr=["add","list","get","delete","update","archive","restore","upsert","untag","export","prune","dedupe","stats","paths","setup","auth","remote","storage","db","wiki","source","ingest","reindex","search","web","ask","build","embeddings","providers","safety","help"],nr={ls:"list",rm:"delete",edit:"update",unarchive:"restore",knowledge:"ask"};function Eo(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r];if(!i.startsWith("-")){t.push(i);continue}switch(i){case"--json":n.json=!0;break;case"--yes":case"-y":n.yes=!0;break;case"--help":case"-h":n.help=!0;break;case"--version":case"-v":n.version=!0;break;case"--desc":n.desc=!0;break;case"--page":case"-p":n.page=Number(e[r+1]),r+=1;break;case"--limit":case"-l":n.limit=Number(e[r+1]),r+=1;break;case"--search":case"-s":n.search=e[r+1],r+=1;break;case"--sort":n.sort=e[r+1],r+=1;break;case"--id":n.id=e[r+1],r+=1;break;case"--store":n.store=e[r+1],r+=1;break;case"--title":n.title=e[r+1],r+=1;break;case"--content":n.content=e[r+1],r+=1;break;case"--url":n.url=e[r+1],r+=1;break;case"--tag":case"-t":n.tag=e[r+1],r+=1;break;case"--format":n.format=e[r+1],r+=1;break;case"--completions":n.completions=e[r+1],r+=1;break;case"--purpose":n.purpose=e[r+1],r+=1;break;case"--model":n.model=e[r+1],r+=1;break;case"--dimensions":n.dimensions=Number(e[r+1]),r+=1;break;case"--semantic":n.semantic=!0;break;case"--context":n.context=!0;break;case"--generate":n.generate=!0;break;case"--approve-write":n.approveWrite=!0;break;case"--provider":n.provider=e[r+1],r+=1;break;case"--mode":n.mode=e[r+1],r+=1;break;case"--api-url":n.apiUrl=e[r+1],r+=1;break;case"--canonical-hasna-xyz":n.canonicalHasnaXyz=!0;break;case"--api-key":n.apiKey=e[r+1],r+=1;break;case"--email":n.email=e[r+1],r+=1;break;case"--org":n.org=e[r+1],r+=1;break;case"--org-id":n.orgId=e[r+1],r+=1;break;case"--user-id":n.userId=e[r+1],r+=1;break;case"--domain":n.domain=[...n.domain??[],e[r+1]],r+=1;break;case"--file-results":n.fileResults=!0;break;case"--full":n.full=!0;break;case"--fake":n.fake=!0;break;case"--no-color":n.noColor=!0;break;case"--scope":n.scope=e[r+1],r+=1;break;case"--older-than":n.olderThan=Number(e[r+1]),r+=1;break;case"--empty":n.empty=!0;break;case"--archived":n.archived=!0;break;case"--include-archived":n.includeArchived=!0;break;default:throw Error(`Unknown flag: ${i}. Run 'open-knowledge --help' for valid options.`)}}return{positional:t,flags:n}}function yo(e){if(!e)return"";return nr[e]??e}function ko(e,t){let n=Array.from({length:e.length+1},()=>Array(t.length+1).fill(0));for(let r=0;r<=e.length;r+=1)n[r][0]=r;for(let r=0;r<=t.length;r+=1)n[0][r]=r;for(let r=1;r<=e.length;r+=1)for(let i=1;i<=t.length;i+=1){let s=e[r-1]===t[i-1]?0:1;n[r][i]=Math.min(n[r-1][i]+1,n[r][i-1]+1,n[r-1][i-1]+s)}return n[e.length][t.length]}function bo(e){if(!e)return"";let t=[...tr,...Object.keys(nr)],n="",r=Number.POSITIVE_INFINITY;for(let i of t){let s=ko(e,i);if(s<r)r=s,n=i}return r<=3?n:""}function vo(){return po(process.argv[1]??"")==="knowledge"}function wo(){console.log(`open-knowledge - local agent knowledge store
625
+ updated_at = excluded.updated_at`,[c,"wiki/README.md","Wiki",s.uri,s.hash??null,"active",JSON.stringify({artifact_key:s.key,provenance:kt(s)}),r,r]),fo(e,c,"Wiki",s,zn(),r)}}function go(e){if(!e)return;let t=e.trim().toLowerCase();if(t==="local"||t==="offline")return"local";if(t==="hosted"||t==="remote"||t==="knowledge.hasna.xyz")return"hosted";throw Error("Invalid setup mode. Use hosted or local.")}class Qn{options;ensuredWorkspace;cachedConfig;constructor(e={}){this.options=e}get scope(){return this.options.scope??"global"}get workspace(){return this.ensuredWorkspace??Rt(this.options.scope,this.options.cwd)}ensureWorkspace(){if(!this.ensuredWorkspace)this.ensuredWorkspace=wt(this.workspace.home);return this.ensuredWorkspace}jsonStorePath(){return this.ensureWorkspace().jsonStorePath}config(){if(!this.cachedConfig){let e=this.ensureWorkspace();this.cachedConfig=St(e.configPath)}return this.cachedConfig}safetyPolicy(){return En(this.config(),this.ensureWorkspace())}artifactStore(){return Ut(this.config(),this.ensureWorkspace())}storageContract(){return mt(this.config(),this.ensureWorkspace(),this.scope)}validateStorage(){return pt(this.config(),this.ensureWorkspace())}setup(e={}){let t=this.ensureWorkspace(),n=this.config(),r=go(e.mode)??n.mode,i=e.apiUrl?X(e.apiUrl):n.hosted?.api_url?X(n.hosted.api_url):null,s={...n,mode:r,hosted:{...n.hosted??{},...i?{api_url:i}:{}},storage:e.canonicalHasnaXyz?Tt():n.storage};xt(t.configPath,s),this.cachedConfig=s;let c=mt(s,t,this.scope);return{ok:!0,mode:r,api_url:s.hosted?.api_url??null,storage_type:s.storage.type,artifact_uri_prefix:c.artifact_store.uri_prefix,canonical_hasna_xyz:c.canonical_hasna_xyz,config_path:t.configPath,next:r==="hosted"?["knowledge auth login --api-key <key>","knowledge storage status --json","knowledge remote contracts --json"]:["knowledge search <query>","knowledge <prompt>"],message:`Set knowledge mode to ${r}`}}authStatus(e=process.env){return Kt(this.config(),e)}saveAuth(e,t=process.env){let n=e.apiUrl??this.config().hosted?.api_url;return Mt({api_key:e.apiKey,email:e.email,org_id:e.orgId,org_slug:e.orgSlug,user_id:e.userId,api_url:n},t)}clearAuth(e=process.env){return jt(e)}remoteContract(){let e=this.storageContract();return Cn({mode:this.config().mode,sourceSchemes:this.config().sources.allowed_schemes,storageType:e.artifact_store.type,artifactUriPrefix:e.artifact_store.uri_prefix})}remoteClient(e=process.env){return We.fromConfig(this.config(),e)}paths(){let e=this.ensureWorkspace();return{ok:!0,scope:this.scope,home:e.home,config_path:e.configPath,json_store_path:e.jsonStorePath,knowledge_db_path:e.knowledgeDbPath,artifacts_dir:e.artifactsDir,indexes_dir:e.indexesDir,logs_dir:e.logsDir,runs_dir:e.runsDir,schemas_dir:e.schemasDir,wiki_dir:e.wikiDir,config:this.config(),message:e.home}}initDb(){return x(this.ensureWorkspace().knowledgeDbPath)}dbStats(){let e=this.ensureWorkspace();return x(e.knowledgeDbPath),It(e.knowledgeDbPath)}async initWiki(){let e=this.ensureWorkspace();x(e.knowledgeDbPath);let t=await Yn(this.artifactStore()),n=b(e.knowledgeDbPath);try{me(n,t.artifacts),Vn(n,t.artifacts)}finally{n.close()}return t}async compileWiki(e={}){let t=this.ensureWorkspace();return Bn({...e,dbPath:t.knowledgeDbPath,store:this.artifactStore()})}async fileAnswer(e){let t=this.ensureWorkspace(),n=await this.retrieveContext({query:e.prompt,limit:e.limit,semantic:e.semantic,modelRef:e.modelRef,dimensions:e.dimensions,fake:e.fake});return Jn({dbPath:t.knowledgeDbPath,store:this.artifactStore(),prompt:e.prompt,answer:e.answer,context:n,approveWrite:e.approveWrite})}lintWiki(){let e=this.ensureWorkspace();return Gn({dbPath:e.knowledgeDbPath})}async ingestManifest(e){let t=this.ensureWorkspace();return Tn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}async ingestSource(e,t){let n=this.ensureWorkspace();return Sn({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t,config:this.config(),safetyPolicy:this.safetyPolicy()})}async resolveSource(e,t={}){let n=this.ensureWorkspace();return Me({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t.purpose,limit:t.limit,safetyPolicy:this.safetyPolicy()})}async consumeOutbox(e){let t=this.ensureWorkspace();return vn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}reindexHealth(e={}){let t=this.ensureWorkspace();return Nn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}enqueueReindex(e={}){let t=this.ensureWorkspace();return gt({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async refreshEmbeddings(e={}){let t=this.ensureWorkspace();return An({...e,dbPath:t.knowledgeDbPath,config:this.config()})}providerStatus(e=process.env){return Ht(this.config(),e)}modelRegistry(){return it(this.config())}embeddingStatus(){let e=this.ensureWorkspace();return Zt(e.knowledgeDbPath)}async indexEmbeddings(e={}){let t=this.ensureWorkspace();return Se({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async semanticSearch(e){let t=this.ensureWorkspace();return xe({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async search(e){let t=this.ensureWorkspace();return Ie({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async retrieveContext(e){let t=this.ensureWorkspace();return Ce({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async runPrompt(e){let t=this.ensureWorkspace();return _n({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async webSearch(e){let t=this.ensureWorkspace();return Fn({...e,dbPath:t.knowledgeDbPath,config:this.config(),safetyPolicy:this.safetyPolicy()})}}function Zn(e={}){return new Qn(e)}import{basename as po}from"path";var pe={name:"@hasna/knowledge",version:"0.2.29",description:"Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",type:"module",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},main:"./dist/index.js",types:"./dist/index.d.ts",bin:{knowledge:"bin/knowledge.js","knowledge-mcp":"bin/knowledge-mcp.js"},files:["bin","dist","docs","LICENSE","README.md"],scripts:{test:"bun test","test:cli":"bun test tests/cli.test.ts",build:"rm -rf dist && bun build --target=bun --outfile=bin/knowledge.js --minify --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/cli.ts && bun build --target=bun --outfile=bin/knowledge-mcp.js --external @modelcontextprotocol/sdk --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek src/mcp.js && bun build ./src/index.ts --outdir ./dist --target bun --external @aws-sdk/client-s3 --external @aws-sdk/credential-providers --external ai --external @ai-sdk/openai --external @ai-sdk/anthropic --external @ai-sdk/deepseek && bunx tsc -p tsconfig.build.json",prepublishOnly:"bun run build"},keywords:["knowledge","cli","agents","json","notes","local","store"],license:"Apache-2.0",publishConfig:{registry:"https://registry.npmjs.org",access:"public"},repository:{type:"git",url:"git+https://github.com/hasna/knowledge.git"},bugs:{url:"https://github.com/hasna/knowledge/issues"},author:"Hasna Inc. <hasna@example.com>",engines:{bun:">=1.0",node:">=18"},dependencies:{"@ai-sdk/anthropic":"^3.0.81","@ai-sdk/deepseek":"^2.0.35","@ai-sdk/openai":"^3.0.68","@aws-sdk/client-s3":"^3.1063.0","@aws-sdk/credential-providers":"^3.1063.0","@modelcontextprotocol/sdk":"^1.29.0","@types/json-schema":"^7.0.15",ai:"^6.0.197",zod:"^4.3.6"},devDependencies:{"@types/bun":"^1.3.14"}};var er={debug:0,info:1,warn:2,error:3},ho=()=>{if(process.env.DEBUG)return"debug";if(process.env.LOG_LEVEL==="debug")return"debug";if(process.env.LOG_LEVEL==="warn")return"warn";if(process.env.LOG_LEVEL==="error")return"error";return"info"};function te(e,t,n){if(er[e]<er[ho()])return;let r={debug:"[DEBUG]",info:"[INFO]",warn:"[WARN]",error:"[ERROR]"}[e],i=n?`${r} ${t} ${JSON.stringify(n)}`:`${r} ${t}`;if(e==="error")console.error(i);else console.error(i)}var tr=["add","list","get","delete","update","archive","restore","upsert","untag","export","prune","dedupe","stats","paths","setup","auth","remote","storage","db","wiki","source","ingest","reindex","search","web","ask","build","embeddings","providers","safety","help"],nr={ls:"list",rm:"delete",edit:"update",unarchive:"restore"};function Eo(e){let t=[],n={};for(let r=0;r<e.length;r+=1){let i=e[r];if(!i.startsWith("-")){t.push(i);continue}switch(i){case"--json":n.json=!0;break;case"--yes":case"-y":n.yes=!0;break;case"--help":case"-h":n.help=!0;break;case"--version":case"-v":n.version=!0;break;case"--desc":n.desc=!0;break;case"--page":case"-p":n.page=Number(e[r+1]),r+=1;break;case"--limit":case"-l":n.limit=Number(e[r+1]),r+=1;break;case"--search":case"-s":n.search=e[r+1],r+=1;break;case"--sort":n.sort=e[r+1],r+=1;break;case"--id":n.id=e[r+1],r+=1;break;case"--store":n.store=e[r+1],r+=1;break;case"--title":n.title=e[r+1],r+=1;break;case"--content":n.content=e[r+1],r+=1;break;case"--url":n.url=e[r+1],r+=1;break;case"--tag":case"-t":n.tag=e[r+1],r+=1;break;case"--format":n.format=e[r+1],r+=1;break;case"--completions":n.completions=e[r+1],r+=1;break;case"--purpose":n.purpose=e[r+1],r+=1;break;case"--model":n.model=e[r+1],r+=1;break;case"--dimensions":n.dimensions=Number(e[r+1]),r+=1;break;case"--semantic":n.semantic=!0;break;case"--context":n.context=!0;break;case"--generate":n.generate=!0;break;case"--approve-write":n.approveWrite=!0;break;case"--provider":n.provider=e[r+1],r+=1;break;case"--mode":n.mode=e[r+1],r+=1;break;case"--api-url":n.apiUrl=e[r+1],r+=1;break;case"--canonical-hasna-xyz":n.canonicalHasnaXyz=!0;break;case"--api-key":n.apiKey=e[r+1],r+=1;break;case"--email":n.email=e[r+1],r+=1;break;case"--org":n.org=e[r+1],r+=1;break;case"--org-id":n.orgId=e[r+1],r+=1;break;case"--user-id":n.userId=e[r+1],r+=1;break;case"--domain":n.domain=[...n.domain??[],e[r+1]],r+=1;break;case"--file-results":n.fileResults=!0;break;case"--full":n.full=!0;break;case"--fake":n.fake=!0;break;case"--no-color":n.noColor=!0;break;case"--scope":n.scope=e[r+1],r+=1;break;case"--older-than":n.olderThan=Number(e[r+1]),r+=1;break;case"--empty":n.empty=!0;break;case"--archived":n.archived=!0;break;case"--include-archived":n.includeArchived=!0;break;default:throw Error(`Unknown flag: ${i}. Run 'knowledge --help' for valid options.`)}}return{positional:t,flags:n}}function yo(e){if(!e)return"";return nr[e]??e}function ko(e,t){let n=Array.from({length:e.length+1},()=>Array(t.length+1).fill(0));for(let r=0;r<=e.length;r+=1)n[r][0]=r;for(let r=0;r<=t.length;r+=1)n[0][r]=r;for(let r=1;r<=e.length;r+=1)for(let i=1;i<=t.length;i+=1){let s=e[r-1]===t[i-1]?0:1;n[r][i]=Math.min(n[r-1][i]+1,n[r][i-1]+1,n[r-1][i-1]+s)}return n[e.length][t.length]}function bo(e){if(!e)return"";let t=[...tr,...Object.keys(nr)],n="",r=Number.POSITIVE_INFINITY;for(let i of t){let s=ko(e,i);if(s<r)r=s,n=i}return r<=3?n:""}function vo(){return po(process.argv[1]??"").replace(/\.(?:js|ts|mjs|cjs)$/,"")==="knowledge"}function To(){console.log(`knowledge - local agent knowledge store
626
626
 
627
627
  Usage:
628
- open-knowledge <command> [options]
628
+ knowledge <command> [options]
629
629
 
630
630
  Commands:
631
631
  add <title> <content> Add an item
@@ -719,5 +719,5 @@ Export Options:
719
719
 
720
720
  Prune Options:
721
721
  --older-than <days> Remove items older than N days
722
- --empty Remove items with empty content`)}function To(e){if(e==="add"){console.log("Usage: open-knowledge add <title> <content> [--url <url>] [-t <tag>] [--json]");return}if(e==="list"||e==="ls"){console.log("Usage: open-knowledge list|ls [--format table|json] [-p <page>] [-l <limit>] [-s <search>] [-t <tag>] [--sort created|title] [--desc] [--json]");return}if(e==="get"){console.log("Usage: open-knowledge get --id <id> [--json]");return}if(e==="update"||e==="edit"){console.log("Usage: open-knowledge update|edit --id <id> [--title <title>] [--content <content>] [--url <url>] [-t <tag>] [--json]");return}if(e==="archive"){console.log("Usage: open-knowledge archive --id <id> [--json]");return}if(e==="restore"||e==="unarchive"){console.log("Usage: open-knowledge restore|unarchive --id <id> [--json]");return}if(e==="upsert"){console.log("Usage: open-knowledge upsert [title] [content] [--id <id>] [--title <title>] [--content <content>] [--url <url>] [-t <tag>] [--json]");return}if(e==="untag"){console.log("Usage: open-knowledge untag --id <id> -t <tag> [--json]");return}if(e==="delete"||e==="rm"){console.log("Usage: open-knowledge delete|rm --id <id> -y [--json]");return}if(e==="export"){console.log("Usage: open-knowledge export [--format jsonl] [--json]");return}if(e==="prune"){console.log("Usage: open-knowledge prune --yes [--older-than <days>] [--empty] [--json]");return}if(e==="dedupe"){console.log("Usage: open-knowledge dedupe --yes [--json]");return}if(e==="stats"){console.log("Usage: open-knowledge stats [--json]");return}if(e==="paths"){console.log("Usage: open-knowledge paths [--scope local|global|project] [--json]");return}if(e==="setup"){console.log("Usage: open-knowledge setup --mode local|hosted [--api-url https://...] [--canonical-hasna-xyz] [--scope local|global|project] [--json]");return}if(e==="auth"){console.log("Usage: open-knowledge auth login|whoami|logout [--api-key <key>] [--email <email>] [--org <slug>] [--api-url https://...] [--scope local|global|project] [--json]");return}if(e==="remote"){console.log("Usage: open-knowledge remote contracts|status [--scope local|global|project] [--json]");return}if(e==="storage"){console.log("Usage: open-knowledge storage status|validate [--scope local|global|project] [--json]");return}if(e==="db"){console.log("Usage: open-knowledge db init|stats [--scope local|global|project] [--json]");return}if(e==="wiki"){console.log("Usage: open-knowledge wiki init|compile|file-answer|lint [query|prompt] [--title <title>] [--content <answer>] [--approve-write] [--limit <n>] [--scope local|global|project] [--json]");return}if(e==="source"){console.log("Usage: open-knowledge source resolve <source-ref> [--purpose knowledge_answer|knowledge_index] [--limit <n>] [--scope local|global|project] [--json]");return}if(e==="ingest"){console.log("Usage: open-knowledge ingest manifest <file|s3://bucket/key> | source <source-ref> [--purpose knowledge_index] [--scope local|global|project] [--json]");return}if(e==="reindex"){console.log("Usage: open-knowledge reindex status|enqueue|embeddings|outbox [file|s3://bucket/key] [--full] [--fake] [--scope local|global|project] [--json]");return}if(e==="search"){console.log("Usage: open-knowledge search <query> [--context] [--semantic] [--model openai:text-embedding-3-small] [--limit <n>] [--dimensions <n>] [--fake] [--scope local|global|project] [--json]");return}if(e==="web"){console.log("Usage: open-knowledge web search <query> [--provider openai|anthropic] [--model provider:model] [--domain <domain>] [--file-results] [--fake] [--scope local|global|project] [--json]");return}if(e==="ask"||e==="build"||e==="knowledge"){console.log("Usage: open-knowledge ask|build <prompt> [--generate] [--semantic] [--model default|provider:model] [--approve-write] [--scope local|global|project] [--json]");return}if(e==="embeddings"){console.log("Usage: open-knowledge embeddings status|index|search [query] [--model openai:text-embedding-3-small] [--limit <n>] [--dimensions <n>] [--fake] [--scope local|global|project] [--json]");return}if(e==="providers"){console.log("Usage: open-knowledge providers status|models|check [provider|model-alias] [--scope local|global|project] [--json]");return}if(e==="safety"){console.log("Usage: open-knowledge safety status|check|approve|audit|redact [args] [--scope local|global|project] [--json]");return}wo()}function Ro(e){if(e.noColor||process.env.NO_COLOR)return!1;if(process.env.FORCE_COLOR)return!0;return process.stdout.isTTY===!0}function y(e,t,n){if(t){console.log(JSON.stringify(e,null,2));return}if(typeof e==="string"){console.log(e);return}console.log(e.message??JSON.stringify(e,null,2))}function he(e){if(!e.id)throw Error("Missing required --id. Example: open-knowledge get --id <id>")}function So(e,t){let n=t.sort??"created";if(n!=="created"&&n!=="title")throw Error("Invalid --sort value. Use 'created' or 'title'.");let r=[...e].sort((i,s)=>{if(n==="title")return i.title.localeCompare(s.title);return i.created_at.localeCompare(s.created_at)});if(t.desc)r.reverse();return{sorted:r,sort:n,direction:t.desc?"desc":"asc"}}async function xo(e){let{positional:t,flags:n}=Eo(e);if(te("debug","CLI invoked",{command:t[0],flags:{json:n.json,store:n.store}}),n.version){console.log(n.json?JSON.stringify({name:pe.name,version:pe.version},null,2):`${pe.name} ${pe.version}`);return}if(n.completions){let a=n.completions;if(a==="bash")console.log('_open_knowledge() { local cur; cur="${COMP_WORDS[COMP_CWORD]}"; COMPREPLY=($(compgen -W "add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive knowledge --json --yes --help --version --desc --page --limit --search --sort --id --store --title --content --url --tag --format --completions --purpose --model --dimensions --semantic --context --generate --approve-write --provider --mode --api-url --canonical-hasna-xyz --api-key --email --org --org-id --user-id --domain --file-results --full --fake --no-color --scope --archived --include-archived" -- "$cur")); }; complete -F _open_knowledge open-knowledge');else if(a==="zsh")console.log(`#compdef open-knowledge
723
- _open_knowledge() { _arguments -C "1: :(add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive knowledge)" "(--json)--json" "(--yes)-y" "(--help)--help" "(--version)--version" "(--desc)--desc" "(--archived)--archived" "(--include-archived)--include-archived" "(--semantic)--semantic" "(--context)--context" "(--generate)--generate" "(--approve-write)--approve-write" "(--canonical-hasna-xyz)--canonical-hasna-xyz" "(--file-results)--file-results" "(--full)--full" "(--fake)--fake" "(-p --page)"{-p,--page}"[page number]:number:" "(-l --limit)"{-l,--limit}"[items per page]:number:" "(-s --search)"{-s,--search}"[search text]:text:" "(--sort)--sort"{created,title}:" "(--id)--id[item id]:id:" "(--store)--store[store path]:path:" "(--title)--title[new title]:" "(--content)--content[new content]:" "(--url)--url[source url]:" "(-t --tag)"{-t,--tag}"[tag]:tag:" "(--format)--format[json|jsonl]:" "(--completions)--completions[output completions]:shell:(bash zsh fish):" "(--purpose)--purpose[purpose]:" "(--model)--model[model ref]:" "(--dimensions)--dimensions[embedding dimensions]:number:" "(--provider)--provider[provider]:" "(--mode)--mode"{local,hosted}:" "(--api-url)--api-url[hosted API URL]:" "(--api-key)--api-key[hosted API key]:" "(--email)--email[email]:" "(--org)--org[org slug]:" "(--org-id)--org-id[org id]:" "(--user-id)--user-id[user id]:" "(--domain)--domain[domain]:" "(--no-color)--no-color[disable color]" "(--scope)--scope"{local,global,project}:" }; _open_knowledge`);else if(a==="fish")console.log('complete -c open-knowledge -f; complete -c open-knowledge -a "add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive knowledge"; complete -c open-knowledge -l json; complete -c open-knowledge -l yes -s y; complete -c open-knowledge -l help -s h; complete -c open-knowledge -l version -s v; complete -c open-knowledge -l desc; complete -c open-knowledge -l archived; complete -c open-knowledge -l include-archived; complete -c open-knowledge -l semantic; complete -c open-knowledge -l context; complete -c open-knowledge -l generate; complete -c open-knowledge -l approve-write; complete -c open-knowledge -l canonical-hasna-xyz; complete -c open-knowledge -l provider; complete -c open-knowledge -l mode; complete -c open-knowledge -l api-url; complete -c open-knowledge -l api-key; complete -c open-knowledge -l email; complete -c open-knowledge -l org; complete -c open-knowledge -l org-id; complete -c open-knowledge -l user-id; complete -c open-knowledge -l domain; complete -c open-knowledge -l file-results; complete -c open-knowledge -l full; complete -c open-knowledge -l fake; complete -c open-knowledge -s p -l page; complete -c open-knowledge -s l -l limit; complete -c open-knowledge -s s -l search; complete -c open-knowledge -l sort; complete -c open-knowledge -l id; complete -c open-knowledge -l store; complete -c open-knowledge -l title; complete -c open-knowledge -l content; complete -c open-knowledge -l url; complete -c open-knowledge -s t -l tag; complete -c open-knowledge -l format; complete -c open-knowledge -l completions; complete -c open-knowledge -l purpose; complete -c open-knowledge -l model; complete -c open-knowledge -l dimensions; complete -c open-knowledge -l no-color; complete -c open-knowledge -l scope -a "local global project"');else throw Error("Invalid --completions value. Use 'bash', 'zsh', or 'fish'.");return}let r=yo(t[0]),i=1;if(vo()&&r&&!tr.includes(r))r="ask",i=0;if(!r||n.help||r==="help"){To(t[1]);return}let s=Zn({scope:n.scope}),c=n.store;if(!c)if(n.scope==="project"||n.scope==="local")c=s.jsonStorePath();else c=Ye();if(r==="paths"){y(s.paths(),n.json);return}if(r==="setup"){let a=s.setup({mode:n.mode,apiUrl:n.apiUrl,canonicalHasnaXyz:n.canonicalHasnaXyz});y(a,n.json);return}if(r==="auth"){let a=t[1]??"whoami";if(a==="whoami"||a==="status"){let u=s.authStatus(process.env);y({ok:!0,...u,message:u.authenticated?`Authenticated via ${u.source}`:"Not authenticated"},n.json);return}if(a==="login"){let u=n.apiKey??process.env.KNOWLEDGE_API_KEY??process.env.HASNA_KNOWLEDGE_API_KEY;if(!u)throw Error("Usage: open-knowledge auth login --api-key <key> [--email <email>]");let o=s.saveAuth({apiKey:u,email:n.email,orgSlug:n.org,orgId:n.orgId,userId:n.userId,apiUrl:n.apiUrl},process.env);y({ok:!0,authenticated:!0,email:o.email??null,org_slug:o.org_slug??null,api_url:o.api_url??s.authStatus(process.env).api_url,auth_path:s.authStatus(process.env).auth_path,message:`Saved hosted credentials for ${o.email??"API key"}`},n.json);return}if(a==="logout"){let u=s.clearAuth(process.env);y({ok:!0,removed:u,message:u?"Removed hosted credentials":"No hosted credentials found"},n.json);return}throw Error("Invalid auth action. Use 'login', 'whoami', or 'logout'.")}if(r==="remote"){let a=t[1]??"status";if(a==="contracts"||a==="contract"){let u=s.authStatus(process.env);y({ok:!0,authenticated:u.authenticated,api_url:u.api_url,contract:s.remoteContract(),message:`Remote contract v${s.remoteContract().contract_version}`},n.json);return}if(a==="status"){let u=s.authStatus(process.env),o=s.remoteContract();y({ok:!0,mode:s.config().mode,authenticated:u.authenticated,auth_source:u.source,api_url:u.api_url,client_ready:Boolean(s.remoteClient(process.env)),contract_version:o.contract_version,capabilities:o.capabilities,message:u.authenticated?`Remote client ready for ${u.api_url}`:"Remote client not authenticated"},n.json);return}throw Error("Invalid remote action. Use 'contracts' or 'status'.")}if(r==="storage"){let a=t[1]??"status";if(a==="status"){let u=s.storageContract(),o=s.validateStorage();y({ok:o.ok,...u,validation:o,message:`${u.storage_type} artifact storage at ${u.artifact_store.uri_prefix}`},n.json);return}if(a==="validate"){let u=s.validateStorage();y({ok:u.ok,validation:u,message:u.ok?"Storage contract valid":`Storage contract invalid: ${u.errors.join("; ")}`},n.json);return}throw Error("Invalid storage action. Use 'status' or 'validate'.")}if(r==="db"){let a=t[1]??"init";if(a!=="init"&&a!=="stats")throw Error("Invalid db action. Use 'init' or 'stats'.");if(a==="init"){let o=s.initDb();y({ok:!0,...o,message:`Initialized ${o.path}`},n.json);return}let u=s.dbStats();y({ok:!0,path:s.workspace.knowledgeDbPath,...u,message:`knowledge.db schema v${u.schema_version}`},n.json);return}if(r==="wiki"){let a=t[1]??"init";if(a==="init"){let u=await s.initWiki();y({ok:!0,...u,message:`Initialized wiki layout in ${s.workspace.home}`},n.json);return}if(a==="compile"){let u=t.slice(2),o=u.filter((f)=>/^(open-files|file|s3|https?):\/\//.test(f)),_=u.filter((f)=>!/^(open-files|file|s3|https?):\/\//.test(f)).join(" "),l=await s.compileWiki({title:n.title,query:_||n.search,sourceRefs:o.length>0?o:void 0,limit:n.limit});y({ok:!0,...l,message:`Compiled wiki page ${l.path}`},n.json);return}if(a==="file-answer"||a==="answer"){let u=t.slice(2).join(" ");if(!u)throw Error("Usage: open-knowledge wiki file-answer <prompt> --content <answer> --approve-write");if(!n.content)throw Error("Missing --content <answer> for wiki file-answer.");let o=await s.fileAnswer({prompt:u,answer:n.content,approveWrite:n.approveWrite,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o},n.json);return}if(a==="lint"){let u=s.lintWiki();y({ok:u.ok,...u,message:u.ok?"Wiki lint passed":`Wiki lint found ${u.issue_count} issue(s)`},n.json);return}throw Error("Invalid wiki action. Use 'init', 'compile', 'file-answer', or 'lint'.")}if(r==="safety"){let a=t[1]??"status",u=s.ensureWorkspace(),o=s.safetyPolicy();s.initDb();let _=b(u.knowledgeDbPath);try{if(a==="status"){y({ok:!0,mode:o.mode,workspace:u.home,allow_write_roots:o.allowWriteRoots,read_only_source_access:o.readOnlySourceAccess,network:o.network,redaction:o.redaction,approvals:o.approvals,message:`Safety policy: ${o.mode}`},n.json);return}if(a==="check"){let l=t[2]??"generated_write",f=t[3]??null,m;try{if(l==="web_search")ie(o),m={action:l,target_uri:f,approval_required:!1,approved:!0,decision:"allow"};else if(l==="s3_read"){if(!f)throw Error("safety check s3_read requires an s3:// target.");J(f,o),m={action:l,target_uri:f,approval_required:!1,approved:!0,decision:"allow"}}else m=kn(_,o,l,f);I(_,{event_type:"safety_check",action:l,target_uri:f,decision:m.decision==="allow"?"allow":"requires_approval",metadata:m}),y({ok:!0,...m,message:`Safety check ${m.decision}`},n.json);return}catch(E){throw I(_,{event_type:"safety_check",action:l,target_uri:f,decision:"deny",metadata:{error:E instanceof Error?E.message:String(E)}}),E}}if(a==="approve"){let l=t[2]??"generated_write",f=t[3]??null,m=yn(_,{action:l,target_uri:f,reason:"local-cli approval",metadata:{scope:n.scope??"global"}});I(_,{event_type:"approval",action:l,target_uri:f,decision:"allow",metadata:{approval_id:m.id}}),y({ok:!0,...m,action:l,target_uri:f,message:`Approved ${l}`},n.json);return}if(a==="audit"){let l=_.query("SELECT id, event_type, action, target_uri, decision, metadata_json, created_at FROM audit_events ORDER BY created_at DESC LIMIT 50").all().map((f)=>({id:f.id,event_type:f.event_type,action:f.action,target_uri:f.target_uri,decision:f.decision,metadata:JSON.parse(f.metadata_json),created_at:f.created_at}));y({ok:!0,events:l,message:`${l.length} audit event(s)`},n.json);return}if(a==="redact"){let l=t.slice(2).join(" ");if(!l)throw Error("Usage: open-knowledge safety redact <text>");let f=De(l,o);if(f.findings.length>0)Ue(_,{source_uri:"safety://redact",findings:f.findings,metadata:{command:"safety redact"}});I(_,{event_type:"redaction",action:"safety_redact",target_uri:"safety://redact",decision:f.findings.length>0?"redacted":"allow",metadata:{findings:f.findings.length}}),y({ok:!0,text:f.text,findings:f.findings,message:`Redacted ${f.findings.length} finding(s)`},n.json);return}throw Error("Invalid safety action. Use 'status', 'check', 'approve', 'audit', or 'redact'.")}finally{_.close()}}if(r==="source"){if((t[1]??"")!=="resolve")throw Error("Invalid source action. Use 'resolve'.");let u=t[2];if(!u)throw Error("Usage: open-knowledge source resolve <source-ref>");let o=await s.resolveSource(u,{purpose:n.purpose,limit:n.limit});y({ok:!0,...o,message:o.resolved?`Resolved ${o.source_ref} (${o.content.chunks_returned}/${o.content.chunks_total} chunks)`:`Source not indexed: ${u}`},n.json);return}if(r==="ingest"){let a=t[1]??"";if(a==="manifest"){let u=t[2];if(!u)throw Error("Usage: open-knowledge ingest manifest <file|s3://bucket/key>");let o=await s.ingestManifest(u);y({ok:!0,...o,message:`Ingested ${o.items_seen} manifest item(s)`},n.json);return}if(a==="source"){let u=t[2];if(!u)throw Error("Usage: open-knowledge ingest source <source-ref>");let o=await s.ingestSource(u,n.purpose);y({ok:!0,...o,message:`Ingested source ${o.source_ref} (${o.chunks_inserted} chunks)`},n.json);return}throw Error("Invalid ingest action. Use 'manifest' or 'source'.")}if(r==="reindex"){let a=t[1]??"status";if(a==="status"){let u=s.reindexHealth({modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`${u.missing_embeddings} chunk(s) missing embeddings`},n.json);return}if(a==="enqueue"){let u=s.enqueueReindex({modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Queued ${u.enqueued} embedding refresh item(s)`},n.json);return}if(a==="embeddings"){let u=await s.refreshEmbeddings({full:n.full,limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Embedded ${u.indexed.chunks_embedded} chunk(s)`},n.json);return}if(a==="outbox"){let u=t[2];if(!u)throw Error("Usage: open-knowledge reindex outbox <file|s3://bucket/key>");let o=await s.consumeOutbox(u);y({ok:!0,...o,message:`Consumed ${o.events_seen} outbox event(s)`},n.json);return}throw Error("Invalid reindex action. Use 'status', 'enqueue', 'embeddings', or 'outbox'.")}if(r==="embeddings"){let a=t[1]??"status";if(a==="status"){let u=s.embeddingStatus();y({ok:!0,...u,message:`${u.total_vector_entries} vector index entries`},n.json);return}if(a==="index"){let u=await s.indexEmbeddings({limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Embedded ${u.chunks_embedded} chunk(s)`},n.json);return}if(a==="search"){let u=t.slice(2).join(" ");if(!u)throw Error("Usage: open-knowledge embeddings search <query>");let o=await s.semanticSearch({query:u,limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o,message:`${o.results.length} semantic result(s)`},n.json);return}throw Error("Invalid embeddings action. Use 'status', 'index', or 'search'.")}if(r==="search"){let a=t.slice(1).join(" ");if(!a)throw Error("Usage: open-knowledge search <query>");if(n.context){let o=await s.retrieveContext({query:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o,message:`${o.excerpts.length} context excerpt(s)`},n.json);return}let u=await s.search({query:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`${u.results.length} search result(s)`},n.json);return}if(r==="web"){if((t[1]??"search")!=="search")throw Error("Invalid web action. Use 'search'.");let u=t.slice(2).join(" ");if(!u)throw Error("Usage: open-knowledge web search <query>");let o=await s.webSearch({query:u,limit:n.limit,modelRef:n.model,provider:n.provider,domains:n.domain,fake:n.fake,fileResults:n.fileResults});y({ok:!0,...o,message:`${o.sources.length} web source(s)`},n.json);return}if(r==="ask"||r==="build"){let a=t.slice(i).join(" ");if(!a)throw Error("Usage: open-knowledge ask <prompt>");let u=await s.runPrompt({prompt:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake,generate:n.generate,approveWrite:n.approveWrite});y({ok:!0,...u,message:u.generated?"Generated answer with citations":"Prepared citation context draft"},n.json);return}if(r==="providers"){let a=t[1]??"status";if(a==="status"){let u=s.providerStatus(),o=u.providers.filter((_)=>_.configured).length;y({ok:!0,...u,message:`${o}/${u.providers.length} provider credential(s) configured`},n.json);return}if(a==="models"){let u=s.modelRegistry();y({ok:!0,models:u,message:`${u.length} model alias(es)`},n.json);return}if(a==="check"){let u=t[2]??"default",o=H(u,s.config()),_=C(o),l=z(_.provider,s.config());y({ok:!0,target:u,model_ref:o,provider:_.provider,model:_.model,credential:l,message:`${_.provider} credentials configured`},n.json);return}throw Error("Invalid providers action. Use 'status', 'models', or 'check'.")}if(Ve(c),r==="add"){let a=t[1],u=t[2];if(!a||!u)throw Error("Usage: open-knowledge add <title> <content>");P(c,()=>{let o=U(c),_={id:Qe(),title:a,content:u,url:n.url??null,tags:n.tag?[n.tag]:[],created_at:new Date().toISOString(),updated_at:new Date().toISOString()};o.items.push(_),$(c,o),te("info","Item added",{id:_.id,title:_.title}),y({ok:!0,item:_,message:`Added ${_.id}`},n.json)});return}if(r==="list"){if(n.format!==void 0&&n.format!=="table"&&n.format!=="json")throw Error("Invalid --format value for list. Use 'table' or 'json'.");P(c,()=>{let a=U(c),u=Number.isFinite(n.page)&&n.page>0?n.page:1,o=Number.isFinite(n.limit)&&n.limit>0?n.limit:20,_=n.search?String(n.search).toLowerCase():"",l=n.tag?String(n.tag).toLowerCase():"",f=n.format==="table"||!n.json&&!n.format&&Ro(n),m=n.json||n.format==="json",E=a.items;if(n.archived)E=E.filter((w)=>w.archived===!0);else if(!n.includeArchived)E=E.filter((w)=>!w.archived);if(_)E=E.filter((w)=>w.title.toLowerCase().includes(_)||w.content.toLowerCase().includes(_));if(l)E=E.filter((w)=>w.tags&&w.tags.map((Be)=>Be.toLowerCase()).includes(l));let{sorted:h,sort:T,direction:k}=So(E,n),p=(u-1)*o,R=h.slice(p,p+o),v=Math.max(1,Math.ceil(h.length/o));if(m){y({ok:!0,page:u,limit:o,total:h.length,total_pages:v,sort:T,direction:k,items:R},!0);return}if(R.length===0){y(`No items found (search=${_||"none"}, tag=${l||"none"})`,!1);return}if(f){let w=(W)=>W,Be=`${w("ID")} ${w("TITLE")} ${w("CREATED")} ${w("URL")} ${w("TAGS")}`;console.log(Be);for(let W of R)console.log(`${W.id} ${w(W.title)} ${W.created_at} ${W.url?w(W.url):""} ${W.tags?.length?w(`[${W.tags.join(", ")}]`):""}`);console.log(`Page ${u}/${v} | showing ${R.length} of ${h.length} | sort=${T} ${k} | search=${_||"none"} | tag=${l||"none"}`)}else{for(let w of R)console.log(`${w.id} ${w.title} ${w.created_at}${w.url?` ${w.url}`:""}${w.tags?.length?` [${w.tags.join(", ")}]`:""}`);console.log(`Page ${u}/${v} | showing ${R.length} of ${h.length} | sort=${T} ${k} | search=${_||"none"} | tag=${l||"none"}`)}});return}if(r==="get"){he(n),P(c,()=>{let u=U(c).items.find((o)=>o.id===n.id||o.short_id===n.id);if(!u)throw Error(`Item not found: ${n.id}`);y({ok:!0,item:u,message:`${u.id}: ${u.title}`},n.json)});return}if(r==="update"){he(n),P(c,()=>{let a=U(c),u=a.items.findIndex((_)=>_.id===n.id||_.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u];if(n.title!==void 0)o.title=n.title;if(n.content!==void 0)o.content=n.content;if(n.url!==void 0)o.url=n.url;if(n.tag!==void 0){if(o.tags=o.tags||[],!o.tags.map((_)=>_.toLowerCase()).includes(n.tag.toLowerCase()))o.tags.push(n.tag)}o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,message:`Updated ${o.id}`},n.json)});return}if(r==="archive"||r==="restore"){he(n),P(c,()=>{let a=U(c),u=a.items.findIndex((_)=>_.id===n.id||_.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u];o.archived=r==="archive",o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,message:`${r==="archive"?"Archived":"Restored"} ${o.id}`},n.json)});return}if(r==="untag"){if(he(n),!n.tag)throw Error("Missing required --tag. Example: open-knowledge untag --id <id> -t <tag>");P(c,()=>{let a=U(c),u=a.items.findIndex((l)=>l.id===n.id||l.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u],_=o.tags?.length??0;o.tags=(o.tags??[]).filter((l)=>l.toLowerCase()!==n.tag.toLowerCase()),o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,removed:_-o.tags.length,message:`Removed tag from ${o.id}`},n.json)});return}if(r==="upsert"){let a=n.title??t[1],u=n.content??t[2];P(c,()=>{let o=U(c),_=n.id?o.items.findIndex((m)=>m.id===n.id||m.short_id===n.id):-1,l=new Date().toISOString();if(_===-1){if(!a||!u)throw Error("New item requires title and content. Example: open-knowledge upsert <title> <content> [--id <id>]");let m=n.id??Qe(),E={id:m,short_id:At(m),title:a,content:u,url:n.url??null,tags:n.tag?[n.tag]:[],metadata:{},archived:!1,created_at:l,updated_at:l};o.items.push(E),$(c,o),y({ok:!0,created:!0,item:E,message:`Upserted ${E.id}`},n.json);return}let f=o.items[_];if(a!==void 0)f.title=a;if(u!==void 0)f.content=u;if(n.url!==void 0)f.url=n.url;if(n.tag!==void 0){if(f.tags=f.tags||[],!f.tags.map((m)=>m.toLowerCase()).includes(n.tag.toLowerCase()))f.tags.push(n.tag)}f.updated_at=l,o.items[_]=f,$(c,o),y({ok:!0,created:!1,item:f,message:`Upserted ${f.id}`},n.json)});return}if(r==="delete"){if(he(n),!n.yes)throw Error("Refusing delete without --yes. Re-run with: open-knowledge delete --id <id> --yes");P(c,()=>{let a=U(c),u=a.items.length;a.items=a.items.filter((_)=>_.id!==n.id&&_.short_id!==n.id);let o=u!==a.items.length;if($(c,a),!o)throw Error(`Item not found: ${n.id}`);te("info","Item deleted",{id:n.id}),y({ok:!0,deleted_id:n.id,message:`Deleted ${n.id}`},n.json)});return}if(r==="export"){let a=n.format??"json";if(a!=="json"&&a!=="jsonl")throw Error("Invalid --format. Use 'json' or 'jsonl'.");P(c,()=>{let u=U(c);if(a==="jsonl")for(let o of u.items)console.log(JSON.stringify(o));else y({ok:!0,items:u.items},n.json)});return}if(r==="prune"){if(!n.yes)throw Error("Refusing prune without --yes. Re-run with: open-knowledge prune --yes [--older-than <days>] [--empty]");P(c,()=>{let a=U(c),u=a.items.length;if(n.olderThan!==void 0){let _=new Date;_.setDate(_.getDate()-n.olderThan),a.items=a.items.filter((l)=>new Date(l.created_at)>=_)}if(n.empty)a.items=a.items.filter((_)=>_.content.trim().length>0);let o=u-a.items.length;$(c,a),te("info","Prune completed",{pruned:o,remaining:a.items.length}),y({ok:!0,pruned:o,remaining:a.items.length,message:`Pruned ${o} item(s)`},n.json)});return}if(r==="dedupe"){if(!n.yes)throw Error("Refusing dedupe without --yes. Re-run with: open-knowledge dedupe --yes [--json]");P(c,()=>{let a=U(c),u=new Set,o=a.items.length;a.items=a.items.filter((l)=>{let f=`${l.title}\x00${l.content}`;if(u.has(f))return!1;return u.add(f),!0});let _=o-a.items.length;$(c,a),te("info","Dedupe completed",{removed:_,remaining:a.items.length}),y({ok:!0,removed:_,remaining:a.items.length,message:`Dedupe removed ${_} duplicate(s)`},n.json)});return}if(r==="stats"){P(c,()=>{let a=U(c),u=a.items.filter((k)=>!k.archived),o=u.length,_=a.items.length-o,l=u.filter((k)=>k.url).length,f=u.filter((k)=>k.tags&&k.tags.length>0).length,m=o>0?u.map((k)=>k.created_at).sort()[0]:null,E=o>0?u.map((k)=>k.created_at).sort()[o-1]:null,h={};for(let k of u)for(let p of k.tags||[])h[p]=(h[p]||0)+1;let T=Object.entries(h).sort((k,p)=>p[1]-k[1]).slice(0,5).map(([k,p])=>({tag:k,count:p}));y({ok:!0,total:o,archived:_,with_url:l,with_tags:f,oldest:m,newest:E,top_tags:T,message:`${o} items | ${l} with URL | ${f} with tags`},n.json)});return}let d=bo(t[0]),g=d?` Did you mean '${d}'?`:"";throw te("warn","Unknown command",{input:t[0],suggestion:d}),Error(`Unknown command: ${t[0]}.${g} Run 'open-knowledge --help' for available commands.`)}if(import.meta.main)xo(process.argv.slice(2)).catch((e)=>{let t=e instanceof Error?e.message:String(e);te("error","CLI error",{message:t,stack:e instanceof Error?e.stack:void 0}),console.error(`Error: ${t}`),process.exitCode=1});export{bo as suggestCommand,So as sortItems,xo as run,Eo as parseArgs};
722
+ --empty Remove items with empty content`)}function wo(e){if(e==="add"){console.log("Usage: knowledge add <title> <content> [--url <url>] [-t <tag>] [--json]");return}if(e==="list"||e==="ls"){console.log("Usage: knowledge list|ls [--format table|json] [-p <page>] [-l <limit>] [-s <search>] [-t <tag>] [--sort created|title] [--desc] [--json]");return}if(e==="get"){console.log("Usage: knowledge get --id <id> [--json]");return}if(e==="update"||e==="edit"){console.log("Usage: knowledge update|edit --id <id> [--title <title>] [--content <content>] [--url <url>] [-t <tag>] [--json]");return}if(e==="archive"){console.log("Usage: knowledge archive --id <id> [--json]");return}if(e==="restore"||e==="unarchive"){console.log("Usage: knowledge restore|unarchive --id <id> [--json]");return}if(e==="upsert"){console.log("Usage: knowledge upsert [title] [content] [--id <id>] [--title <title>] [--content <content>] [--url <url>] [-t <tag>] [--json]");return}if(e==="untag"){console.log("Usage: knowledge untag --id <id> -t <tag> [--json]");return}if(e==="delete"||e==="rm"){console.log("Usage: knowledge delete|rm --id <id> -y [--json]");return}if(e==="export"){console.log("Usage: knowledge export [--format jsonl] [--json]");return}if(e==="prune"){console.log("Usage: knowledge prune --yes [--older-than <days>] [--empty] [--json]");return}if(e==="dedupe"){console.log("Usage: knowledge dedupe --yes [--json]");return}if(e==="stats"){console.log("Usage: knowledge stats [--json]");return}if(e==="paths"){console.log("Usage: knowledge paths [--scope local|global|project] [--json]");return}if(e==="setup"){console.log("Usage: knowledge setup --mode local|hosted [--api-url https://...] [--canonical-hasna-xyz] [--scope local|global|project] [--json]");return}if(e==="auth"){console.log("Usage: knowledge auth login|whoami|logout [--api-key <key>] [--email <email>] [--org <slug>] [--api-url https://...] [--scope local|global|project] [--json]");return}if(e==="remote"){console.log("Usage: knowledge remote contracts|status [--scope local|global|project] [--json]");return}if(e==="storage"){console.log("Usage: knowledge storage status|validate [--scope local|global|project] [--json]");return}if(e==="db"){console.log("Usage: knowledge db init|stats [--scope local|global|project] [--json]");return}if(e==="wiki"){console.log("Usage: knowledge wiki init|compile|file-answer|lint [query|prompt] [--title <title>] [--content <answer>] [--approve-write] [--limit <n>] [--scope local|global|project] [--json]");return}if(e==="source"){console.log("Usage: knowledge source resolve <source-ref> [--purpose knowledge_answer|knowledge_index] [--limit <n>] [--scope local|global|project] [--json]");return}if(e==="ingest"){console.log("Usage: knowledge ingest manifest <file|s3://bucket/key> | source <source-ref> [--purpose knowledge_index] [--scope local|global|project] [--json]");return}if(e==="reindex"){console.log("Usage: knowledge reindex status|enqueue|embeddings|outbox [file|s3://bucket/key] [--full] [--fake] [--scope local|global|project] [--json]");return}if(e==="search"){console.log("Usage: knowledge search <query> [--context] [--semantic] [--model openai:text-embedding-3-small] [--limit <n>] [--dimensions <n>] [--fake] [--scope local|global|project] [--json]");return}if(e==="web"){console.log("Usage: knowledge web search <query> [--provider openai|anthropic] [--model provider:model] [--domain <domain>] [--file-results] [--fake] [--scope local|global|project] [--json]");return}if(e==="ask"||e==="build"){console.log("Usage: knowledge ask|build <prompt> [--generate] [--semantic] [--model default|provider:model] [--approve-write] [--scope local|global|project] [--json]");return}if(e==="embeddings"){console.log("Usage: knowledge embeddings status|index|search [query] [--model openai:text-embedding-3-small] [--limit <n>] [--dimensions <n>] [--fake] [--scope local|global|project] [--json]");return}if(e==="providers"){console.log("Usage: knowledge providers status|models|check [provider|model-alias] [--scope local|global|project] [--json]");return}if(e==="safety"){console.log("Usage: knowledge safety status|check|approve|audit|redact [args] [--scope local|global|project] [--json]");return}To()}function Ro(e){if(e.noColor||process.env.NO_COLOR)return!1;if(process.env.FORCE_COLOR)return!0;return process.stdout.isTTY===!0}function y(e,t,n){if(t){console.log(JSON.stringify(e,null,2));return}if(typeof e==="string"){console.log(e);return}console.log(e.message??JSON.stringify(e,null,2))}function he(e){if(!e.id)throw Error("Missing required --id. Example: knowledge get --id <id>")}function So(e,t){let n=t.sort??"created";if(n!=="created"&&n!=="title")throw Error("Invalid --sort value. Use 'created' or 'title'.");let r=[...e].sort((i,s)=>{if(n==="title")return i.title.localeCompare(s.title);return i.created_at.localeCompare(s.created_at)});if(t.desc)r.reverse();return{sorted:r,sort:n,direction:t.desc?"desc":"asc"}}async function xo(e){let{positional:t,flags:n}=Eo(e);if(te("debug","CLI invoked",{command:t[0],flags:{json:n.json,store:n.store}}),n.version){console.log(n.json?JSON.stringify({name:pe.name,version:pe.version},null,2):`${pe.name} ${pe.version}`);return}if(n.completions){let a=n.completions;if(a==="bash")console.log('_knowledge() { local cur; cur="${COMP_WORDS[COMP_CWORD]}"; COMPREPLY=($(compgen -W "add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive --json --yes --help --version --desc --page --limit --search --sort --id --store --title --content --url --tag --format --completions --purpose --model --dimensions --semantic --context --generate --approve-write --provider --mode --api-url --canonical-hasna-xyz --api-key --email --org --org-id --user-id --domain --file-results --full --fake --no-color --scope --archived --include-archived" -- "$cur")); }; complete -F _knowledge knowledge');else if(a==="zsh")console.log(`#compdef knowledge
723
+ _knowledge() { _arguments -C "1: :(add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive)" "(--json)--json" "(--yes)-y" "(--help)--help" "(--version)--version" "(--desc)--desc" "(--archived)--archived" "(--include-archived)--include-archived" "(--semantic)--semantic" "(--context)--context" "(--generate)--generate" "(--approve-write)--approve-write" "(--canonical-hasna-xyz)--canonical-hasna-xyz" "(--file-results)--file-results" "(--full)--full" "(--fake)--fake" "(-p --page)"{-p,--page}"[page number]:number:" "(-l --limit)"{-l,--limit}"[items per page]:number:" "(-s --search)"{-s,--search}"[search text]:text:" "(--sort)--sort"{created,title}:" "(--id)--id[item id]:id:" "(--store)--store[store path]:path:" "(--title)--title[new title]:" "(--content)--content[new content]:" "(--url)--url[source url]:" "(-t --tag)"{-t,--tag}"[tag]:tag:" "(--format)--format[json|jsonl]:" "(--completions)--completions[output completions]:shell:(bash zsh fish):" "(--purpose)--purpose[purpose]:" "(--model)--model[model ref]:" "(--dimensions)--dimensions[embedding dimensions]:number:" "(--provider)--provider[provider]:" "(--mode)--mode"{local,hosted}:" "(--api-url)--api-url[hosted API URL]:" "(--api-key)--api-key[hosted API key]:" "(--email)--email[email]:" "(--org)--org[org slug]:" "(--org-id)--org-id[org id]:" "(--user-id)--user-id[user id]:" "(--domain)--domain[domain]:" "(--no-color)--no-color[disable color]" "(--scope)--scope"{local,global,project}:" }; _knowledge`);else if(a==="fish")console.log('complete -c knowledge -f; complete -c knowledge -a "add list get update archive restore upsert untag delete export prune dedupe stats paths setup auth remote storage db wiki source ingest reindex search web ask build embeddings providers safety help ls rm edit unarchive"; complete -c knowledge -l json; complete -c knowledge -l yes -s y; complete -c knowledge -l help -s h; complete -c knowledge -l version -s v; complete -c knowledge -l desc; complete -c knowledge -l archived; complete -c knowledge -l include-archived; complete -c knowledge -l semantic; complete -c knowledge -l context; complete -c knowledge -l generate; complete -c knowledge -l approve-write; complete -c knowledge -l canonical-hasna-xyz; complete -c knowledge -l provider; complete -c knowledge -l mode; complete -c knowledge -l api-url; complete -c knowledge -l api-key; complete -c knowledge -l email; complete -c knowledge -l org; complete -c knowledge -l org-id; complete -c knowledge -l user-id; complete -c knowledge -l domain; complete -c knowledge -l file-results; complete -c knowledge -l full; complete -c knowledge -l fake; complete -c knowledge -s p -l page; complete -c knowledge -s l -l limit; complete -c knowledge -s s -l search; complete -c knowledge -l sort; complete -c knowledge -l id; complete -c knowledge -l store; complete -c knowledge -l title; complete -c knowledge -l content; complete -c knowledge -l url; complete -c knowledge -s t -l tag; complete -c knowledge -l format; complete -c knowledge -l completions; complete -c knowledge -l purpose; complete -c knowledge -l model; complete -c knowledge -l dimensions; complete -c knowledge -l no-color; complete -c knowledge -l scope -a "local global project"');else throw Error("Invalid --completions value. Use 'bash', 'zsh', or 'fish'.");return}let r=yo(t[0]),i=1;if(vo()&&r&&!tr.includes(r))r="ask",i=0;if(!r||n.help||r==="help"){wo(t[1]);return}let s=Zn({scope:n.scope}),c=n.store;if(!c)if(n.scope==="project"||n.scope==="local")c=s.jsonStorePath();else c=Ye();if(r==="paths"){y(s.paths(),n.json);return}if(r==="setup"){let a=s.setup({mode:n.mode,apiUrl:n.apiUrl,canonicalHasnaXyz:n.canonicalHasnaXyz});y(a,n.json);return}if(r==="auth"){let a=t[1]??"whoami";if(a==="whoami"||a==="status"){let u=s.authStatus(process.env);y({ok:!0,...u,message:u.authenticated?`Authenticated via ${u.source}`:"Not authenticated"},n.json);return}if(a==="login"){let u=n.apiKey??process.env.KNOWLEDGE_API_KEY??process.env.HASNA_KNOWLEDGE_API_KEY;if(!u)throw Error("Usage: knowledge auth login --api-key <key> [--email <email>]");let o=s.saveAuth({apiKey:u,email:n.email,orgSlug:n.org,orgId:n.orgId,userId:n.userId,apiUrl:n.apiUrl},process.env);y({ok:!0,authenticated:!0,email:o.email??null,org_slug:o.org_slug??null,api_url:o.api_url??s.authStatus(process.env).api_url,auth_path:s.authStatus(process.env).auth_path,message:`Saved hosted credentials for ${o.email??"API key"}`},n.json);return}if(a==="logout"){let u=s.clearAuth(process.env);y({ok:!0,removed:u,message:u?"Removed hosted credentials":"No hosted credentials found"},n.json);return}throw Error("Invalid auth action. Use 'login', 'whoami', or 'logout'.")}if(r==="remote"){let a=t[1]??"status";if(a==="contracts"||a==="contract"){let u=s.authStatus(process.env);y({ok:!0,authenticated:u.authenticated,api_url:u.api_url,contract:s.remoteContract(),message:`Remote contract v${s.remoteContract().contract_version}`},n.json);return}if(a==="status"){let u=s.authStatus(process.env),o=s.remoteContract();y({ok:!0,mode:s.config().mode,authenticated:u.authenticated,auth_source:u.source,api_url:u.api_url,client_ready:Boolean(s.remoteClient(process.env)),contract_version:o.contract_version,capabilities:o.capabilities,message:u.authenticated?`Remote client ready for ${u.api_url}`:"Remote client not authenticated"},n.json);return}throw Error("Invalid remote action. Use 'contracts' or 'status'.")}if(r==="storage"){let a=t[1]??"status";if(a==="status"){let u=s.storageContract(),o=s.validateStorage();y({ok:o.ok,...u,validation:o,message:`${u.storage_type} artifact storage at ${u.artifact_store.uri_prefix}`},n.json);return}if(a==="validate"){let u=s.validateStorage();y({ok:u.ok,validation:u,message:u.ok?"Storage contract valid":`Storage contract invalid: ${u.errors.join("; ")}`},n.json);return}throw Error("Invalid storage action. Use 'status' or 'validate'.")}if(r==="db"){let a=t[1]??"init";if(a!=="init"&&a!=="stats")throw Error("Invalid db action. Use 'init' or 'stats'.");if(a==="init"){let o=s.initDb();y({ok:!0,...o,message:`Initialized ${o.path}`},n.json);return}let u=s.dbStats();y({ok:!0,path:s.workspace.knowledgeDbPath,...u,message:`knowledge.db schema v${u.schema_version}`},n.json);return}if(r==="wiki"){let a=t[1]??"init";if(a==="init"){let u=await s.initWiki();y({ok:!0,...u,message:`Initialized wiki layout in ${s.workspace.home}`},n.json);return}if(a==="compile"){let u=t.slice(2),o=u.filter((f)=>/^(open-files|file|s3|https?):\/\//.test(f)),_=u.filter((f)=>!/^(open-files|file|s3|https?):\/\//.test(f)).join(" "),l=await s.compileWiki({title:n.title,query:_||n.search,sourceRefs:o.length>0?o:void 0,limit:n.limit});y({ok:!0,...l,message:`Compiled wiki page ${l.path}`},n.json);return}if(a==="file-answer"||a==="answer"){let u=t.slice(2).join(" ");if(!u)throw Error("Usage: knowledge wiki file-answer <prompt> --content <answer> --approve-write");if(!n.content)throw Error("Missing --content <answer> for wiki file-answer.");let o=await s.fileAnswer({prompt:u,answer:n.content,approveWrite:n.approveWrite,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o},n.json);return}if(a==="lint"){let u=s.lintWiki();y({ok:u.ok,...u,message:u.ok?"Wiki lint passed":`Wiki lint found ${u.issue_count} issue(s)`},n.json);return}throw Error("Invalid wiki action. Use 'init', 'compile', 'file-answer', or 'lint'.")}if(r==="safety"){let a=t[1]??"status",u=s.ensureWorkspace(),o=s.safetyPolicy();s.initDb();let _=b(u.knowledgeDbPath);try{if(a==="status"){y({ok:!0,mode:o.mode,workspace:u.home,allow_write_roots:o.allowWriteRoots,read_only_source_access:o.readOnlySourceAccess,network:o.network,redaction:o.redaction,approvals:o.approvals,message:`Safety policy: ${o.mode}`},n.json);return}if(a==="check"){let l=t[2]??"generated_write",f=t[3]??null,m;try{if(l==="web_search")ie(o),m={action:l,target_uri:f,approval_required:!1,approved:!0,decision:"allow"};else if(l==="s3_read"){if(!f)throw Error("safety check s3_read requires an s3:// target.");J(f,o),m={action:l,target_uri:f,approval_required:!1,approved:!0,decision:"allow"}}else m=kn(_,o,l,f);I(_,{event_type:"safety_check",action:l,target_uri:f,decision:m.decision==="allow"?"allow":"requires_approval",metadata:m}),y({ok:!0,...m,message:`Safety check ${m.decision}`},n.json);return}catch(E){throw I(_,{event_type:"safety_check",action:l,target_uri:f,decision:"deny",metadata:{error:E instanceof Error?E.message:String(E)}}),E}}if(a==="approve"){let l=t[2]??"generated_write",f=t[3]??null,m=yn(_,{action:l,target_uri:f,reason:"local-cli approval",metadata:{scope:n.scope??"global"}});I(_,{event_type:"approval",action:l,target_uri:f,decision:"allow",metadata:{approval_id:m.id}}),y({ok:!0,...m,action:l,target_uri:f,message:`Approved ${l}`},n.json);return}if(a==="audit"){let l=_.query("SELECT id, event_type, action, target_uri, decision, metadata_json, created_at FROM audit_events ORDER BY created_at DESC LIMIT 50").all().map((f)=>({id:f.id,event_type:f.event_type,action:f.action,target_uri:f.target_uri,decision:f.decision,metadata:JSON.parse(f.metadata_json),created_at:f.created_at}));y({ok:!0,events:l,message:`${l.length} audit event(s)`},n.json);return}if(a==="redact"){let l=t.slice(2).join(" ");if(!l)throw Error("Usage: knowledge safety redact <text>");let f=De(l,o);if(f.findings.length>0)Ue(_,{source_uri:"safety://redact",findings:f.findings,metadata:{command:"safety redact"}});I(_,{event_type:"redaction",action:"safety_redact",target_uri:"safety://redact",decision:f.findings.length>0?"redacted":"allow",metadata:{findings:f.findings.length}}),y({ok:!0,text:f.text,findings:f.findings,message:`Redacted ${f.findings.length} finding(s)`},n.json);return}throw Error("Invalid safety action. Use 'status', 'check', 'approve', 'audit', or 'redact'.")}finally{_.close()}}if(r==="source"){if((t[1]??"")!=="resolve")throw Error("Invalid source action. Use 'resolve'.");let u=t[2];if(!u)throw Error("Usage: knowledge source resolve <source-ref>");let o=await s.resolveSource(u,{purpose:n.purpose,limit:n.limit});y({ok:!0,...o,message:o.resolved?`Resolved ${o.source_ref} (${o.content.chunks_returned}/${o.content.chunks_total} chunks)`:`Source not indexed: ${u}`},n.json);return}if(r==="ingest"){let a=t[1]??"";if(a==="manifest"){let u=t[2];if(!u)throw Error("Usage: knowledge ingest manifest <file|s3://bucket/key>");let o=await s.ingestManifest(u);y({ok:!0,...o,message:`Ingested ${o.items_seen} manifest item(s)`},n.json);return}if(a==="source"){let u=t[2];if(!u)throw Error("Usage: knowledge ingest source <source-ref>");let o=await s.ingestSource(u,n.purpose);y({ok:!0,...o,message:`Ingested source ${o.source_ref} (${o.chunks_inserted} chunks)`},n.json);return}throw Error("Invalid ingest action. Use 'manifest' or 'source'.")}if(r==="reindex"){let a=t[1]??"status";if(a==="status"){let u=s.reindexHealth({modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`${u.missing_embeddings} chunk(s) missing embeddings`},n.json);return}if(a==="enqueue"){let u=s.enqueueReindex({modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Queued ${u.enqueued} embedding refresh item(s)`},n.json);return}if(a==="embeddings"){let u=await s.refreshEmbeddings({full:n.full,limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Embedded ${u.indexed.chunks_embedded} chunk(s)`},n.json);return}if(a==="outbox"){let u=t[2];if(!u)throw Error("Usage: knowledge reindex outbox <file|s3://bucket/key>");let o=await s.consumeOutbox(u);y({ok:!0,...o,message:`Consumed ${o.events_seen} outbox event(s)`},n.json);return}throw Error("Invalid reindex action. Use 'status', 'enqueue', 'embeddings', or 'outbox'.")}if(r==="embeddings"){let a=t[1]??"status";if(a==="status"){let u=s.embeddingStatus();y({ok:!0,...u,message:`${u.total_vector_entries} vector index entries`},n.json);return}if(a==="index"){let u=await s.indexEmbeddings({limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`Embedded ${u.chunks_embedded} chunk(s)`},n.json);return}if(a==="search"){let u=t.slice(2).join(" ");if(!u)throw Error("Usage: knowledge embeddings search <query>");let o=await s.semanticSearch({query:u,limit:n.limit,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o,message:`${o.results.length} semantic result(s)`},n.json);return}throw Error("Invalid embeddings action. Use 'status', 'index', or 'search'.")}if(r==="search"){let a=t.slice(1).join(" ");if(!a)throw Error("Usage: knowledge search <query>");if(n.context){let o=await s.retrieveContext({query:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...o,message:`${o.excerpts.length} context excerpt(s)`},n.json);return}let u=await s.search({query:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake});y({ok:!0,...u,message:`${u.results.length} search result(s)`},n.json);return}if(r==="web"){if((t[1]??"search")!=="search")throw Error("Invalid web action. Use 'search'.");let u=t.slice(2).join(" ");if(!u)throw Error("Usage: knowledge web search <query>");let o=await s.webSearch({query:u,limit:n.limit,modelRef:n.model,provider:n.provider,domains:n.domain,fake:n.fake,fileResults:n.fileResults});y({ok:!0,...o,message:`${o.sources.length} web source(s)`},n.json);return}if(r==="ask"||r==="build"){let a=t.slice(i).join(" ");if(!a)throw Error("Usage: knowledge ask <prompt>");let u=await s.runPrompt({prompt:a,limit:n.limit,semantic:n.semantic,modelRef:n.model,dimensions:n.dimensions,fake:n.fake,generate:n.generate,approveWrite:n.approveWrite});y({ok:!0,...u,message:u.generated?"Generated answer with citations":"Prepared citation context draft"},n.json);return}if(r==="providers"){let a=t[1]??"status";if(a==="status"){let u=s.providerStatus(),o=u.providers.filter((_)=>_.configured).length;y({ok:!0,...u,message:`${o}/${u.providers.length} provider credential(s) configured`},n.json);return}if(a==="models"){let u=s.modelRegistry();y({ok:!0,models:u,message:`${u.length} model alias(es)`},n.json);return}if(a==="check"){let u=t[2]??"default",o=H(u,s.config()),_=C(o),l=z(_.provider,s.config());y({ok:!0,target:u,model_ref:o,provider:_.provider,model:_.model,credential:l,message:`${_.provider} credentials configured`},n.json);return}throw Error("Invalid providers action. Use 'status', 'models', or 'check'.")}if(Ve(c),r==="add"){let a=t[1],u=t[2];if(!a||!u)throw Error("Usage: knowledge add <title> <content>");P(c,()=>{let o=U(c),_={id:Qe(),title:a,content:u,url:n.url??null,tags:n.tag?[n.tag]:[],created_at:new Date().toISOString(),updated_at:new Date().toISOString()};o.items.push(_),$(c,o),te("info","Item added",{id:_.id,title:_.title}),y({ok:!0,item:_,message:`Added ${_.id}`},n.json)});return}if(r==="list"){if(n.format!==void 0&&n.format!=="table"&&n.format!=="json")throw Error("Invalid --format value for list. Use 'table' or 'json'.");P(c,()=>{let a=U(c),u=Number.isFinite(n.page)&&n.page>0?n.page:1,o=Number.isFinite(n.limit)&&n.limit>0?n.limit:20,_=n.search?String(n.search).toLowerCase():"",l=n.tag?String(n.tag).toLowerCase():"",f=n.format==="table"||!n.json&&!n.format&&Ro(n),m=n.json||n.format==="json",E=a.items;if(n.archived)E=E.filter((T)=>T.archived===!0);else if(!n.includeArchived)E=E.filter((T)=>!T.archived);if(_)E=E.filter((T)=>T.title.toLowerCase().includes(_)||T.content.toLowerCase().includes(_));if(l)E=E.filter((T)=>T.tags&&T.tags.map((Be)=>Be.toLowerCase()).includes(l));let{sorted:h,sort:w,direction:k}=So(E,n),p=(u-1)*o,R=h.slice(p,p+o),v=Math.max(1,Math.ceil(h.length/o));if(m){y({ok:!0,page:u,limit:o,total:h.length,total_pages:v,sort:w,direction:k,items:R},!0);return}if(R.length===0){y(`No items found (search=${_||"none"}, tag=${l||"none"})`,!1);return}if(f){let T=(W)=>W,Be=`${T("ID")} ${T("TITLE")} ${T("CREATED")} ${T("URL")} ${T("TAGS")}`;console.log(Be);for(let W of R)console.log(`${W.id} ${T(W.title)} ${W.created_at} ${W.url?T(W.url):""} ${W.tags?.length?T(`[${W.tags.join(", ")}]`):""}`);console.log(`Page ${u}/${v} | showing ${R.length} of ${h.length} | sort=${w} ${k} | search=${_||"none"} | tag=${l||"none"}`)}else{for(let T of R)console.log(`${T.id} ${T.title} ${T.created_at}${T.url?` ${T.url}`:""}${T.tags?.length?` [${T.tags.join(", ")}]`:""}`);console.log(`Page ${u}/${v} | showing ${R.length} of ${h.length} | sort=${w} ${k} | search=${_||"none"} | tag=${l||"none"}`)}});return}if(r==="get"){he(n),P(c,()=>{let u=U(c).items.find((o)=>o.id===n.id||o.short_id===n.id);if(!u)throw Error(`Item not found: ${n.id}`);y({ok:!0,item:u,message:`${u.id}: ${u.title}`},n.json)});return}if(r==="update"){he(n),P(c,()=>{let a=U(c),u=a.items.findIndex((_)=>_.id===n.id||_.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u];if(n.title!==void 0)o.title=n.title;if(n.content!==void 0)o.content=n.content;if(n.url!==void 0)o.url=n.url;if(n.tag!==void 0){if(o.tags=o.tags||[],!o.tags.map((_)=>_.toLowerCase()).includes(n.tag.toLowerCase()))o.tags.push(n.tag)}o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,message:`Updated ${o.id}`},n.json)});return}if(r==="archive"||r==="restore"){he(n),P(c,()=>{let a=U(c),u=a.items.findIndex((_)=>_.id===n.id||_.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u];o.archived=r==="archive",o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,message:`${r==="archive"?"Archived":"Restored"} ${o.id}`},n.json)});return}if(r==="untag"){if(he(n),!n.tag)throw Error("Missing required --tag. Example: knowledge untag --id <id> -t <tag>");P(c,()=>{let a=U(c),u=a.items.findIndex((l)=>l.id===n.id||l.short_id===n.id);if(u===-1)throw Error(`Item not found: ${n.id}`);let o=a.items[u],_=o.tags?.length??0;o.tags=(o.tags??[]).filter((l)=>l.toLowerCase()!==n.tag.toLowerCase()),o.updated_at=new Date().toISOString(),a.items[u]=o,$(c,a),y({ok:!0,item:o,removed:_-o.tags.length,message:`Removed tag from ${o.id}`},n.json)});return}if(r==="upsert"){let a=n.title??t[1],u=n.content??t[2];P(c,()=>{let o=U(c),_=n.id?o.items.findIndex((m)=>m.id===n.id||m.short_id===n.id):-1,l=new Date().toISOString();if(_===-1){if(!a||!u)throw Error("New item requires title and content. Example: knowledge upsert <title> <content> [--id <id>]");let m=n.id??Qe(),E={id:m,short_id:At(m),title:a,content:u,url:n.url??null,tags:n.tag?[n.tag]:[],metadata:{},archived:!1,created_at:l,updated_at:l};o.items.push(E),$(c,o),y({ok:!0,created:!0,item:E,message:`Upserted ${E.id}`},n.json);return}let f=o.items[_];if(a!==void 0)f.title=a;if(u!==void 0)f.content=u;if(n.url!==void 0)f.url=n.url;if(n.tag!==void 0){if(f.tags=f.tags||[],!f.tags.map((m)=>m.toLowerCase()).includes(n.tag.toLowerCase()))f.tags.push(n.tag)}f.updated_at=l,o.items[_]=f,$(c,o),y({ok:!0,created:!1,item:f,message:`Upserted ${f.id}`},n.json)});return}if(r==="delete"){if(he(n),!n.yes)throw Error("Refusing delete without --yes. Re-run with: knowledge delete --id <id> --yes");P(c,()=>{let a=U(c),u=a.items.length;a.items=a.items.filter((_)=>_.id!==n.id&&_.short_id!==n.id);let o=u!==a.items.length;if($(c,a),!o)throw Error(`Item not found: ${n.id}`);te("info","Item deleted",{id:n.id}),y({ok:!0,deleted_id:n.id,message:`Deleted ${n.id}`},n.json)});return}if(r==="export"){let a=n.format??"json";if(a!=="json"&&a!=="jsonl")throw Error("Invalid --format. Use 'json' or 'jsonl'.");P(c,()=>{let u=U(c);if(a==="jsonl")for(let o of u.items)console.log(JSON.stringify(o));else y({ok:!0,items:u.items},n.json)});return}if(r==="prune"){if(!n.yes)throw Error("Refusing prune without --yes. Re-run with: knowledge prune --yes [--older-than <days>] [--empty]");P(c,()=>{let a=U(c),u=a.items.length;if(n.olderThan!==void 0){let _=new Date;_.setDate(_.getDate()-n.olderThan),a.items=a.items.filter((l)=>new Date(l.created_at)>=_)}if(n.empty)a.items=a.items.filter((_)=>_.content.trim().length>0);let o=u-a.items.length;$(c,a),te("info","Prune completed",{pruned:o,remaining:a.items.length}),y({ok:!0,pruned:o,remaining:a.items.length,message:`Pruned ${o} item(s)`},n.json)});return}if(r==="dedupe"){if(!n.yes)throw Error("Refusing dedupe without --yes. Re-run with: knowledge dedupe --yes [--json]");P(c,()=>{let a=U(c),u=new Set,o=a.items.length;a.items=a.items.filter((l)=>{let f=`${l.title}\x00${l.content}`;if(u.has(f))return!1;return u.add(f),!0});let _=o-a.items.length;$(c,a),te("info","Dedupe completed",{removed:_,remaining:a.items.length}),y({ok:!0,removed:_,remaining:a.items.length,message:`Dedupe removed ${_} duplicate(s)`},n.json)});return}if(r==="stats"){P(c,()=>{let a=U(c),u=a.items.filter((k)=>!k.archived),o=u.length,_=a.items.length-o,l=u.filter((k)=>k.url).length,f=u.filter((k)=>k.tags&&k.tags.length>0).length,m=o>0?u.map((k)=>k.created_at).sort()[0]:null,E=o>0?u.map((k)=>k.created_at).sort()[o-1]:null,h={};for(let k of u)for(let p of k.tags||[])h[p]=(h[p]||0)+1;let w=Object.entries(h).sort((k,p)=>p[1]-k[1]).slice(0,5).map(([k,p])=>({tag:k,count:p}));y({ok:!0,total:o,archived:_,with_url:l,with_tags:f,oldest:m,newest:E,top_tags:w,message:`${o} items | ${l} with URL | ${f} with tags`},n.json)});return}let d=bo(t[0]),g=d?` Did you mean '${d}'?`:"";throw te("warn","Unknown command",{input:t[0],suggestion:d}),Error(`Unknown command: ${t[0]}.${g} Run 'knowledge --help' for available commands.`)}if(import.meta.main)xo(process.argv.slice(2)).catch((e)=>{let t=e instanceof Error?e.message:String(e);te("error","CLI error",{message:t,stack:e instanceof Error?e.stack:void 0}),console.error(`Error: ${t}`),process.exitCode=1});export{bo as suggestCommand,So as sortItems,xo as run,Eo as parseArgs};