@hasna/knowledge 0.2.27 → 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.
Files changed (64) hide show
  1. package/README.md +140 -99
  2. package/bin/{open-knowledge-mcp.js → knowledge-mcp.js} +22 -15
  3. package/bin/{open-knowledge.js → knowledge.js} +5 -5
  4. package/dist/agent.d.ts +35 -0
  5. package/dist/artifact-store.d.ts +63 -0
  6. package/dist/auth.d.ts +35 -0
  7. package/dist/embeddings.d.ts +77 -0
  8. package/dist/index.d.ts +20 -0
  9. package/dist/index.js +5709 -0
  10. package/dist/knowledge-db.d.ts +27 -0
  11. package/dist/manifest-ingest.d.ts +35 -0
  12. package/dist/outbox-consume.d.ts +25 -0
  13. package/dist/provenance.d.ts +50 -0
  14. package/dist/providers.d.ts +89 -0
  15. package/dist/reindex.d.ts +37 -0
  16. package/dist/remote-client.d.ts +108 -0
  17. package/dist/retrieval.d.ts +71 -0
  18. package/dist/safety.d.ts +70 -0
  19. package/dist/sdk.d.ts +72 -0
  20. package/dist/search.d.ts +65 -0
  21. package/dist/service.d.ts +117 -0
  22. package/dist/source-ingest.d.ts +18 -0
  23. package/dist/source-ref.d.ts +30 -0
  24. package/dist/source-resolver.d.ts +92 -0
  25. package/dist/storage-contract.d.ts +106 -0
  26. package/dist/web-search.d.ts +40 -0
  27. package/dist/wiki-compiler.d.ts +67 -0
  28. package/dist/wiki-layout.d.ts +23 -0
  29. package/dist/workspace.d.ts +111 -0
  30. package/docs/architecture/ai-native-knowledge-base.md +16 -16
  31. package/docs/architecture/hosted-wrapper-responsibilities.md +5 -5
  32. package/docs/architecture/hybrid-semantic-search.md +12 -12
  33. package/docs/canonical-secrets-bootstrap-2026-06-08.md +1 -1
  34. package/docs/examples/company-wiki-workflow.md +19 -19
  35. package/docs/migration/json-to-sqlite.md +17 -17
  36. package/package.json +17 -10
  37. package/src/agent.ts +0 -367
  38. package/src/artifact-store.ts +0 -184
  39. package/src/auth.ts +0 -123
  40. package/src/cli.ts +0 -1184
  41. package/src/embeddings.ts +0 -516
  42. package/src/knowledge-db.ts +0 -354
  43. package/src/manifest-ingest.ts +0 -515
  44. package/src/mcp-http.js +0 -110
  45. package/src/mcp.js +0 -1503
  46. package/src/outbox-consume.ts +0 -463
  47. package/src/provenance.ts +0 -93
  48. package/src/providers.ts +0 -308
  49. package/src/reindex.ts +0 -260
  50. package/src/remote-client.ts +0 -268
  51. package/src/retrieval.ts +0 -326
  52. package/src/safety.ts +0 -265
  53. package/src/schema.js +0 -25
  54. package/src/search.ts +0 -510
  55. package/src/service.ts +0 -443
  56. package/src/source-ingest.ts +0 -268
  57. package/src/source-ref.ts +0 -104
  58. package/src/source-resolver.ts +0 -436
  59. package/src/storage-contract.ts +0 -346
  60. package/src/store.ts +0 -113
  61. package/src/web-search.ts +0 -330
  62. package/src/wiki-compiler.ts +0 -711
  63. package/src/wiki-layout.ts +0 -251
  64. package/src/workspace.ts +0 -251
@@ -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=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"?["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 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.27",description:"Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",type:"module",bin:{knowledge:"bin/open-knowledge.js","open-knowledge":"bin/open-knowledge.js","open-knowledge-mcp":"bin/open-knowledge-mcp.js"},files:["bin","src","docs","LICENSE","README.md"],scripts:{test:"bun test","test:cli":"bun test tests/cli.test.ts",build:"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",prepublishOnly:"bun run build",postinstall:"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:{"@aws-sdk/client-s3":"^3.1063.0","@aws-sdk/credential-providers":"^3.1063.0","@ai-sdk/anthropic":"^3.0.81","@ai-sdk/deepseek":"^2.0.35","@ai-sdk/openai":"^3.0.68","@modelcontextprotocol/sdk":"^1.29.0",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 To(){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 wo(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}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: 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"){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: 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((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: 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 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 '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};
@@ -0,0 +1,35 @@
1
+ import { type KnowledgeContextPack, type RetrievalOptions } from './retrieval';
2
+ export interface KnowledgePromptOptions extends Omit<RetrievalOptions, 'query'> {
3
+ prompt: string;
4
+ generate?: boolean;
5
+ approveWrite?: boolean;
6
+ now?: Date;
7
+ }
8
+ export interface KnowledgePromptResult {
9
+ run_id: string;
10
+ prompt: string;
11
+ generated: boolean;
12
+ provider: string;
13
+ model: string;
14
+ answer: string;
15
+ context: KnowledgeContextPack;
16
+ citations: KnowledgeContextPack['citations'];
17
+ proposed_wiki_updates: Array<{
18
+ kind: 'answer_note';
19
+ title: string;
20
+ citations: string[];
21
+ requires_approval: boolean;
22
+ }>;
23
+ write_policy: {
24
+ approved: boolean;
25
+ durable_writes_performed: false;
26
+ reason: string;
27
+ };
28
+ usage: {
29
+ input_tokens: number;
30
+ output_tokens: number;
31
+ cost_usd: number;
32
+ };
33
+ warnings: string[];
34
+ }
35
+ export declare function runKnowledgePrompt(options: KnowledgePromptOptions): Promise<KnowledgePromptResult>;
@@ -0,0 +1,63 @@
1
+ import type { KnowledgeConfig, KnowledgeWorkspace } from './workspace';
2
+ interface S3ClientLike {
3
+ send(command: unknown): Promise<any>;
4
+ }
5
+ export interface ArtifactWrite {
6
+ key: string;
7
+ body: string | Uint8Array;
8
+ content_type?: string;
9
+ metadata?: Record<string, string>;
10
+ }
11
+ export interface ArtifactStore {
12
+ readonly type: 'local' | 's3';
13
+ readonly canRead: boolean;
14
+ readonly canWrite: boolean;
15
+ put(entry: ArtifactWrite): Promise<{
16
+ key: string;
17
+ uri: string;
18
+ }>;
19
+ getText(key: string): Promise<string>;
20
+ exists(key: string): Promise<boolean>;
21
+ }
22
+ export declare function normalizeArtifactKey(key: string): string;
23
+ export declare class LocalArtifactStore implements ArtifactStore {
24
+ private readonly root;
25
+ readonly type: "local";
26
+ readonly canRead = true;
27
+ readonly canWrite = true;
28
+ constructor(root: string);
29
+ put(entry: ArtifactWrite): Promise<{
30
+ key: string;
31
+ uri: string;
32
+ }>;
33
+ getText(key: string): Promise<string>;
34
+ exists(key: string): Promise<boolean>;
35
+ }
36
+ export interface S3ArtifactStoreOptions {
37
+ bucket: string;
38
+ prefix?: string;
39
+ region?: string;
40
+ profile?: string;
41
+ max_attempts?: number;
42
+ server_side_encryption?: 'AES256' | 'aws:kms';
43
+ kms_key_id?: string;
44
+ client?: S3ClientLike;
45
+ }
46
+ export declare class S3ArtifactStore implements ArtifactStore {
47
+ private readonly options;
48
+ readonly type: "s3";
49
+ readonly canRead = true;
50
+ readonly canWrite = true;
51
+ private client?;
52
+ constructor(options: S3ArtifactStoreOptions);
53
+ private getClient;
54
+ private objectKey;
55
+ put(entry: ArtifactWrite): Promise<{
56
+ key: string;
57
+ uri: string;
58
+ }>;
59
+ getText(key: string): Promise<string>;
60
+ exists(key: string): Promise<boolean>;
61
+ }
62
+ export declare function createArtifactStore(config: KnowledgeConfig, workspace: KnowledgeWorkspace): ArtifactStore;
63
+ export {};
package/dist/auth.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ import type { KnowledgeConfig } from './workspace';
2
+ export interface KnowledgeAuthConfig {
3
+ api_key: string;
4
+ email?: string;
5
+ org_id?: string;
6
+ org_slug?: string;
7
+ user_id?: string;
8
+ api_url?: string;
9
+ created_at: string;
10
+ }
11
+ export interface KnowledgeAuthStatus {
12
+ authenticated: boolean;
13
+ source: 'env' | 'file' | 'none';
14
+ api_url: string;
15
+ auth_path: string;
16
+ email: string | null;
17
+ org_id: string | null;
18
+ org_slug: string | null;
19
+ user_id: string | null;
20
+ api_key_present: boolean;
21
+ }
22
+ export declare const DEFAULT_KNOWLEDGE_API_URL = "https://knowledge.hasna.xyz";
23
+ export declare function normalizeKnowledgeApiOrigin(apiUrl: string): string;
24
+ export declare function knowledgeAuthPath(env?: Record<string, string | undefined>): string;
25
+ export declare function resolveKnowledgeApiUrl(config?: KnowledgeConfig, env?: Record<string, string | undefined>): string;
26
+ export declare function getKnowledgeAuth(env?: Record<string, string | undefined>): KnowledgeAuthConfig | null;
27
+ export declare function saveKnowledgeAuth(auth: Omit<KnowledgeAuthConfig, 'created_at'> & {
28
+ created_at?: string;
29
+ }, env?: Record<string, string | undefined>): KnowledgeAuthConfig;
30
+ export declare function clearKnowledgeAuth(env?: Record<string, string | undefined>): boolean;
31
+ export declare function getKnowledgeApiKey(env?: Record<string, string | undefined>): {
32
+ apiKey: string | null;
33
+ source: KnowledgeAuthStatus['source'];
34
+ };
35
+ export declare function knowledgeAuthStatus(config?: KnowledgeConfig, env?: Record<string, string | undefined>): KnowledgeAuthStatus;
@@ -0,0 +1,77 @@
1
+ import { type AiProviderId } from './providers';
2
+ import { type KnowledgeProvenance } from './provenance';
3
+ import type { KnowledgeConfig } from './workspace';
4
+ export interface EmbeddingRuntimeOptions {
5
+ config?: KnowledgeConfig;
6
+ env?: Record<string, string | undefined>;
7
+ modelRef?: string;
8
+ dimensions?: number;
9
+ fake?: boolean;
10
+ batchSize?: number;
11
+ maxParallelCalls?: number;
12
+ }
13
+ export interface EmbeddingIndexOptions extends EmbeddingRuntimeOptions {
14
+ dbPath: string;
15
+ limit?: number;
16
+ sourceRevisionId?: string;
17
+ now?: Date;
18
+ }
19
+ export interface EmbeddingSearchOptions extends EmbeddingRuntimeOptions {
20
+ dbPath: string;
21
+ query: string;
22
+ limit?: number;
23
+ }
24
+ export interface EmbeddingUsage {
25
+ input_tokens: number;
26
+ }
27
+ export interface EmbeddingVectorResult {
28
+ provider: AiProviderId;
29
+ model: string;
30
+ dimensions: number;
31
+ vectors: number[][];
32
+ usage: EmbeddingUsage;
33
+ }
34
+ export interface EmbeddingIndexResult {
35
+ provider: AiProviderId;
36
+ model: string;
37
+ dimensions: number;
38
+ chunks_seen: number;
39
+ chunks_embedded: number;
40
+ embeddings_upserted: number;
41
+ vector_entries_upserted: number;
42
+ usage: EmbeddingUsage;
43
+ }
44
+ export interface EmbeddingStatusResult {
45
+ total_embeddings: number;
46
+ total_vector_entries: number;
47
+ indexes: Array<{
48
+ provider: string;
49
+ model: string;
50
+ dimensions: number;
51
+ entries: number;
52
+ updated_at: string | null;
53
+ }>;
54
+ }
55
+ export interface SemanticSearchResult {
56
+ provider: AiProviderId;
57
+ model: string;
58
+ dimensions: number;
59
+ query: string;
60
+ results: Array<{
61
+ chunk_id: string;
62
+ score: number;
63
+ text: string;
64
+ source_uri: string | null;
65
+ source_ref: string | null;
66
+ revision: string | null;
67
+ hash: string | null;
68
+ provenance: KnowledgeProvenance | null;
69
+ }>;
70
+ }
71
+ export declare const DEFAULT_EMBEDDING_MODEL_REF = "openai:text-embedding-3-small";
72
+ export declare const DEFAULT_EMBEDDING_DIMENSIONS = 1536;
73
+ export declare function resolveEmbeddingModelRef(modelRef?: string, config?: KnowledgeConfig): string;
74
+ export declare function embedTexts(texts: string[], options?: EmbeddingRuntimeOptions): Promise<EmbeddingVectorResult>;
75
+ export declare function indexKnowledgeEmbeddings(options: EmbeddingIndexOptions): Promise<EmbeddingIndexResult>;
76
+ export declare function embeddingIndexStatus(dbPath: string): EmbeddingStatusResult;
77
+ export declare function searchVectorIndex(options: EmbeddingSearchOptions): Promise<SemanticSearchResult>;
@@ -0,0 +1,20 @@
1
+ export { createKnowledgeClient, createKnowledgeSdk, type KnowledgeAskOptions, type KnowledgeAuthInput, type KnowledgeClient, type KnowledgeClientOptions, type KnowledgeContextOptions, type KnowledgeSearchOptions, type KnowledgeSetupOptions, type KnowledgeWebSearchOptions, } from './sdk.js';
2
+ export { createKnowledgeService, KnowledgeService, type KnowledgePathsResult, type KnowledgeServiceOptions, type KnowledgeSetupResult, } from './service.js';
3
+ export { HASNA_KNOWLEDGE_APP_PATH, HASNA_XYZ_KNOWLEDGE_CANONICAL, canonicalHasnaXyzKnowledgeStorage, defaultKnowledgeConfig, ensureKnowledgeWorkspace, globalKnowledgeHome, projectKnowledgeHome, readKnowledgeConfig, resolveScopedWorkspace, workspaceForHome, writeKnowledgeConfig, type KnowledgeConfig, type KnowledgeWorkspace, } from './workspace.js';
4
+ export { createArtifactStore, LocalArtifactStore, S3ArtifactStore, normalizeArtifactKey, type ArtifactStore, type ArtifactWrite, type S3ArtifactStoreOptions, } from './artifact-store.js';
5
+ export { artifactKindForKey, hashArtifactBody, resolveStorageContract, validateStorageConfig, type GeneratedStorageObject, type StorageArtifactClass, type StorageContract, type StorageValidationResult, } from './storage-contract.js';
6
+ export { parseSourceRef, catalogSourceUriForRef, revisionIdForSourceRef, isSupportedSourceRef, type BaseSourceRef, type FileSourceRef, type OpenFilesSourceRef, type S3SourceRef, type SourceRef, type SourceRefKind, type WebSourceRef, } from './source-ref.js';
7
+ export { hybridSearch, type HybridSearchEntry, type HybridSearchOptions, type HybridSearchResult, type SearchProvenance, type SearchResultKind, } from './search.js';
8
+ export { retrieveKnowledgeContext, type KnowledgeContextPack, type RetrievalCitation, type RetrievalExcerpt, type RetrievalGraphEvidence, type RetrievalOptions, type RerankedSearchEntry, } from './retrieval.js';
9
+ export { runKnowledgePrompt, type KnowledgePromptOptions, type KnowledgePromptResult, } from './agent.js';
10
+ export { DEFAULT_EMBEDDING_DIMENSIONS, DEFAULT_EMBEDDING_MODEL_REF, embedTexts, embeddingIndexStatus, indexKnowledgeEmbeddings, resolveEmbeddingModelRef, searchVectorIndex, type EmbeddingIndexOptions, type EmbeddingIndexResult, type EmbeddingRuntimeOptions, type EmbeddingSearchOptions, type EmbeddingStatusResult, type EmbeddingUsage, type EmbeddingVectorResult, type SemanticSearchResult, } from './embeddings.js';
11
+ export { createAiSdkProviderRegistry, languageModelFor, listModelRegistry, modelAliases, parseModelRef, providerCredentialStatus, providerSettings, providerStatus, resolveModelRef, type AiProviderId, type AiProviderRuntimeOptions, type AiProviderSettings, type AiProvidersConfig, type ModelCapabilities, type ModelRegistryEntry, type ProviderCredentialStatus, type ProviderStatusResult, } from './providers.js';
12
+ export { runProviderWebSearch, type WebSearchOptions, type WebSearchResult, type WebSearchSource, } from './web-search.js';
13
+ export { compileWikiPage, fileAnswerToWiki, lintWiki, type WikiAnswerFileOptions, type WikiAnswerFileResult, type WikiCompileOptions, type WikiCompileResult, type WikiLintIssue, type WikiLintResult, } from './wiki-compiler.js';
14
+ export { ingestOpenFilesManifest, ingestOpenFilesManifestItems, type ManifestIngestOptions, type ManifestIngestResult, type ManifestItemsIngestOptions, type ManifestObject, } from './manifest-ingest.js';
15
+ export { ingestSourceRef, type SourceIngestOptions, type SourceIngestResult, } from './source-ingest.js';
16
+ export { resolveOpenFilesSource, type ResolvedSourceChunk, type ResolvedSourceCitation, type SourceResolveOptions, type SourceResolveResult, type SourceResolverEvidence, } from './source-resolver.js';
17
+ export { consumeOpenFilesOutbox, type OutboxConsumeOptions, type OutboxConsumeResult, } from './outbox-consume.js';
18
+ export { enqueueMissingEmbeddings, refreshEmbeddingIndex, reindexHealth, type ReindexEmbeddingsResult, type ReindexEnqueueResult, type ReindexHealthResult, type ReindexRuntimeOptions, } from './reindex.js';
19
+ export { DEFAULT_KNOWLEDGE_API_URL, clearKnowledgeAuth, getKnowledgeApiKey, getKnowledgeAuth, knowledgeAuthPath, knowledgeAuthStatus, normalizeKnowledgeApiOrigin, resolveKnowledgeApiUrl, saveKnowledgeAuth, type KnowledgeAuthConfig, type KnowledgeAuthStatus, } from './auth.js';
20
+ export { REMOTE_KNOWLEDGE_CONTRACT_VERSION, RemoteKnowledgeClient, knowledgeRegistryContract, normalizeRemoteKnowledgeRunContract, type RemoteKnowledgeArtifact, type RemoteKnowledgeArtifactContract, type RemoteKnowledgeLogEntry, type RemoteKnowledgePromptRequest, type RemoteKnowledgeRegistryContract, type RemoteKnowledgeRunContract, type RemoteKnowledgeRunStatus, type RemoteKnowledgeSearchRequest, type RemoteKnowledgeSourceContract, type RemoteKnowledgeSyncRequest, } from './remote-client.js';