nativesoul 1.1.2 → 1.1.3
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.
- package/CHANGELOG.md +20 -0
- package/README.md +5 -5
- package/dist/package.json +1 -1
- package/dist/packages/cli/src/index.js +66 -66
- package/dist/packages/mcp-server/src/index.js +1 -1
- package/docs/adr/ADR-043-versioning-and-release-policy.md +1 -1
- package/docs/adr/ADR-045-paid-only-closed-distribution.md +11 -1
- package/package.json +1 -1
|
@@ -877,7 +877,7 @@ ${r.content}`),semantic_score:0,final_rank:o+1,reason:"fts_fallback"}}))}functio
|
|
|
877
877
|
`),u={host:e.host,generated_at:i,degraded:!0,warnings:c,tokens_used:mi(l),tokens_max:1900,content:l,targetPath:r,stale:s};if(e.recordTelemetry!==!1){await m({home:t.home,type:"bootstrap_context_cache_read",details:{...u,content:"[omitted]"}});let d=Hu(o);await Me({home:t.home,host:e.host,outcome:"degraded",tier:"D",cwd:d.cwd,project:d.project,tokensUsed:u.tokens_used,tokensMax:u.tokens_max,source:"bootstrap-cache",warnings:c})}return u}async function Zo(e){let t=await Qo({home:e.home,host:e.host,ttlDays:e.ttlDays,recordTelemetry:e.recordTelemetry});if(!t.warnings.includes("BOOTSTRAP_CACHE_MISSING")||!e.projectCwd)return t;let r=await Qo({home:pi(e.projectCwd),host:e.host,ttlDays:e.ttlDays,recordTelemetry:!1});return r.warnings.includes("BOOTSTRAP_CACHE_MISSING")?t:r}function ui(e,t){return di.join(e,"generated",t,"last-context.md")}function pi(e){return di.join(e,".nativesoul-cache")}async function Du(e){let t=new Date().toISOString(),r=["BOOTSTRAP_CACHE_MISSING"],o=["---","nativesoul: bootstrap-context-cache",`host: ${e.host}`,`generated_at: ${t}`,"degraded: true",`warnings: ${r.join(", ")}`,"---","","Bootstrap context cache is not available. Run `nativesoul bootstrap --format inject` after install."].join(`
|
|
878
878
|
`),n={host:e.host,generated_at:t,degraded:!0,warnings:r,tokens_used:mi(o),tokens_max:1900,content:o,targetPath:e.targetPath,stale:!1};return e.recordTelemetry!==!1&&(await m({home:e.home,type:"bootstrap_context_cache_missing",details:{...n,content:"[omitted]"}}),await Me({home:e.home,host:e.host,outcome:"degraded",tier:"D",cwd:null,project:null,tokensUsed:n.tokens_used,tokensMax:n.tokens_max,source:"bootstrap-cache",warnings:r})),n}function mi(e){return Math.ceil(e.length/4)}function Hu(e){let t=e.match(/^- CWD:\s*(.+)$/mu)?.[1]?.trim()??null,r=e.match(/^- ID:\s*(.+)$/mu)?.[1]?.trim()??null;return{cwd:t,project:r}}var Uu=3e3,Bu=new WeakMap;async function _t(e){let t=e.readOnly?p(e.home):await y(e.home),r=await Ku(t.home),o=Math.min(Math.max(e.tokensMax??r.defaultTokens,1),Uu),n=[];e.readOnly!==!0&&await tr({cwd:e.cwd,home:t.home});let a=ce(e.cwd,t.home),s=a.id;if(e.readOnly!==!0){let M=await pr({home:t.home,resolution:a});M.warning&&n.push(M.warning)}let i=qu({explicitQuery:e.query,project:s,host:e.host,cwd:e.cwd,seed:r.memoryQuerySeed}),c=await Vu({database:t.database,readOnly:e.readOnly===!0,memoryQuery:i,project:s,limit:r.recallLimit,warnings:n}),l=c.memories,u=await Ke({home:t.home,host:e.host,readyOnly:!0,limit:8,readOnly:e.readOnly}),d=await Yu(t.home,e.host,e.readOnly===!0),f=await No({home:t.home,host:e.host,query:e.query??`${fe.basename(e.cwd)} ${e.host}`,limit:8,readOnly:e.readOnly}),h=await Lo({home:t.home,project:s,status:"open",limit:8,readOnly:e.readOnly}),A=await G(t.home,"IDENTITY.md"),z=await G(t.home,"SOUL.md"),de=await G(t.home,"AGENTS.md"),Y=await G(t.home,"USER.md"),Ae=await G(t.home,"BOOTSTRAP.md"),$e=new Date().toISOString().slice(0,10),Nt=fe.join(t.home,"memory","daily",`${$e}.md`);n.push(...d?[]:[`HOST_ADAPTER_UNAVAILABLE:${e.host}`,"CAPABILITY_REFRESH_STALE"],...f.warnings),!await _(fe.join(t.home,"state","onboarding.complete"))&&Ae.trim().length>0&&n.push("BOOTSTRAP_RITUAL_PENDING"),await _(Nt)&&n.push(`DAILY_MEMORY_AVAILABLE:${Nt}`),r.warnEmptyMemories&&l.length===0&&n.push("PROJECT_MEMORY_EMPTY");let k={bootstrap_schema:2,identity:{name:Ne(A,"Name")??"NativeSoul",mission:Ne(A,"Mission")??"Provide local continuity across native coding-agent hosts.",creature:Ne(A,"Creature"),role:Ne(A,"Role"),vibe:Ne(A,"Vibe"),emoji:Ne(A,"Emoji")},soul_summary:ci(z||"Continuity, clarity, and safe local-first operation.",500),agents_operating_summary:li(de||"Load NativeSoul context before continuity-sensitive work. Use MCP when available and CLI fallback when needed."),tool_hints:Xu(),user:{preferences_summary:zu(Y)},project:{id:s,cwd:fe.resolve(e.cwd),state:"local-bootstrap"},commitments:h.map(M=>({id:M.id,status:M.status,summary:M.summary,due_at:M.due_at,ttl_expires_at:M.ttl_expires_at})),relevant_memories:l.map(M=>({id:M.id,summary:M.summary,scope:M.scope})),capabilities:u.map(M=>({uid:M.uid,host:M.host,ready:M.ready,source:M.source})),capability_cards:f.cards,policy:{mode:"safe",approval_required:["external_write","destructive","identity_policy_change"]},warnings:n},Xn=Qu(k,o),zn=dt(JSON.stringify(Xn)),Or={...Xn,context_budget:{tokens_used:zn,tokens_max:o}};return Bu.set(Or,{files:Wu({home:t.home,identityText:A,soulText:z,agentsText:de,userText:Y,bootstrapText:Ae,payload:Or}),memoryRecall:{query:i,limit:r.recallLimit,returned:l.length,mode:c.mode},cache:Ju(t.home,e.host)}),e.readOnly||await m({home:t.home,type:"bootstrap_created",details:{host:e.host,cwd:fe.resolve(e.cwd),project:s,tokens:zn}}),Or}async function Vu(e){if(!await _(e.database))return e.warnings.push("BOOTSTRAP_DATABASE_MISSING"),{memories:[],mode:"disabled"};let t=null;try{t=g(e.database,{readOnly:e.readOnly});let r=cr({database:e.database,query:e.memoryQuery,project:e.project,limit:e.limit,readOnly:e.readOnly});return{memories:r.memories.length===0?t.recentMemories(e.project,e.limit):r.memories,mode:r.mode}}catch(r){return e.warnings.push(`BOOTSTRAP_DATABASE_UNAVAILABLE:${Gu(r)}`),{memories:[],mode:"disabled"}}finally{t?.close()}}function Wu(e){return[yt({home:e.home,relativePath:"IDENTITY.md",role:"identity",rawText:e.identityText,injectedText:Object.values(e.payload.identity).filter(t=>typeof t=="string").join(`
|
|
879
879
|
`),fallbackReason:"missing; default identity fields injected"}),yt({home:e.home,relativePath:"SOUL.md",role:"soul_summary",rawText:e.soulText,injectedText:e.payload.soul_summary,fallbackReason:"missing; default soul summary injected"}),yt({home:e.home,relativePath:"AGENTS.md",role:"agents_operating_summary",rawText:e.agentsText,injectedText:e.payload.agents_operating_summary,fallbackReason:"missing; default agent operating summary injected"}),yt({home:e.home,relativePath:"USER.md",role:"user_preferences",rawText:e.userText,injectedText:e.payload.user.preferences_summary,fallbackReason:"missing; empty user-preferences fallback injected"}),yt({home:e.home,relativePath:"BOOTSTRAP.md",role:"onboarding_bootstrap",rawText:e.bootstrapText,injectedText:"",fallbackReason:"missing; no onboarding bootstrap warning",presentReason:"omitted; used only to emit BOOTSTRAP_RITUAL_PENDING"})]}function yt(e){let t=e.rawText.length,r=e.injectedText.length,o=t>0,n=r>0,a=o?e.presentReason??(r<t?"included; summarized to fit budget":"included"):e.fallbackReason;return{path:fe.join(e.home,e.relativePath),role:e.role,included:n,reason:a,rawChars:t,injectedChars:r,truncated:o&&n&&r<t,hash:o?$(e.rawText):null}}function Ju(e,t){let r=fe.join(e,"generated",t,"last-context.md");return{hit:Fu(r),key:r}}function Gu(e){return(e instanceof Error?e.message:String(e)).replace(/[^a-zA-Z0-9_.:-]+/g,"_").slice(0,120)}async function Ku(e){let t=await G(e,"config.yaml"),r=t.match(/^\s*default_tokens:\s*(\d+)\s*$/mu),o=t.match(/^\s*(?:bootstrap_recall_limit|recall_limit):\s*(\d+)\s*$/mu),n=t.match(/^\s*memory_query_seed:\s*["']?(.+?)["']?\s*$/mu),a=t.match(/^\s*warn_empty_memories:\s*(true|false)\s*$/imu),s=r?.[1]?Number(r[1]):1900,i=o?.[1]?Number(o[1]):5;return{defaultTokens:Number.isFinite(s)?s:1900,recallLimit:Number.isFinite(i)?Math.min(Math.max(i,1),8):5,memoryQuerySeed:n?.[1]?.trim()||null,warnEmptyMemories:a?.[1]?.toLowerCase()==="true"}}function qu(e){return[e.explicitQuery,e.project,e.host,fe.basename(fe.resolve(e.cwd)),e.seed].filter(t=>typeof t=="string"&&t.trim().length>0).join(" ")}function Xu(){return[{tool:"life_bootstrap",use_when:"Start a new session or refresh NativeSoul identity, project context, memories, and capability cards."},{tool:"life_recall",use_when:"Search local memories for project-specific continuity before making assumptions."},{tool:"life_remember_propose",use_when:"Propose durable memory from user-approved facts, outcomes, or preferences."},{tool:"life_onboarding_status",use_when:"Check whether onboarding is pending before drafting or applying identity files."}]}function zu(e){let t=e.trim();return t.length===0?"No curated user preferences yet.":t.length<=160?t:`${t.slice(0,157)}...`}async function Yu(e,t,r=!1){let o=await Ke({home:e,host:t,includeShared:!1,limit:20,readOnly:r});if(t==="codex"&&!o.some(i=>i.source.startsWith("codex app server ")))return!1;let n=o[0]?.last_seen_at;if(!n)return!1;let a=Date.parse(n);if(!Number.isFinite(a))return!1;let s=1440*60*1e3;return Date.now()-a<=s}function Qu(e,t){let r=[e,ke(e,1200,420,150),ke(e,900,320,130),ke(e,650,240,110),ke(e,420,180,90),ke(e,240,120,80),en(ke(e,240,120,80),8,8),en(ke(e,240,120,80),5,5),en(ke(e,240,120,80),3,3)];return r.find(o=>dt(JSON.stringify(o))<=t)??r[r.length-1]??e}function en(e,t,r){return{...e,capabilities:e.capabilities.slice(0,t),capability_cards:e.capability_cards.slice(0,r),relevant_memories:e.relevant_memories.slice(0,t),commitments:e.commitments.slice(0,t)}}function ke(e,t,r,o){return{...e,soul_summary:lr(e.soul_summary,r),agents_operating_summary:lr(e.agents_operating_summary,t),user:{...e.user,preferences_summary:lr(e.user.preferences_summary,o)}}}import{existsSync as bn}from"node:fs";import Vi from"node:path";function tn(e){let t={bootstrap:Zu(e),mcp:ep(e),plugins_hooks:tp(e),heartbeat:rp(e),recall_auto_trigger:op(e),memory_candidate_hooks:np(e),memory_promotion_policy:ap(e),cross_host_verification:sp(e)},r=Object.values(t),o=ip(r),n=r.flatMap(s=>s.plan_actions),a=cp(e.profile,o,r);return{schema_version:1,home:e.home,target_root:e.targetRoot,host:e.host,profile:e.profile,overall_status:o,components:t,plan:n,summary:a}}function gi(e){return tn(e).summary}function Zu(e){return e.onboardingComplete&&e.activationComplete&&e.profile?x("bootstrap","active","Identity onboarding and activation marker are present.",{onboarding_complete:!0,activation_complete:!0}):x("bootstrap",e.onboardingComplete?"approval_required":"not_configured",e.onboardingComplete?"Activation profile still needs explicit approval.":"Identity onboarding is not complete.",{onboarding_complete:e.onboardingComplete,activation_complete:e.activationComplete},[Le("activation-profile","bootstrap","approval_required","Write activation profile and completion marker.",`${e.home}/state/activation-profile.json`,!0,"17.1 activation apply is explicit-approval only.")])}function ep(e){let t=e.hosts.filter(r=>r.mcp_registration.configured);if(t.length>0){let r=t.some(o=>o.mcp_registration.issues.length>0);return x("mcp",r?"degraded":"active",r?"MCP is configured but doctor reported warnings.":"MCP registration is configured.",{configured_hosts:t.map(X),checked_hosts:e.hosts.map(X)})}return x("mcp","not_configured","No MCP registration was detected for the selected host scope.",{checked_hosts:e.hosts.map(X)},[Le("mcp-registration","mcp","not_configured","Install MCP registration for selected hosts.",`nativesoul mcp install --host ${e.host} --apply`,!0,"MCP registration changes host config files.")])}function tp(e){let t=e.hosts.filter(o=>o.plugin.enabled||o.plugin.hook_registered);if(t.length>0){let o=t.some(n=>n.provider_parity.hooks==="official-fallback");return x("plugins_hooks",o?"degraded":"active",o?"Plugin/hooks are available through fallback support.":"Native plugin or hook support is active.",{enabled_hosts:t.map(X),hook_modes:Object.fromEntries(e.hosts.map(n=>[X(n),n.provider_parity.hooks]))})}let r=e.hosts.length>0&&e.hosts.every(o=>o.plugin.package_kind==="unsupported-native");return x("plugins_hooks",r?"blocked_by_host":"not_configured",r?"Selected hosts do not expose a native plugin path.":"No plugin or hook registration was detected.",{checked_hosts:e.hosts.map(X)},[Le("plugin-install","plugins_hooks",r?"blocked_by_host":"not_configured","Install NativeSoul plugin/hook package where the host supports it.",`nativesoul install --host ${e.host} --apply`,!0,"Host plugin/hook setup modifies host-specific config.")])}function rp(e){if(!e.profile||!e.profile.heartbeat_enabled)return x("heartbeat","not_configured","Heartbeat is not enabled in the activation profile.",{profile_present:e.profile!==null});let t=e.hosts.filter(r=>r.full_native_evidence.blocked_by_host);return t.length>0?x("heartbeat","blocked_by_host","At least one selected host lacks native scheduler support.",{blocked_hosts:t.map(X),heartbeat_modes:Object.fromEntries(e.hosts.map(r=>[X(r),r.provider_parity.heartbeat]))},[Le("heartbeat-scheduler","heartbeat","blocked_by_host","Choose a native scheduler-capable host or keep external fallback explicit.",`nativesoul schedule reconcile --host ${e.host} --mode leader --apply`,!0,"Scheduler writes must remain explicit and host-aware.")]):e.hosts.some(r=>r.provider_parity.heartbeat==="native")?x("heartbeat","active","Heartbeat has native scheduler support in the selected scope.",{native_hosts:e.hosts.filter(r=>r.provider_parity.heartbeat==="native").map(X)}):e.hosts.some(r=>r.provider_parity.heartbeat==="official-fallback")?x("heartbeat","degraded","Heartbeat is available only through fallback scheduling in the selected scope.",{fallback_hosts:e.hosts.filter(r=>r.provider_parity.heartbeat==="official-fallback").map(X)}):x("heartbeat","approval_required","Heartbeat profile is enabled, but no scheduler desired state is active yet.",{checked_hosts:e.hosts.map(X)},[Le("heartbeat-enable","heartbeat","approval_required","Create/reconcile recurring heartbeat schedule.",`nativesoul schedule reconcile --host ${e.host} --mode leader --apply`,!0,"Recurring automation requires explicit approval.")])}function op(e){return e.profile?e.profile.recall_auto_trigger?x("recall_auto_trigger","active","Automatic recall trigger is enabled in the activation profile.",{keywords:e.profile.recall_auto_trigger_keywords,denylist:e.profile.recall_auto_trigger_denylist,auto_promotion_threshold:e.profile.candidate_auto_promotion_threshold}):x("recall_auto_trigger","approval_required","Automatic recall trigger is intentionally disabled until explicit approval.",{recall_auto_trigger:!1},[Le("recall-auto-trigger","recall_auto_trigger","approval_required","Set recall_auto_trigger=true in activation profile.","state/activation-profile.json:recall_auto_trigger",!0,"Prompt injection into host sessions must be explicitly approved.")]):x("recall_auto_trigger","not_configured","No activation profile is present.",{})}function np(e){if(!e.profile||!e.profile.memory_candidates)return x("memory_candidate_hooks","not_configured","Memory candidate hooks are not enabled in the activation profile.",{});let t=e.hosts.every(r=>r.provider_parity.hooks==="unsupported-native");return x("memory_candidate_hooks",t?"degraded":"active",t?"Memory candidates are enabled, but hooks are not native on every selected host.":"Memory candidate capture is enabled with candidate-only policy.",{memory_candidate_policy:e.profile.memory_candidate_policy,hook_modes:Object.fromEntries(e.hosts.map(r=>[X(r),r.provider_parity.hooks]))})}function ap(e){return e.profile?e.profile.auto_promotion?x("memory_promotion_policy","active","Automatic promotion is enabled by activation policy.",{promotion_policy:e.profile.promotion_policy,candidate_auto_promotion_threshold:e.profile.candidate_auto_promotion_threshold,sensitive_auto_promotion_allowed:!1}):x("memory_promotion_policy","approval_required","Memory promotion requires explicit approval.",{auto_promotion:!1,promotion_policy:e.profile.promotion_policy}):x("memory_promotion_policy","not_configured","No activation profile is present.",{})}function sp(e){let t=new Set(e.hosts.map(o=>o.host)).size,r=e.hosts.reduce((o,n)=>o+n.cross_host_inventory_summary.ready_other_hosts,0);return t>1&&e.hosts.every(o=>o.status==="ready")?x("cross_host_verification","active","Multiple selected hosts were verified by deep doctor.",{host_count:t,ready_other_hosts:r}):x("cross_host_verification",r>0?"degraded":"approval_required","Cross-host verification needs an all-host deep doctor pass before full activation claims.",{host_count:t,ready_other_hosts:r},[Le("cross-host-verify","cross_host_verification","approval_required","Run all-host deep verification.","nativesoul doctor --deep --all-hosts --json",!1,"Verification is read-only but must be run against every host.")])}function x(e,t,r,o,n=[]){return{key:e,status:t,summary:r,evidence:o,plan_actions:n}}function Le(e,t,r,o,n,a,s){return{id:e,component:t,status:r,action:o,target:n,dry_run:!0,requires_user_confirmed:a,reason:s}}function ip(e){let t=e.map(r=>r.status);return t.includes("blocked_by_host")?"blocked_by_host":t.includes("degraded")?"degraded":t.includes("approval_required")?"approval_required":t.includes("not_configured")?"not_configured":"active"}function cp(e,t,r){return{overall_status:t,profile:e?.profile??null,active:bt(r,"active"),not_configured:bt(r,"not_configured"),approval_required:bt(r,"approval_required"),blocked_by_host:bt(r,"blocked_by_host"),degraded:bt(r,"degraded"),full_native_claimed:!1}}function bt(e,t){return e.filter(r=>r.status===t).length}function X(e){return e.surface==="default"?e.host:`${e.host}:${e.surface}`}import{existsSync as lp}from"node:fs";import dp from"node:path";async function rn(e){let t=p(e),r=[],o=["AGENTS.md","SOUL.md","IDENTITY.md","USER.md","POLICY.md","MEMORY.md","HEARTBEAT.md","config.yaml"];for(let a of o)await _(dp.join(t.home,a))||r.push({code:"MISSING_HUMAN_FILE",severity:"warn",message:`${a} is missing`,remediation:"Run nativesoul init"});if(!lp(t.database))return r.push({code:"MISSING_DATABASE",severity:"error",message:"SQLite state database is missing",remediation:"Run nativesoul init"}),{home:t.home,healthy:!1,integrity:"missing",issues:r};let n=(()=>{let a=g(t.database,{readOnly:!0});try{return a.integrityCheck()}finally{a.close()}})();n!=="ok"&&r.push({code:"SQLITE_INTEGRITY",severity:"error",message:`SQLite integrity check returned ${n}`,remediation:"Restore from backup or rebuild the workspace"}),r.push(...up(t.home,t.database));try{await m({home:t.home,type:"doctor_completed",details:{integrity:n,issueCount:r.length}})}catch{}return{home:t.home,healthy:r.every(a=>a.severity!=="error"),integrity:n,issues:r}}function up(e,t){let r=ce(process.cwd(),e),o=g(t,{readOnly:!0});try{let n=new Set(o.listMemories({limit:200,includeForgotten:!0}).map(a=>a.scope.project).filter(a=>a!==r.id));return n.size===0?[]:[{code:"PROJECT_ID_RECONCILE_AVAILABLE",severity:"info",message:`Found ${n.size} memory project id(s) different from normalized current project ${r.id}.`,remediation:"Review with nativesoul memory export --project <old-id>; a future reconcile command will migrate aliases after approval."}]}finally{o.close()}}import te from"node:os";import D from"node:path";function fi(e){switch(e){case"grok":return"Agents.md";case"codex":return"AGENTS.md";case"claude":return"CLAUDE.md";case"antigravity":case"gemini":return"GEMINI.md"}}function hi(e){return e==="claude"?".claude.json":e==="gemini"?"settings.json":e==="antigravity"?"mcp_config.json":"mcp.json"}function mr(e,t){if(t==null||t==="default")return e==="claude"?"claude-code":"default";if(e!=="claude")throw new Error(`--surface ${t} is only supported for --host claude`);return t}function vt(e,t){return t&&t!=="default"?[mr(e,t)]:e==="claude"?["claude-code","claude-desktop"]:["default"]}function kt(e,t){return t==="default"?e:t}function yi(e){switch(e){case"codex":return D.join(te.homedir(),".codex","AGENTS.md");case"claude":return D.join(te.homedir(),".claude","CLAUDE.md");case"grok":return D.join(te.homedir(),".grok","Agents.md");case"antigravity":case"gemini":return D.join(te.homedir(),".gemini","GEMINI.md")}}function gr(e){switch(e){case"codex":return D.join(te.homedir(),".codex","mcp.json");case"claude":return D.join(te.homedir(),".claude.json");case"grok":return D.join(te.homedir(),".grok","mcp.json");case"antigravity":return D.join(te.homedir(),".gemini","antigravity-cli","mcp_config.json");case"gemini":return D.join(te.homedir(),".gemini","settings.json")}}function _i(){return bi({platform:process.platform,home:te.homedir(),env:process.env})}function bi(e){let t=e.platform==="win32"?D.win32:D.posix;if(e.platform==="darwin")return t.join(e.home,"Library","Application Support","Claude","claude_desktop_config.json");if(e.platform==="win32"){let o=e.env?.APPDATA&&e.env.APPDATA.trim().length>0?e.env.APPDATA:t.join(e.home,"AppData","Roaming");return t.join(o,"Claude","claude_desktop_config.json")}let r=e.env?.XDG_CONFIG_HOME&&e.env.XDG_CONFIG_HOME.trim().length>0?e.env.XDG_CONFIG_HOME:t.join(e.home,".config");return t.join(r,"Claude","claude_desktop_config.json")}function vi(e,t){if(e!=="claude")return null;if(!t)return D.join(te.homedir(),".claude","mcp.json");let r=D.resolve(t),o=D.dirname(r);return D.basename(o)==="claude"?D.join(o,"mcp.json"):D.join(o,".claude","mcp.json")}function ki(e,t){return t?si(e):pp()}function pp(){return{provider_id:"local-hash",model_id:"local-hash-bow-v1",schema_version:1,available:!1,indexable_count:0,indexed_count:0,stale_count:0,healthy:!1,remediation:"Run nativesoul init, then nativesoul memory index"}}function Ri(e){return!e.available||e.stale_count===0?[]:[{code:"SEMANTIC_INDEX_STALE",severity:"warn",message:`${e.stale_count} memory record(s) need semantic indexing.`,remediation:e.remediation??"Run nativesoul memory index"}]}function Si(e){let t=new Map;for(let o of e){let n=t.get(o.host)??{capability_count:0,ready_capability_count:0};t.set(o.host,{capability_count:n.capability_count+1,ready_capability_count:n.ready_capability_count+(o.ready?1:0)})}let r=Array.from(t.entries()).map(([o,n])=>({host:o,...n}));return{host_count:r.length,capability_count:r.reduce((o,n)=>o+n.capability_count,0),ready_capability_count:r.reduce((o,n)=>o+n.ready_capability_count,0),hosts:r}}function fr(e){let t=g(e,{readOnly:!0});try{return t.listCapabilities({limit:1e4}).map(r=>({host:r.host,ready:r.ready}))}finally{t.close()}}import{existsSync as Bp}from"node:fs";import{readFile as Vp,stat as Wp}from"node:fs/promises";import Ui from"node:path";import wt from"node:path";import{existsSync as Ik}from"node:fs";import{cp as jk,mkdir as Ck,rm as Ok}from"node:fs/promises";import Mk from"node:path";import{existsSync as Se}from"node:fs";import{readFile as kr}from"node:fs/promises";import ye from"node:path";import mp from"node:path";function hr(e){return e.split(/[\\/]/u).join("/")}function Rt(e,t){return hr(mp.relative(e,t))}import{existsSync as wi}from"node:fs";import on from"node:path";function nn(e){if(on.isAbsolute(e))return wi(e)?e:null;let t=(process.env.PATH??"").split(on.delimiter).filter(Boolean),r=process.platform==="win32"?(process.env.PATHEXT??".EXE;.CMD;.BAT").split(";"):[""];for(let o of t)for(let n of r){let a=on.join(o,`${e}${n}`);if(wi(a))return a}return null}import{spawnSync as dv}from"node:child_process";import{existsSync as br}from"node:fs";import{mkdir as mv,readFile as vr,writeFile as gv}from"node:fs/promises";import gp from"node:os";import he from"node:path";import{existsSync as ov}from"node:fs";import St from"node:os";import re from"node:path";import{fileURLToPath as iv}from"node:url";function Re(e,t,r){return yr(e,t)?r?re.join(re.resolve(r),e,"plugins","nativesoul"):e==="claude"?re.join(St.homedir(),".claude","plugins","nativesoul"):e==="codex"?re.join(St.homedir(),".codex","plugins","nativesoul"):e==="gemini"?re.join(St.homedir(),".gemini","extensions","nativesoul"):e==="grok"?re.join(St.homedir(),".grok","plugins","nativesoul"):e==="antigravity"?re.join(St.homedir(),".antigravity","plugins","nativesoul"):null:null}function yr(e,t){return e==="codex"||e==="gemini"||e==="grok"||e==="antigravity"||e==="claude"&&(t==="claude-code"||t==="claude-desktop")}function _r(e,t){return e==="claude"?re.join(t,".claude-plugin","plugin.json"):e==="gemini"?re.join(t,"gemini-extension.json"):e==="grok"||e==="antigravity"?re.join(t,"plugin.json"):re.join(t,".codex-plugin","plugin.json")}var Ei="nativesoul",Ai="nativesoul";async function Ii(e){let t=e?_p(e):he.join(gp.homedir(),".grok","config.toml");if(!br(t))return null;let r=await vr(t,"utf8");return Pi(r,"disabled",Ei)?!1:Pi(r,"enabled",Ei)?!0:null}async function Ti(e){let t=yp(e);if(!br(t))return!1;let r=JSON.parse(await vr(t,"utf8"));return fp(r)}async function ji(e){let t=Ci(e),r=he.join(t,"agents",`${Ai}.md`),o=he.join(t,"config.toml");if(!br(r)||!br(o))return!1;let[n,a]=await Promise.all([vr(r,"utf8"),vr(o,"utf8")]);return n.includes("NativeSoul continuity agent")&&bp(a)===Ai}function Pi(e,t,r){let a=(e.match(/\[plugins\][\s\S]*?(?=\n\[|$)/u)?.[0]??e).match(new RegExp(`${t}\\s*=\\s*\\[([^\\]]*)\\]`,"u"))?.[1];return a?a.split(",").some(s=>s.replace(/["'\s]/gu,"")===r):!1}function fp(e){let t=e.hooks;return!t||Array.isArray(t)||typeof t!="object"?!1:[["SessionStart","session-start --host grok"],["UserPromptSubmit","prompt-bootstrap --host grok"],["PreToolUse","pre-tool-use --host grok"],["Stop","memory-flush --host grok"],["PreCompact","memory-flush --host grok"]].every(([o,n])=>hp(t,o,n))}function hp(e,t,r){let o=e[t];return Array.isArray(o)?o.some(n=>vp(n)?.includes(r)===!0):!1}function yp(e){return he.join(Ci(e),"hooks","nativesoul.json")}function Ci(e){return he.resolve(e,"..","..")}function _p(e){let t=he.resolve(e),r=he.basename(t);return r==="grok"||r===".grok"?he.join(t,"config.toml"):he.join(t,".grok","config.toml")}function bp(e){return e.match(/\[agent\][\s\S]*?(?=\n\[|$)/u)?.[0]?.match(/\bname\s*=\s*["']([^"']+)["']/u)?.[1]??null}function vp(e){if(!e||Array.isArray(e)||typeof e!="object")return null;let t=e.hooks;if(!Array.isArray(t)||t.length===0)return null;let r=t[0];if(!r||Array.isArray(r)||typeof r!="object")return null;let o=r.command;return typeof o=="string"?o:null}import kp from"node:path";var an=[{event:"SessionStart",commandFragment:"hooks/session-start.cjs",fileName:"session-start.cjs"},{event:"PreToolUse",commandFragment:"hooks/pre-tool-use.cjs",fileName:"pre-tool-use.cjs"},{event:"Stop",commandFragment:"hooks/memory-flush.cjs",fileName:"memory-flush.cjs"},{event:"PreCompact",commandFragment:"hooks/memory-flush.cjs",fileName:"memory-flush.cjs"},{event:"UserPromptSubmit",commandFragment:"hooks/user-prompt-submit.cjs",fileName:"user-prompt-submit.cjs"}],Rp={grok:[{event:"SessionStart",commandFragment:"host-hook.cjs"},{event:"UserPromptSubmit",commandFragment:"prompt-bootstrap --host grok"},{event:"PreToolUse",commandFragment:"pre-tool-use --host grok"},{event:"Stop",commandFragment:"memory-flush --host grok"},{event:"PreCompact",commandFragment:"memory-flush --host grok"}],gemini:[{event:"SessionStart",commandFragment:"host-hook.cjs"},{event:"BeforeAgent",commandFragment:"prompt-bootstrap --host gemini"},{event:"BeforeTool",commandFragment:"pre-tool-use --host gemini"},{event:"AfterAgent",commandFragment:"memory-flush --host gemini"},{event:"PreCompress",commandFragment:"memory-flush --host gemini"}],antigravity:[{event:"SessionStart",commandFragment:"host-hook.cjs"},{event:"UserPromptSubmit",commandFragment:"prompt-bootstrap --host antigravity"},{event:"PreToolUse",commandFragment:"pre-tool-use --host antigravity"},{event:"Stop",commandFragment:"memory-flush --host antigravity"},{event:"PreCompact",commandFragment:"memory-flush --host antigravity"}]};function sn(e,t){return e==="codex"||e==="claude"||e==="grok"||e==="antigravity"?{packageKind:"native-plugin",nativeHooksSupported:!0}:e==="gemini"?{packageKind:"official-extension",nativeHooksSupported:!0}:{packageKind:"unsupported-native",nativeHooksSupported:!1}}function Sp(e){return e==="grok"||e==="gemini"||e==="antigravity"?Rp[e]:an}function cn(e){return e==="grok"||e==="gemini"?["hooks/hooks.json"]:e==="antigravity"?["hooks.json"]:[...new Set(an.map(t=>t.fileName).filter(t=>!!t))].map(t=>kp.join("hooks",t))}function Oi(e,t){return t==="official-extension"?typeof e.name=="string"&&e.name==="nativesoul":typeof e.name=="string"&&e.name.includes("nativesoul")}function Ni(e,t){return ln(e,t).length===0}function ln(e,t){return Sp(e).filter(({event:r,commandFragment:o})=>!wp(t,r,o)).map(({event:r})=>r)}function dn(e){return e==="claude"?[".claude-plugin/plugin.json"]:e==="codex"?[".mcp.json"]:e==="gemini"?["gemini-extension.json"]:e==="grok"?[".mcp.json"]:e==="antigravity"?["mcp_config.json"]:[]}function un(e){return e==="claude"?[".claude-plugin/plugin.json"]:e==="codex"?[".codex-plugin/plugin.json"]:e==="gemini"||e==="grok"?["hooks/hooks.json"]:e==="antigravity"?["hooks.json"]:[]}function wp(e,t,r){if(!e.hooks||Array.isArray(e.hooks)||typeof e.hooks!="object")return!1;let n=e.hooks[t];return!Array.isArray(n)||n.length===0?!1:n.some(a=>{if(!a||Array.isArray(a)||typeof a!="object")return!1;let s=a.hooks;return!Array.isArray(s)||s.length===0?!1:s.some(i=>{if(!i||Array.isArray(i)||typeof i!="object")return!1;let c=i.command;return typeof c=="string"&&hr(c).includes(r)})})}async function ze(e){if(!e.targetPath||!yr(e.host,e.surface))return{host:e.host,surface:e.surface,targetPath:e.targetPath,target_exists:!1,manifest_exists:!1,enabled:!1,hook_registered:!1,package_kind:"unsupported-native",native_hooks_supported:!1,native_scheduler_supported:!1,issues:[]};let t=sn(e.host,e.surface),r=Se(e.targetPath),o=_r(e.host,e.targetPath),n=Se(o),a=t.nativeHooksSupported&&e.targetPath?cn(e.host).filter(Y=>!Se(ye.join(e.targetPath,Y))):cn(e.host),s=t.nativeHooksSupported?a.length===0:!0,i=[],c=!1,l=!t.nativeHooksSupported,u=e.host!=="grok";if(!r)i.push({code:"PLUGIN_NOT_INSTALLED",severity:"warn",message:`NativeSoul plugin is not installed for ${e.host}:${e.surface}.`,remediation:`Run nativesoul install --host ${e.host} --apply`});else if(!n)i.push({code:"PLUGIN_MANIFEST_MISSING",severity:"error",message:`NativeSoul plugin manifest is missing: ${o}`,remediation:"Reinstall the NativeSoul plugin"});else{let Y=JSON.parse(await kr(o,"utf8")),Ae=t.nativeHooksSupported?await Ep(e.host,e.targetPath,Y):Y;if(c=t.nativeHooksSupported?e.host==="grok"?await Ti(e.targetPath):Ni(e.host,Ae):Oi(Y,t.packageKind),l=!t.nativeHooksSupported||await Ap({host:e.host,targetPath:e.targetPath,manifest:Y}),u=e.host==="grok"?await ji(e.targetPath):!0,e.host==="grok"&&!u&&i.push({code:"GROK_AGENT_PROFILE_MISSING",severity:"error",message:"NativeSoul Grok hooks are installed, but Grok is not configured to use the NativeSoul agent profile for first-turn bootstrap.",remediation:"Run `nativesoul install --host grok --apply` to install ~/.grok/agents/nativesoul.md and set [agent].name."}),t.nativeHooksSupported&&!l&&i.push({code:"PLUGIN_MCP_COMMAND_UNRESOLVED",severity:"error",message:"NativeSoul plugin MCP server command is not resolved for daemon-safe startup.",remediation:"Reinstall the NativeSoul plugin so its MCP server command is rendered with an absolute or executable command"}),!c&&t.nativeHooksSupported){let $e=ln(e.host,Ae);i.push({code:"PLUGIN_HOOK_MISSING",severity:"error",message:$e.length>0?`NativeSoul plugin manifest is missing required hook registrations: ${$e.join(", ")}.`:"NativeSoul plugin manifest does not register required continuity hooks.",remediation:"Reinstall the NativeSoul plugin"})}!c&&!t.nativeHooksSupported&&i.push({code:"PLUGIN_PACKAGE_MANIFEST_INVALID",severity:"error",message:`NativeSoul ${t.packageKind} manifest is invalid for ${e.host}.`,remediation:"Reinstall the NativeSoul package"})}r&&t.nativeHooksSupported&&!s&&i.push({code:"PLUGIN_HOOK_FILE_MISSING",severity:"error",message:`NativeSoul required hook files are missing under ${e.targetPath}: ${a.join(", ")}`,remediation:"Reinstall the NativeSoul plugin"});let d=e.targetPath?ye.join(e.targetPath,"shared","hooks","lib.cjs"):null;r&&t.nativeHooksSupported&&(!d||!Se(d))&&i.push({code:"PLUGIN_SHARED_HOOKS_MISSING",severity:"error",message:"NativeSoul shared hook support files are missing under shared/hooks.",remediation:"Reinstall the NativeSoul plugin"});let f=e.targetPath?ye.resolve(ye.dirname(ye.dirname(e.targetPath))):void 0,h=!t.nativeHooksSupported||d!==null&&Se(d),A=t.nativeHooksSupported?s&&h:!0,z=r&&n&&c&&A&&l&&u,de=e.host==="grok"?await Ii(f):null;return e.host==="grok"&&z&&de===!1&&i.push({code:"GROK_PLUGIN_RUNTIME_DISABLED",severity:"error",message:"NativeSoul is installed for Grok but disabled in grok config, so SessionStart hooks will not run.",remediation:"Run `grok plugin enable nativesoul` or `nativesoul install --host grok --apply`."}),{host:e.host,surface:e.surface,targetPath:e.targetPath,target_exists:r,manifest_exists:n,enabled:z&&de!==!1,hook_registered:t.nativeHooksSupported?c&&s:!1,package_kind:t.packageKind,native_hooks_supported:t.nativeHooksSupported,native_scheduler_supported:!1,issues:i}}async function Ep(e,t,r){let o=un(e);if(o.length===0)return r;let n=Rt(t,_r(e,t)),a=o[0];if(!a||a===n)return r;let s=ye.join(t,a);return Se(s)?JSON.parse(await kr(s,"utf8")):{}}async function Ap(e){let t=dn(e.host),r=Rt(e.targetPath,_r(e.host,e.targetPath));if(t.length>0&&!t.includes(r)){for(let o of t){let n=ye.join(e.targetPath,o);if(Se(n)&&pn(JSON.parse(await kr(n,"utf8"))))return!0}return!1}if(e.host==="codex"){let o=ye.join(e.targetPath,".mcp.json");return Se(o)?pn(JSON.parse(await kr(o,"utf8"))):!1}return pn(e.manifest)}function pn(e){let r=(!e.mcpServers||Array.isArray(e.mcpServers)||typeof e.mcpServers!="object"?null:e.mcpServers)?.nativesoul??(!e.nativeSoul||Array.isArray(e.nativeSoul)||typeof e.nativeSoul!="object"?null:e.nativeSoul.mcpServer);if(!r||Array.isArray(r)||typeof r!="object")return!1;let o=r.command,n=r.args;return typeof o!="string"||o.length===0?!1:o==="nativesoul-mcp"||nn(o)||o===process.execPath?!0:Array.isArray(n)&&n.some(a=>typeof a=="string"&&ye.isAbsolute(a))}import{cp as Nv,mkdir as Mv,readFile as Lv,readdir as Dv}from"node:fs/promises";import $v from"node:path";import{existsSync as ek}from"node:fs";import{cp as rk,mkdir as ok,readFile as nk,writeFile as ak}from"node:fs/promises";import ik from"node:path";import{fileURLToPath as lk}from"node:url";import{spawnSync as Wv}from"node:child_process";import{accessSync as Gv,constants as Kv,existsSync as qv}from"node:fs";import zv from"node:path";function Rr(e,t,r){let o=mr(e,r);if(e==="claude"&&o==="claude-desktop")return{surface:o,managedBlock:null,mcpRegistration:t?wt.join(wt.resolve(t,e),"claude_desktop_config.json"):_i(),plugin:Re(e,o,t)};if(!t)return{surface:o,managedBlock:yi(e),mcpRegistration:gr(e),plugin:Re(e,o)};let n=wt.resolve(t,e);return{surface:o,managedBlock:wt.join(n,fi(e)),mcpRegistration:wt.join(n,hi(e)),plugin:Re(e,o,t)}}import{accessSync as xp,constants as Ip,existsSync as Et}from"node:fs";import{mkdir as rR,readFile as mn,rm as oR,writeFile as nR}from"node:fs/promises";import le from"node:path";async function hn(e){let t=le.resolve(e.targetPath??Hi(e.host)),r=vi(e.host,e.targetPath),o=Et(t),n=[],a=await Tp(e.host,t,r);if(a&&n.push(a),!o)return n.push({code:"MCP_CONFIG_MISSING",severity:"warn",message:`MCP config target is missing: ${t}`,remediation:"Run nativesoul mcp install --host <host> --target <path> --apply"}),{host:e.host,targetPath:t,target_exists:!1,parse_ok:!1,configured:!1,command:null,command_ok:!1,issues:n};let s=null;try{s=gn(await mn(t,"utf8"))}catch(d){n.push({code:"MCP_CONFIG_INVALID_JSON",severity:"error",message:d instanceof Error?d.message:"MCP config is invalid JSON",remediation:"Fix the JSON syntax or roll back from an NativeSoul snapshot"})}let i=s?fn(s):null,c=typeof i?.command=="string"?i.command:null,l=Array.isArray(i?.args)?i.args.filter(d=>typeof d=="string"):[];i?c||n.push({code:"NATIVESOUL_MCP_COMMAND_MISSING",severity:"error",message:"nativesoul MCP server command is missing",remediation:"Re-run nativesoul mcp install"}):n.push({code:"NATIVESOUL_MCP_MISSING",severity:"warn",message:"nativesoul MCP server entry is not configured",remediation:"Run nativesoul mcp install --host <host> --target <path> --apply"});let u=c?e.checkCommand===!1?{ok:!0,issues:[]}:jp(c,l,t):{ok:!1,issues:[]};return n.push(...u.issues),{host:e.host,targetPath:t,target_exists:o,parse_ok:s!==null,configured:i!==null,command:c,command_ok:u.ok,issues:n}}function Hi(e){return gr(e)}function gn(e){if(e===null||e.trim().length===0)return{};let t=JSON.parse(e);if(!t||typeof t!="object"||Array.isArray(t))throw new Error("MCP config root must be a JSON object");return t}function fn(e){let t=e.mcpServers;if(!t||typeof t!="object"||Array.isArray(t))return null;let r=t.nativesoul;return!r||typeof r!="object"||Array.isArray(r)?null:r}async function Tp(e,t,r){if(e!=="claude"||r===null||le.resolve(r)===t||!Et(r))return null;try{let o=gn(await mn(r,"utf8")),n=fn(o);if(!n)return null;if(Et(t)){let a=gn(await mn(t,"utf8")),s=fn(a);if(s&&JSON.stringify(Li(s))===JSON.stringify(Li(n)))return null}}catch{return null}return{code:"LEGACY_MCP_PATH",severity:"warn",message:`Legacy Claude MCP registration detected at ${r}.`,remediation:"Migrate to ~/.claude.json with nativesoul mcp install --host claude --apply, then uninstall or roll back the legacy ~/.claude/mcp.json entry."}}function Li(e){return{command:typeof e.command=="string"?e.command:null,args:Array.isArray(e.args)?e.args.filter(t=>typeof t=="string"):[]}}function jp(e,t,r){let o=[],n=Cp(e);if(!n)return o.push({code:"NATIVESOUL_MCP_COMMAND_UNRESOLVED",severity:"error",message:`nativesoul MCP command does not resolve to an executable: ${e}`,remediation:"Reinstall with NATIVESOUL_MCP_COMMAND set to an absolute nativesoul-mcp path, or run npm install -g nativesoul and retry."}),{ok:!1,issues:o};if(Op(e,n)){let a=t[0],s=a?le.isAbsolute(a)?a:le.resolve(le.dirname(r),a):null;if(!s||!Et(s))return o.push({code:"NATIVESOUL_MCP_NODE_SCRIPT_MISSING",severity:"error",message:"nativesoul MCP command uses node but the server script is missing.",remediation:"Re-run nativesoul mcp install with --command-mode absolute or rebuild the local package."}),{ok:!1,issues:o}}return{ok:!0,issues:o}}function Cp(e){if(le.isAbsolute(e))return Di(e)?e:null;let t=(process.env.PATH??"").split(le.delimiter).filter(Boolean),r=process.platform==="win32"?(process.env.PATHEXT??".EXE;.CMD;.BAT").split(";"):[""];for(let o of t)for(let n of r){let a=le.join(o,`${e}${n}`);if(Di(a))return a}return null}function Di(e){if(process.platform==="win32"&&Et(e))return!0;try{return xp(e,Ip.X_OK),!0}catch{return!1}}function Op(e,t){let r=le.basename(e).toLowerCase(),o=le.basename(t).toLowerCase();return r==="node"||r==="node.exe"||o==="node"||o==="node.exe"}async function yn(e){let t=e.readOnly?p(e.home):await y(e.home);if(e.readOnly&&!await _(t.database))return[];let r=g(t.database,{readOnly:e.readOnly});try{return r.listSchedules({host:e.host,limit:Math.min(Math.max(e.limit??50,1),200)})}finally{r.close()}}function _n(e){let t=e.observedAt??new Date().toISOString(),r=e.plugin.enabled&&["native-plugin","official-extension"].includes(e.plugin.package_kind),o=e.plugin.native_hooks_supported&&e.plugin.hook_registered,n=e.mcpRegistration.configured,a=e.schedules.some(h=>Mp(h,t)),s=$p(e.capabilities,e.adapterDiagnostics),i=[At("native_package",r,t,e.plugin.targetPath??e.plugin.package_kind,"Native package/extension is not installed or enabled."),At("native_hooks",o,t,e.plugin.targetPath??e.plugin.package_kind,"Native lifecycle hook registration is missing."),At("mcp",n,t,e.mcpRegistration.targetPath,"MCP registration is missing or invalid."),At("native_scheduler",a,t,Dp(e.schedules),Fp(e.host,e.schedules)),At("official_inventory",s,t,Hp(e.capabilities),"Official non-degraded capability inventory evidence is missing.")],c=i.filter(h=>!h.satisfied).map(h=>h.requirement),l=r&&o&&n,u=!s,d=c.includes("native_scheduler")&&Fi(e.host),f=c.length===0;return{schema_version:1,host:e.host,surface:e.surface,status:Up({fullNative:f,blockedByHost:d,degradedScan:u,ready:l}),ready:l,full_native:f,blocked_by_host:d,degraded_scan:u,generated_at:t,requirements:i,missing_requirements:c}}function At(e,t,r,o,n){return{requirement:e,satisfied:t,evidence:t?[{source_kind:"doctor",reference:o,observed_at:r,confidence:Np(o)}]:[],missing_reason:t?null:n}}function Np(e){return e.startsWith("not-applicable:")||e==="missing"?"low":"medium"}function Mp(e,t){return e.enabled&&e.native_schedule_supported&&e.native_id!==null&&!Lp(e.updated_at,t)}function Lp(e,t){if(!e)return!1;let r=Date.parse(e),o=Date.parse(t);return!Number.isFinite(r)||!Number.isFinite(o)?!0:o-r>10080*60*1e3}function Dp(e){let t=e.find(r=>r.native_id!==null);return t?.native_id?t.updated_at?`${t.native_id}@${t.updated_at}`:t.native_id:"missing"}function Hp(e){return e.find(t=>t.ready)?.source??"missing"}function $p(e,t){return t.some(r=>r.severity==="error"||r.severity==="warn")?!1:e.some(r=>r.ready&&r.schema_hash?.startsWith("official:")===!0)}function Fp(e,t){return Fi(e)?e==="claude"?"Claude local Scheduled Tasks proof is missing, UI-only, or cloud-routine-only for this surface.":e==="antigravity"?"Antigravity scheduler write/list/status/cancel contract proof is missing or stale.":`Host ${e} has no proven native scheduler support.`:t.some(r=>r.enabled)?"Enabled schedule uses fallback or has no native_id mapping.":"No enabled native schedule evidence is available."}function Fi(e){return e==="codex"||e==="claude"||e==="grok"||e==="gemini"||e==="antigravity"}function Up(e){return e.fullNative?"full_native":e.blockedByHost?"blocked_by_host":e.degradedScan?"degraded_scan":e.ready?"ready_fallback":"ready"}async function Bi(e){let t=Rr(e.host,e.targetRoot,e.surface),r=t.managedBlock??`not-applicable:${kt(e.host,e.surface)}`,o=t.managedBlock?await Hs({host:e.host,targetPath:r}):Qp(e.host,e.surface),n=await hn({host:e.host,targetPath:t.mcpRegistration,checkCommand:e.targetRoot===void 0}),a=await ze({host:e.host,surface:e.surface,targetPath:t.plugin}),s=await zo({home:e.home,host:e.host}),c=(e.databaseExists?await yn({home:e.home,host:e.host,limit:200,readOnly:!0}):[]).filter(k=>Jp(e.host,e.surface,k)),l=e.databaseExists?await Ke({home:e.home,host:e.host,limit:100,readOnly:!0}):[],u=e.databaseExists?fr(p(e.home).database):[],d=e.targetRoot!==void 0,f=d?[]:(await Co(e.host))[0]?.diagnostics??[],h=c.length===0&&e.databaseExists?[{code:"SCHEDULE_DESIRED_STATE_MISSING",severity:"warn",message:`No persisted schedule desired state found for ${e.host}.`,remediation:e.targetRoot?`Run nativesoul install --host ${e.host} --apply --target-root ${e.targetRoot}`:"Run nativesoul install --host <host> --apply"}]:[],A=s.stale?[{code:"HANDSHAKE_STALE",severity:"warn",message:`Last ${e.host} handshake is ${s.age_hours??"unknown"} hour(s) old.`,remediation:`Run nativesoul bootstrap --host ${e.host} --cwd <current-working-directory> --format inject`}]:[],z=await qp({host:e.host,managedBlock:o,handshake:s}),de=await Xp(e.host),Y=c.filter(k=>k.enabled&&k.native_schedule_supported&&k.native_id===null).map(k=>({code:"NATIVE_SCHEDULE_MAPPING_MISSING",severity:"warn",message:`Schedule ${k.id} reports native support but has no native_id mapping.`,remediation:e.targetRoot?`Run nativesoul schedule reconcile --host ${e.host} --apply --target-root ${e.targetRoot}`:`Run nativesoul schedule reconcile --host ${e.host} --apply`})),Ae=c.filter(k=>k.enabled&&!k.native_schedule_supported&&!a.enabled&&a.package_kind!=="unsupported-native").map(k=>({code:"NATIVE_SCHEDULE_UNSUPPORTED_NO_FALLBACK_INSTALLED",severity:"warn",message:`Schedule ${k.id} has no native scheduler support and no NativeSoul package fallback is installed.`,remediation:`Run nativesoul install --host ${e.host} --apply`})),$e=Kp({managedBlock:o,mcpRegistration:n,plugin:a,schedules:c,capabilities:l}),Nt=_n({host:e.host,surface:e.surface,mcpRegistration:n,plugin:a,schedules:c,capabilities:l,adapterDiagnostics:f}),Cr=[...o.issues,...n.issues,...a.issues,...f,...h,...A,...z,...de,...Y,...Ae];return{host:e.host,surface:e.surface,status:Cr.some(k=>k.severity==="error"||k.severity==="warn")?"degraded":"ready",targets:{managed_block:r,mcp_registration:n.targetPath},native_adapter_diagnostics_skipped:d,adapter_diagnostics:f,managed_block:o,mcp_registration:n,plugin:a,provider_parity:$e,full_native_evidence:Nt,handshake:s,schedule_count:c.length,enabled_schedule_count:c.filter(k=>k.enabled).length,native_schedule_mappings:c.map(k=>({id:k.id,native_schedule_supported:k.native_schedule_supported,native_id:k.native_id})),capability_count:l.length,ready_capability_count:l.filter(k=>k.ready).length,cross_host_inventory_summary:{current_host:l.length,other_hosts:u.filter(k=>k.host!==e.host&&k.host!=="all").length,ready_other_hosts:u.filter(k=>k.host!==e.host&&k.host!=="all"&&k.ready).length},issues:Cr}}function Jp(e,t,r){return e!=="claude"?!0:Gp(r.desired)===t}function Gp(e){if(e&&typeof e=="object"&&!Array.isArray(e)&&"surface"in e){let t=e.surface;if(t==="claude-desktop"||t==="claude-code")return t}return"claude-code"}function Kp(e){let t=e.plugin.enabled,r=e.mcpRegistration.configured,o=e.managedBlock.configured||t,n=e.schedules.some(d=>d.enabled),s=e.schedules.some(d=>d.enabled&&d.native_schedule_supported)?"native":n&&t?"official-fallback":"unsupported-native",i=e.plugin.native_hooks_supported?e.plugin.hook_registered?"native":"unsupported-native":t?"official-fallback":"unsupported-native",c=e.plugin.package_kind==="unsupported-native"?"unsupported-native":t?"ready":"degraded",l=e.capabilities.length===0||e.capabilities.some(d=>d.ready);return{level:o&&r&&c==="ready"&&i!=="unsupported-native"&&s!=="unsupported-native"?"ready":e.plugin.package_kind==="native-plugin"?"native":e.plugin.package_kind==="unsupported-native"?"unsupported-native":"official-fallback",bootstrap:o?"ready":"degraded",mcp:r?"ready":"degraded",package:c,hooks:i,memory_recall:r?"ready":"degraded",policy_guard:o?"ready":"degraded",capability_scan:l?"ready":"degraded",heartbeat:s}}async function qp(e){if(!e.managedBlock.configured||e.managedBlock.targetPath.startsWith("not-applicable:"))return[];let t=10080*60*1e3,r=await Yp(e.managedBlock.targetPath),o=e.handshake.age_ms;return r!==null&&r<=t?[]:o!==null&&o<=t?[]:[{code:"HANDSHAKE_NOT_OBSERVED",severity:"warn",message:`NativeSoul managed block is present for ${e.host}, but no handshake was observed in the last 7 days.`,remediation:`Start a host session or run nativesoul bootstrap --host ${e.host} --cwd <current-working-directory> --format inject`}]}async function Xp(e){let t=zp(e).map(r=>Ui.resolve(process.cwd(),r));for(let r of t){if(!Bp(r))continue;let o=await Vp(r,"utf8"),n=dt(o);if(n>2e3)return[{code:"PROJECT_CONTEXT_HEAVY",severity:"info",message:`Project instruction file is heavy (${n} estimated tokens): ${r}`,remediation:"Keep project rules authoritative for code boundaries; NativeSoul persona remains advisory continuity."}]}return[]}function zp(e){switch(e){case"claude":return["CLAUDE.md",Ui.join(".claude","CLAUDE.md")];case"codex":return["AGENTS.md"];case"grok":return["Agents.md","AGENTS.md"];case"antigravity":case"gemini":return["GEMINI.md"]}}async function Yp(e){try{let t=await Wp(e);return Math.max(Date.now()-t.mtimeMs,0)}catch{return null}}function Qp(e,t){return{host:e,targetPath:`not-applicable:${kt(e,t)}`,target_exists:!1,configured:!0,markers_valid:!0,issues:[]}}async function Pt(e){let t=p(e.home),r=await rn(e.home),o=bn(t.database),n=Ge(e.host),a=[],s=o?fr(t.database):[],i=ki(t.database,o),c=await qe(t.home),l=bn(or(t.home)),u=bn(ct(t.home));for(let h of n)for(let A of vt(h,e.surface))a.push(await Bi({home:t.home,host:h,surface:A,targetRoot:e.targetRoot,databaseExists:o}));let d=[...r.issues,...Ri(i),...a.flatMap(h=>h.issues)],f=r.healthy&&!d.some(h=>h.severity==="error");return{home:t.home,healthy:f,status:d.some(h=>h.severity==="error"||h.severity==="warn")?"degraded":"ready",workspace:r,target_root:e.targetRoot?Vi.resolve(e.targetRoot):null,cross_host_inventory:Si(s),activation_summary:gi({home:t.home,targetRoot:e.targetRoot?Vi.resolve(e.targetRoot):null,host:e.host,profile:c,onboardingComplete:l,activationComplete:u,hosts:a}),full_native_matrix:Zp(a),semantic_index:i,hosts:a,issues:d}}function Zp(e){let t=e.map(r=>({host:r.host,surface:r.surface,status:r.full_native_evidence.status,full_native:r.full_native_evidence.full_native,blocked_by_host:r.full_native_evidence.blocked_by_host,degraded_scan:r.full_native_evidence.degraded_scan,missing_requirements:r.full_native_evidence.missing_requirements}));return{require_full_native_ready:t.length>0&&t.every(r=>r.full_native),host_count:t.length,full_native_count:t.filter(r=>r.full_native).length,blocked_count:t.filter(r=>r.blocked_by_host).length,degraded_scan_count:t.filter(r=>r.degraded_scan).length,ready_fallback_count:t.filter(r=>r.status==="ready_fallback").length,hosts:t}}import{existsSync as tS}from"node:fs";import{mkdir as oS,readdir as nS,readFile as aS,writeFile as sS}from"node:fs/promises";import cS from"node:path";import{lstat as vS,readdir as kS,readFile as RS}from"node:fs/promises";import wS from"node:path";import{lstat as NS,readFile as MS}from"node:fs/promises";import DS from"node:path";var De={state:"unlicensed",license_key:null,instance_id:null,purchased_at:null,version_at_activation:null,updates_until:null,last_checked_at:null,source:"none"};import{chmod as em,mkdir as tm,readFile as rm,rm as qS,writeFile as om}from"node:fs/promises";import{randomUUID as nm}from"node:crypto";import Wi from"node:path";function vn(e){return Wi.join(p(e).home,"license.json")}async function He(e){let t=vn(e);if(!await _(t))return null;try{let r=JSON.parse(await rm(t,"utf8"));return am(r)?r:null}catch{return null}}async function Sr(e,t){let r=vn(e);return await tm(Wi.dirname(r),{recursive:!0,mode:448}),await om(r,`${JSON.stringify(t,null,2)}
|
|
880
|
-
`,{encoding:"utf8",mode:384}),await em(r,384),t}async function kn(e){let t=await He(e);if(t?.instance_id)return t.instance_id;let r=nm();return await Sr(e,{...De,instance_id:r,purchased_at:t?.purchased_at??null,version_at_activation:t?.version_at_activation??null,updates_until:t?.updates_until??null,license_key_instance_id:t?.license_key_instance_id??null}),r}function am(e){return(e.state==="licensed"||e.state==="unlicensed")&&(typeof e.license_key=="string"||e.license_key===null)&&(typeof e.instance_id=="string"||e.instance_id===null)&&(typeof e.purchased_at=="string"||e.purchased_at===null||e.purchased_at===void 0)&&(typeof e.version_at_activation=="string"||e.version_at_activation===null||e.version_at_activation===void 0)&&(typeof e.updates_until=="string"||e.updates_until===null)&&(typeof e.last_checked_at=="string"||e.last_checked_at===null)&&(e.source==="dodo"||e.source==="none")&&(typeof e.license_key_instance_id=="string"||e.license_key_instance_id===null)}var Ji={name:"nativesoul",version:"1.1.2",description:"Local-first continuity layer for coding agents.",type:"module",license:"UNLICENSED",main:"dist/packages/cli/src/index.js",repository:{type:"git",url:"git+https://github.com/fillipeweb/nativesoul.git"},bugs:{url:"https://github.com/fillipeweb/nativesoul/issues"},homepage:"https://github.com/fillipeweb/nativesoul#readme",files:["dist/","plugins/","policy-packs/","schemas/","docs/adr/","docs/legal/","llm-install.txt","README.md","CHANGELOG.md"],bin:{nativesoul:"dist/packages/cli/src/index.js","nativesoul-mcp":"dist/packages/mcp-server/src/index.js"},scripts:{lint:"eslint .",typecheck:"tsc -p tsconfig.json --noEmit",test:"npm run build && npm run test:non-e2e","test:non-e2e":"node scripts/run-non-e2e-tests.mjs",build:"npm run build:ts && npm run build:minify","build:ts":"tsc -p tsconfig.build.json","build:minify":"node scripts/build-min.mjs","policy:generate":"node scripts/generate-policy-fail-closed.mjs","policy:check":"node scripts/generate-policy-fail-closed.mjs --check","release:security:audit":"node scripts/release-security-audit.mjs","release:provenance:dry-run":"node scripts/release-provenance-dry-run.mjs","package:local":"node scripts/package-local.mjs","package:dry-run":"node scripts/package-dry-run.mjs","package:smoke":"node scripts/package-smoke.mjs","test:e2e":"npm run build && vitest run tests/e2e"},engines:{node:">=22.17.0"},dependencies:{},devDependencies:{"@eslint/js":"^10.0.1","@types/node":"^26.0.0",esbuild:"^0.28.1",eslint:"^10.5.0",typescript:"^6.0.3","typescript-eslint":"^8.62.0",vitest:"^4.1.9"}};var Gi=Ji.version;var cm="https://api.dodopayments.com",lm=1440*60*1e3,dm=14;async function Rn(e){let t=p(e.home).home,r=e.now??new Date,o=await He(t),n=e.key??o?.license_key,a=o?.instance_id??null;if(!n)return await xt(t,"license_validate_missing",null,"INVALID_KEY","blocked"),{ok:!1,reason:"INVALID_KEY",license:o?wr(o):De};if(o?.state==="licensed"&&um(o.last_checked_at,r))return await xt(t,"license_validate_cache_hit",n,null,"ok"),{ok:!0,license:wr(o)};let s=await mm(e,"/licenses/validate",{license_key:n});if(s.ok){let i=await Sr(t,{state:"licensed",license_key:n,instance_id:a??await kn(t),license_key_instance_id:o?.license_key_instance_id??null,purchased_at:o?.purchased_at??null,version_at_activation:o?.version_at_activation??null,updates_until:o?.updates_until??null,last_checked_at:r.toISOString(),source:"dodo"});return await xt(t,"license_validated",n,null,"ok"),{ok:!0,license:wr(i)}}return s.reason==="NETWORK"&&o?.state==="licensed"&&pm(o.last_checked_at,r,e.graceDays)?(await xt(t,"license_validate_grace_served",n,"NETWORK","ok"),{ok:!0,license:wr(o)}):(await xt(t,"license_validate_failed",n,s.reason,"blocked"),{ok:!1,reason:s.reason,license:{...De,instance_id:a}})}function wr(e){return{state:e.state,license_key:e.license_key,instance_id:e.instance_id,purchased_at:e.purchased_at??null,version_at_activation:e.version_at_activation??null,updates_until:e.updates_until,last_checked_at:e.last_checked_at,source:e.source}}function um(e,t){return e?t.getTime()-new Date(e).getTime()<lm:!1}function pm(e,t,r=dm){return e?t.getTime()-new Date(e).getTime()<=r*24*60*60*1e3:!1}async function mm(e,t,r){let o=e.fetch??globalThis.fetch;try{let n=await o(new URL(t,gm(e.endpointBaseUrl)).toString(),{method:"POST",headers:{"content-type":"application/json",accept:"application/json"},body:JSON.stringify(r)}),a=await fm(n);return n.ok?t==="/licenses/validate"&&a.valid!==!0?{ok:!1,reason:Ki(a)}:{ok:!0,license_key_instance_id:hm(a),purchased_at:ym(a)}:{ok:!1,reason:Ki(a)}}catch{return{ok:!1,reason:"NETWORK"}}}function gm(e=process.env.NATIVESOUL_DODO_LICENSE_API_BASE_URL??cm){return e.endsWith("/")?e:`${e}/`}async function fm(e){try{let t=await e.json();return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function hm(e){let r=[e.license_key_instance_id,e.licenseKeyInstanceId,e.id,It(e.data)?e.data.license_key_instance_id:null,It(e.data)?e.data.id:null].find(o=>typeof o=="string"&&o.length>0);return typeof r=="string"?r:null}function ym(e){let t=It(e.data)?e.data:{},r=It(e.license_key)?e.license_key:It(t.license_key)?t.license_key:{},n=[e.purchased_at,e.purchase_date,e.created_at,t.purchased_at,t.purchase_date,t.created_at,r.purchased_at,r.purchase_date,r.created_at].find(a=>typeof a=="string"&&!Number.isNaN(Date.parse(a)));return typeof n=="string"?new Date(n).toISOString():null}function Ki(e){let t=String(e.reason??e.code??e.error??"").toUpperCase();return t.includes("LIMIT")?"ACTIVATION_LIMIT":t.includes("ACTIVE")?"NOT_ACTIVE":"INVALID_KEY"}function It(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}async function xt(e,t,r,o,n){await m({home:e,type:t,result:n,details:{provider:"dodo",license_key_ref:r?_m(r):null,reason:o}})}function _m(e){return e.length<=8?"[REDACTED_LICENSE_KEY]":`${e.slice(0,4)}\u2026${e.slice(-4)}`}var Er="https://docs.nativesoul.dev/account/licensing";async function Ar(e){let t=bm(e),r=p(t.home).home;try{let o=await He(r),n=await Rn(t);if(n.ok)return{ok:!0,license:n.license};let a=n.reason==="NETWORK"&&o?.state==="licensed"?"GRACE_EXPIRED":"UNLICENSED",s=t.activateUrl??Er;return{ok:!1,reason:a,activate_url:s,message:Sn({reason:a,activate_url:s}),license:n.license}}catch{let o=t.activateUrl??Er;return{ok:!1,reason:"UNLICENSED",activate_url:o,message:Sn({reason:"UNLICENSED",activate_url:o}),license:De}}}function Sn(e){return`${e.reason==="GRACE_EXPIRED"?"License offline grace expired.":"NativeSoul is not activated."} NativeSoul is paid-only. Run \`nativesoul license activate <key>\` after purchase: ${e.activate_url}`}function bm(e){return typeof e=="string"?{home:e}:e??{}}import{readdir as fw,readFile as hw,stat as yw}from"node:fs/promises";import bw from"node:path";var Xi={inbox:["assigned","in_progress"],assigned:["in_progress"],in_progress:["review","blocked","done","failed"],review:["in_progress","done","failed"],blocked:["in_progress","failed"],done:[],failed:[]};async function En(e){let t=await y(e.home),r=new Date().toISOString(),o=N(e.title).value,n=e.description===void 0||e.description===null?null:N(e.description).value,a={id:P("work"),project_id:e.project,title:o,description:n,status:"inbox",priority:e.priority??"normal",assigned_host:e.host??null,source:e.source??"cli",tags:O(e.tags??[]),metadata:O(e.metadata??{}),created_at:r,updated_at:r,claimed_at:null,completed_at:null},s=zi({workItem:a,type:"created",fromStatus:null,toStatus:"inbox",actor:e.host??"cli",details:{priority:a.priority,source:a.source},now:r}),i=g(t.database),c;try{c=i.insertWorkItem(a),i.insertWorkItemEvent(s)}finally{i.close()}return await Yi(t.home,"work_item_created",c,{redacted:o!==e.title||e.description!==void 0&&e.description!==null&&n!==e.description,event_id:s.id}),c}async function An(e){let t=e.readOnly?p(e.home):await y(e.home);if(e.readOnly&&!await _(t.database))return[];let r=g(t.database,{readOnly:e.readOnly}),o;try{o=r.listWorkItems({project:e.project,status:e.status,priority:e.priority,assignedHost:e.assignedHost,limit:Rm(e.limit)})}finally{r.close()}return e.readOnly||await m({home:t.home,type:"work_items_listed",details:{project:e.project??null,status:e.status??null,priority:e.priority??null,assigned_host:e.assignedHost??null,count:o.length}}),o}async function Pn(e){return Tn({home:e.home,id:e.id,actor:e.host,eventType:"claimed",auditType:"work_item_claimed",mutate:(t,r)=>{if(jn(t.status))throw new Error(`Work item already terminal: ${t.id} (${t.status})`);return Pr(t.status,"in_progress"),{status:"in_progress",assignedHost:e.host,claimedAt:t.claimed_at??r,updatedAt:r,details:{assigned_host:e.host}}}})}async function xn(e){return Tn({home:e.home,id:e.id,actor:e.assignedHost??"cli",eventType:e.status?"status_changed":"updated",auditType:"work_item_updated",mutate:(t,r)=>{let o=e.status??t.status;e.status&&Pr(t.status,e.status);let n=e.description===void 0||e.description===null?e.description:N(e.description).value;return{status:o,priority:e.priority,assignedHost:e.assignedHost,description:n,tags:e.tags===void 0?void 0:O(e.tags),metadata:e.metadata===void 0?void 0:wm(t.metadata,O(e.metadata)),completedAt:jn(o)?r:void 0,updatedAt:r,details:{priority:e.priority??null,assigned_host:e.assignedHost??null,fields:km(e),redacted:e.description!==void 0&&e.description!==null&&n!==e.description}}}})}async function In(e){let t=e.status??"done";return Tn({home:e.home,id:e.id,actor:"cli",eventType:"completed",auditType:"work_item_completed",mutate:(r,o)=>{if(jn(r.status))throw new Error(`Work item already terminal: ${r.id} (${r.status})`);return Pr(r.status,t),{status:t,completedAt:o,updatedAt:o,details:{terminal_status:t}}}})}function Pr(e,t){if(e!==t&&!Xi[e].includes(t))throw new Error(`Illegal work item transition: ${e} -> ${t}`)}async function Tn(e){let t=await y(e.home),r=g(t.database),o,n;try{let a=r.getWorkItem(e.id);if(!a)throw new Error(`Work item not found: ${e.id}`);let s=new Date().toISOString(),i=e.mutate(a,s);n=zi({workItem:a,type:e.eventType,fromStatus:a.status,toStatus:i.status??a.status,actor:e.actor,details:i.details,now:s}),o=r.updateWorkItem({id:a.id,status:i.status,priority:i.priority,assignedHost:i.assignedHost,description:i.description,tags:i.tags,metadata:i.metadata,claimedAt:i.claimedAt,completedAt:i.completedAt,updatedAt:i.updatedAt,event:n})}finally{r.close()}if(!o)throw new Error(`Work item not found: ${e.id}`);return await Yi(t.home,e.auditType,o,{event_id:n.id,event_type:n.type,from_status:n.from_status,to_status:n.to_status,details:n.details}),o}function zi(e){return{id:P("work_evt"),work_item_id:e.workItem.id,project_id:e.workItem.project_id,type:e.type,from_status:e.fromStatus,to_status:e.toStatus,actor:e.actor,details:e.details,created_at:e.now}}async function Yi(e,t,r,o){await m({home:e,type:t,details:{id:r.id,project:r.project_id,status:r.status,...Sm(o)}})}function km(e){return[e.status===void 0?null:"status",e.priority===void 0?null:"priority",e.assignedHost===void 0?null:"assigned_host",e.description===void 0?null:"description",e.tags===void 0?null:"tags",e.metadata===void 0?null:"metadata"].filter(t=>t!==null)}function jn(e){return e==="done"||e==="failed"}function Rm(e){return!e||!Number.isFinite(e)?50:Math.min(Math.max(Math.trunc(e),1),200)}function Sm(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{value:e}}function wm(e,t){return qi(e)&&qi(t)?{...e,...t}:t}function qi(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}import{readdir as lE,readFile as dE}from"node:fs/promises";import pE from"node:path";import{existsSync as Lw}from"node:fs";import{mkdir as Jw,readdir as Am,readFile as Pm,writeFile as Gw}from"node:fs/promises";import Tt from"node:path";var xm=new Set(["SOUL.MD","POLICY.MD"]),Im=5e3,Qi=new Map;async function jt(e){let t=p(e),r=Qi.get(t.home);if(r&&r.expiresAt>Date.now())return r.orders;let o=Tt.join(t.home,"standing-orders"),n;try{n=await Am(o)}catch{return[]}let a=[];for(let s of n.filter(i=>i.endsWith(".yaml")||i.endsWith(".yml")).sort()){let i=Tt.join(o,s),c=await Pm(i,"utf8");a.push(Tm(c,i))}return Qi.set(t.home,{expiresAt:Date.now()+Im,orders:a}),a}async function Ct(e){let t=await jt(e.home),r=e.target??null,o=r?jm(r):null,n=t.filter(i=>Cn(i,e)),a=n.find(i=>i.allowed.includes(e.action)),s=n.find(i=>i.approval_required.includes(e.action));if(o&&xm.has(o))return we(e,"proposal_required",["PROTECTED_HUMAN_FILE"],null);if(e.className==="identity_policy_change")return we(e,"proposal_required",["IDENTITY_POLICY_CHANGE"],null);if(e.className==="destructive")return we(e,"denied",["DESTRUCTIVE_DENIED_BY_DEFAULT"],a?.id??s?.id??null);if(s)return we(e,"approval_required",["STANDING_ORDER_REQUIRES_APPROVAL"],s.id);if(a)return we(e,"allowed",["STANDING_ORDER_ALLOWED"],a.id);switch(e.className){case"read_local":case"probe_external":case"write_local":return we(e,"allowed",["DEFAULT_ALLOWED"],null);case"write_project":return we(e,"approval_required",["PROJECT_WRITE_REQUIRES_APPROVAL"],null);case"external_write":return we(e,"approval_required",["EXTERNAL_WRITE_REQUIRES_APPROVAL"],null)}}function we(e,t,r,o){return{action:e.action,class:e.className,target:e.target??null,decision:t,reasons:r,matched_standing_order:o}}function Tm(e,t){return{id:Cm(e,"id")??Tt.basename(t,Tt.extname(t)),allowed:Ye(e,"allowed"),approval_required:Ye(e,"approval_required"),scope_projects:Ye(e,"projects").concat(Ye(e,"scope_projects")),scope_hosts:Ye(e,"hosts").concat(Ye(e,"scope_hosts")),source:t}}function Cn(e,t){return!(e.scope_projects.length>0&&(!t.project||!e.scope_projects.includes(t.project))||e.scope_hosts.length>0&&(!t.host||!e.scope_hosts.includes(t.host)))}function jm(e){return Tt.basename(e.replaceAll("\\","/")).toUpperCase()}function Cm(e,t){let r=new RegExp(`^\\s*${t}:\\s*([^\\n#]+)`,"mu");return e.match(r)?.[1]?.trim().replace(/^["']|["']$/gu,"")??null}function Ye(e,t){let r=e.match(new RegExp(`^\\s*${t}:\\s*\\[([^\\]]*)\\]`,"mu"));if(r?.[1])return r[1].split(",").map(i=>i.trim().replace(/^["']|["']$/gu,"")).filter(Boolean);let o=e.split(/\r?\n/u),n=[],a=!1,s=0;for(let i of o){let c=i.trim();if(!a){let u=i.match(new RegExp(`^(\\s*)${t}:\\s*$`,"u"));u&&(a=!0,s=u[1]?.length??0);continue}let l=i.length-i.trimStart().length;if(c&&l<=s&&!c.startsWith("-"))break;c.startsWith("-")&&n.push(c.slice(1).trim().replace(/^["']|["']$/gu,""))}return n.filter(Boolean)}import{mkdir as RE,writeFile as SE}from"node:fs/promises";import EE from"node:path";import{readdir as jE,readFile as CE,realpath as OE}from"node:fs/promises";import ME from"node:path";import{mkdir as KE,readFile as qE,writeFile as XE}from"node:fs/promises";import YE from"node:path";async function Nn(e){let t=p(e.home),r=g(t.database),o;try{let n=r.findPendingApprovalMatch(On(e));if(!n.available)return{approval:null,created:!1,available:!1,warning:n.warning};if(n.approval)return{approval:n.approval,created:!1,available:!0,warning:null};let a=r.createApproval({id:P("approval"),...On(e)});o={approval:a.approval,created:!!a.approval,available:a.available,warning:a.warning}}finally{r.close()}return o.created&&o.approval&&await m({home:t.home,type:"approval_requested",details:Dn(o.approval)}),o}async function Mn(e){let t=p(e.home),r=g(t.database),o;try{let n=r.decideApproval(e.id,{status:e.status,reviewer:e.reviewer??"local-operator",reason:e.reason??null});o={approval:n.approval,available:n.available,warning:n.warning}}catch(n){throw n instanceof ne,n}finally{r.close()}return o.approval&&await m({home:t.home,type:o.approval.status==="approved"?"approval_approved":"approval_rejected",details:Dn(o.approval)}),o}async function Ln(e){let t=p(e.home),r=g(t.database),o;try{let n=r.createDecidedApproval({id:P("approval"),...On(e),status:"approved",reviewer:`standing-order:${e.standingOrderId}`,reason:e.reason});o={approval:n.approval,available:n.available,warning:n.warning,created:!!n.approval}}finally{r.close()}return o.approval&&await m({home:t.home,type:"approval_auto_approved",details:{...Dn(o.approval),standing_order:e.standingOrderId}}),o}function On(e){return{action:e.action,class:e.class,target:e.target??null,project:e.project??null,host:e.host??null}}function Dn(e){return{id:e.id,action:e.action,class:e.class,target:e.target,project:e.project,host:e.host,status:e.status,reviewer:e.reviewer,reason:e.reason}}async function Qe(e){let t=await Ct(e),r=await $m(e,t);if(r){let n=await Ln({home:e.home,action:t.action,class:t.class,target:t.target,project:e.project??null,host:e.host??null,standingOrderId:r.id,reason:`standing-order allowed:${t.action}`});return{evaluation:t,approval:n.approval,approval_created:n.created,approval_available:n.available,warning:n.warning}}if(t.decision!=="approval_required")return{evaluation:t,approval:null,approval_created:!1,approval_available:!0,warning:null};let o=await Nn({home:e.home,action:t.action,class:t.class,target:t.target,project:e.project??null,host:e.host??null});return{evaluation:t,approval:o.approval,approval_created:o.created,approval_available:o.available,warning:o.warning}}async function $m(e,t){return t.decision!=="allowed"||!t.matched_standing_order||!Fm(e.className)?null:(await jt(e.home)).find(o=>o.id===t.matched_standing_order&&o.allowed.includes(e.action)&&Cn(o,e))??null}function Fm(e){return e==="write_project"||e==="external_write"}import{readFile as Zi}from"node:fs/promises";import ec from"node:path";var xr=1500;async function $n(e){let t=await y(e.home),r=await Vm(t.home),o=await Wm(t.home),n=new Date,a=Um(e.ttlSeconds??r.ttlSeconds),s=new Date(n.getTime()+a*1e3).toISOString(),i=Un(e.project,e.slot),c=g(t.database),l;try{l=c.claimHeartbeatLease({id:P("lease"),slot:e.slot,holder:e.host,idempotencyKey:i,now:n.toISOString(),expiresAt:s})}finally{c.close()}return await m({home:t.home,type:l.claimed?"heartbeat_claimed":"heartbeat_skipped",details:{slot:e.slot,host:e.host,project:e.project,lease_id:l.lease.id,reason:l.reason}}),{slot:e.slot,host:e.host,project:e.project,claimed:l.claimed,reason:l.reason,silent_ack:l.claimed||l.reason==="LEASE_OCCUPIED"&&!r.skipWhenBusy?null:"HEARTBEAT_OK",lease:l.lease,...l.claimed&&o?{heartbeat_checklist:o}:{}}}async function Fn(e){let t=await y(e.home),r=new Date().toISOString(),o=Un(e.project,e.slot),n=O(e.result??"HEARTBEAT_OK"),a=O(Bm(e.evidence??{},e.workItemId)),s=O(e.cost??{}),i=Fe(s),c=g(t.database),l;try{l=c.completeHeartbeatLease({idempotencyKey:o,host:e.host,project:e.project,result:n,evidence:a,cost:i,completedAt:r,runId:P("run")})}finally{c.close()}return await m({home:t.home,type:l.completed?"heartbeat_completed":"heartbeat_completion_replayed",details:{slot:e.slot,host:e.host,project:e.project,lease_id:l.lease.id,run_id:l.run?.id??null}}),{slot:e.slot,project:e.project,completed:l.completed,silent_ack:"HEARTBEAT_OK",lease:l.lease,run:l.run}}function Un(e,t){return`heartbeat:${e}:${t}`}function Um(e){return Number.isFinite(e)?Math.min(Math.max(Math.trunc(e),1),1440*60):xr}function Bm(e,t){return t?{...e&&typeof e=="object"&&!Array.isArray(e)?e:{},work_item_id:t}:e}async function Vm(e){let t;try{t=await Zi(ec.join(e,"config.yaml"),"utf8")}catch{return{ttlSeconds:xr,skipWhenBusy:!0}}return{ttlSeconds:Jm(t),skipWhenBusy:Gm(t,"skip_when_busy",!0)}}async function Wm(e){let t;try{t=await Zi(ec.join(e,"HEARTBEAT.md"),"utf8")}catch{return""}return t.split(/\r?\n/u).filter(r=>{let o=r.trim();return o.length>0&&!o.startsWith("#")}).join(`
|
|
880
|
+
`,{encoding:"utf8",mode:384}),await em(r,384),t}async function kn(e){let t=await He(e);if(t?.instance_id)return t.instance_id;let r=nm();return await Sr(e,{...De,instance_id:r,purchased_at:t?.purchased_at??null,version_at_activation:t?.version_at_activation??null,updates_until:t?.updates_until??null,license_key_instance_id:t?.license_key_instance_id??null}),r}function am(e){return(e.state==="licensed"||e.state==="unlicensed")&&(typeof e.license_key=="string"||e.license_key===null)&&(typeof e.instance_id=="string"||e.instance_id===null)&&(typeof e.purchased_at=="string"||e.purchased_at===null||e.purchased_at===void 0)&&(typeof e.version_at_activation=="string"||e.version_at_activation===null||e.version_at_activation===void 0)&&(typeof e.updates_until=="string"||e.updates_until===null)&&(typeof e.last_checked_at=="string"||e.last_checked_at===null)&&(e.source==="dodo"||e.source==="none")&&(typeof e.license_key_instance_id=="string"||e.license_key_instance_id===null)}var Ji={name:"nativesoul",version:"1.1.3",description:"Local-first continuity layer for coding agents.",type:"module",license:"UNLICENSED",main:"dist/packages/cli/src/index.js",repository:{type:"git",url:"git+https://github.com/fillipeweb/nativesoul.git"},bugs:{url:"https://github.com/fillipeweb/nativesoul/issues"},homepage:"https://github.com/fillipeweb/nativesoul#readme",files:["dist/","plugins/","policy-packs/","schemas/","docs/adr/","docs/legal/","llm-install.txt","README.md","CHANGELOG.md"],bin:{nativesoul:"dist/packages/cli/src/index.js","nativesoul-mcp":"dist/packages/mcp-server/src/index.js"},scripts:{lint:"eslint .",typecheck:"tsc -p tsconfig.json --noEmit",test:"npm run build && npm run test:non-e2e","test:non-e2e":"node scripts/run-non-e2e-tests.mjs",build:"npm run build:ts && npm run build:minify","build:ts":"tsc -p tsconfig.build.json","build:minify":"node scripts/build-min.mjs","policy:generate":"node scripts/generate-policy-fail-closed.mjs","policy:check":"node scripts/generate-policy-fail-closed.mjs --check","release:security:audit":"node scripts/release-security-audit.mjs","release:provenance:dry-run":"node scripts/release-provenance-dry-run.mjs","package:local":"node scripts/package-local.mjs","package:dry-run":"node scripts/package-dry-run.mjs","package:smoke":"node scripts/package-smoke.mjs","test:e2e":"npm run build && vitest run tests/e2e"},engines:{node:">=22.17.0"},dependencies:{},devDependencies:{"@eslint/js":"^10.0.1","@types/node":"^26.0.0",esbuild:"^0.28.1",eslint:"^10.5.0",typescript:"^6.0.3","typescript-eslint":"^8.62.0",vitest:"^4.1.9"}};var Gi=Ji.version;var cm="https://live.dodopayments.com",lm=1440*60*1e3,dm=14;async function Rn(e){let t=p(e.home).home,r=e.now??new Date,o=await He(t),n=e.key??o?.license_key,a=o?.instance_id??null;if(!n)return await xt(t,"license_validate_missing",null,"INVALID_KEY","blocked"),{ok:!1,reason:"INVALID_KEY",license:o?wr(o):De};if(o?.state==="licensed"&&um(o.last_checked_at,r))return await xt(t,"license_validate_cache_hit",n,null,"ok"),{ok:!0,license:wr(o)};let s=await mm(e,"/licenses/validate",{license_key:n});if(s.ok){let i=await Sr(t,{state:"licensed",license_key:n,instance_id:a??await kn(t),license_key_instance_id:o?.license_key_instance_id??null,purchased_at:o?.purchased_at??null,version_at_activation:o?.version_at_activation??null,updates_until:o?.updates_until??null,last_checked_at:r.toISOString(),source:"dodo"});return await xt(t,"license_validated",n,null,"ok"),{ok:!0,license:wr(i)}}return s.reason==="NETWORK"&&o?.state==="licensed"&&pm(o.last_checked_at,r,e.graceDays)?(await xt(t,"license_validate_grace_served",n,"NETWORK","ok"),{ok:!0,license:wr(o)}):(await xt(t,"license_validate_failed",n,s.reason,"blocked"),{ok:!1,reason:s.reason,license:{...De,instance_id:a}})}function wr(e){return{state:e.state,license_key:e.license_key,instance_id:e.instance_id,purchased_at:e.purchased_at??null,version_at_activation:e.version_at_activation??null,updates_until:e.updates_until,last_checked_at:e.last_checked_at,source:e.source}}function um(e,t){return e?t.getTime()-new Date(e).getTime()<lm:!1}function pm(e,t,r=dm){return e?t.getTime()-new Date(e).getTime()<=r*24*60*60*1e3:!1}async function mm(e,t,r){let o=e.fetch??globalThis.fetch;try{let n=await o(new URL(t,gm(e.endpointBaseUrl)).toString(),{method:"POST",headers:{"content-type":"application/json",accept:"application/json"},body:JSON.stringify(r)}),a=await fm(n);return n.ok?t==="/licenses/validate"&&a.valid!==!0?{ok:!1,reason:Ki(a)}:{ok:!0,license_key_instance_id:hm(a),purchased_at:ym(a)}:n.status>=500||n.status===429||n.status===408?{ok:!1,reason:"NETWORK"}:{ok:!1,reason:Ki(a)}}catch{return{ok:!1,reason:"NETWORK"}}}function gm(e=process.env.NATIVESOUL_DODO_LICENSE_API_BASE_URL??cm){return e.endsWith("/")?e:`${e}/`}async function fm(e){try{let t=await e.json();return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function hm(e){let r=[e.license_key_instance_id,e.licenseKeyInstanceId,e.id,It(e.data)?e.data.license_key_instance_id:null,It(e.data)?e.data.id:null].find(o=>typeof o=="string"&&o.length>0);return typeof r=="string"?r:null}function ym(e){let t=It(e.data)?e.data:{},r=It(e.license_key)?e.license_key:It(t.license_key)?t.license_key:{},n=[e.purchased_at,e.purchase_date,e.created_at,t.purchased_at,t.purchase_date,t.created_at,r.purchased_at,r.purchase_date,r.created_at].find(a=>typeof a=="string"&&!Number.isNaN(Date.parse(a)));return typeof n=="string"?new Date(n).toISOString():null}function Ki(e){let t=String(e.reason??e.code??e.error??"").toUpperCase();return t.includes("LIMIT")?"ACTIVATION_LIMIT":t.includes("ACTIVE")?"NOT_ACTIVE":"INVALID_KEY"}function It(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}async function xt(e,t,r,o,n){await m({home:e,type:t,result:n,details:{provider:"dodo",license_key_ref:r?_m(r):null,reason:o}})}function _m(e){return e.length<=8?"[REDACTED_LICENSE_KEY]":`${e.slice(0,4)}\u2026${e.slice(-4)}`}var Er="https://docs.nativesoul.dev/account/licensing";async function Ar(e){let t=bm(e),r=p(t.home).home;try{let o=await He(r),n=await Rn(t);if(n.ok)return{ok:!0,license:n.license};let a=n.reason==="NETWORK"&&o?.state==="licensed"?"GRACE_EXPIRED":"UNLICENSED",s=t.activateUrl??Er;return{ok:!1,reason:a,activate_url:s,message:Sn({reason:a,activate_url:s}),license:n.license}}catch{let o=t.activateUrl??Er;return{ok:!1,reason:"UNLICENSED",activate_url:o,message:Sn({reason:"UNLICENSED",activate_url:o}),license:De}}}function Sn(e){return`${e.reason==="GRACE_EXPIRED"?"License offline grace expired.":"NativeSoul is not activated."} NativeSoul is paid-only. Run \`nativesoul license activate <key>\` after purchase: ${e.activate_url}`}function bm(e){return typeof e=="string"?{home:e}:e??{}}import{readdir as fw,readFile as hw,stat as yw}from"node:fs/promises";import bw from"node:path";var Xi={inbox:["assigned","in_progress"],assigned:["in_progress"],in_progress:["review","blocked","done","failed"],review:["in_progress","done","failed"],blocked:["in_progress","failed"],done:[],failed:[]};async function En(e){let t=await y(e.home),r=new Date().toISOString(),o=N(e.title).value,n=e.description===void 0||e.description===null?null:N(e.description).value,a={id:P("work"),project_id:e.project,title:o,description:n,status:"inbox",priority:e.priority??"normal",assigned_host:e.host??null,source:e.source??"cli",tags:O(e.tags??[]),metadata:O(e.metadata??{}),created_at:r,updated_at:r,claimed_at:null,completed_at:null},s=zi({workItem:a,type:"created",fromStatus:null,toStatus:"inbox",actor:e.host??"cli",details:{priority:a.priority,source:a.source},now:r}),i=g(t.database),c;try{c=i.insertWorkItem(a),i.insertWorkItemEvent(s)}finally{i.close()}return await Yi(t.home,"work_item_created",c,{redacted:o!==e.title||e.description!==void 0&&e.description!==null&&n!==e.description,event_id:s.id}),c}async function An(e){let t=e.readOnly?p(e.home):await y(e.home);if(e.readOnly&&!await _(t.database))return[];let r=g(t.database,{readOnly:e.readOnly}),o;try{o=r.listWorkItems({project:e.project,status:e.status,priority:e.priority,assignedHost:e.assignedHost,limit:Rm(e.limit)})}finally{r.close()}return e.readOnly||await m({home:t.home,type:"work_items_listed",details:{project:e.project??null,status:e.status??null,priority:e.priority??null,assigned_host:e.assignedHost??null,count:o.length}}),o}async function Pn(e){return Tn({home:e.home,id:e.id,actor:e.host,eventType:"claimed",auditType:"work_item_claimed",mutate:(t,r)=>{if(jn(t.status))throw new Error(`Work item already terminal: ${t.id} (${t.status})`);return Pr(t.status,"in_progress"),{status:"in_progress",assignedHost:e.host,claimedAt:t.claimed_at??r,updatedAt:r,details:{assigned_host:e.host}}}})}async function xn(e){return Tn({home:e.home,id:e.id,actor:e.assignedHost??"cli",eventType:e.status?"status_changed":"updated",auditType:"work_item_updated",mutate:(t,r)=>{let o=e.status??t.status;e.status&&Pr(t.status,e.status);let n=e.description===void 0||e.description===null?e.description:N(e.description).value;return{status:o,priority:e.priority,assignedHost:e.assignedHost,description:n,tags:e.tags===void 0?void 0:O(e.tags),metadata:e.metadata===void 0?void 0:wm(t.metadata,O(e.metadata)),completedAt:jn(o)?r:void 0,updatedAt:r,details:{priority:e.priority??null,assigned_host:e.assignedHost??null,fields:km(e),redacted:e.description!==void 0&&e.description!==null&&n!==e.description}}}})}async function In(e){let t=e.status??"done";return Tn({home:e.home,id:e.id,actor:"cli",eventType:"completed",auditType:"work_item_completed",mutate:(r,o)=>{if(jn(r.status))throw new Error(`Work item already terminal: ${r.id} (${r.status})`);return Pr(r.status,t),{status:t,completedAt:o,updatedAt:o,details:{terminal_status:t}}}})}function Pr(e,t){if(e!==t&&!Xi[e].includes(t))throw new Error(`Illegal work item transition: ${e} -> ${t}`)}async function Tn(e){let t=await y(e.home),r=g(t.database),o,n;try{let a=r.getWorkItem(e.id);if(!a)throw new Error(`Work item not found: ${e.id}`);let s=new Date().toISOString(),i=e.mutate(a,s);n=zi({workItem:a,type:e.eventType,fromStatus:a.status,toStatus:i.status??a.status,actor:e.actor,details:i.details,now:s}),o=r.updateWorkItem({id:a.id,status:i.status,priority:i.priority,assignedHost:i.assignedHost,description:i.description,tags:i.tags,metadata:i.metadata,claimedAt:i.claimedAt,completedAt:i.completedAt,updatedAt:i.updatedAt,event:n})}finally{r.close()}if(!o)throw new Error(`Work item not found: ${e.id}`);return await Yi(t.home,e.auditType,o,{event_id:n.id,event_type:n.type,from_status:n.from_status,to_status:n.to_status,details:n.details}),o}function zi(e){return{id:P("work_evt"),work_item_id:e.workItem.id,project_id:e.workItem.project_id,type:e.type,from_status:e.fromStatus,to_status:e.toStatus,actor:e.actor,details:e.details,created_at:e.now}}async function Yi(e,t,r,o){await m({home:e,type:t,details:{id:r.id,project:r.project_id,status:r.status,...Sm(o)}})}function km(e){return[e.status===void 0?null:"status",e.priority===void 0?null:"priority",e.assignedHost===void 0?null:"assigned_host",e.description===void 0?null:"description",e.tags===void 0?null:"tags",e.metadata===void 0?null:"metadata"].filter(t=>t!==null)}function jn(e){return e==="done"||e==="failed"}function Rm(e){return!e||!Number.isFinite(e)?50:Math.min(Math.max(Math.trunc(e),1),200)}function Sm(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{value:e}}function wm(e,t){return qi(e)&&qi(t)?{...e,...t}:t}function qi(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}import{readdir as lE,readFile as dE}from"node:fs/promises";import pE from"node:path";import{existsSync as Lw}from"node:fs";import{mkdir as Jw,readdir as Am,readFile as Pm,writeFile as Gw}from"node:fs/promises";import Tt from"node:path";var xm=new Set(["SOUL.MD","POLICY.MD"]),Im=5e3,Qi=new Map;async function jt(e){let t=p(e),r=Qi.get(t.home);if(r&&r.expiresAt>Date.now())return r.orders;let o=Tt.join(t.home,"standing-orders"),n;try{n=await Am(o)}catch{return[]}let a=[];for(let s of n.filter(i=>i.endsWith(".yaml")||i.endsWith(".yml")).sort()){let i=Tt.join(o,s),c=await Pm(i,"utf8");a.push(Tm(c,i))}return Qi.set(t.home,{expiresAt:Date.now()+Im,orders:a}),a}async function Ct(e){let t=await jt(e.home),r=e.target??null,o=r?jm(r):null,n=t.filter(i=>Cn(i,e)),a=n.find(i=>i.allowed.includes(e.action)),s=n.find(i=>i.approval_required.includes(e.action));if(o&&xm.has(o))return we(e,"proposal_required",["PROTECTED_HUMAN_FILE"],null);if(e.className==="identity_policy_change")return we(e,"proposal_required",["IDENTITY_POLICY_CHANGE"],null);if(e.className==="destructive")return we(e,"denied",["DESTRUCTIVE_DENIED_BY_DEFAULT"],a?.id??s?.id??null);if(s)return we(e,"approval_required",["STANDING_ORDER_REQUIRES_APPROVAL"],s.id);if(a)return we(e,"allowed",["STANDING_ORDER_ALLOWED"],a.id);switch(e.className){case"read_local":case"probe_external":case"write_local":return we(e,"allowed",["DEFAULT_ALLOWED"],null);case"write_project":return we(e,"approval_required",["PROJECT_WRITE_REQUIRES_APPROVAL"],null);case"external_write":return we(e,"approval_required",["EXTERNAL_WRITE_REQUIRES_APPROVAL"],null)}}function we(e,t,r,o){return{action:e.action,class:e.className,target:e.target??null,decision:t,reasons:r,matched_standing_order:o}}function Tm(e,t){return{id:Cm(e,"id")??Tt.basename(t,Tt.extname(t)),allowed:Ye(e,"allowed"),approval_required:Ye(e,"approval_required"),scope_projects:Ye(e,"projects").concat(Ye(e,"scope_projects")),scope_hosts:Ye(e,"hosts").concat(Ye(e,"scope_hosts")),source:t}}function Cn(e,t){return!(e.scope_projects.length>0&&(!t.project||!e.scope_projects.includes(t.project))||e.scope_hosts.length>0&&(!t.host||!e.scope_hosts.includes(t.host)))}function jm(e){return Tt.basename(e.replaceAll("\\","/")).toUpperCase()}function Cm(e,t){let r=new RegExp(`^\\s*${t}:\\s*([^\\n#]+)`,"mu");return e.match(r)?.[1]?.trim().replace(/^["']|["']$/gu,"")??null}function Ye(e,t){let r=e.match(new RegExp(`^\\s*${t}:\\s*\\[([^\\]]*)\\]`,"mu"));if(r?.[1])return r[1].split(",").map(i=>i.trim().replace(/^["']|["']$/gu,"")).filter(Boolean);let o=e.split(/\r?\n/u),n=[],a=!1,s=0;for(let i of o){let c=i.trim();if(!a){let u=i.match(new RegExp(`^(\\s*)${t}:\\s*$`,"u"));u&&(a=!0,s=u[1]?.length??0);continue}let l=i.length-i.trimStart().length;if(c&&l<=s&&!c.startsWith("-"))break;c.startsWith("-")&&n.push(c.slice(1).trim().replace(/^["']|["']$/gu,""))}return n.filter(Boolean)}import{mkdir as RE,writeFile as SE}from"node:fs/promises";import EE from"node:path";import{readdir as jE,readFile as CE,realpath as OE}from"node:fs/promises";import ME from"node:path";import{mkdir as KE,readFile as qE,writeFile as XE}from"node:fs/promises";import YE from"node:path";async function Nn(e){let t=p(e.home),r=g(t.database),o;try{let n=r.findPendingApprovalMatch(On(e));if(!n.available)return{approval:null,created:!1,available:!1,warning:n.warning};if(n.approval)return{approval:n.approval,created:!1,available:!0,warning:null};let a=r.createApproval({id:P("approval"),...On(e)});o={approval:a.approval,created:!!a.approval,available:a.available,warning:a.warning}}finally{r.close()}return o.created&&o.approval&&await m({home:t.home,type:"approval_requested",details:Dn(o.approval)}),o}async function Mn(e){let t=p(e.home),r=g(t.database),o;try{let n=r.decideApproval(e.id,{status:e.status,reviewer:e.reviewer??"local-operator",reason:e.reason??null});o={approval:n.approval,available:n.available,warning:n.warning}}catch(n){throw n instanceof ne,n}finally{r.close()}return o.approval&&await m({home:t.home,type:o.approval.status==="approved"?"approval_approved":"approval_rejected",details:Dn(o.approval)}),o}async function Ln(e){let t=p(e.home),r=g(t.database),o;try{let n=r.createDecidedApproval({id:P("approval"),...On(e),status:"approved",reviewer:`standing-order:${e.standingOrderId}`,reason:e.reason});o={approval:n.approval,available:n.available,warning:n.warning,created:!!n.approval}}finally{r.close()}return o.approval&&await m({home:t.home,type:"approval_auto_approved",details:{...Dn(o.approval),standing_order:e.standingOrderId}}),o}function On(e){return{action:e.action,class:e.class,target:e.target??null,project:e.project??null,host:e.host??null}}function Dn(e){return{id:e.id,action:e.action,class:e.class,target:e.target,project:e.project,host:e.host,status:e.status,reviewer:e.reviewer,reason:e.reason}}async function Qe(e){let t=await Ct(e),r=await $m(e,t);if(r){let n=await Ln({home:e.home,action:t.action,class:t.class,target:t.target,project:e.project??null,host:e.host??null,standingOrderId:r.id,reason:`standing-order allowed:${t.action}`});return{evaluation:t,approval:n.approval,approval_created:n.created,approval_available:n.available,warning:n.warning}}if(t.decision!=="approval_required")return{evaluation:t,approval:null,approval_created:!1,approval_available:!0,warning:null};let o=await Nn({home:e.home,action:t.action,class:t.class,target:t.target,project:e.project??null,host:e.host??null});return{evaluation:t,approval:o.approval,approval_created:o.created,approval_available:o.available,warning:o.warning}}async function $m(e,t){return t.decision!=="allowed"||!t.matched_standing_order||!Fm(e.className)?null:(await jt(e.home)).find(o=>o.id===t.matched_standing_order&&o.allowed.includes(e.action)&&Cn(o,e))??null}function Fm(e){return e==="write_project"||e==="external_write"}import{readFile as Zi}from"node:fs/promises";import ec from"node:path";var xr=1500;async function $n(e){let t=await y(e.home),r=await Vm(t.home),o=await Wm(t.home),n=new Date,a=Um(e.ttlSeconds??r.ttlSeconds),s=new Date(n.getTime()+a*1e3).toISOString(),i=Un(e.project,e.slot),c=g(t.database),l;try{l=c.claimHeartbeatLease({id:P("lease"),slot:e.slot,holder:e.host,idempotencyKey:i,now:n.toISOString(),expiresAt:s})}finally{c.close()}return await m({home:t.home,type:l.claimed?"heartbeat_claimed":"heartbeat_skipped",details:{slot:e.slot,host:e.host,project:e.project,lease_id:l.lease.id,reason:l.reason}}),{slot:e.slot,host:e.host,project:e.project,claimed:l.claimed,reason:l.reason,silent_ack:l.claimed||l.reason==="LEASE_OCCUPIED"&&!r.skipWhenBusy?null:"HEARTBEAT_OK",lease:l.lease,...l.claimed&&o?{heartbeat_checklist:o}:{}}}async function Fn(e){let t=await y(e.home),r=new Date().toISOString(),o=Un(e.project,e.slot),n=O(e.result??"HEARTBEAT_OK"),a=O(Bm(e.evidence??{},e.workItemId)),s=O(e.cost??{}),i=Fe(s),c=g(t.database),l;try{l=c.completeHeartbeatLease({idempotencyKey:o,host:e.host,project:e.project,result:n,evidence:a,cost:i,completedAt:r,runId:P("run")})}finally{c.close()}return await m({home:t.home,type:l.completed?"heartbeat_completed":"heartbeat_completion_replayed",details:{slot:e.slot,host:e.host,project:e.project,lease_id:l.lease.id,run_id:l.run?.id??null}}),{slot:e.slot,project:e.project,completed:l.completed,silent_ack:"HEARTBEAT_OK",lease:l.lease,run:l.run}}function Un(e,t){return`heartbeat:${e}:${t}`}function Um(e){return Number.isFinite(e)?Math.min(Math.max(Math.trunc(e),1),1440*60):xr}function Bm(e,t){return t?{...e&&typeof e=="object"&&!Array.isArray(e)?e:{},work_item_id:t}:e}async function Vm(e){let t;try{t=await Zi(ec.join(e,"config.yaml"),"utf8")}catch{return{ttlSeconds:xr,skipWhenBusy:!0}}return{ttlSeconds:Jm(t),skipWhenBusy:Gm(t,"skip_when_busy",!0)}}async function Wm(e){let t;try{t=await Zi(ec.join(e,"HEARTBEAT.md"),"utf8")}catch{return""}return t.split(/\r?\n/u).filter(r=>{let o=r.trim();return o.length>0&&!o.startsWith("#")}).join(`
|
|
881
881
|
`).trim()}function Jm(e){let t=Hn(e,"ttl_seconds"),r=Hn(e,"lease_ttl"),o=Km(e,"heartbeat_ttl_seconds"),n=qm(t??r??o);return Number.isFinite(n)?n:xr}function Gm(e,t,r){let o=Hn(e,t);return o?/^(true|yes|1)$/i.test(o)?!0:/^(false|no|0)$/i.test(o)?!1:r:r}function Hn(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`^\\s*heartbeat:\\s*$[\\s\\S]*?^\\s{2}${r}:\\s*([^#\\n]+)`,"mu"))?.[1]?.trim().replace(/^["']|["']$/g,"")??null}function Km(e,t){let r=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return e.match(new RegExp(`^\\s*${r}:\\s*([^#\\n]+)`,"mu"))?.[1]?.trim().replace(/^["']|["']$/g,"")??null}function qm(e){if(!e)return xr;let t=e.match(/^(\d+)$/);if(t)return Number(t[1]);let r=e.match(/^(\d+)\s*([smh])$/i);if(!r)return Number.NaN;let o=Number(r[1]),n=r[2]?.toLowerCase();return n==="s"?o:n==="m"?o*60:o*60*60}import xA from"node:path";import{rm as TA}from"node:fs/promises";var oc={"memory.promote":{action:"memory.promote",className:"write_local"},"memory.forget":{action:"memory.forget",className:"write_local"},"memory.reject":{action:"memory.reject",className:"write_local"},"work_item.create":{action:"work_item.create",className:"write_local"},"work_item.claim":{action:"work_item.claim",className:"write_local"},"work_item.complete":{action:"work_item.complete",className:"write_local"},"install.apply":{action:"install.apply",className:"write_local"},"policy_pack.apply":{action:"policy_pack.apply",className:"write_local"}};async function Bn(e,t={}){let r=oc[e],o={home:t.home,action:r.action,className:r.className,target:t.target??void 0,project:t.project??void 0,host:t.host??void 0},n,a,s,i;try{let c=await Qe(o);n=c.evaluation,a=c.approval?.id??null,s=c.approval_created,i=c.warning}catch(c){return await rc(r,t,["POLICY_GATE_UNAVAILABLE"],"error"),{status:"deny",decision:"denied",reason:`policy gate unavailable (fail-closed): ${c.message}`,evaluation:null}}return n.decision==="allowed"?{status:"allow",decision:"allowed",evaluation:n}:n.decision==="approval_required"?{status:"approval_required",decision:"approval_required",approvalId:a,approvalCreated:s,warning:i,evaluation:n}:(await rc(r,t,n.reasons,"blocked"),{status:"deny",decision:n.decision,reason:`${r.action} ${n.decision}: ${n.reasons.join(", ")}`,evaluation:n})}async function rc(e,t,r,o){try{let n=await y(t.home);await m({home:n.home,type:"policy_blocked",result:"blocked",details:{boundary:"sensitive_operation",action:e.action,class:e.className,target:t.target??null,project:t.project??null,host:t.host??null,outcome:o,reasons:r}})}catch{}}import{existsSync as cP}from"node:fs";import{mkdir as dP,readFile as uP,rm as pP,writeFile as mP}from"node:fs/promises";import fP from"node:path";import{existsSync as YA}from"node:fs";import{readdir as ZA,readFile as eP}from"node:fs/promises";import rP from"node:path";import{fileURLToPath as nP}from"node:url";import JA from"node:path";var nc=["AGENTS.md","CLAUDE.md","GEMINI.md","Agents.md",".claude/CLAUDE.md"],GA=new Set(nc);import ng from"node:path";async function Ir(e={}){let t=p(e.home),r=e.host??"all",[o,n,a,s]=await Promise.all([qe(t.home),_(or(t.home)),_(ct(t.home)),Pt({home:t.home,host:r,surface:e.surface,targetRoot:e.targetRoot})]);return tn({home:t.home,targetRoot:e.targetRoot?ng.resolve(e.targetRoot):null,host:r,profile:o,onboardingComplete:n,activationComplete:a,hosts:s.hosts})}async function Vn(e={}){let t=await Ir(e);if(!e.profile||t.profile?.profile===e.profile)return t;let r={...t.profile??$o,profile:e.profile,updated_at:t.profile?.updated_at??"dry-run"};return{...t,profile:r,plan:[{id:"activation-profile-switch",component:"bootstrap",status:"approval_required",action:`Switch activation profile to ${e.profile}.`,target:`${t.home}/state/activation-profile.json`,dry_run:!0,requires_user_confirmed:!0,reason:"Activation profile replacement requires explicit reset/user confirmation."},...t.plan]}}import{randomUUID as ag}from"node:crypto";import sg from"node:path";var ig="NativeSoul activation verification marker";async function Jn(e={}){let t=ug(e),r=ce(t.projectCwd,e.home),o=await Pt({home:e.home,host:e.host??"all",surface:e.surface,targetRoot:e.targetRoot}),n=[];for(let l of o.hosts)n.push(await cg({home:o.home,inputHost:l,testCwd:t.projectCwd}));let a=await dg({home:e.home,testProject:`${r.id}-${ag()}`,apply:e.apply===!0,userConfirmed:e.userConfirmed===!0,retainTestData:e.retainTestData===!0}),s=[...new Set([...n.flatMap(l=>l.recommendations),...a.status==="failed"?["Review memory persistence and rerun verification."]:[]])],i=n.map(l=>l.status),c=mg(i,a.status);return{schema_version:1,home:o.home,target_root:o.target_root,host:e.host??"all",surface:e.surface??null,project:{requested_cwd:t.projectCwd,normalized:r.id,source:r.source,git_root:r.git_root,remote:r.remote,alias_key:r.alias_key},overall_status:c,memory_recall:a,hosts:n,recommendations:s}}async function cg(e){let t=[],r=await lg({home:e.home,host:e.inputHost.host,cwd:e.testCwd,warnings:e.inputHost.handshake.last?.warnings??[]});e.inputHost.mcp_registration.configured||t.push(`Install MCP registration for ${e.inputHost.host}: nativesoul mcp install --host ${e.inputHost.host} --apply --json`),r.status!=="ready"&&t.push(`Regenerate bootstrap context for ${e.inputHost.host}: nativesoul bootstrap --host ${e.inputHost.host} --cwd ${e.testCwd} --format inject --json`);let o=pg(e.inputHost.provider_parity.heartbeat),n=[...e.inputHost.full_native_evidence.missing_requirements];o==="unsupported"&&(n.includes("native_scheduler")||n.push("native_scheduler"),t.push(`Choose a host with native scheduler support or configure external scheduler workflow for ${e.inputHost.host}.`));let s=e.inputHost.provider_parity.heartbeat==="unsupported-native"&&e.inputHost.host!=="codex"?"blocked_by_host":r.status==="failed"||r.status==="degraded"||r.cache.status==="degraded"||r.cache.status==="missing"||!e.inputHost.plugin.enabled?"degraded":"ready";return{host:e.inputHost.host,surface:e.inputHost.surface,status:s,mcp:{configured:e.inputHost.mcp_registration.configured,issues:e.inputHost.mcp_registration.issues.map(i=>i.message)},bootstrap:r,heartbeat:{status:o,requirements:n},recommendations:t}}async function lg(e){let t=[...e.warnings],r=[],o="ready",n=!1,a="",s="ready";try{let i=await _t({home:e.home,host:e.host,cwd:e.cwd,readOnly:!0});t.push(...i.warnings),i.warnings.some(c=>c.startsWith("HOST_ADAPTER_UNAVAILABLE")||c==="PROJECT_MEMORY_EMPTY")&&(s="degraded")}catch(i){t.push(`bootstrap_injection_failed:${Wn(i)}`),s="failed"}try{let i=await Zo({home:e.home,host:e.host,projectCwd:e.cwd,recordTelemetry:!1});a=i.targetPath,n=i.stale,r.push(...i.warnings),r.length>0&&(o=i.warnings.some(c=>c==="BOOTSTRAP_CACHE_MISSING")?"missing":"degraded",s==="ready"&&(s="degraded"))}catch{r.push("bootstrap_cache_check_failed"),o="missing",s==="ready"&&(s="degraded")}return{status:s,warnings:t,cache:{status:o,warnings:r,targetPath:a,stale:n}}}async function dg(e){let t=[],r=null,o=!1,n=!1;try{let a=`verify-${e.testProject}`,s=`${ig} ${e.testProject}`;r=await ge(e.home,{project:a,content:s,confidence:.91,source:{host:"activation-verification",session_id:`verification-${e.testProject}`}});let i=await ft(e.home,s,a,8),c=await dr({home:e.home,project:a,status:"candidate",limit:8}),l=i.some(u=>u.id===r?.id)||c.some(u=>u.id===r?.id);if(e.apply&&e.userConfirmed&&r){let u=await pt(e.home,r.id);r=u,n=r.id===u.id&&r.status==="active"}if(!e.retainTestData&&r)try{r.status==="candidate"?await mt(e.home,r.id):await gt(e.home,r.id),o=!0}catch(u){t.push(`memory_cleanup_failed:${Wn(u)}`)}return{test_project:e.testProject,candidate_id:r?.id??"",candidate_status:r?.status??"candidate",recalled:l,promoted:n,status:l?"passed":"failed",warnings:t,cleanup_performed:o}}catch(a){return t.push(`memory_recall_check_failed:${Wn(a)}`),{test_project:e.testProject,candidate_id:r?.id??"",candidate_status:r?.status??"candidate",recalled:!1,promoted:!1,status:"failed",warnings:t,cleanup_performed:!1}}}function ug(e){return{projectCwd:sg.resolve(e.projectCwd??process.cwd())}}function pg(e){return e==="native"?"native":e==="official-fallback"?"official_fallback":"unsupported"}function mg(e,t){return e.includes("blocked_by_host")?"blocked_by_host":e.includes("degraded")||t==="failed"?"degraded":e.length>0?"ready":"degraded"}function Wn(e){return e instanceof Error?e.message:String(e)}function sc(e){let t=p(e);if(!gg(t.database))return{home:t.home,initialized:!1,database:t.database,migrations:0,memories:0,events:0,capabilities:0,ledger:fg()};let r=g(t.database,{readOnly:!0});try{return{home:t.home,initialized:!0,database:t.database,...r.counts()}}finally{r.close()}}function fg(){return{hosts:0,sessions:0,memory_edges:0,commitments:0,standing_orders:0,capability_sources:0,capability_experience:0,schedules:0,leases:0,runs:0,work_items:0,work_item_events:0}}var ic={life_activation_status:async(e,t)=>await Ir({home:t,host:Gn(e.host),targetRoot:Ee(e.target_root)??Ee(e.targetRoot)}),life_activation_plan:async(e,t)=>await Vn({home:t,host:Gn(e.host),targetRoot:Ee(e.target_root)??Ee(e.targetRoot),profile:hg(e.profile)}),life_activation_verify:async(e,t)=>await Jn({home:t,host:Gn(e.host),surface:yg(e.surface),targetRoot:Ee(e.target_root)??Ee(e.targetRoot),projectCwd:Ee(e.project_cwd)??Ee(e.projectCwd),apply:Kn(e.apply),userConfirmed:Kn(e["user-confirmed"]),retainTestData:Kn(e["retain-test-data"])})},cc=[{name:"life_activation_status",description:"Return activation status by component, including bootstrap, MCP, plugins/hooks, heartbeat, recall, memory, and cross-host verification.",inputSchema:{type:"object",properties:{host:{type:"string"},target_root:{type:"string"},targetRoot:{type:"string"}}}},{name:"life_activation_plan",description:"Return a read-only dry-run activation plan with exact files, settings, scheduler actions, and approvals.",inputSchema:{type:"object",properties:{host:{type:"string"},profile:{type:"string"},target_root:{type:"string"},targetRoot:{type:"string"}}}},{name:"life_activation_verify",description:"Run cross-host activation verification for bootstrap cache, MCP, scheduler evidence, and memory recall.",inputSchema:{type:"object",properties:{host:{type:"string"},surface:{type:"string"},project_cwd:{type:"string"},projectCwd:{type:"string"},target_root:{type:"string"},targetRoot:{type:"string"},apply:{type:"boolean"},"user-confirmed":{type:"boolean"},"retain-test-data":{type:"boolean"}}}}];function Gn(e){if(e===void 0)return"all";if(e==="all"||e==="codex"||e==="claude"||e==="grok"||e==="antigravity"||e==="gemini")return e;throw new Error("Invalid activation host")}function hg(e){if(e!==void 0){if(e==="quickstart"||e==="advanced")return e;throw new Error("Invalid activation profile")}}function yg(e){if(e!==void 0){if(e==="desktop"||e==="claude-desktop")return"claude-desktop";if(e==="claude-code")return"claude-code";throw new Error("activation verify surface must be claude-code, desktop, or claude-desktop")}}function Ee(e){return typeof e=="string"?e:void 0}function Kn(e){return e===!0}var _g=["2025-11-25","2024-11-05","2024-10-07"],mc={...ic,life_status:(e,t)=>sc(t),life_bootstrap:async(e,t)=>await Eg({home:t,host:S(e.host,"codex"),cwd:S(e.cwd,process.cwd()),query:I(e.query)}),life_recall:async(e,t)=>await ft(t,S(e.query,""),S(e.project,"default"),jr(e.limit,5)),life_remember_propose:async(e,t)=>await ge(t,{project:S(e.project,"default"),content:S(e.content,""),type:I(e.type),confidence:lc(e.confidence),source:{host:"mcp",session_id:"local"}}),life_memory_promote:async(e,t)=>await pt(t,S(e.id,"")),life_memory_reject:async(e,t)=>await mt(t,S(e.id,"")),life_memory_forget:async(e,t)=>await gt(t,S(e.id,"")),life_memory_expire:async(e,t)=>await Go(t,S(e.id,"")),life_capability_search:async(e,t)=>await Oo({home:t,query:S(e.query,""),host:xg(e)?void 0:I(e.host)??"codex",readyOnly:Ze(e.readyOnly,!1),limit:jr(e.limit,8)}),life_capability_status:async(e,t)=>{let r=S(e.uid,""),o=r?await Zt({home:t,uid:r}):null;if(!o)throw new Error(`Capability not found: ${r}`);return o},life_policy_evaluate:async(e,t)=>await Ct({home:t,action:S(e.action,""),className:pc(e.class),target:I(e.target)}),life_approval_request:async(e,t)=>await Cg({home:t,action:S(e.action,""),className:pc(e.class),target:I(e.target),project:I(e.project),host:I(e.host)}),life_approval_decide:async(e,t)=>{let r=S(e.id,""),o=await Mn({home:t,id:r,status:jg(e.status),reviewer:S(e.host,"mcp"),reason:I(e.reason)??null});if(!o.approval)throw new Error(`Approval not found: ${r}`);return o},life_commitment_create:async(e,t)=>await Mo({home:t,project:S(e.project,"default"),summary:S(e.summary,""),dueAt:I(e.due_at),ttlSeconds:lc(e.ttl_seconds),source:{host:"mcp",session_id:"local"}}),life_commitment_complete:async(e,t)=>await Do(t,S(e.id,"")),life_work_item_create:async(e,t)=>await En({home:t,project:S(e.project,"default"),title:S(e.title,""),description:I(e.description),priority:qn(e.priority),source:"mcp",tags:dc(e.tags),host:I(e.host)}),life_work_item_list:async(e,t)=>await An({home:t,project:I(e.project),status:uc(e.status),priority:qn(e.priority),assignedHost:I(e.host),limit:jr(e.limit,50)}),life_work_item_claim:async(e,t)=>await Pn({home:t,id:S(e.id,""),host:S(e.host,"mcp")}),life_work_item_update:async(e,t)=>await xn({home:t,id:S(e.id,""),status:uc(e.status),priority:qn(e.priority),assignedHost:I(e.host),description:I(e.description),tags:e.tags===void 0?void 0:dc(e.tags)}),life_work_item_complete:async(e,t)=>await In({home:t,id:S(e.id,""),status:Pg(e.status)}),life_heartbeat_claim:async(e,t)=>await $n({home:t,slot:S(e.slot,""),host:S(e.host,"codex"),project:S(e.project,"default"),ttlSeconds:jr(e.ttl_seconds,1500)}),life_heartbeat_complete:async(e,t)=>await Fn({home:t,slot:S(e.slot,""),host:S(e.host,"codex"),project:S(e.project,"default"),result:e.result??"HEARTBEAT_OK",evidence:e.evidence??{},workItemId:I(e.work_item_id)}),life_onboarding_status:async(e,t)=>await Uo(t),life_onboard_apply:async(e,t)=>await Bo({home:t,dry_run:Ze(e.dry_run,!0),user_confirmed:Ze(e.user_confirmed,!1),files:Ig(e.files),config_patch:Tg(e.config_patch)}),life_onboard_complete:async(e,t)=>await Vo({home:t,archive:e.archive===void 0?!0:Ze(e.archive,!0)})},bg=new Set(Object.keys(mc));function vg(e){return e.method?.startsWith("notifications/")?!0:!Object.prototype.hasOwnProperty.call(e,"id")}async function kg(e,t){if(vg(e))return null;let r=e.id??null;try{if(e.method==="initialize"){let o=Ot(e.params),n=I(o.protocolVersion),a=n&&_g.includes(n)?n:"2024-11-05";return _e(r,{protocolVersion:a,serverInfo:{name:"nativesoul",version:"0.1.0"},capabilities:{tools:{}}})}if(e.method==="ping")return _e(r,{});if(e.method==="resources/list")return _e(r,{resources:[]});if(e.method==="prompts/list")return _e(r,{prompts:[]});if(e.method==="tools/list")return _e(r,{tools:[{name:"life_status",description:"Return local NativeSoul health and counts.",inputSchema:{type:"object"}},{name:"life_bootstrap",description:"Return compact bootstrap context for a host and cwd.",inputSchema:{type:"object",required:["host","cwd"],properties:{host:{type:"string"},cwd:{type:"string"},query:{type:"string"}}}},{name:"life_recall",description:"Search project-scoped memory.",inputSchema:{type:"object",required:["query","project"],properties:{query:{type:"string"},project:{type:"string"},limit:{type:"number"}}}},{name:"life_remember_propose",description:"Create a redacted local candidate memory for a project.",inputSchema:{type:"object",required:["project","content"],properties:{project:{type:"string"},content:{type:"string"},type:{type:"string"},confidence:{type:"number"}}}},{name:"life_memory_promote",description:"Promote a candidate memory to active status.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"}}}},{name:"life_memory_reject",description:"Reject a candidate memory.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"}}}},{name:"life_memory_forget",description:"Forget an active memory.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"}}}},{name:"life_memory_expire",description:"Expire an active memory.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"}}}},{name:"life_capability_search",description:"Search persisted local capability records.",inputSchema:{type:"object",required:["query"],properties:{query:{type:"string"},host:{type:"string"},allHosts:{type:"boolean"},all_hosts:{type:"boolean"},readyOnly:{type:"boolean"},limit:{type:"number"}}}},{name:"life_capability_status",description:"Return one persisted capability record by uid.",inputSchema:{type:"object",required:["uid"],properties:{uid:{type:"string"}}}},{name:"life_policy_evaluate",description:"Evaluate a proposed action against local policy and standing orders.",inputSchema:{type:"object",required:["action","class"],properties:{action:{type:"string"},class:{type:"string"},target:{type:"string"}}}},{name:"life_approval_request",description:"Request approval for a sensitive action. If blocked, stop and return control to the human; there is no server or polling in this turn-based protocol.",inputSchema:{type:"object",required:["action","class"],properties:{action:{type:"string"},class:{type:"string"},target:{type:"string"},project:{type:"string"},host:{type:"string"}}}},{name:"life_approval_decide",description:"Record a human-driven approval decision. Acting agents must not self-approve; use this only from a human-operated host turn.",inputSchema:{type:"object",required:["id","status"],properties:{id:{type:"string"},status:{type:"string",enum:["approved","rejected"]},reason:{type:"string"},host:{type:"string"}}}},{name:"life_commitment_create",description:"Create a local project-scoped commitment with optional TTL.",inputSchema:{type:"object",required:["project","summary"],properties:{project:{type:"string"},summary:{type:"string"},due_at:{type:"string"},ttl_seconds:{type:"number"}}}},{name:"life_commitment_complete",description:"Complete a local commitment by id.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"}}}},{name:"life_work_item_create",description:"Create a local project-scoped work item.",inputSchema:{type:"object",required:["project","title"],properties:{project:{type:"string"},title:{type:"string"},description:{type:"string"},priority:{type:"string",enum:["low","normal","high","urgent"]},tags:{type:"array",items:{type:"string"}},host:{type:"string"}}}},{name:"life_work_item_list",description:"List local work items with optional filters.",inputSchema:{type:"object",properties:{project:{type:"string"},status:{type:"string",enum:["inbox","assigned","in_progress","review","blocked","done","failed"]},priority:{type:"string",enum:["low","normal","high","urgent"]},host:{type:"string"},limit:{type:"number"}}}},{name:"life_work_item_claim",description:"Claim one work item for a host.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"},host:{type:"string"}}}},{name:"life_work_item_update",description:"Update one work item through the shared status machine.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"},status:{type:"string",enum:["inbox","assigned","in_progress","review","blocked","done","failed"]},priority:{type:"string",enum:["low","normal","high","urgent"]},host:{type:"string"},description:{type:"string"},tags:{type:"array",items:{type:"string"}}}}},{name:"life_work_item_complete",description:"Complete one work item as done or failed.",inputSchema:{type:"object",required:["id"],properties:{id:{type:"string"},status:{type:"string",enum:["done","failed"]}}}},{name:"life_heartbeat_claim",description:"Claim a local heartbeat lease for a project and slot.",inputSchema:{type:"object",required:["slot","host","project"],properties:{slot:{type:"string"},host:{type:"string"},project:{type:"string"},ttl_seconds:{type:"number"}}}},{name:"life_heartbeat_complete",description:"Complete a local heartbeat lease and record a run.",inputSchema:{type:"object",required:["slot","host","project"],properties:{slot:{type:"string"},host:{type:"string"},project:{type:"string"},result:{type:"string"},evidence:{type:"object"},work_item_id:{type:"string"}}}},{name:"life_onboarding_status",description:"Return onboarding ritual status, per-theme interview guidance, file_generation_rules, and optional heartbeat/scan offers. Call before drafting files.",inputSchema:{type:"object"}},...cc,{name:"life_onboard_apply",description:"Dry-run or apply AI-generated onboarding human files.",inputSchema:{type:"object",required:["files"],properties:{dry_run:{type:"boolean"},user_confirmed:{type:"boolean"},files:{type:"object"},config_patch:{type:"object"}}}},{name:"life_onboard_complete",description:"Archive BOOTSTRAP.md and mark onboarding ritual complete.",inputSchema:{type:"object",properties:{archive:{type:"boolean"}}}}]});if(e.method==="tools/call"){let o=await Ar(t);if(!o.ok)return _e(r,o);let n=Ag(e.params);return _e(r,await Sg(n.name??"",n.arguments??{},t))}if(bg.has(e.method)){let o=await Ar(t);return o.ok?_e(r,await fc(e.method,Ot(e.params),t)):_e(r,o)}return Tr(r,-32601,`Unknown method: ${e.method}`)}catch(o){return o instanceof Oe?Tr(r,-32010,o.message,{code:o.code,id:o.id,from:o.from,to:o.to}):o instanceof ne?Tr(r,-32011,o.message,{code:o.code,id:o.id,status:o.status}):Tr(r,-32603,o instanceof Error?o.message:"Unknown MCP error")}}async function gc(e){let t="";process.stdin.setEncoding("utf8"),process.stdin.on("data",r=>{t+=r;let o=t.split(/\r?\n/u);t=o.pop()??"";for(let n of o){let a=n.trim();a&&Rg(a,e).catch(s=>{process.stderr.write(`NativeSoul MCP response error: ${Og(s)}
|
|
882
882
|
`)})}})}async function Rg(e,t){let r;try{r=JSON.parse(e)}catch{process.stdout.write(`${JSON.stringify({jsonrpc:"2.0",id:null,error:{code:-32700,message:"Parse error"}})}
|
|
883
883
|
`);return}let o=await kg(r,t);o&&process.stdout.write(`${JSON.stringify(o)}
|
|
@@ -46,7 +46,7 @@ Enquanto a versão for `0.x`, o produto é pré-1.0 e sai pelo canal `@beta`. **
|
|
|
46
46
|
| `@beta` | `0.x` e pré-releases `-beta.N` | `npm publish --tag beta` |
|
|
47
47
|
| `@latest` | builds estáveis (≥1.0.0) | `npm dist-tag add nativesoul@<v> latest` |
|
|
48
48
|
|
|
49
|
-
Critério de promoção beta→latest e runbook operacional vivem em [`docs/guides/versioning-and-releases.md`](../guides/versioning-and-releases.md). `npm publish` e `dist-tag` são **exclusivos do @devops** (agent-authority). Nota operacional 2026-07-01: o primeiro publish de `nativesoul@0.1.0` criou `beta: 0.1.0` e `latest: 0.1.0`; isso é realidade de registry, não mudança da política geral de 0.x. Nota operacional 2026-07-06: por decisão explícita do founder, `0.1.3` foi publicado em `@beta` **e** promovido a `@latest` (`beta: 0.1.3` / `latest: 0.1.3`), para que `npm install nativesoul` aponte ao build atual em vez do `0.1.0` antigo. É uma exceção consciente à regra geral (`@latest` = ≥1.0.0), reversível via `npm dist-tag`; a política de corte de `1.0.0` (item 2) permanece inalterada. **Exceção encerrada 2026-07-06:** `1.0.0` foi cortado, tornando `@latest` legítimo (≥1.0.0); a promoção do `1.0.0` a `@latest` substitui a exceção do `0.1.3`.
|
|
49
|
+
Critério de promoção beta→latest e runbook operacional vivem em [`docs/guides/versioning-and-releases.md`](../guides/versioning-and-releases.md). `npm publish` e `dist-tag` são **exclusivos do @devops** (agent-authority). Nota operacional 2026-07-01: o primeiro publish de `nativesoul@0.1.0` criou `beta: 0.1.0` e `latest: 0.1.0`; isso é realidade de registry, não mudança da política geral de 0.x. Nota operacional 2026-07-06: por decisão explícita do founder, `0.1.3` foi publicado em `@beta` **e** promovido a `@latest` (`beta: 0.1.3` / `latest: 0.1.3`), para que `npm install nativesoul` aponte ao build atual em vez do `0.1.0` antigo. É uma exceção consciente à regra geral (`@latest` = ≥1.0.0), reversível via `npm dist-tag`; a política de corte de `1.0.0` (item 2) permanece inalterada. **Exceção encerrada 2026-07-06:** `1.0.0` foi cortado, tornando `@latest` legítimo (≥1.0.0); a promoção do `1.0.0` a `@latest` substitui a exceção do `0.1.3`. **Política de `@beta` esclarecida 2026-07-08 (founder):** na ausência de uma pré-release ativa (`-beta.N`), `@beta` **espelha o último patch estável** de `@latest`, de modo que `npm i nativesoul@beta` nunca fique atrás do build corrente. Cada patch estável é apontado nas duas tags (`beta: <v>` == `latest: <v>`); quando houver uma pré-release em andamento, `@beta` passa a apontar para ela até a promoção. Estado atual: `beta: 1.1.2` == `latest: 1.1.2`.
|
|
50
50
|
|
|
51
51
|
### 6. CHANGELOG
|
|
52
52
|
`CHANGELOG.md` (raiz, formato *Keep a Changelog* + SemVer) é mantido a cada release e **incluído no tarball publicado** (`package.json` `files`, ADR-012), para o comprador verificar quais features cada major entrega.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# ADR-045: Paid-only closed distribution ($29) + Dodo-managed licensing
|
|
2
2
|
|
|
3
3
|
## Status
|
|
4
|
-
Accepted (2026-06-30) — supersedes ADR-040 (free-to-install) and ADR-044 (pro-awareness); largely supersedes ADR-039 (offline Ed25519 licensing)
|
|
4
|
+
Accepted (2026-06-30) — supersedes ADR-040 (free-to-install) and ADR-044 (pro-awareness); largely supersedes ADR-039 (offline Ed25519 licensing). **Amended 2026-07-08:** founder price $29 → $19 (same single product; see [Amendments](#amendments)).
|
|
5
5
|
|
|
6
6
|
## Context
|
|
7
7
|
|
|
@@ -53,3 +53,13 @@ A license check is not usage telemetry; this remains a strong, truthful privacy
|
|
|
53
53
|
- **Cost:** recurring ≈ $0 (no certs, no SEA, no CI matrix; only per-sale gateway fees + an optional free-tier serverless function).
|
|
54
54
|
- **Accepted risk:** the lock is bypassable; revenue depends on convenience + money-back + goodwill, not enforcement; conversion is unproven for a cumulative-value, no-audience product. This is the founder's deliberate bet.
|
|
55
55
|
- **Relation to ADR-043:** perpetual-fallback + 1-year-updates + the major-version soft-nudge (18.10) are kept; only the distribution/licensing mechanics change.
|
|
56
|
+
|
|
57
|
+
## Amendments
|
|
58
|
+
|
|
59
|
+
### 2026-07-08 — Founder price $29 → $19 (same product)
|
|
60
|
+
The founder lowered the launch price of the **single existing paid product** from **$29 to $19**. This is a **price-only** change:
|
|
61
|
+
- **Same product**, same Dodo Product ID, same commercial terms (buy once, 1 year of updates, keep the build forever, 30-day money-back, no subscription). **No two-tier**, no cap-flip, no checkout/integration change — the Dodo product itself now charges $19, so displaying $19 is truthful.
|
|
62
|
+
- **Founder-cohort counter kept** ("N of 100 founder spots left · at $19"): a real, founder-maintained cap, not fabricated scarcity — the count must stay true (ADR-045 price-goes-up-after-launch promise).
|
|
63
|
+
- **Scope of the doc update (customer-facing "current price"):** sales page + pixels/analytics value, help center (docs.nativesoul.dev), npm `README`, and `feature-registry.yaml` claims (`pricing_paid_only`, `founder_spots`) + the `marketing-audit` test fixture. Verified: built page 0×`$29`, `marketing-audit` PASS.
|
|
64
|
+
- **Deliberately NOT rewritten:** dated decision records that state the price as-decided-on-2026-06-30 ($29) — this ADR body, EPIC-018/025/026 change logs, the PRD Q-008 resolution, the roadmap pivot log, and the `1.0.0` CHANGELOG entry. They record history; this amendment is the single source of the price change.
|
|
65
|
+
- **Deferred (founder: "depois pensamos no outro valor"):** an eventual second $19/$29 tier with real cap enforcement is out of scope here and remains unbuilt.
|