@devflow-tools/devflow@0.18.14: AI-agent control-surface risk | LPM Firewall
Soft block: AI-agent control surface
Warn by default; block when configured. Unconsented control over the consumer project's AI-agent tool-call path.
registry /
@devflow-tools/devflow / 0.18.14
@devflow-tools/devflow@0.18.14 Installable DevFlow distribution containing the CLI, runtime hooks, and Claude plugin.
AI Security Reviewscanned 26d ago · by lpm-firewall-ai LPM flags this version as an AI-agent control-surface risk. Installing the package automatically modifies the consuming project's Claude Code hook configuration. The added wildcard PreToolUse command runs this package's handler for tool calls.
Static reason
High-risk behavior combination matched malicious policy.; source matched previously finalized malicious package; routed for review
Trigger
npm postinstall during package installation.
Impact
Unconsented control over the consumer project's AI-agent tool-call path.
Mechanism
Automatic wildcard Claude PreToolUse hook registration.
Policy narrative
The postinstall hook locates the consumer project, creates .claude when absent, and writes a merged hooks.json entry. That entry matches every PreToolUse event and executes the package's pre-tool-use handler, establishing an AI-agent control surface without an explicit user command or consent.
AI rationale
This is an automatic install-time mutation of a foreign, broad AI-agent control surface. The wildcard command hook meets the publish-block policy even without a hard-coded network endpoint.
Evidence
package.json scripts/postinstall.js .claude .claude/hooks.json dist/hooks/pre-tool-use.js
Decision evidencepublic snapshot AI identified this as a dangerous AI-agent capability at 99.0% confidence with false-positive risk.
low
Evidence for policy risk
The manifest runs a postinstall script automatically. The installer finds the consumer project and targets its .claude hooks configuration. It registers a command hook for every PreToolUse event. It merges and writes the modified hooks configuration into the consumer project. Evidence against
The installer contains no hard-coded external network endpoint. Behavioral surface
Source ChildProcess Crypto DynamicRequire EnvironmentVars Filesystem Network Shell
Supply chain HighEntropyStrings Minified PossibleObfuscation UrlStrings
Manifest No manifest risk signals triggered.
scanned 79 file(s), 2.76 MB of source, external domains: 127.0.0.1, github.com, nextjs.org, react.dev, reactflow.dev, www.w3.org
Source & flagged code14 flagged · loading source • scripts.postinstall = node scripts/postinstall.js
High Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.json View on unpkg • scripts.postinstall = node scripts/postinstall.js
Medium Ambiguous Install Lifecycle Script
Install-time lifecycle script is not statically allowlisted and needs review.
package.json View on unpkg dist/plugin/dist/hooks/hook-daemon.js View file 1 import {createServer,createConnection}from'net';import {createHash,randomUUID as randomUUID$1}from'node:crypto';import {execFileSync,spawn}from'node:child_process';import {dirname,...
L2: `;rotateDiagnosticLogFile({path:n,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(n,o);}catch{}}function Ci(e){return new Promise(t=>setTimeout...
High Child Process
Package source references child process execution.
dist/plugin/dist/hooks/hook-daemon.js View on unpkg · L1 • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.13
matchedPath = dist/hooks/hook-daemon.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.13
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/plugin/dist/hooks/hook-daemon.js View on unpkg 241 ${S.green("\u2713")} ${n} deactivated and uninstalled`);}catch(o){console.error(`
L242: ${S.red("\u2717")} Uninstallation failed: ${o.message}`),process.exitCode=1;}});});function Xt(e){let t=join(e,".devflow","config.json");if(existsSync(t))try{let n=readFileSync(t,"...
L243: `));}let n=Xt(t);console.error(S.blue(`DevFlow init \u2014 mode: ${n}`));let{initProject:o,renderInitReport:r}=await Promise.resolve().then(()=>(Uo(),Wo)),s=await o(t,{force:e.forc...
1 #!/usr/bin/env node
L2: import {createRequire as createRequire$1,isBuiltin}from'node:module';import {join as join$1,resolve,basename,dirname,relative,sep,isAbsolute,extname}from'node:path';import {createR...
L3: `)}var Co=D(()=>{});function xt(){let e=dirname(fileURLToPath(import.meta.url)),t=[join$1(e,"..","plugin-files"),join$1(e,"plugin"),join$1(e,"..","..","dist","plugin-files"),join$1...
...
L8: `);}function me(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Wi(e,t){let n=join$1(e,"package.json");if(!existsSync$1(n))return;let o=JSON.parse(readFileSync$1...
L9: `)}var Mo,Gi,Uo=D(()=>{Je();Mo=To.default??To,Gi=createRequire(import.meta.url);});var qo={};j(qo,{reviewPluginMemoryHints:()=>na});async function na(e,t,n={}){let o=n.isTTY??!!pro...
L10: `,"utf-8"),rena
High Same File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
dist/cli.js View on unpkg · L1 • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/cli.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View file • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/dashboard/_next/static/chunks/main-09803f06c26fe6d9.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View on unpkg 1 (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[792],{1315:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r={HTTPAccessErrorStatus:function(){re...
L2: link[rel="prefetch"][href^="${t}"],
Medium Dynamic Require
Package source references dynamic require/import behavior.
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View on unpkg · L1 2 Install-time AI-agent control hijack evidence:
L2: //
L3: // Auto-configures .claude/hooks.json in the consuming project so that Claude
L4: // Code invokes the devflow PreToolUse hook on every tool call.
...
L11:
L12: import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs';
L13: import { join, dirname } from 'node:path';
...
L55:
L56: const claudeDir = join(projectRoot, '.claude');
L57: const hooksFile = join(claudeDir, 'hooks.json');
...
L59:
L60: // 1. Ensure .claude/ directory exists
L61: if (!existsSync(claudeDir)) {
Payload evidence from dist/plugin/dist/skills/devflow:animation/SKILL.md:
L54:
L55: 以下版本描述知识源,不代表目标项目版本;目标项目的 package.json 与 lockfile 证据始终优先。
L56:
L57: - animation-docs: 2024 — https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animations
L58:
Critical Ai Agent Control Hijack
Source creates an unconsented AI-agent control surface through install-time mutation or a default unauthenticated remote skill channel.
scripts/postinstall.js View on unpkg · L2 • Manifest-trigger-reachable source links an external AI-agent control path to a behavior-bearing write operation.
import { writefilesync, existssync, mkdirsync, readfilesync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileurltopath } from 'node:url';
const tag = '[devflow]';
function findprojectroot() {
let dir = process.cwd();
for (let i = 0; i < 10; i++) {
const pkgjson = join(dir, 'package.json');
const nodemodules = join(dir, 'node_modules');
if (existssync(pkgjson) && existssync(nodemodules)) {
return dir;
}
const parent = dirname(dir);
if (parent === dir) break;
High Trigger Reachable External Ai Agent Control Surface Mutation
Manifest-trigger-reachable source writes behavior-bearing configuration into a user or project AI-agent control surface.
dist/hooks/user-prompt-submit.js#virtual:normalized:round1 View file • stage = ast_semantic_analysis; reason = ast_parse_error; limitedFiles = 2
High Semantic Analysis Limited
A bounded semantic-analysis stage reached its safety limit; remaining detectors completed, but this package requires AI review.
dist/hooks/user-prompt-submit.js#virtual:normalized:round1 View on unpkg • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.13
matchedPath = dist/hooks/hook-daemon.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.13
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/hooks/hook-daemon.js View on unpkg dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js View file • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js View on unpkg Findings1 Critical 11 High 5 Medium 4 Low
Critical Ai Agent Control Hijack scripts/postinstall.js
High Install Time Lifecycle Scripts package.json
High Child Process dist/plugin/dist/hooks/hook-daemon.js
High Shell dist/cli.js
High Same File Env Network Execution dist/cli.js
High Trigger Reachable External Ai Agent Control Surface Mutation scripts/postinstall.js
High Semantic Analysis Limited dist/hooks/user-prompt-submit.js#virtual:normalized:round1
High Known Malware Source Similarity dist/cli.js
High Known Malware Source Similarity dist/hooks/hook-daemon.js
High Known Malware Source Similarity dist/plugin/dist/hooks/hook-daemon.js
High Known Malware Source Similarity dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js
High Known Malware Source Similarity dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js
Medium Ambiguous Install Lifecycle Script package.json
Medium Dynamic Require dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js
Medium Network
Medium Environment Vars
Medium Structural Risk Force Deep Review
Low Scripts Present
Low Filesystem
Low High Entropy Strings
Low Url Strings
Affected versions and remediation This report applies to @devflow-tools/devflow@0.18.14 .
See version security history for other recorded verdicts.
Avoid installing @devflow-tools/devflow@0.18.14. Remove it from direct dependencies and check your lockfile for transitive copies. Choose an independently verified alternative or release. This report does not establish that other versions are safe. If this version ran, investigate the affected machine and build environment. Rotate credentials it could access and rebuild from a trusted environment. Evidence last updated: 2026-09-13 03:40:33.428Z (UTC) .
99% Malicious
AI assessment confidence
This finding concerns changes to an AI agent's instructions or configuration without explicit user action. It does not by itself establish malware intent. The CLI warns by default and blocks when configured for this policy.
Package metadata npm Version 0.18.14
Latest on npm 0.18.20
Published Sep 8, 2026
License MIT
Dependencies 28
Integrity verified
Package size 907 KB
Files 250
Runtime surface package.json Entrypoints bin → devflow
Runtime node >=22.13.0
Artifact 3.33 MB · 250 files 1 signature(s)
Install lifecycle postinstall
Behavioral surface ChildProcess Crypto DynamicRequire EnvironmentVars Filesystem Network Shell HighEntropyStrings Minified PossibleObfuscation UrlStrings Manifest: clean
LPM.dev Registry
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/cli.js View on unpkg scripts/postinstall.js
Source & flagged code14 flagged Lines 1-38 json
2 "name" : "@devflow-tools/devflow" ,
5 "description" : "Installable DevFlow distribution containing the CLI, runtime hooks, and Claude plugin." ,
7 "devflow" : "./bin/devflow"
11 "bundle:dashboard" : "test -f ../../apps/dashboard/out/index.html || npm run build -w apps/dashboard; rm -rf dist/dashboard && mkdir -p dist/dashboard && cp -R ../../apps/dashboard/out/. dist/dashboard/" ,
12 "audit-session-data" : "node --import tsx scripts/audit-session-data.ts" ,
13 "maintain:semantic-reliability" : "node --import tsx scripts/semantic-reliability-maintenance.ts" ,
14 "build:watch" : "tsup --watch" ,
15 "clean" : "rm -rf dist" ,
16 "postbuild" : "cp ../../apps/server/public/fallback.html dist/fallback.html && node --import tsx scripts/bundle-plugin.ts" ,
17 "prepack" : "npm run build && npm run bundle:dashboard" ,
18 "postinstall" : "node scripts/postinstall.js"
High Install Time Lifecycle Scripts
Package defines install-time lifecycle scripts.
package.json View on unpkg · L18 Medium Ambiguous Install Lifecycle Script
Install-time lifecycle script is not statically allowlisted and needs review.
package.json View on unpkg · L18 21 "@colbymchenry/codegraph" : "^1.1.1" ,
22 "@devflow-tools/adapters" : "0.18.14" ,
23 "@devflow-tools/benchmark" : "0.18.14" ,
24 "@devflow-tools/context-engine" : "0.18.14" ,
25 "@devflow-tools/database" : "0.18.14" ,
26 "@devflow-tools/delivery-line" : "0.18.14" ,
27 "@devflow-tools/knowledge-engine" : "0.18.14" ,
28 "@devflow-tools/mcp-server" : "0.18.14" ,
29 "@devflow-tools/memory-engine" : "0.18.14" ,
30 "@devflow-tools/retrieval-engine" : "0.18.14" ,
31 "@devflow-tools/sdk" : "0.18.14" ,
32 "@devflow-tools/semantic-engine" : "0.18.14" ,
33 "@devflow-tools/server" : "0.18.14" ,
34 "@devflow-tools/task-runtime" : "0.18.14" ,
35 "@devflow-tools/telemetry" : "0.18.14" ,
36 "@devflow-tools/workflow-engine" : "0.18.14" ,
37 "@inquirer/prompts" : "^7.10.1" ,
38 "@modelcontextprotocol/sdk" : "^1.30.0" ,
dist/plugin/dist/hooks/hook-daemon.js View file Lines 1-21 javascript
1 import {createServer,createConnection} from 'net' ; import {createHash,randomUUID as randomUUID$1} from 'node:crypto' ; import {execFileSync,spawn} from 'node:child_process' ; import {dirname,join as join$1} from 'path' ; import {mkdirSync,lstatSync,openSync,writeFileSync,fstatSync,closeSync,readFileSync,unlinkSync,existsSync
Lines 1-21 javascript
2 import {createRequire as createRequire$1,isBuiltin} from 'node:module' ; import {join as join$1,resolve,basename,dirname,relative,sep,isAbsolute,extname} from 'node:path' ; import {createRuntimeManager,resolveStableProjectIdentity,loadPlugins,getPluginInstallRoot,resolveProjectCapabilityProfile,stableRuntimeHash,readPersistedClaudeHookNode,resolveClaudeHookRuntime,verifyClaudeHookNativeRuntime,redactMcpInventory,readMcpInventory,checkMcpHealth,readCachedMcpHealth,DOCTOR_SCHEMA_VERSION,getLocalHmacSecret,createDefaultHostAdapterRegistry,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRunti ...
3 `)}var Co=D(()=>{});function xt(){let e=dirname(fileURLToPath(import.meta.url)),t=[join$1(e,"..","plugin-files"),join$1(e,"plugin"),join$1(e,"..","..","dist","plugin-files"),join$1(e,"..","..","..","..","plugins","claude-code")];for(let n of t)if(existsSync$1(join$1(n,".claude-plugin","plugin.json")))return n;throw new Error("Plugin files not found. Run `
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View file Lines 1-5 javascript
1 (self.webpackChunk_N_E = self.webpackChunk_N_E || []). push ([[ 792 ],{ 1315 :( e , t ) => { "use strict" ;Object. defineProperty (t, "__esModule" ,{value: ! 0 }); var
Lines 1-22 javascript
1 // packages/devflow/scripts/postinstall.js
3 // Auto-configures .claude/hooks.json in the consuming project so that Claude
4 // Code invokes the devflow PreToolUse hook on every tool call.
6 // This file is plain ESM JavaScript (not TypeScript) because it must run during
7 // `npm install` before any build step has compiled the package.
9 // If anything goes wrong we log a warning and exit 0 — we must never break a
10 // user's `npm install`.
dist/hooks/user-prompt-submit.js#virtual:normalized:round1 View file • stage = ast_semantic_analysis; reason = ast_parse_error; limitedFiles = 2
High Semantic Analysis Limited
A bounded semantic-analysis stage reached its safety limit; remaining detectors completed, but this package requires AI review.
dist/hooks/user-prompt-submit.js#virtual:normalized:round1 View on unpkg • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.13
matchedPath = dist/hooks/hook-daemon.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.13
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/hooks/hook-daemon.js View on unpkg dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js View file • matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/dashboard/_next/static/chunks/237-34a3fbfba7ff0de5.js View on unpkg as
existsSync$1,readdirSync,rmSync,linkSync,renameSync
as
renameSync$1}
from
'fs'
;
import
{getLocalApiKey,getDevFlowStateRoot,getDaemonSocketPath,getDaemonPidPath,resolveCapabilityRollout,loadConfig,createRuntimeManager,selectHostAdapter,getProjectStateDir,acquireRuntimeHttpCircuit,register ...
2 `;rotateDiagnosticLogFile({path:n,maxBytes:50 * 1024 * 1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(n,o);}catch{}}function Ci(e){return new Promise(t=>setTimeout(t,e))}var En=1e4,Fi=3e4,Ae=500,Z=class{constructor(t){this.retryScheduled=false;this.metricAggregationScheduled=false;this.apiUrl=t?.apiUrl,this.cacheDir=t?.cacheDir??join$1(getDevFlowStateRoot(), "global" , "telemetry-cache" ),this.database=t?.database??null,this.ownsDatabase=!t?.database;let n=t?.busyTimeoutMs??Number(process.env.DEVFLOW_TELEMETRY_DB_BUSY_TIMEOUT_MS);this.busyTimeoutMs=Number.isSafeInteger(n)&&n>=0?n: ...
High Child Process
Package source references child process execution.
dist/plugin/dist/hooks/hook-daemon.js View on unpkg · L1 4 `)}function ns(e,t){return {candidateId:e.id,version:e.overlayVersion,state:t,instruction:e.instruction,trigger:e.trigger,confidence:e.confidence,evidenceReceipt:e.graderReceipt??` candidate:${e.id}:v${e.overlayVersion} `,expiresAt:e.expiresAt}}function os(e,t){let n=Math.max(0,Math.min(t.maxLearnedEntries??3,3)),o=Math.max(0,Math.min(t.learnedCharacterBudget??1600,4e3)),r=[],i=0;for(let s of e){if(r.length>=n)break;let a=s.instruction.length+4;i+a>o||(r.push(s),i+=a);}return r}function rs(e,t,n){let o=e.trigger,r=t.replace(/^devflow:/,"").split(":").pop()??t,i=Ce(o.skills);if(i.length>0&&!i.som ...
5 ` ,{mode:384});}function gs(e){let t=createRequire(import.meta.url),o=[process.env.DEVFLOW_SERVER_ENTRY,ys(()=>t.resolve( "@devflow-tools/server/dist/main.js" )),join(e, "node_modules" , "@devflow-tools" , "server" , "dist" , "main.js" ),join(e, "apps" , "server" , "dist" , "main.js" )].filter(r=>!!r).find(existsSync);if(!o)throw new Error( "DevFlow server entry point is not installed or built" );return {command:process.execPath,args:[o],cwd:e}}function ys(e){try{return e()}catch{return}}var Oe=class{constructor(t){this.projectRoot=t;this.runtime=createRuntimeManager();}addRef(t){let n=mt();n.sessions.includes(t)||n ...
7 `)}function xo(e){let t=e.runtimeStore??new q(e.projectRoot),n=t.listEvidenceObligations(e.sessionId);if(n.length===0)return ha(e,t),null;let o=St(e.transcriptPath,n);if(!o.answer){let s=o.degradationReason?? "transcript_answer_unavailable" ;for(let a of n)t.degradeEvidenceObligation(e.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of n)t.degradeEvidenceObligation(e.sessionId,s.obligationId, "transcript_identity_unavailable" );return null}let i=[];for(let s of n){let a=Eo(o.answer,[s]);if(a.length===0){t.resolveEvidenceObligation(e.sessionId,s.obligationId),Ne(e,s,"sa ...
13 `)}}function Eo(e,t){let n=new Set,o=new Set(t.flatMap(c=>c.contract.requiredSections)),r=Ao(e.split(/\r?\n/)),i=To(r.headingLines);for(let c of o)i.found.has(c)||n.add(` missing_section:${c} `);if(t.every(c=>c.contract.runtimeProfilingOccurred))return [...n];let a=t.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let d=r.claimLines[c].trim();if(!d||Ia(d))continue;let u=i.byLine.get(c);for(let l of Sa(d))ka(l,u,a,n);}return [...n]}function Ao(e){let t=false,n=[],o=[];for(let r of e){if(/^ \s *``` /.test(r)){t=!t,n.push( "" ),o.push(r.replace(/^\s * ```+[^\s` ] * /, "" ). ...
14 `)+1)));let d=c.split(/\r?\n/).slice(-ma),u=t.length>0?Math.min(...t.map(f=>f.promptedAt)):0,l=Aa(d,u),p=[...l].reverse().find(f=>Ea(f.text,t))??l.at(-1);return p?.text?{answer:p.text,fingerprint:p.fingerprint}:{degradationReason: "transcript_answer_unavailable" }}catch{return {degradationReason: "transcript_unreadable" }}finally{n!==void 0&&closeSync$1(n);}}function Ea(e,t){let n=new Set(t.flatMap(r=>r.contract.requiredSections)),o=To(Ao(e.split(/\r?\n/u)).headingLines);return [...n].every(r=>o.found.has(r))}function We(e){return St(e,[]).answer}function Aa(e,t){let n=[];for(let o=0;o<e.length;o+ ...
15 `):"";if(u.trim()){let l=u.trim(),m=typeof a.id=="string"&&a.id?` message:${a.id} `:typeof i.uuid=="string"&&i.uuid?` uuid:${i.uuid} `:` record:${String(i.timestamp?? "" )}:${o}:${createHash( "sha256" ).update(r).digest( "hex" )} `,p=createHash("sha256").update(l).digest("hex"),f=createHash("sha256").update(` ${m}\0${p} `).digest("hex");n.push({text:l,timestamp:c,fingerprint:f});}}catch{continue}}return n}function Ta(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e!="string")return 0;let t=Date.parse(e);return Number.isFinite(t)?t:0}function To(e){let t=new Set,n=new Map,o;for(let r=0;r<e.l ...
16 ` ).slice(0,4e3);if(!e||typeof e!= "object" )return "" ;let t=e;return [t.text,t.content,t.message].map(Tt).filter(Boolean).join( `
17 ` ).slice(0,4e3)}var Ja={open:[ "intent_bound" ],intent_bound:[ "context_ready" , "context_degraded" ],context_ready:[ "action_required" , "action_not_required" ],context_degraded:[ "action_required" , "action_not_required" ],action_required:[ "action_satisfied" , "action_degraded" , "action_failed" ],action_not_required:[ "memory_decided" , "memory_quarantined" ],action_satisfied:[ "memory_decided" , "memory_quarantined" ],action_degraded:[ "memory_decided" , "memory_quarantined" ],action_failed:[ "action_satisfied" , "action_degraded" ],memory_decided:[ "closed" , "closed_with_degradation" , "closed_with_retry_work" ],memory_quaranti ...
18 `).filter(Boolean).flatMap(t=>{try{let n=JSON.parse(t);return typeof n.content=="string"&&typeof n.createdAt=="number"?[n]:[]}catch{return []}})}catch{return []}}function Go(e){let t=fc(e),n=` ${t}.claim- `,o=` ${basename(t)}.claim- `,r=(()=>{try{return readdirSync$1(dirname$1(t)).filter(a=>a.startsWith(o)&&!a.includes(".tmp-")).sort()[0]}catch{return}})(),i=r?join(dirname$1(t),r):` ${n}${Date.now()}-${process.pid} `;if(!r)try{renameSync(t,i);}catch{return null}let s=gc(i);if(s.length===0){try{unlinkSync$1(i);}catch{}return null}return {path:i,intents:s}}function Ct(e){if(e.intents.shift(),e.intents ...
20 ` ,{mode:384}),renameSync(t,e.path);}function ze(e){let t=e.trim().replace(/^\ //,"");if(!t.startsWith("devflow:"))return null;let n=t.slice(8).replace(/^devflow-/,"");return /^[a-z0-9][a-z0-9-]*$/i.test(n)?`devflow:${n.toLowerCase()}`:null}function Yo(e){let t=e.trimStart().match(/^\/(devflow:[a-z0-9][a-z0-9-]*)\b/i);if(!t)return null;let n=ze(t[1]);return n?{rawName:t[1],skillName:n}:null}function ve(e,t){return t?`evt_tool_${createHash$1("sha256").update(`${e}\0${t}`).digest("hex").slice(0,24)}`:`evt_${Date.now()}_${Math.random().toString(36).slice(2,11)}`}var Ie=1,Ht="memory-snapshot-v1.json ...
21 DevFlow memory snapshot=degraded; reason=${c}. Memory result completeness is not authoritative; do not conclude that the project has no memories. `:r.memories.length===0&&d.length>0?` ## Project memory
Long lines were clipped for display.
• matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.13
matchedPath = dist/hooks/hook-daemon.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.13
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/plugin/dist/hooks/hook-daemon.js View on unpkg npm run build` first.
")}function xe(e=homedir$1(),t={}){let n=t.installedPluginsPath??join$1(e,"
.claude
","
plugins
","
installed_plugins.json
"),o=t.pluginCachePath??join$1(e,"
.claude
","
plugins
","
cache");for(let i of Mi)try{let c=JSON.parse(readFi ...
4 `, "utf-8" ),a}function Li(e){let t=new Map,n;try{n=readdirSync(e,{withFileTypes:!0});}catch{return t}for(let o of n){if(!o.isDirectory())continue;let r=join$1(e,o.name, "SKILL.md" ),s=jo(r);s&&t.set(s.name,r);}return t}function jo(e){try{if(!lstatSync(e).isFile())return null;let t=readFileSync$1(e, "utf-8" ),n=t.match(/^name:\s * ([^\s]+)\s * $/m);return n?.[1]?{name:n[1],content:t}:null}catch{return null}}function rn(e){return createHash( "sha256" ).update(e).digest( "hex" )}function Do(e){try{let t=JSON.parse(readFileSync$1(join$1(e, "package.json" ), "utf-8" ));return typeof t.version== "string" ?t.version:nu ...
5 `);}function No(e,t){let n=join$1(e, ".claude" ),o=join$1(n, "mcp.json" ),r={};if(existsSync$1(o))try{r=JSON.parse(readFileSync$1(o, "utf-8" ));}catch{console.warn( "Warning: Could not parse existing mcp.json, skipping MCP config" );return}else mkdirSync$1(n,{recursive:true});let s=r.mcpServers??{};s.devflow||(s.devflow={command:t,args:[],env:{}},r.mcpServers=s,writeFileSync$1(o,JSON.stringify(r,null,2)));}function Ot(e,t,n){let o=join$1(t,qe,sn,n);rmSync(o,{recursive:true,force:true}),mkdirSync$1(o,{recursive:true});let r=join$1(e, "hooks" );existsSync$1(r)&&Pt(r,join$1(o, "hooks" ));for(let c of [ "CLAUD .. .
6 `);let i=join$1(n,"known_marketplaces.json"),a={};if(existsSync$1(i)){let c;try{c=JSON.parse(readFileSync$1(i,"utf-8"));}catch{throw new Error(` Could not parse Claude marketplace registry: ${i} `)}if(!me(c))throw new Error(` Invalid Claude marketplace registry: ${i} `);a=c;}a[qe]={source:{source:"directory",path:o},installLocation:o,lastUpdated:new Date().toISOString()},writeFileSync$1(i,` ${JSON.stringify(a,null,2)}
7 `);}function Hi(e,t,n){let o=join$1(e,"..","installed_plugins.json"),r={version:2,plugins:{}};if(existsSync$1(o)){let f;try{f=JSON.parse(readFileSync$1(o,"utf-8"));}catch{throw new Error(` Could not parse Claude plugin registry: ${o} `)}if(!me(f))throw new Error(` Invalid Claude plugin registry: ${o} `);r=f;}else mkdirSync$1(dirname(o),{recursive:true});let s=r.plugins;if(s!==void 0&&!me(s))throw new Error(` Invalid Claude plugin registry plugins: ${o} `);let i=s??{},a=i[Et];if(a!==void 0&&!Array.isArray(a))throw new Error(` Invalid Claude plugin registration for ${Et} `);let c=a??[],l=c.find(f=>me(f) ...
8 ` );}function me(e){return typeof e== "object" &&e!==null&&!Array.isArray(e)}function Wi(e,t){let n=join$1(e, "package.json" );if(!existsSync$1(n))return;let o=JSON.parse(readFileSync$1(n, "utf-8" )),r=Object.keys(o.dependencies??{});if(r.length===0)return;let s={...process.env};delete s.npm_config_allow_scripts,delete s.NPM_CONFIG_ALLOW_SCRIPTS;let i=r.filter(u=>u.startsWith( "@devflow-tools/" )),a=i.map(u=>join$1(t, "../../packages" ,u.slice(15))).filter(u=>existsSync$1(join$1(u, "package.json" ))),c=[ "install" , "--omit=dev" , "--no-audit" , "--no-fund" , "--package-lock=false" ];if(i.length>0&&a.length===i.leng ...
9 `)}var Mo,Gi,Uo=D(()=>{Je();Mo=To.default??To,Gi=createRequire(import.meta.url);});var qo={};j(qo,{reviewPluginMemoryHints:()=>na});async function na(e,t,n={}){let o=n.isTTY??!!process.stdout.isTTY,r=new Set(t.split(",").map(oa).filter(Boolean));if(!o||r.size===0)return {available:0,selected:0};let s=await(n.load??loadPlugins)(),i=[];for(let u of r){let p=s.get(u);for(let g of p?.memory?.project?.conventions??[])i.push({id:` ${u}:${g.key} `,pluginName:u,convention:g});}if(i.length===0)return {available:0,selected:0};let a=i.map(u=>({name:` ${u.pluginName}: ${u.convention.value} `,value:u.id,checke ...
10 ` , "utf-8" ),renameSync$1(o,n);}async function Ae(e,t=process.cwd(),n){return $(t,async o=>await o.installPlugin(e),async()=>{let o=tr(e),r=o.replace(/^@devflow-tools\/plugin-/, "" );mkdirSync(st,{recursive:true});let i=readPluginInstallState().plugins[o];execFileSync$1( "npm" ,[ "install" , "--prefix" ,st,o],{stdio: "pipe" ,timeout:6e4});let a=nr(t);a.plugins||(a.plugins=[]),a.plugins.includes(r)||(a.plugins.push(r),or(t,a));let c=[],l= "0.0.0" ,u=join(st, "node_modules" ,...o.split( "/" ));try{let p=JSON.parse(readFileSync(join(u, "package.json" ), "utf-8" ));c=p?.devflow?.templates??[],l=typeof p.version=="strin ...
High Same File Env Network Execution
A single source file combines environment access, network access, and code or shell execution; review context before blocking.
dist/cli.js View on unpkg · L1 11 No plugins available. You can install plugins later with: `),console.log(" devflow plugin list"),console.log(` devflow plugin install <name>
13 \u{1F50C} Plugin Installation Guide
14 `);let n=resolveProjectCapabilityProfile(e,{registry:t}),o=n.detectedStacks;o.length>0&&console.log(` Detected tech stack: ${o.join( ", " )}
15 `);let r=new Set(n.selectedPlugins);if(!process.stdout.isTTY){console.log(` Non-interactive terminal detected. Installing recommended plugins...
16 `);let a=[...r];for(let c of a)try{await Ae(c,e,!0),console.log(` \u2713 ${c} `);}catch{console.error(` \u2717 Failed to install ${c} `);}return a}let s=t.plugins.map(a=>({name:` ${a.name.replace( "@devflow-tools/" , "" )} - ${a.description.substring(0,50)} `,value:a.name,checked:r.has(a.name)})),i;try{i=await checkbox({message:"Select plugins to install (space to select, enter to confirm):",choices:s});}catch{return console.log(`
17 Plugin installation cancelled.
18 `),[]}if(i.length>0){console.log(`
19 Installing selected plugins...
20 `);for(let a of i)try{await Ae(a,e,!0),console.log(` \u2713 ${a}
21 `);}catch{console.error(` \u2717 Failed to install ${a}
Long lines were clipped for display.
Lines 221-245 javascript
221 Stored : ${ getGlobalDevFlowDbPath ()} (${r.runId}) `}async function kd(e={}){let t=e.database??openGlobalDevFlowDatabase(),n,o=null;try{n=e.runId?t.getBenchmarkReport(e.runId):t.getLatestBenchmarkReport(),e.baselineRunId&&(o=t.getBenchmarkReport(e.baselineRunId));}finally{e.database||t.close();}if(!n)throw new Error(e.runId?` Benchmark report "${e.runId}" not found `:"No benchmark reports found. Run ` devflow benchmark run ` first.");if(e.baselineRunId&&!o)throw new Error(` Benchmark baseline "${e.baselineRunId}" not found `);let r=e.output??"text",s=renderBenchmarkReport(n,r);if(!o||r==="json")return ...
222 ## Change From Prior Baseline
224 ${ i . map ( a => `- ${ a }` ). join ( `
228 Change from ${ o . runId }:
229 ${ i . map ( a => `- ${ a }` ). join ( `
230 ` ) }` } function wd ( e , t ){ let n = e.summary.devflow,o = t.summary.devflow; return [ Vt ( "tokensUsed" ,n.avgTokensUsed,o.avgTokensUsed, false ), Vt ( "filesTouched" ,n.avgFilesTouched,o.avgFilesTouched, false ), Vt ( "correctnessScore"
231 `)}var Fs=D(()=>{});var bt={};j(bt,{resolveRuntimeLocale:()=>Ws,runtimeMessage:()=>X,runtimeMessages:()=>Hs});function Ws(e=process.env){return (e.DEVFLOW_LANG?.trim()||Intl.DateTimeFormat().resolvedOptions().locale).toLowerCase().startsWith("zh")?"zh":"en"}function X(e,t={},n){return Hs[Ws(n)][e].replace(/ \{ ( \w +) \} /gu,(o,r)=>String(t[r]??` {${r}} `))}var Hs,De=D(()=>{Hs={en:{starting:"Starting the DevFlow Runtime...",ready:"Dashboard ready at {url}",reused:"Reused the existing DevFlow Runtime.",stopped:"DevFlow Runtime stopped.",notRunning:"No DevFlow Runtime is running.",portInUse:"Port {port} ...
232 Run "devflow plugin list" to see available plugins.` ); return }console. log ( `Installed plugins:
233 ` ),n. forEach ( o => { let r = t.plugins. find ( s => s.name === o);r ? (console. log ( ` ${ S . green ( r . name ) }@${ r . version }`
234 ` ); let n = Math. max ( ... t.plugins. map ( o => o.name. length ));t.plugins. forEach ( o => { let r = " " . repeat (n - o.name. length + 2 );console.
235 Install a plugin: devflow plugin install <name>` );}});}); var Xs = {}; j (Xs,{ pluginSearchCommand :() => eg}); var eg,ei = D (() => { jt ();eg =new Command ( "search" ). description ( "Search for plugins" ). argument ( "<keyword>"
236 Try: devflow plugin list` ); return }console. log ( `Found ${ o . length } plugin(s) matching "${ e }":
237 ` ),o. forEach ( r => {console. log ( ` ${ S . green ( r . name ) }@${ r . version }` ),console. log ( ` ${ r . description }` ),r.tags. length > 0
238 ${ S . green ( " \u2713 " )} ${n}@${o.version} installed and activated `),console.log(`
239 Run "devflow plugin list --installed" to verify. `);}catch(o){console.error(`
240 ${ S . red ( " \u2717 " )} Installation failed : ${o.message} `),process.exitCode=1;}});});var si={};j(si,{pluginUninstallCommand:()=>rg});var rg,ii=D(()=>{_e();rg=new Command("uninstall").description("Uninstall a plugin").argument("<name>","Plugin name (with or without @devflow-tools/ prefix)").action(async e=>{let n=` @devflow - tools / plugin - ${e.replace(/^@devflow-tools\/(?:plugin - ) ?/ , "" )} `;console.log(` Uninstalling ${n} ... `);try{await gn(n,process.cwd(),!0),console.log(`
241 ${S.green( " \u2713 " )} ${n} deactivated and uninstalled `);}catch(o){console.error(`
242 ${S.red( " \u2717 " )} Uninstallation failed: ${o.message} `),process.exitCode=1;}});});function Xt(e){let t=join(e,".devflow","config.json");if(existsSync(t))try{let n=readFileSync(t,"utf-8");if(JSON.parse(n).serverUrl)return "server"}catch{}return "local"}var ai=createRequire(import.meta.url),mo="0.0.0";try{mo=ai("../package.json").version;}catch{try{mo=ai("../../package.json").version;}catch{}}var E=new Command,cg=await Promise.resolve().then(()=>(_o(),So));E.addCommand(cg.createDefaultDeliveryCommand());function lg(e){let t=new URL(e);if(t.protocol!=="http:"||t.hostname!=="127.0.0.1")return Pro ...
243 ` ));}let n = Xt (t);console. error ( S . blue ( `DevFlow init \u2014 mode: ${ n }` ));let{initProject:o,renderInitReport:r} =await Promise . resolve (). then (() => ( Uo (),Wo)),s =await o (t,{force:e.force,plugins:e.plugins !==
244 ${e} docs synced to .devflow/knowledge/${e}/ `));}else {let r=await o.getSources();for(let s of r){let i=await o.syncDocs(s.source.name);for(let a of i)a.added>0?console.log(` ${S.green( " \u2713 " )} ${a.source} \u2192 ${a.added} chunks `):console.log(` ${S.red( " \u2717 " )} ${a.source} \u2014 ${a.errors.join( ", " )|| "no content" } `);}console.log(S.green(`
245 All docs synced. `));}});fo.command("backfill-vectors").description("Backfill missing knowledge chunk vectors").option("--source <name>","Only backfill one knowledge source").option("--batch-size <count>","Embedding batch size","32").action(async e=>{let{backfillKnowledgeVectors:t}=await Promise.resolve().then(()=>(In(),$n)),n=await t({source:e.source,batchSize:Number.parseInt(e.batchSize,10),onProgress:({processed:o,remaining:r})=>{console.log(` vectors : ${o} processed, ${r} remaining `);}});console.log(S.green(` Knowledge vectors ready: ${n.processed} added, ${n.remaining} remaining `));});fo ...
Long lines were clipped for display.
• matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/cli.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/cli.js View on unpkg r
=
{
HTTPAccessErrorStatus
:
function
(){
return
a},
HTTP_ERROR_FALLBACK_ERROR_CODE
:
function
(){
return
i},
getAccessFallbackErrorTypeByStatus
:
function
(){
return
l},
getAccessFallbackHTTPStatus
:
function
(){
return
s},
isHTTPAccessFallbackError
:
function
(){
return
u}};
for
(
var
n
in
r)Object.
defineProperty
(t,n,{enumerable:
!
0
,get:r[n]});
let
a
=
{NOT_FOUND:
404
,FORBIDDEN:
403
,UNAUTHORIZED:
401
},o
=new
Set
(Object.
values
(a)),i
=
"NEXT_HTTP_ERROR_FALLBACK"
;
function
u
(
e
){
if
(
"object"
!=
typ
...
2 link[rel = "prefetch" ][href ^= "${t}" ],
Medium Dynamic Require
Package source references dynamic require/import behavior.
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View on unpkg · L1 3 link[rel = "preload" ][href ^= "${t}" ],
4 script[src ^= "${t}" ] `;if(document.querySelector(o))return e();n=document.createElement("link"),r&&(n.as=r),n.rel="prefetch",n.crossOrigin=void 0,n.onload=e,n.onerror=()=>a(p(Object.defineProperty(Error(` Failed to prefetch: ${t} `),"__NEXT_ERROR_CODE",{value:"E268",enumerable:!1,configurable:!0}))),n.href=t,document.head.appendChild(n)})}):[])).then(()=>{(0,u.requestIdleCallback)(()=>this.loadRoute(t,!0).catch(()=>{}))}).catch(()=>{})}}}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{ ...
5 ${ e . stack }` :e + "" )}})})});let _ = f; function m (){ let e = i.default. useContext (s.RouterContext); if ( ! e) throw Object. defineProperty ( Error ( "NextRouter was not mounted. https://nextjs.org/docs/messages/next-router-not-mounted" ), "__NEXT_ERROR_CODE" ,{value: "E509" ,enumerable: ! 1 ,configurable: ! 0 }); return e} function g ( ... e ){ return f.router =new u. default ( ... e),f.readyCallbacks. forEach ( e => e ()),f.readyCallbacks = [],f.router} function E ( e ){ let t = {}; for ( let r of d){ if ( "object" ==typeof e[r]){t[r] = Object. assign (Array. isArray (e[r]) ? [] : {},e[r]); continue }t[r] = e[r]} return t.events = u.default.events,p. forEach ( r => {t[r] = ( ... t ...
Long lines were clipped for display.
• matchType = normalized_sha256
matchedPackage = @devflow-tools/devflow@0.18.18
matchedPath = dist/dashboard/_next/static/chunks/main-09803f06c26fe6d9.js
matchedIdentity = npm:QGRldmZsb3ctdG9vbHMvZGV2Zmxvdw:0.18.18
similarity = 1.000
summary = normalized source hash matched finalized malicious source
High Known Malware Source Similarity
Source file is highly similar to a previously finalized malicious package; route for source-aware review.
dist/dashboard/_next/static/chunks/main-9bbdbe1dbba0ab29.js View on unpkg 12 import { writeFileSync, existsSync, mkdirSync, readFileSync } from 'node:fs' ;
13 import { join, dirname } from 'node:path' ;
Critical Ai Agent Control Hijack
Source creates an unconsented AI-agent control surface through install-time mutation or a default unauthenticated remote skill channel.
scripts/postinstall.js View on unpkg · L2 14 import { fileURLToPath } from 'node:url' ;
16 const TAG = '[devflow]' ;
19 * Walk up from CWD looking for a directory that contains both a package.json
20 * and a node_modules folder. That's the consumer's project root.
22 function findProjectRoot () {
• Manifest-trigger-reachable source links an external AI-agent control path to a behavior-bearing write operation.
import { writefilesync, existssync, mkdirsync, readfilesync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileurltopath } from 'node:url';
const tag = '[devflow]';
function findprojectroot() {
let dir = process.cwd();
for (let i = 0; i < 10; i++) {
const pkgjson = join(dir, 'package.json');
const nodemodules = join(dir, 'node_modules');
if (existssync(pkgjson) && existssync(nodemodules)) {
return dir;
}
const parent = dirname(dir);
if (parent === dir) break;
High Trigger Reachable External Ai Agent Control Surface Mutation
Manifest-trigger-reachable source writes behavior-bearing configuration into a user or project AI-agent control surface.
scripts/postinstall.js View on unpkg ,n.avgCorrectnessScore,o.avgCorrectnessScore,
true
),
Vt
(
"durationMs"
,n.avgDurationMs,o.avgDurationMs,
false
)]}
function
Vt
(
e
,
t
,
n
,
o
){
let
r
=
t
>
0
?
(n
-
t)
/
t
:
0
,s
=
o
?
r
<-
0.1
:
r
>
.1
,i
=
r
>
0
?
"+"
:
""
;
return
`${
e
}: ${
i
}${
(
r
*
100
).
toFixed
(
1
)
}%${
s
?
" (regression >10%)"
:
""}`
}
var
so
=
D
(()
=>
{});
var
ao
=
{};
j
(ao,{
reportEvaluationCommand
:()
=>
Dd,
runEvaluationCommand
:()
=>
Cd});
async
function
Cd
(
e
){
let
t
=
getBenchmarkSuite
(e.s
...
),console.
log
(
` ${
r
.
description
}`
))
:
console.
log
(
` ${
S
.
green
(
o
)
}`
);});}
else
{
if
(t.plugins.
length
===
0
){console.
log
(
"No plugins available."
);
return
}console.
log
(
`Available plugins (${
t
.
plugins
.
length
}):
log
(
` ${
S
.
green
(
o
.
name
)
}${
r
}v${
o
.
version
}`
),console.
log
(
` ${" "
.
repeat
(
n
)
}${
o
.
description
.
substring
(
0
,
60
)
}`
),o.tags.
length
>
0
&&
console.
log
(
` ${" "
.
repeat
(
n
)
}Tags: ${
o
.
tags
.
join
(
", "
)
}`
),console.
log
(
""
);}),console.
log
(
`
,
"Search keyword"
).
action
(
async
e
=>
{
let
t
=
je
(),n
=
e.
toLowerCase
(),o
=
t.plugins.
filter
(
r
=>
r.name.
toLowerCase
().
includes
(n)
||
r.description.
toLowerCase
().
includes
(n)
||
r.tags.
some
(
s
=>
s.
toLowerCase
().
includes
(n)));
if
(o.
length
===
0
){console.
log
(
`No plugins found matching "${
e
}"`
),console.
log
(
`
&&
console.
log
(
` Tags: ${
r
.
tags
.
join
(
", "
)
}`
),console.
log
(
` Size: ${
r
.
size
}`
),console.
log
(
""
);});});});
var
ni
=
{};
j
(ni,{
pluginInstallCommand
:()
=>
ng});
var
ng,oi
=
D
(()
=>
{
_e
();ng
=new
Command
(
"install"
).
description
(
"Install a plugin"
).
argument
(
"<name>"
,
"Plugin name (with or without @devflow-tools/ prefix)"
).
action
(
async
e
=>
{
let
n
=
`@devflow-tools/plugin-${
e
.
replace
(
/
^
@devflow-tools
\/
(?:plugin-)
?
/
,
""
)
}`
;console.
log
(
`Installing ${
n
}...`
);
try
{
let
o
=await
Ae
(n,process.
cwd
(),
!
0
);consol
...
false
,scan:e.scan
!==
false
,migrateLegacySkills:e.migrateLegacySkills});
if
(e.json
&&
s.onboardingPack)console.
log
(
JSON
.
stringify
(s.onboardingPack,
null
,
2
));else
if
(e.report
&&
s.onboardingPack)console.
log
(
r
(s.onboardingPack));else {
if
(s.created.length>0){console.
log
(
S
.
green
(
"Created:"
));
for
(
let
i
of
s.created)console.
log
(
` ${
S
.
dim
(
"+"
)
} ${
i
}`
);}else console.log(S.dim(
"Already initialized. Use --force ..
.