@hasna/knowledge 0.2.23 → 0.2.25
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.
|
@@ -13660,7 +13660,7 @@ import { existsSync as existsSync8, readFileSync as readFileSync8, writeFileSync
|
|
|
13660
13660
|
// package.json
|
|
13661
13661
|
var package_default = {
|
|
13662
13662
|
name: "@hasna/knowledge",
|
|
13663
|
-
version: "0.2.
|
|
13663
|
+
version: "0.2.25",
|
|
13664
13664
|
description: "Agent-friendly local knowledge CLI with JSON output, pagination, and safe destructive actions",
|
|
13665
13665
|
type: "module",
|
|
13666
13666
|
bin: {
|
package/bin/open-knowledge.js
CHANGED
|
@@ -622,7 +622,7 @@ 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`,[u,"wiki/README.md","Wiki",s.uri,s.hash??null,"active",JSON.stringify({artifact_key:s.key,provenance:Et(s)}),r,r]),lo(e,u,"Wiki",s,Jn(),r)}}function _o(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 Yn{options;ensuredWorkspace;cachedConfig;constructor(e={}){this.options=e}get scope(){return this.options.scope??"global"}get workspace(){return this.ensuredWorkspace??wt(this.options.scope,this.options.cwd)}ensureWorkspace(){if(!this.ensuredWorkspace)this.ensuredWorkspace=bt(this.workspace.home);return this.ensuredWorkspace}jsonStorePath(){return this.ensureWorkspace().jsonStorePath}config(){if(!this.cachedConfig){let e=this.ensureWorkspace();this.cachedConfig=vt(e.configPath)}return this.cachedConfig}safetyPolicy(){return pn(this.config(),this.ensureWorkspace())}artifactStore(){return Lt(this.config(),this.ensureWorkspace())}storageContract(){return Kn(this.config(),this.ensureWorkspace(),this.scope)}validateStorage(){return gt(this.config(),this.ensureWorkspace())}setup(e={}){let t=this.ensureWorkspace(),n=this.config(),r=_o(e.mode)??n.mode,i=e.apiUrl?$(e.apiUrl):n.hosted?.api_url?$(n.hosted.api_url):null,s={...n,mode:r,hosted:{...n.hosted??{},...i?{api_url:i}:{}}};return St(t.configPath,s),this.cachedConfig=s,{ok:!0,mode:r,api_url:s.hosted?.api_url??null,config_path:t.configPath,next:r==="hosted"?["open-knowledge auth login --api-key <key>","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 Dt({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 Ut(e)}remoteContract(){let e=this.storageContract();return An({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),Ot(e.knowledgeDbPath)}async initWiki(){let e=this.ensureWorkspace();x(e.knowledgeDbPath);let t=await zn(this.artifactStore()),n=b(e.knowledgeDbPath);try{ge(n,t.artifacts),Gn(n,t.artifacts)}finally{n.close()}return t}async compileWiki(e={}){let t=this.ensureWorkspace();return qn({...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 Hn({dbPath:t.knowledgeDbPath,store:this.artifactStore(),prompt:e.prompt,answer:e.answer,context:n,approveWrite:e.approveWrite})}lintWiki(){let e=this.ensureWorkspace();return Bn({dbPath:e.knowledgeDbPath})}async ingestManifest(e){let t=this.ensureWorkspace();return yn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}async ingestSource(e,t){let n=this.ensureWorkspace();return vn({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t,config:this.config(),safetyPolicy:this.safetyPolicy()})}async resolveSource(e,t={}){let n=this.ensureWorkspace();return Ke({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t.purpose,limit:t.limit,safetyPolicy:this.safetyPolicy()})}async consumeOutbox(e){let t=this.ensureWorkspace();return kn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}reindexHealth(e={}){let t=this.ensureWorkspace();return Rn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}enqueueReindex(e={}){let t=this.ensureWorkspace();return ft({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async refreshEmbeddings(e={}){let t=this.ensureWorkspace();return xn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}providerStatus(e=process.env){return $t(this.config(),e)}modelRegistry(){return rt(this.config())}embeddingStatus(){let e=this.ensureWorkspace();return Yt(e.knowledgeDbPath)}async indexEmbeddings(e={}){let t=this.ensureWorkspace();return Te({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async semanticSearch(e){let t=this.ensureWorkspace();return Re({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async search(e){let t=this.ensureWorkspace();return Ae({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async retrieveContext(e){let t=this.ensureWorkspace();return Le({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async runPrompt(e){let t=this.ensureWorkspace();return un({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async webSearch(e){let t=this.ensureWorkspace();return Pn({...e,dbPath:t.knowledgeDbPath,config:this.config(),safetyPolicy:this.safetyPolicy()})}}function Vn(e={}){return new Yn(e)}import{basename as go}from"path";var pe={name:"@hasna/knowledge",version:"0.2.23",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 Qn={debug:0,info:1,warn:2,error:3},po=()=>{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 ee(e,t,n){if(Qn[e]<Qn[po()])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 Zn=["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"],er={ls:"list",rm:"delete",edit:"update",unarchive:"restore",knowledge:"ask"};function mo(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"--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 ho(e){if(!e)return"";return er[e]??e}function Eo(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 ko(e){if(!e)return"";let t=[...Zn,...Object.keys(er)],n="",r=Number.POSITIVE_INFINITY;for(let i of t){let s=Eo(e,i);if(s<r)r=s,n=i}return r<=3?n:""}function yo(){return go(process.argv[1]??"")==="knowledge"}function bo(){console.log(`open-knowledge - local agent knowledge store
|
|
625
|
+
updated_at = excluded.updated_at`,[u,"wiki/README.md","Wiki",s.uri,s.hash??null,"active",JSON.stringify({artifact_key:s.key,provenance:Et(s)}),r,r]),lo(e,u,"Wiki",s,Jn(),r)}}function _o(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 Yn{options;ensuredWorkspace;cachedConfig;constructor(e={}){this.options=e}get scope(){return this.options.scope??"global"}get workspace(){return this.ensuredWorkspace??wt(this.options.scope,this.options.cwd)}ensureWorkspace(){if(!this.ensuredWorkspace)this.ensuredWorkspace=bt(this.workspace.home);return this.ensuredWorkspace}jsonStorePath(){return this.ensureWorkspace().jsonStorePath}config(){if(!this.cachedConfig){let e=this.ensureWorkspace();this.cachedConfig=vt(e.configPath)}return this.cachedConfig}safetyPolicy(){return pn(this.config(),this.ensureWorkspace())}artifactStore(){return Lt(this.config(),this.ensureWorkspace())}storageContract(){return Kn(this.config(),this.ensureWorkspace(),this.scope)}validateStorage(){return gt(this.config(),this.ensureWorkspace())}setup(e={}){let t=this.ensureWorkspace(),n=this.config(),r=_o(e.mode)??n.mode,i=e.apiUrl?$(e.apiUrl):n.hosted?.api_url?$(n.hosted.api_url):null,s={...n,mode:r,hosted:{...n.hosted??{},...i?{api_url:i}:{}}};return St(t.configPath,s),this.cachedConfig=s,{ok:!0,mode:r,api_url:s.hosted?.api_url??null,config_path:t.configPath,next:r==="hosted"?["open-knowledge auth login --api-key <key>","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 Dt({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 Ut(e)}remoteContract(){let e=this.storageContract();return An({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),Ot(e.knowledgeDbPath)}async initWiki(){let e=this.ensureWorkspace();x(e.knowledgeDbPath);let t=await zn(this.artifactStore()),n=b(e.knowledgeDbPath);try{ge(n,t.artifacts),Gn(n,t.artifacts)}finally{n.close()}return t}async compileWiki(e={}){let t=this.ensureWorkspace();return qn({...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 Hn({dbPath:t.knowledgeDbPath,store:this.artifactStore(),prompt:e.prompt,answer:e.answer,context:n,approveWrite:e.approveWrite})}lintWiki(){let e=this.ensureWorkspace();return Bn({dbPath:e.knowledgeDbPath})}async ingestManifest(e){let t=this.ensureWorkspace();return yn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}async ingestSource(e,t){let n=this.ensureWorkspace();return vn({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t,config:this.config(),safetyPolicy:this.safetyPolicy()})}async resolveSource(e,t={}){let n=this.ensureWorkspace();return Ke({dbPath:n.knowledgeDbPath,sourceRef:e,purpose:t.purpose,limit:t.limit,safetyPolicy:this.safetyPolicy()})}async consumeOutbox(e){let t=this.ensureWorkspace();return kn({dbPath:t.knowledgeDbPath,input:e,config:this.config(),safetyPolicy:this.safetyPolicy()})}reindexHealth(e={}){let t=this.ensureWorkspace();return Rn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}enqueueReindex(e={}){let t=this.ensureWorkspace();return ft({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async refreshEmbeddings(e={}){let t=this.ensureWorkspace();return xn({...e,dbPath:t.knowledgeDbPath,config:this.config()})}providerStatus(e=process.env){return $t(this.config(),e)}modelRegistry(){return rt(this.config())}embeddingStatus(){let e=this.ensureWorkspace();return Yt(e.knowledgeDbPath)}async indexEmbeddings(e={}){let t=this.ensureWorkspace();return Te({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async semanticSearch(e){let t=this.ensureWorkspace();return Re({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async search(e){let t=this.ensureWorkspace();return Ae({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async retrieveContext(e){let t=this.ensureWorkspace();return Le({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async runPrompt(e){let t=this.ensureWorkspace();return un({...e,dbPath:t.knowledgeDbPath,config:this.config()})}async webSearch(e){let t=this.ensureWorkspace();return Pn({...e,dbPath:t.knowledgeDbPath,config:this.config(),safetyPolicy:this.safetyPolicy()})}}function Vn(e={}){return new Yn(e)}import{basename as go}from"path";var pe={name:"@hasna/knowledge",version:"0.2.25",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 Qn={debug:0,info:1,warn:2,error:3},po=()=>{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 ee(e,t,n){if(Qn[e]<Qn[po()])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 Zn=["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"],er={ls:"list",rm:"delete",edit:"update",unarchive:"restore",knowledge:"ask"};function mo(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"--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 ho(e){if(!e)return"";return er[e]??e}function Eo(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 ko(e){if(!e)return"";let t=[...Zn,...Object.keys(er)],n="",r=Number.POSITIVE_INFINITY;for(let i of t){let s=Eo(e,i);if(s<r)r=s,n=i}return r<=3?n:""}function yo(){return go(process.argv[1]??"")==="knowledge"}function bo(){console.log(`open-knowledge - local agent knowledge store
|
|
626
626
|
|
|
627
627
|
Usage:
|
|
628
628
|
open-knowledge <command> [options]
|
|
@@ -43,6 +43,13 @@ The future hosted/SaaS wrapper owns:
|
|
|
43
43
|
The OSS package must stay useful without a hosted account. Hosted mode should be
|
|
44
44
|
an optional remote client over explicit API contracts.
|
|
45
45
|
|
|
46
|
+
The detailed hosted boundary is specified in
|
|
47
|
+
[`hosted-wrapper-responsibilities.md`](./hosted-wrapper-responsibilities.md).
|
|
48
|
+
That document is the source of truth for responsibilities that must stay out of
|
|
49
|
+
the OSS package, including tenants, ACL enforcement, connector credentials,
|
|
50
|
+
bucket provisioning, secrets, queues, billing, admin controls, observability, and
|
|
51
|
+
the hosted web UI.
|
|
52
|
+
|
|
46
53
|
The local hosted-aware contract follows the `open-skills` pattern: `mode` is
|
|
47
54
|
`local` by default, `setup --mode hosted` records `hosted.api_url`, env vars
|
|
48
55
|
`KNOWLEDGE_API_URL` and `KNOWLEDGE_API_KEY` can override local config, and
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Hosted Wrapper Responsibilities
|
|
2
|
+
|
|
3
|
+
`open-knowledge` stays local-first and open source. A future hosted/SaaS wrapper
|
|
4
|
+
can implement remote APIs around the same contracts, but tenant state,
|
|
5
|
+
infrastructure ownership, and commercial controls must live outside this
|
|
6
|
+
package.
|
|
7
|
+
|
|
8
|
+
## Boundary
|
|
9
|
+
|
|
10
|
+
The OSS package owns:
|
|
11
|
+
|
|
12
|
+
- Local CLI and MCP behavior.
|
|
13
|
+
- `.hasna/apps/knowledge` workspaces.
|
|
14
|
+
- Local SQLite schema, local artifact catalog, generated wiki artifacts, local
|
|
15
|
+
vector rows, run ledgers, and BYOK provider calls.
|
|
16
|
+
- Source refs, derived chunks, citations, provenance, and read-only resolver
|
|
17
|
+
contracts.
|
|
18
|
+
- Remote client shapes for `registry`, `search`, `ask`, `build`, `sync`,
|
|
19
|
+
`run_status`, `run_logs`, and `run_artifacts`.
|
|
20
|
+
|
|
21
|
+
The hosted wrapper owns:
|
|
22
|
+
|
|
23
|
+
- Tenants, users, orgs, projects, memberships, roles, invitations, sessions, API
|
|
24
|
+
keys, and service accounts.
|
|
25
|
+
- Per-tenant permission checks before retrieval, generation, web search,
|
|
26
|
+
artifact reads, artifact writes, and source sync.
|
|
27
|
+
- Hosted databases, object storage, queue infrastructure, workers, secret
|
|
28
|
+
storage, web UI, billing, rate limits, moderation, observability, and admin
|
|
29
|
+
operations.
|
|
30
|
+
|
|
31
|
+
Local mode must not require hosted identity, billing, queue workers, or hosted
|
|
32
|
+
object storage. Hosted mode is an explicit remote boundary selected through
|
|
33
|
+
`open-knowledge setup --mode hosted` plus `KNOWLEDGE_API_URL` and
|
|
34
|
+
`KNOWLEDGE_API_KEY`.
|
|
35
|
+
|
|
36
|
+
## Identity And Access
|
|
37
|
+
|
|
38
|
+
The hosted wrapper should model:
|
|
39
|
+
|
|
40
|
+
- `users`: human accounts, verified emails, auth identities, MFA state, disabled
|
|
41
|
+
state, and profile metadata.
|
|
42
|
+
- `orgs`: billing/legal tenants, org slugs, data residency settings, default
|
|
43
|
+
retention policies, and owner/admin contacts.
|
|
44
|
+
- `projects`: knowledge workspaces under an org, project slugs, connected
|
|
45
|
+
source scopes, default model/search settings, and artifact storage policy.
|
|
46
|
+
- `memberships`: user to org/project role assignments.
|
|
47
|
+
- `api_keys`: scoped keys for CLI, MCP, CI, workers, and web UI sessions.
|
|
48
|
+
- `service_accounts`: non-human actors for ingestion, sync, indexing, and
|
|
49
|
+
scheduled maintenance.
|
|
50
|
+
|
|
51
|
+
Permission checks must happen before context assembly. The wrapper should never
|
|
52
|
+
retrieve broad context and filter after generation. The retrieval API should
|
|
53
|
+
accept caller identity, project id, requested purpose, source refs, and requested
|
|
54
|
+
operations, then return only authorized source chunks, generated artifacts, and
|
|
55
|
+
citations.
|
|
56
|
+
|
|
57
|
+
## Open-Files Integration
|
|
58
|
+
|
|
59
|
+
`open-files` remains the source of truth for raw source bytes. The hosted wrapper
|
|
60
|
+
should own connector orchestration and source sync:
|
|
61
|
+
|
|
62
|
+
- Google Drive, Slack, GitHub, Notion, S3, local-upload, web crawl, and future
|
|
63
|
+
connector credentials.
|
|
64
|
+
- Connector OAuth flows, refresh tokens, webhook registrations, cursor state,
|
|
65
|
+
backoff, retries, and error recovery.
|
|
66
|
+
- Source snapshots, immutable object ids, revisions, hashes, MIME metadata,
|
|
67
|
+
extracted text refs, ACL metadata, and change outboxes.
|
|
68
|
+
- Read-only resolver APIs that expose derived extracted text or allowed chunks
|
|
69
|
+
to `open-knowledge` without exposing storage credentials.
|
|
70
|
+
|
|
71
|
+
`open-knowledge` should continue to consume manifests, source refs, and outbox
|
|
72
|
+
events. It should not own connector credentials or raw source object lifecycle.
|
|
73
|
+
|
|
74
|
+
## Storage And Secrets
|
|
75
|
+
|
|
76
|
+
The hosted wrapper should provision and enforce:
|
|
77
|
+
|
|
78
|
+
- Per-org/project generated-artifact prefixes in S3 or another object store.
|
|
79
|
+
- Bucket policies, KMS keys, retention rules, lifecycle rules, replication, and
|
|
80
|
+
object lock settings where required.
|
|
81
|
+
- Secrets for provider keys, connector keys, AWS roles, RDS URLs, webhook
|
|
82
|
+
secrets, and encryption material.
|
|
83
|
+
- Migration aliases from legacy bucket and secret names to canonical names.
|
|
84
|
+
|
|
85
|
+
The OSS package may know a storage contract, bucket name, prefix, region, and
|
|
86
|
+
profile. It must not contain tenant secret values, connector credentials, RDS
|
|
87
|
+
passwords, hosted KMS key material, or privileged AWS role assumptions.
|
|
88
|
+
|
|
89
|
+
Generated artifacts are safe to sync remotely only when they remain derived:
|
|
90
|
+
wiki pages, index shards, schema files, logs, exports, run payloads, embeddings,
|
|
91
|
+
and citation metadata. Raw source bytes stay in `open-files`.
|
|
92
|
+
|
|
93
|
+
## Remote Jobs
|
|
94
|
+
|
|
95
|
+
The wrapper should implement durable jobs for:
|
|
96
|
+
|
|
97
|
+
- Manifest import and source sync from `open-files`.
|
|
98
|
+
- Extraction and redaction refresh.
|
|
99
|
+
- Embedding index refresh and stale-revision invalidation.
|
|
100
|
+
- Provider-native web search with audit logs and source capture.
|
|
101
|
+
- Wiki compile, answer filing, lint, and maintenance runs.
|
|
102
|
+
- Artifact sync between local clients and hosted storage.
|
|
103
|
+
- Remote search, ask, and build workflows.
|
|
104
|
+
|
|
105
|
+
Jobs should expose the same run contract as the local package: status, prompt or
|
|
106
|
+
query, provider/model, usage, citations, artifacts, events, logs, errors,
|
|
107
|
+
timestamps, and cost metadata. Workers should be idempotent and keyed by source
|
|
108
|
+
revision, artifact hash, or run id where possible.
|
|
109
|
+
|
|
110
|
+
## API Surface
|
|
111
|
+
|
|
112
|
+
The wrapper should implement the contract printed by:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
open-knowledge remote contracts --scope project --json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Required endpoint families:
|
|
119
|
+
|
|
120
|
+
- `registry`: service capabilities, contract version, source contract, artifact
|
|
121
|
+
contract, and limits.
|
|
122
|
+
- `search`: permission-aware hybrid retrieval.
|
|
123
|
+
- `ask`: retrieval plus answer generation.
|
|
124
|
+
- `build`: retrieval plus generated artifact proposals or approved writes.
|
|
125
|
+
- `sync`: source/artifact synchronization.
|
|
126
|
+
- `runs`: status, logs, events, usage, and artifacts.
|
|
127
|
+
- `artifacts`: generated artifact reads and writes with policy checks.
|
|
128
|
+
|
|
129
|
+
The web UI should use the same API surface as CLI/MCP clients. It should not
|
|
130
|
+
gain hidden write paths that bypass approval gates, source permission checks, or
|
|
131
|
+
run ledgers.
|
|
132
|
+
|
|
133
|
+
## Billing, Limits, And Abuse Controls
|
|
134
|
+
|
|
135
|
+
The hosted wrapper owns:
|
|
136
|
+
|
|
137
|
+
- Plan limits for seats, projects, sources, storage, embeddings, web search,
|
|
138
|
+
provider tokens, and scheduled jobs.
|
|
139
|
+
- Per-user, per-org, per-project, and per-key rate limits.
|
|
140
|
+
- Provider cost attribution and billing events.
|
|
141
|
+
- Abuse detection for web search, provider calls, bulk exports, connector syncs,
|
|
142
|
+
and artifact downloads.
|
|
143
|
+
- Admin controls to pause projects, rotate keys, disable connectors, revoke API
|
|
144
|
+
keys, and quarantine generated artifacts.
|
|
145
|
+
|
|
146
|
+
Local OSS mode may report provider usage, but it must not require billing.
|
|
147
|
+
|
|
148
|
+
## Audit And Observability
|
|
149
|
+
|
|
150
|
+
The hosted wrapper should record:
|
|
151
|
+
|
|
152
|
+
- Authentication and API-key events.
|
|
153
|
+
- Source connector reads, source resolver reads, and source permission denials.
|
|
154
|
+
- Search, ask, build, compile, lint, web-search, sync, and export runs.
|
|
155
|
+
- Generated artifact writes, approvals, rejections, and rollbacks.
|
|
156
|
+
- Admin and moderation actions.
|
|
157
|
+
- Worker retries, dead-letter events, queue latency, token usage, cost, and
|
|
158
|
+
storage growth.
|
|
159
|
+
|
|
160
|
+
Local run ledgers and audit events remain useful for offline workflows. Hosted
|
|
161
|
+
audit logs should add tenant identity, actor identity, IP/user-agent metadata,
|
|
162
|
+
request ids, and retention controls.
|
|
163
|
+
|
|
164
|
+
## Non-Goals For OSS
|
|
165
|
+
|
|
166
|
+
The OSS package should not implement:
|
|
167
|
+
|
|
168
|
+
- Hosted user/org/project management.
|
|
169
|
+
- Billing, plans, commercial rate limits, or invoices.
|
|
170
|
+
- Hosted connector OAuth flows or connector credential storage.
|
|
171
|
+
- Shared multi-tenant ACL enforcement.
|
|
172
|
+
- Hosted queue workers, RDS provisioning, bucket provisioning, KMS management,
|
|
173
|
+
or admin/moderation workflows.
|
|
174
|
+
- A privileged web UI write path.
|
|
175
|
+
|
|
176
|
+
The OSS package can expose the contracts and local behavior needed to make those
|
|
177
|
+
systems straightforward to build on top.
|