Local-first, agent-friendly Markdown knowledge base with a cross-platform CLI and web editor
AI Security Review
scanned 1mo ago · by lpm-firewall-ai
The source confirms an automatic agent-skill maintenance path during normal CLI startup, but not a malicious npm lifecycle chain or covert exfiltration. Classify as a warning for agent-extension lifecycle risk rather than a publish block.
The user runs `ok start` or enables semantic search with an API key.
Impact
It can alter installed agent skill content and, when enabled, disclose indexed content to the configured provider.
Mechanism
CLI-driven agent-skill maintenance and opt-in embeddings requests.
AI rationale
The source confirms an automatic agent-skill maintenance path during normal CLI startup, but not a malicious npm lifecycle chain or covert exfiltration. Classify as a warning for agent-extension lifecycle risk rather than a publish block.
Evidence
dist/cli.mjsdist/index.mjs.agents/skills
Network endpoints1
api.openai.com/v1
Decision evidence
public snapshot
AI called this Suspicious at 87.0% confidence as Dangerous Capability with medium false-positive risk.
Evidence for warning
The CLI automatically refreshes bundled skill files when the user runs `ok start`.
Its skill-repair code can write into an existing `.agents/skills` directory.
Optional semantic search sends queries and matching document content to the configured embeddings provider.
Evidence against
The manifest has no preinstall, install, or postinstall lifecycle hook.
The skill writer requires an existing agent directory rather than creating one.
Embeddings egress is disabled by default and requires a configured API key.
1import{i as e,o as t,t as n}from"./rolldown-runtime-tZXQYakl.mjs";import{Ad as r,Hu as i,Id as a,Md as o,Nd as s,Nl as c,Pd as l,ju as u}from"./md-manager-BGnqyqi1-2OuNJ75u.mjs";im...
L2: `),B(()=>t?.onBackendSelected?.({backend:`keyring`})),new ze(new Re(t?.onKeychainRead),new V(e))}catch(n){let r=n instanceof Error?`${n.name}: ${n.message}`:String(n);return proces...
1import{t as e}from"./chunk-DXB73IDG-MLBj3lvC.mjs";function t(){let e=[{prop:`Function`,target:globalThis,violationType:`function_constructor`,strategy:`throw`,reason:`Function cons...
L2: `);n.register(`data:text/javascript,${encodeURIComponent(e)}`),i.importHooksRegistered=!0}}catch(e){console.debug(`[DefenseInDepthBox] Could not register import() hooks:`,e instanc...
1import{o as e}from"./rolldown-runtime-tZXQYakl.mjs";import{Es as t,Gc as n,Hd as r,Ls as i,Mn as a,Nn as o,To as s,Vn as c,Wc as l,ju as u,qc as d,xc as ee}from"./md-manager-BGnqyq...
L2: `);y.addBuffer(Buffer.from(M,`utf8`),`README.md`),y.end();let N=le(r);return y.outputStream.pipe(N),await new Promise((e,t)=>{N.on(`close`,e),N.on(`error`,t)}),i?.info({bundlePath:...
...
L7: `)?`
L8: `:``;q(e,`${JSON.stringify(r,null,2)}${i}`)}catch{let r=mt(n,t.contentDir);r!==n&&q(e,r)}}function yt(e,t){let n=W(e,`utf-8`),r=mt(n,t.contentDir);r!==n&&q(e,r)}function bt(e){try{...
L9: `)}\n`:null}catch{return null}}function Kt(e){let t=z(e,`.git`,`ok`);if(!H(t))return null;let n=I(`git`,[`-C`,t,`log`,`--oneline`,`-50`],C({encoding:`utf-8`,timeout:2e3}));return n...
High
Same File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
•Manifest-reachable source captures an API credential, sends it to a fixed unofficial gateway, and persists that redirection in agent or shell configuration.
dist/cli.mjs:
import{o as e}from"./rolldown-runtime-tZXQYakl.mjs";import{$a as t,Ec as n,Gu as r,Hd as i,Iu as a,Kc as o,Ld as s,Lo as c,Ma as l,Ml as u,Nd as d,Nl as f,Pa as p,Ps as m,Qc as h,Q...
`)}const ki={out:e=>process.stdout.write(`${e}\n`),err:e=>process.stderr.write(`${e}\n`)};function Ai(e){return new A(`audit`).description(`Unified validation audit (markdown lint ...
`)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function Ii(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>r.push(...
`)}var ha=class extends Error{constructor(e,t,n){super(ma(n)),this.request=e,
High
Credential Redirect Persistence
Manifest-reachable source sends a prompted API credential to a fixed unofficial gateway and persists the redirection.
20*/
L21: var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,...
L22: changing to the minimum size of: 2`),this._maxSize=2)}record(e){this.updateByIncrement(e,1)}setStartTime(e){this.startTime=e}toPointValue(){return{hasMinMax:this._recordMinMax,min:...
L23: \t- OR - create a new view with the name ${e.name} and description '${e.description}' and InstrumentSelector ${r}
...
L31: causes have become circular...`;let o=r(e);return o?(t.add(e),a+`
L32: caused by: `+i(o,t)):a},a=e=>i(e,new Set),o=(e,t,i)=>{if(!n(e))return``;let a=i?``:e.message||``;if(t.has(e))return a+`: ...`;let s=r(e);if(s){t.add(e);let n=typeof e.cause==`funct...
L33: `:`
High
Command Output Exfiltration
Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.
1Cross-file remote execution chain: dist/dist-Dp3k14aI.mjs spawns dist/chunk-5QMZ5MUS-BuB3i_B5.mjs; helper contains network access plus dynamic code execution.
L1: import{a as e,i as t,n,o as r,r as i,t as a}from"./rolldown-runtime-tZXQYakl.mjs";import{$ as o,$a as s,$c as c,$i as l,$l as u,$n as d,$o as f,$r as p,$s as m,$t as h,$u as g,A as...
L2: /**
...
L10: *
L11: * http://www.apache.org/licenses/LICENSE-2.0
L12: *
...
L21: var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,...
L22: changing to the minimum size of: 2`),this._maxSize=2)}record(e){this.updateByIncrement(e,1)}setStartTime(e){this.startTime=e}toPointValue(){return{hasMinMax:this._recordMinMax
High
Cross File Remote Execution Context
Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.
2contains invisible/control Unicode U+200B (zero width space)
आपके बदलाव सहेजे नहीं जाएंगे!`,localStorageQuotaExceeded:``},o={unsupportedFileType:`असमर्थित फाइल प्रकार`,imageInsertError:`प्रतिमा सन्निवेश नहीं की जा सकी. पुनः प्रयत्न करे...`,fileTooBig:`फ़ाइल ज़रूरत से ज़्यादा बड़ी हैं. अधिकतम अनुमित प
Critical
Trojan Source Unicode
Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.
1import{i as e,o as t,t as n}from"./rolldown-runtime-tZXQYakl.mjs";import{Ad as r,Hu as i,Id as a,Md as o,Nd as s,Nl as c,Pd as l,ju as u}from"./md-manager-BGnqyqi1-2OuNJ75u.mjs";import{Cn as d,Eo as f,In as p,Ki as m,Mo as h,Zn as g,_o as _,jo as v,m as y,no as ee}from"./dist-Dp3k14aI.mjs";import{A as b,L as te,M as x,N as S,O as C,Q as ne,T as re,Y as w,ct as ie,d as ae,et as oe,f as se,it as ce,j as le,k as ue,nt as de,o as fe,q as pe,rt as me,st as he,tt as ge,ut as _e,v as ve,w as ye,x as be,y as xe}from"./init-Qrsvh-gM.mjs";import{t as Se}from"./is-object-BGze3w87.mjs";import{t as Ce}from ...
4`)}:{state:`unreadable`,reason:`invalid-json`}}function Gt(e){switch(e){case`invalid-json`:return`the file is not a valid JSON object; repair its JSON, then retry`;case`path-changed`:return`the path changed while waiting for its lock; retry to check its current state`;case`unavailable-root`:return`the filesystem root is unavailable; reconnect the drive or network share, then retry`;default:return le(e)}}function Z(e,t){return{kind:`
1import{t as e}from"./chunk-DXB73IDG-MLBj3lvC.mjs";function t(){let e=[{prop:`Function`,target:globalThis,violationType:`function_constructor`,strategy:`throw`,reason:`Function cons...
L2: `);n.register(`data:text/javascript,${encodeURIComponent(e)}`),i.importHooksRegistered=!0}}catch(e){console.debug(`[DefenseInDepthBox] Could not register import() hooks:`,e instanc...
•Manifest-reachable source captures an API credential, sends it to a fixed unofficial gateway, and persists that redirection in agent or shell configuration.
dist/cli.mjs:
import{o as e}from"./rolldown-runtime-tZXQYakl.mjs";import{$a as t,Ec as n,Gu as r,Hd as i,Iu as a,Kc as o,Ld as s,Lo as c,Ma as l,Ml as u,Nd as d,Nl as f,Pa as p,Ps as m,Qc as h,Q...
`)}const ki={out:e=>process.stdout.write(`${e}\n`),err:e=>process.stderr.write(`${e}\n`)};function Ai(e){return new A(`audit`).description(`Unified validation audit (markdown lint ...
`)){let e=n.trim();if(e===``)continue;let r=e.indexOf(`=`);r!==-1&&(t[e.slice(0,r)]=e.slice(r+1))}return t}function Ii(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>r.push(...
`)}var ha=class extends Error{constructor(e,t,n){super(ma(n)),this.request=e,
High
Credential Redirect Persistence
Manifest-reachable source sends a prompted API credential to a fixed unofficial gateway and persists the redirection.
20*/
L21: var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,...
L22: changing to the minimum size of: 2`),this._maxSize=2)}record(e){this.updateByIncrement(e,1)}setStartTime(e){this.startTime=e}toPointValue(){return{hasMinMax:this._recordMinMax,min:...
L23: \t- OR - create a new view with the name ${e.name} and description '${e.description}' and InstrumentSelector ${r}
...
L31: causes have become circular...`;let o=r(e);return o?(t.add(e),a+`
L32: caused by: `+i(o,t)):a},a=e=>i(e,new Set),o=(e,t,i)=>{if(!n(e))return``;let a=i?``:e.message||``;if(t.has(e))return a+`: ...`;let s=r(e);if(s){t.add(e);let n=typeof e.cause==`funct...
L33: `:`
High
Command Output Exfiltration
Source combines command execution, command-output handling, and outbound requests; review data flow before blocking.
1Cross-file remote execution chain: dist/dist-Dp3k14aI.mjs spawns dist/chunk-5QMZ5MUS-BuB3i_B5.mjs; helper contains network access plus dynamic code execution.
L1: import{a as e,i as t,n,o as r,r as i,t as a}from"./rolldown-runtime-tZXQYakl.mjs";import{$ as o,$a as s,$c as c,$i as l,$l as u,$n as d,$o as f,$r as p,$s as m,$t as h,$u as g,A as...
L2: /**
...
L10: *
L11: * http://www.apache.org/licenses/LICENSE-2.0
L12: *
...
L21: var t=null;try{t=new WebAssembly.Instance(new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0,1,13,2,96,0,1,127,96,4,127,127,127,127,1,127,3,7,6,0,1,1,1,1,1,6,6,1,127,1,65,...
L22: changing to the minimum size of: 2`),this._maxSize=2)}record(e){this.updateByIncrement(e,1)}setStartTime(e){this.startTime=e}toPointValue(){return{hasMinMax:this._recordMinMax
1import"./chunk-SRAX5OIU-E5XcbDos.js";var e={paste:`पेस्ट`,pasteAsPlaintext:`सादे पाठ के रूप में चिपकाएं`,pasteCharts:`चार्ट चिपकाएँ`,chartType_bar:``,chartType_line:``,chartType_radar:``,chartType_plaintext:``,selectAll:`सेलेक्ट ऑल`,multiSelect:`अवयव को चयन में सम्मिलित करें`,moveCanvas:`चित्रपटल को स्थानांतरित करें`
8`:``;q(e,`${JSON.stringify(r,null,2)}${i}`)}catch{let r=mt(n,t.contentDir);r!==n&&q(e,r)}}functionyt(e,t){let n=W(e,`utf-8`),r=mt(n,t.contentDir);r!==n&&q(e,r)}functionbt(e){try{returnG(e,{withFileTypes:!0}).filter(e=>e.isFile()).map(t=>z(e,t.name))}catch{return[]}}constxt=newSet([`agent-presence.json`,`agent-effects.json`,`runtime.json`]);functionSt(e){return/\.log\.\d+$/.test(e)}functionCt(e){return e.endsWith(`.jsonl`)||e.endsWith(`.log`)||St(e)}constwt=[`telemetry`,`logs`,`process`,`diagnostic-reports`];functionTt(e){let t={contentDir:e.contentDir};for(let n of wt)for(let r ofbt( ...
10`:`not-running (${S})\n`;q(z(_,`state`,`server-status.txt`),te);let A=e.diagnosticReports===void 0?`not-collected (no collection attempted)`:Re(e.diagnosticReports,v);if(q(z(_,`state`,`diagnostic-reports-status.txt`),`${A}\n`),e.processDir&&H(e.processDir)){let t=z(_,`process`);U(t,{recursive:!0}),ce(e.processDir,t,{recursive:!0})}let j=e.redact===!0;j&&Tt({stagingDir:_,contentDir:t}),e.note&&q(z(_,`note.txt`),e.note);let M=null;e.scrubSecrets===!0&&(M=pn(_));for(let t of e.extraFiles??[])Q(t.sourcePath,z(_,`extra`,t.zipName??L(t.sourcePath)))||i.logger?.warn({sourcePath:t.sourcePath},`extra f ...
11`)}async function Gn(e={}){let t=e.discover??g,n=e.inspect??(e=>$(e,`server`)),r=e.log??(e=>console.log(e)),i=e.resolveCommand??D,a=e.resolveUsage??k,o=await t(),s=[];for(let e of o){let t=n(e),r=Ln(e,t,t.status===`missing`||t.status===`corrupt`||t.status===`read-error`||t.status===`unverified-owner`?null:i(t.lock.pid),t.status===`missing`||t.status===`corrupt`||t.status===`read-error`||t.status===`unverified-owner`?null:a(t.lock.pid));r!=null&&s.push(r)}if(e.json){let e=s.map(e=>({...e,displayStatus:Rn(e)}));r(JSON.stringify(e,null,2));return}r(Wn(e.all?s:s.filter(e=>zn.has(Rn(e)))))}function ...
`क्लिपबोर्ड पर पीएनजी के रूप में प्रतिलिपि बनायें`
,copyAsSvg:
`क्लिपबोर्ड पर एसवीजी के रूप में प्रतिलिपि बनायें`
,copyText:
`पाठ के रूप में क्लिपबोर्ड पर प्रतिलिपि बनायें`
,copySource:
`स्त्रोत रूप में क्लिपबोर्ड पर प्रतिलिपि बनाएँ`
,convertT
...
2आपके बदलाव सहेजे नहीं जाएंगे!`,localStorageQuotaExceeded:``},o={unsupportedFileType:`असमर्थित फाइल प्रकार`,imageInsertError:`प्रतिमा सन्निवेश नहीं की जा सकी. पुनः प्रयत्न करे...`,fileTooBig:`फ़ाइल ज़रूरत से ज़्यादा बड़ी हैं. अधिकतम अनुमित परिमाण {{maxSize}} हैं`,svgImageInsertError:`एसवीजी प्रतिमा सम्मिलित नहीं कर सके, एसवीजी संरचना लगता है कि अयोग्य हैं.`,failedToFetchImage:`प्रतिमा लाने में विफल.`,cannotResolveCollabServer:`कॉलेब सर्वर से कनेक्शन नहीं हो पा रहा. कृपया पृष्ठ को पुनः लाने का प्रयास करे.`,importLibraryError:`संग्रह प्रतिष्ठापित नहीं किया जा सका`,saveLibraryError:`संग्रह सुरक्षि ...
Critical
Trojan Source Unicode
Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.
3या किसी मौजूदा पाठ संपादक में चिपकायें`,unableToEmbed:`यह यू-आर-एल जड़ने हेतु अस्वीकृत हैं. इस यू-आर-एल को श्वेतसूची मैं सम्मिलित कराने हेतु ग़िटहब पर मुद्दा उठायें`,unrecognizedLinkFormat:`जो कड़ी आपने जड़ी हैं, वह अनपेक्षित प्रारूप में हैं. कृपया मूल साइट द्वारा मुहैय्या कराया हुवा 'जड़ने हेतु' पाठ चिपकाने का प्रयास करें.`,elementLinkCopied:`कड़ी क्लिप बोर्ड पर कॉपी की गयी`},D={transparent:`पारदर्शक`,black:`काला`,white:`सफ़ेद`,red:`लाल`,pink:`गुलाबी`,grape:`अंगूरी`,violet:`जामुनी`,gray:`गहरा`,blue:`नीला`,cyan:`आसमानी`,teal:`हरा-नीला`,green:`हरा`,yellow:`पीला`,orange:`नारंगी`,bronze:`कांस्य`} ...