@team-semicolon/semicolony-cli 4.18.62 → 4.18.63
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/dist/bundle.js
CHANGED
|
@@ -2965,7 +2965,7 @@ Spec: semo-ops docs/superpowers/specs/2026-07-20-semo-semicolony-local-separatio
|
|
|
2965
2965
|
`)}function S4n(t){let e=t._warnings??[];return e.length>0?{id:"config",label:"config.toml forward-compat",level:"warn",detail:e.join("; ")}:t._source?.startsWith("<default:")?{id:"config",label:"config.toml",level:"warn",detail:`\uC5C6\uC74C \u2014 \uAE30\uBCF8\uAC12(profile=${t.profile}) \uC0AC\uC6A9 \uC911. \`semicolony init\` \uC73C\uB85C \uBCF8\uC778 \uD658\uACBD \uACE0\uC815 \uAD8C\uC7A5`}:{id:"config",label:`config.toml (schema ${t.schema_version}, profile=${t.profile})`,level:"ok",detail:t._source}}function Q4n(){let t=[];for(let e of[AA(),hA(),sv()])Bs.existsSync(e)||t.push(e);return t.length>0?{id:"layout",label:"SemiColony 3-layer \uB514\uB809\uD130\uB9AC",level:"fail",detail:`\uB204\uB77D: ${t.join(", ")} \u2014 \`semicolony init\` \uC2E4\uD589 \uD544\uC694`}:{id:"layout",label:"SemiColony 3-layer \uB514\uB809\uD130\uB9AC",level:"ok"}}function Jnt(t,e,n){let r=`sqlite:${t}`,i=`SQLite ${t} DB`;if(!e)return{id:r,label:i,level:"skip",detail:"driver \uAC00 sqlite \uAC00 \uC544\uB2D8"};if(!Bs.existsSync(e))return{id:r,label:i,level:"fail",detail:`${e} \uC5C6\uC74C \u2014 \`semicolony migrate-sqlite --target ${t}\` \uC2E4\uD589`};let s=ks.join(n,t);if(!Bs.existsSync(s))return{id:r,label:i,level:"warn",detail:`migrations-sqlite/${t} \uB514\uB809\uD130\uB9AC \uC5C6\uC74C`};let o=Bs.readdirSync(s).filter(c=>c.endsWith(".sql")).map(c=>c.replace(/\.sql$/,"")),a=new gle.default(e,{readonly:!0});try{if(!a.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='schema_migrations'").get())return{id:r,label:i,level:"warn",detail:`schema_migrations \uD14C\uC774\uBE14 \uC5C6\uC74C \u2014 \`semicolony migrate-sqlite --target ${t}\``};let l=a.prepare("SELECT version FROM schema_migrations").all().map(A=>A.version),u=new Set(l),d=o.filter(A=>!u.has(A));return d.length>0?{id:r,label:i,level:"warn",detail:`\uBBF8\uC801\uC6A9 ${d.length}: ${d.join(", ")} \u2014 \`semicolony migrate-sqlite --target ${t}\``}:{id:r,label:i,level:"ok",detail:`${e} (applied ${l.length})`}}finally{a.close()}}async function D4n(t,e,n=fetch){let r=(t??process.env.OLLAMA_HOST??"http://127.0.0.1:11434").replace(/\/$/,""),i="ollama";try{let s=await n(`${r}/api/tags`);if(!s.ok)return[{id:i,label:"Ollama \uC11C\uBC84",level:"fail",detail:`HTTP ${s.status} from ${r}`}];let a=((await s.json()).models??[]).map(l=>l.name??"").filter(Boolean),c=[{id:i,label:`Ollama \uC11C\uBC84 (${r})`,level:"ok",detail:`${a.length}\uAC1C \uBAA8\uB378`}];for(let l of e){let u=a.some(d=>d===l||d.startsWith(`${l}:`));c.push({id:`ollama:model:${l}`,label:`Ollama \uBAA8\uB378 ${l}`,level:u?"ok":"fail",detail:u?void 0:`\`ollama pull ${l}\` \uD544\uC694`})}return c}catch(s){return[{id:i,label:`Ollama \uC11C\uBC84 (${r})`,level:"fail",detail:`\uB3C4\uB2EC \uBD88\uAC00: ${s.message} \u2014 \`brew install ollama && ollama serve\``},...e.map(o=>({id:`ollama:model:${o}`,label:`Ollama \uBAA8\uB378 ${o}`,level:"skip",detail:"ollama \uC11C\uBC84 \uBBF8\uB3C4\uB2EC"}))]}}function R4n(t,e=process.env){let n=[];if(t.includes("discord")){let r=!!(e.DISCORD_TOKEN||e.DISCORD_BOT_TOKEN);n.push({id:"messaging:discord",label:"Discord \uBD07 \uD1A0\uD070 (DISCORD_TOKEN)",level:r?"ok":"fail",detail:r?void 0:"Discord Developer Portal \uC5D0\uC11C bot token \uBC1C\uAE09 \uD6C4 \uD658\uACBD\uBCC0\uC218 \uC124\uC815"})}if(t.includes("slack")){let r=!!(e.SLACK_BOT_TOKEN&&e.SLACK_APP_TOKEN);n.push({id:"messaging:slack",label:"Slack \uD1A0\uD070 (SLACK_BOT_TOKEN + SLACK_APP_TOKEN)",level:r?"ok":"fail",detail:r?void 0:"bot token (xoxb-) + app token (xapp-) \uC591\uCABD \uD544\uC694"})}return n}function M4n(t,e=process.env){let n=t.execution.target;if(n==="anthropic-api"){let r=t.execution.api_key_env??"ANTHROPIC_API_KEY",i=!!e[r];return{id:"execution",label:`execution=anthropic-api (${r})`,level:i?"ok":"fail",detail:i?void 0:`\uD658\uACBD\uBCC0\uC218 ${r} \uC124\uC815 \uD544\uC694`}}if(n==="openai"||n==="gemini"){let r=t.execution.api_key_env??(n==="openai"?"OPENAI_API_KEY":"GEMINI_API_KEY"),i=!!e[r];return{id:"execution",label:`execution=${n} (${r})`,level:i?"ok":"fail",detail:i?void 0:`\uD658\uACBD\uBCC0\uC218 ${r} \uC124\uC815 \uD544\uC694`}}return n==="claude-code"?{id:"execution",label:"execution=claude-code",level:"ok",detail:"\uC138\uC158\uD480\uC5D0\uC11C \uAD00\uB9AC\uB428 (\uBCC4\uB3C4 preflight \uC5C6\uC74C)"}:n==="ollama"||n==="mlx"?{id:"execution",label:`execution=${n}`,level:"ok",detail:"ollama \uCCB4\uD06C \uD56D\uBAA9 \uCC38\uC870"}:{id:"execution",label:`execution=${n}`,level:"warn",detail:"\uC54C \uC218 \uC5C6\uB294 \uD0C0\uAE43"}}function T4n(t){let e="seats",n="bot seat pool";if(!t)return{id:e,label:n,level:"skip",detail:"ops \uAC00 sqlite \uAC00 \uC544\uB2D8"};if(!Bs.existsSync(t))return{id:e,label:n,level:"skip",detail:"ops DB \uC5C6\uC74C"};let r=new gle.default(t,{readonly:!0});try{if(!r.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='bot_seats'").get())return{id:e,label:n,level:"skip",detail:"bot_seats \uD14C\uC774\uBE14 \uC5C6\uC74C"};let s=r.prepare("SELECT COUNT(*) AS n FROM bot_seats").get();if(s.n===0)return{id:e,label:n,level:"warn",detail:"\uBE48 pool \u2014 `semicolony seats add` \uB85C \uCD5C\uC18C 1\uAC1C \uD655\uBCF4 \uD544\uC694 (bot \uC0DD\uC131 \uC2DC)"};let o=r.prepare("SELECT COUNT(*) AS n FROM bot_seats WHERE status='available'").get();return o.n===0?{id:e,label:n,level:"warn",detail:`${s.n}\uAC1C seat \uBAA8\uB450 \uD560\uB2F9\uB428 \u2014 \uC2E0\uADDC bot \uC0DD\uC131 \uC2DC \`semicolony seats add\` \uB610\uB294 \uAE30\uC874 \uBD07 retire`}:{id:e,label:n,level:"ok",detail:`available ${o.n}/${s.n}`}}finally{r.close()}}function O4n(t){let e="kernel-skills",n="kernel skills \uBA38\uD2F0\uB9AC\uC5BC\uB77C\uC774\uC988";if(t.length===0)return{id:e,label:n,level:"skip",detail:"BUILTIN_KERNEL_SKILLS \uC5C6\uC74C"};let r=ks.join(AA(),"skills");if(!Bs.existsSync(r))return{id:e,label:n,level:"fail",detail:`${r} \uC5C6\uC74C \u2014 \`semicolony update\` \uC2E4\uD589 \uD544\uC694`};let i=[];for(let s of t){let o=ks.join(r,s,"SKILL.md");Bs.existsSync(o)||i.push(s)}return i.length>0?{id:e,label:n,level:"fail",detail:`\uB204\uB77D: ${i.join(", ")} \u2014 \`semicolony update\` \uC2E4\uD589`}:{id:e,label:n,level:"ok",detail:`${t.length}\uAC1C`}}function N4n(t){let e="embedding";if(!t.embedding)return{id:e,label:"embedding provider",level:"warn",detail:"\uBBF8\uC124\uC815 \u2014 FTS5 \uD0A4\uC6CC\uB4DC \uAC80\uC0C9\uB9CC \uAC00\uB2A5 (\uD55C\uAD6D\uC5B4 \uC758\uBBF8 \uAC80\uC0C9 \uC5C6\uC74C)"};if(t.embedding.provider==="none")return{id:e,label:"embedding=none",level:"ok",detail:"FTS5 \uC804\uC6A9"};if(t.embedding.provider==="openai"){let n=t.embedding.api_key_env??"OPENAI_API_KEY",r=!!process.env[n];return{id:e,label:`embedding=openai (${n})`,level:r?"ok":"fail",detail:r?void 0:`${n} \uD658\uACBD\uBCC0\uC218 \uD544\uC694`}}return{id:e,label:`embedding=${t.embedding.provider}`,level:"ok",detail:t.embedding.model??void 0}}function nrt(t,e={}){let n={ok:0,warn:0,fail:0,skip:0};for(let i of t)n[i.level]+=1;let r=n.fail>0||e.strict&&n.warn>0?1:0;return{checks:t,summary:n,exitCode:r}}function rrt(t){return Bs.existsSync(t)?Bs.readFileSync(t,"utf8"):null}function P4n(t){let e=rrt(t.filePath);if(!e)return{id:"worker:env-file",label:"worker env file",level:"warn",detail:`${t.filePath} \uC5C6\uC74C \u2014 ${qA(t.surface)} worker setup \uC2E4\uD589 \uD544\uC694`};let n=[];return!e.includes(`${t.gatewayUrlEnv}=`)&&!e.includes("SEMICOLONY_KB_GATEWAY_URL=")&&n.push("gateway url env"),!e.includes(`${t.tokenEnv}=`)&&!e.includes("SEMICOLONY_WORKER_KB_TOKEN=")&&n.push("worker token env"),e.includes("DATABASE_URL=")&&n.push("DATABASE_URL must not be stored"),n.length>0?{id:"worker:env-file",label:"worker env file",level:"warn",detail:`\uBD88\uC644\uC804: ${n.join(", ")} \u2014 token \uAC12\uC740 \uCD9C\uB825\uD558\uC9C0 \uC54A\uC74C`}:{id:"worker:env-file",label:"worker env file",level:"ok",detail:`${t.filePath} (token redacted)`}}function F4n(t){let e=rrt(t.filePath);if(!e)return{id:"worker:mcp-config",label:"read-only KB MCP config",level:"warn",detail:`${t.filePath} \uC5C6\uC74C \u2014 \uD544\uC694\uD558\uBA74 ${qA(t.surface)} worker setup --with-kb-mcp`};try{let n=JSON.parse(e),r=JSON.stringify(n),i=[];return!r.includes(t.gatewayUrlEnv)&&!r.includes("SEMICOLONY_KB_GATEWAY_URL")&&i.push("gateway url env reference"),!r.includes(t.tokenEnv)&&!r.includes("SEMICOLONY_WORKER_KB_TOKEN")&&i.push("worker token env reference"),r.includes("wck_")&&i.push("plaintext worker token must not be embedded"),i.length>0?{id:"worker:mcp-config",label:"read-only KB MCP config",level:"warn",detail:`\uBD88\uC644\uC804: ${i.join(", ")}`}:{id:"worker:mcp-config",label:"read-only KB MCP config",level:"ok",detail:t.filePath}}catch(n){return{id:"worker:mcp-config",label:"read-only KB MCP config",level:"warn",detail:`JSON \uD30C\uC2F1 \uC2E4\uD328: ${n.message}`}}}function L4n(t){if(!Bs.existsSync(t))return{id:"worker:state-file",label:"worker local state",level:"warn",detail:`${t} \uC5C6\uC74C \u2014 worker setup \uC7AC\uC2E4\uD589 \uC2DC \uC0DD\uC131`};try{let e=ud(t);if(!e)return{id:"worker:state-file",label:"worker local state",level:"warn",detail:"state is empty"};let n=[];e.worker_id||n.push("worker_id"),e.device_id||n.push("device_id"),e.profile_id||n.push("profile_id"),e.installed_profile_version||n.push("installed_profile_version");let r=JSON.stringify(e);if((r.includes("wck_")||r.includes("DATABASE_URL"))&&n.push("secret material must not be stored"),n.length>0)return{id:"worker:state-file",label:"worker local state",level:"warn",detail:`\uBD88\uC644\uC804: ${n.join(", ")}`};let i=KG(e);return i!=="current"?{id:"worker:state-file",label:"worker local state",level:"warn",detail:`${e.worker_id}/${e.device_id} capability=${i}; \uB85C\uCEEC snapshot\uC740 \uAD8C\uD55C \uADFC\uAC70\uAC00 \uC544\uB2C8\uBA70 protected command\uAC00 DB lease\uB97C \uC7AC\uC870\uD68C\uD574\uC57C \uD568`}:{id:"worker:state-file",label:"worker local state",level:"ok",detail:`${e.worker_id}/${e.device_id} profile=${e.profile_id}@${e.installed_profile_version}; capability snapshot current (\uC124\uBA85\uC6A9 cache)`}}catch(e){return{id:"worker:state-file",label:"worker local state",level:"warn",detail:`JSON \uD30C\uC2F1 \uC2E4\uD328: ${e.message}`}}}function oT(t,e){return e.source!=="legacy"?t:{...t,detail:`${t.detail??e.filePath} (read-only legacy fallback)`}}function HH(t,e,n){return{id:t,label:e,level:"warn",detail:`${n.source} worker file rejected: ${n.reason} (${n.filePath})`}}function U4n(t,e){let n=jo(t),r=Uc(t,n.releaseState,Ll(t,"release-state.json"));if(r.status==="rejected")return{check:HH("worker:release-state","worker local release state",r),state:null,readable:null};if(r.status==="absent")return{check:{id:"worker:release-state",label:"worker local release state",level:e?"skip":"warn",detail:e?"release activation in progress; state is persisted after doctor passes":`${n.releaseState} \uC5C6\uC74C \u2014 semo worker update`},state:null,readable:null};try{let i=ew(r.filePath);if(!i)return{check:{id:"worker:release-state",label:"worker local release state",level:"warn",detail:"release state is empty"},state:null,readable:r};let s=Number.isNaN(Date.parse(i.applied_at))||Number.isNaN(Date.parse(i.last_doctor_at));return{check:oT({id:"worker:release-state",label:"worker local release state",level:s?"warn":"ok",detail:s?"release state timestamps are invalid":`${i.applied_release_id}@${i.applied_release_version}`},r),state:i,readable:r}}catch(i){return{check:oT({id:"worker:release-state",label:"worker local release state",level:"warn",detail:`invalid release state: ${i.message}`},r),state:null,readable:r}}}function Knt(t){let e="";try{let a=Bs.lstatSync(t);if(!a.isFile()||a.isSymbolicLink())throw new Error("managed context target is not a regular file");e=Bs.readFileSync(t,"utf8")}catch(a){if(a.code!=="ENOENT")throw a}let n=/<!-- SEMO_OPS_WORKER_RELEASE:([^:\r\n>]+):(BEGIN|END) -->/g,r="<!-- SEMO_OPS_WORKER_RELEASE:",i=[...e.matchAll(n)];if(i.length!==e.split(r).length-1)throw new Error("invalid managed context marker");let s=new Map;for(let a of i){let c=a[1],l=a[2],u=s.get(c)??{};if(l==="BEGIN"){if(u.begin)throw new Error(`managed context ${c} has duplicate markers`);u.begin={index:a.index,length:a[0].length}}else{if(u.end)throw new Error(`managed context ${c} has duplicate markers`);u.end={index:a.index,length:a[0].length}}s.set(c,u)}let o=new Map;for(let[a,c]of s){if(!c.begin||!c.end||c.begin.index>=c.end.index)throw new Error(`managed context ${a} has unpaired markers`);let l=c.begin.index+c.begin.length;e.startsWith(`\r
|
|
2966
2966
|
`,l)?l+=2:e.startsWith(`
|
|
2967
2967
|
`,l)&&(l+=1),o.set(a,{content:e.slice(l,c.end.index)})}return o}function ple(t){return(0,ert.createHash)("sha256").update(t).digest("hex")}function znt(t,e){return ple(t)===e?!0:t.endsWith(`
|
|
2968
|
-
`)&&ple(t.slice(0,-1))===e}function Znt(t,e){let n=`context:${e}:`;return new Map(Object.entries(t.managed_target_digests).filter(([r])=>r.startsWith(n)).map(([r,i])=>[r.slice(n.length),i]))}function GH(t,e){return t.size===e.size&&[...t.keys()].every(n=>e.has(n))}function q4n(t,e,n){try{let r=Knt(ks.join(t,".claude","CLAUDE.md")),i=Knt(ks.join(t,".codex","AGENTS.md"));if(!GH(r,i))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"managed context blocks must be paired in both harnesses"};if(n)return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"ok",detail:`${r.size} paired managed context block(s); activation in progress`};if(!e)return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"no valid local release state is available for managed digest validation"};let s=Znt(e,"claude"),o=Znt(e,"codex");if(!GH(s,o)||!GH(r,s)||!GH(i,o))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"managed context ids do not match the local release state in both harnesses"};for(let[a,c]of r){if(!znt(c.content,s.get(a)))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:`Claude managed context ${a} digest drift`};if(!znt(i.get(a).content,o.get(a)))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:`Codex managed context ${a} digest drift`}}return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"ok",detail:`${r.size} paired managed context block(s) match local release state`}}catch(r){return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:r.message}}}function j4n(t,e){let n=/^skill:(claude|agents):([a-z0-9][a-z0-9-]*)$/.exec(e);return n?ks.join(t,n[1]==="claude"?".claude":".agents","skills",n[2],"SKILL.md"):e==="asset:shared-script:feedback-capture.py"?ks.join(t,".semo","shared","scripts","feedback-capture.py"):null}function $4n(t,e){let n=ks.resolve(t),r=ks.resolve(e),i=ks.relative(n,r);if(i===""||i.startsWith("..")||ks.isAbsolute(i))throw new Error("managed target escapes the worker home");let s=n;for(let a of i.split(ks.sep))if(s=ks.join(s,a),Bs.lstatSync(s).isSymbolicLink())throw new Error("managed target traverses a symlink");let o=Bs.lstatSync(r);if(!o.isFile()||o.isSymbolicLink())throw new Error("managed target is not a regular file");return{content:Bs.readFileSync(r),mode:o.mode&511}}function G4n(t,e,n){let r={id:"worker:managed-targets",label:"managed worker release files"};if(n)return{...r,level:"skip",detail:"activation in progress"};if(!e)return{...r,level:"warn",detail:"no valid local release state is available for managed file validation"};let i=Object.entries(e.managed_target_digests).filter(([s])=>!s.startsWith("context:"));for(let[s,o]of i){let a=j4n(t,s);if(!a)return{...r,level:"warn",detail:`unknown managed target key: ${s}`};try{let c=$4n(t,a);if(ple(c.content)!==o)return{...r,level:"warn",detail:`${s} digest drift`};let l=e.managed_target_modes?.[s]??(s.startsWith("skill:")?"0644":void 0);if(!l)return{...r,level:"warn",detail:`${s} expected mode is not recorded`};if(c.mode!==Number.parseInt(l,8))return{...r,level:"warn",detail:`${s} mode drift (expected ${l})`}}catch(c){let l=c.code;return{...r,level:"warn",detail:`${s} ${l==="ENOENT"?"is missing":c.message}`}}}return{...r,level:"ok",detail:`${i.length} managed skill/asset file(s) match local release state`}}function H4n(t,e){return t?{id:"worker:last-update-doctor",label:"latest successful worker update doctor",level:t.last_doctor_status==="pass"&&!Number.isNaN(Date.parse(t.last_doctor_at))?"ok":"warn",detail:`${t.last_doctor_status} at ${t.last_doctor_at}`}:{id:"worker:last-update-doctor",label:"latest successful worker update doctor",level:e?"skip":"warn",detail:e?"first release activation is awaiting doctor completion":"no successful worker release update is recorded"}}function W4n(t,e,n={}){return new Promise(r=>{(0,Xnt.execFile)(t,e,{env:n.env??process.env,timeout:n.timeoutMs??8e3,windowsHide:!0},(i,s,o)=>{let a=i?.code;r({exitCode:typeof a=="number"?a:i?1:0,stdout:String(s??""),stderr:String(o??"")})})})}async function V4n(t,e){let n=await e(t,["--version"],{timeoutMs:5e3});if(n.exitCode!==0)return{id:`worker:cli:${t}`,label:`${t} CLI binary`,level:"warn",detail:`${t} --version \uC2E4\uD328 \u2014 PATH/global install \uD655\uC778 \uD544\uC694`};let r=n.stdout.split(/\r?\n/).find(Boolean)?.slice(0,120)??"version ok";return{id:`worker:cli:${t}`,label:`${t} CLI binary`,level:"ok",detail:r}}async function Y4n(t,e,n={}){let r=[];r.push(S4n(t)),r.push(Q4n()),t.kb.driver==="sqlite"&&r.push(Jnt("kb",t.kb.sqlite_path,e)),t.ops.driver==="sqlite"&&(r.push(Jnt("ops",t.ops.sqlite_path,e)),r.push(T4n(t.ops.sqlite_path))),r.push(...R4n(t.messaging.sources)),r.push(M4n(t)),r.push(N4n(t));try{let c=((await Promise.resolve().then(()=>(rs(),kA))).BUILTIN_KERNEL_SKILLS??[]).map(l=>l.id);r.push(O4n(c))}catch{r.push({id:"kernel-skills",label:"kernel skills \uBA38\uD2F0\uB9AC\uC5BC\uB77C\uC774\uC988",level:"skip",detail:"@team-semicolon/semicolony-common \uBBF8\uB85C\uB529"})}let i=[],s=t.execution.target==="ollama"?t.execution.ollama_host:t.embedding?.host;return(t.execution.target==="ollama"||t.embedding?.provider==="ollama")&&(t.execution.target==="ollama"&&t.execution.model&&i.push(t.execution.model),t.embedding?.provider==="ollama"&&t.embedding.model&&i.push(t.embedding.model),r.push(...await D4n(s,i,n.fetchImpl))),nrt(r,{strict:n.strict})}async function aT(t={}){let e=t.env??process.env,n=t.homeDir??e.HOME??trt.homedir(),r=t.surface??"semicolony",i=[],s=by(e,r),o=Ey(e,{surface:r}),a=s.value?.replace(/\/$/,""),c=o.value,l=s.envName??XE(r),u=o.envName??bx(r),d=jo(n),A=t.updateInProgress===!0;if(!a||!c){let E=[a?null:s.candidates.join(" or "),c?null:o.candidates.join(" or ")].filter(Boolean);i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"fail",detail:`\uB204\uB77D: ${E.join(", ")} \u2014 Semi\uC5D0\uAC8C worker token \uBC1C\uAE09\uC744 \uC694\uCCAD\uD558\uC138\uC694`})}else c.startsWith("wck_")?i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"ok",detail:`${a}${s.envName?` (${s.envName})`:""}`}):i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"fail",detail:`${o.envName??"worker token"} \uC740 worker-scoped \`wck_\` \uD1A0\uD070\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4`});i.push({id:"worker:direct-db",label:"worker direct DB env",level:e.DATABASE_URL?.trim()?"warn":"ok",detail:e.DATABASE_URL?.trim()?"DATABASE_URL \uC124\uC815\uB428 \u2014 worker profile\uC740 \uAE30\uBCF8\uC801\uC73C\uB85C gateway\uB9CC \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4":"DATABASE_URL unset"});let h=Uc(n,d.env,Ll(n,".env")),f=Uc(n,d.kbMcp,Ll(n,"kb-mcp.json")),g=Uc(n,d.workerState,Ll(n,"worker-state.json")),m=null;if(g.status==="rejected")i.push(HH("worker:state-file","worker local state",g));else if(g.status==="absent")i.push({id:"worker:state-file",label:"worker local state",level:"warn",detail:`${d.workerState} \uC5C6\uC74C \u2014 worker setup \uC7AC\uC2E4\uD589 \uC2DC \uC0DD\uC131`});else{let E=oT(L4n(g.filePath),g);i.push(A&&E.level==="warn"&&E.detail?.includes("capability=")?{...E,level:"ok",detail:`${E.detail}; release activation in progress`}:E);try{m=ud(g.filePath)}catch{m=null}}if(h.status==="rejected"?i.push(HH("worker:env-file","worker env file",h)):h.status==="absent"?i.push({id:"worker:env-file",label:"worker env file",level:"warn",detail:`${d.env} \uC5C6\uC74C \u2014 ${qA(r)} worker setup \uC2E4\uD589 \uD544\uC694`}):i.push(oT(P4n({filePath:h.filePath,surface:r,gatewayUrlEnv:l,tokenEnv:u}),h)),f.status==="rejected")i.push(HH("worker:mcp-config","read-only KB MCP config",f));else if(f.status==="absent"){let E=m?.tool_adapters_enabled.includes("kb-mcp")??!1;i.push({id:"worker:mcp-config",label:"read-only KB MCP config",level:E?"warn":"skip",detail:E?`${d.kbMcp} \uC5C6\uC74C \u2014 ${qA(r)} worker setup --with-kb-mcp`:"kb-mcp adapter is not enabled; config is optional"})}else i.push(oT(F4n({filePath:f.filePath,surface:r,gatewayUrlEnv:l,tokenEnv:u}),f));i.push(...fle(n));let y=U4n(n,A);i.push(y.check),i.push(q4n(n,y.state,A)),i.push(G4n(n,y.state,A)),i.push(H4n(y.state,A));let b=!!(a&&c?.startsWith("wck_")),w=[{id:"worker:kb:hive-service",label:"KB read smoke: hive-service",domain:"semicolon",key:"glossary",subKey:"hive-service"},{id:"worker:kb:setup-guide",label:"KB read smoke: worker setup guide",domain:"semicolon",key:"process",subKey:"worker-environment-setup-via-semi"}];for(let E of w){if(!b){i.push({id:E.id,label:E.label,level:"skip",detail:"worker gateway env \uBBF8\uCDA9\uC871"});continue}try{await wy({baseUrl:a,token:c},E.domain,E.key,E.subKey,t.fetchImpl),i.push({id:E.id,label:E.label,level:"ok",detail:`${E.domain}/${E.key}${E.subKey?`/${E.subKey}`:""}`})}catch(C){i.push({id:E.id,label:E.label,level:"fail",detail:C.message.slice(0,240)})}}if(t.runExternalChecks){let E=t.commandRunner??W4n;i.push(await V4n("semo",E))}return nrt(i,{strict:t.strict})}function J4n(t){return t==="ok"?Vc.default.green("\u2713"):t==="warn"?Vc.default.yellow("\u26A0"):t==="fail"?Vc.default.red("\u2717"):Vc.default.gray("\u25CB")}function WH(t){let e=[""];for(let r of t.checks)e.push(` ${J4n(r.level)} ${r.label}${r.detail?Vc.default.gray(` \u2014 ${r.detail}`):""}`);e.push("");let n=t.summary;if(e.push(` ${Vc.default.bold("\uC694\uC57D")}: ${Vc.default.green(`${n.ok} ok`)} \xB7 ${Vc.default.yellow(`${n.warn} warn`)} \xB7 ${Vc.default.red(`${n.fail} fail`)} \xB7 ${Vc.default.gray(`${n.skip} skip`)}`),t.exitCode===0&&n.fail===0){let r=t.checks.some(i=>i.id.startsWith("worker:"));e.push(" "+Vc.default.green(r?"\u2192 Worker profile \uC900\uBE44 \uC644\uB8CC":"\u2192 Personal \uC2A4\uD0DD \uC900\uBE44 \uC644\uB8CC"))}else n.fail>0&&e.push(" "+Vc.default.red("\u2192 \uBE14\uB85C\uCEE4 \uC788\uC74C \u2014 \uC704 fail \uD56D\uBAA9 \uD574\uACB0 \uD6C4 \uC7AC\uC2E4\uD589"));return e.push(""),e.join(`
|
|
2968
|
+
`)&&ple(t.slice(0,-1))===e}function Znt(t,e){let n=`context:${e}:`;return new Map(Object.entries(t.managed_target_digests).filter(([r])=>r.startsWith(n)).map(([r,i])=>[r.slice(n.length),i]))}function GH(t,e){return t.size===e.size&&[...t.keys()].every(n=>e.has(n))}function q4n(t,e,n){try{let r=Knt(ks.join(t,".claude","CLAUDE.md")),i=Knt(ks.join(t,".codex","AGENTS.md"));if(!GH(r,i))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"managed context blocks must be paired in both harnesses"};if(n)return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"ok",detail:`${r.size} paired managed context block(s); activation in progress`};if(!e)return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"no valid local release state is available for managed digest validation"};let s=Znt(e,"claude"),o=Znt(e,"codex");if(!GH(s,o)||!GH(r,s)||!GH(i,o))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:"managed context ids do not match the local release state in both harnesses"};for(let[a,c]of r){if(!znt(c.content,s.get(a)))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:`Claude managed context ${a} digest drift`};if(!znt(i.get(a).content,o.get(a)))return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:`Codex managed context ${a} digest drift`}}return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"ok",detail:`${r.size} paired managed context block(s) match local release state`}}catch(r){return{id:"worker:managed-context-parity",label:"managed Claude/Codex context parity",level:"warn",detail:r.message}}}function j4n(t,e){let n=/^skill:(claude|agents):([a-z0-9][a-z0-9-]*)$/.exec(e);return n?ks.join(t,n[1]==="claude"?".claude":".agents","skills",n[2],"SKILL.md"):e==="asset:shared-script:feedback-capture.py"?ks.join(t,".semo","shared","scripts","feedback-capture.py"):null}function $4n(t,e){let n=ks.resolve(t),r=ks.resolve(e),i=ks.relative(n,r);if(i===""||i.startsWith("..")||ks.isAbsolute(i))throw new Error("managed target escapes the worker home");let s=n;for(let a of i.split(ks.sep))if(s=ks.join(s,a),Bs.lstatSync(s).isSymbolicLink())throw new Error("managed target traverses a symlink");let o=Bs.lstatSync(r);if(!o.isFile()||o.isSymbolicLink())throw new Error("managed target is not a regular file");return{content:Bs.readFileSync(r),mode:o.mode&511}}function G4n(t,e,n){let r={id:"worker:managed-targets",label:"managed worker release files"};if(n)return{...r,level:"skip",detail:"activation in progress"};if(!e)return{...r,level:"warn",detail:"no valid local release state is available for managed file validation"};let i=Object.entries(e.managed_target_digests).filter(([s])=>!s.startsWith("context:"));for(let[s,o]of i){let a=j4n(t,s);if(!a)return{...r,level:"warn",detail:`unknown managed target key: ${s}`};try{let c=$4n(t,a);if(ple(c.content)!==o)return{...r,level:"warn",detail:`${s} digest drift`};let l=e.managed_target_modes?.[s]??(s.startsWith("skill:")?"0644":void 0);if(!l)return{...r,level:"warn",detail:`${s} expected mode is not recorded`};if(c.mode!==Number.parseInt(l,8))return{...r,level:"warn",detail:`${s} mode drift (expected ${l})`}}catch(c){let l=c.code;return{...r,level:"warn",detail:`${s} ${l==="ENOENT"?"is missing":c.message}`}}}return{...r,level:"ok",detail:`${i.length} managed skill/asset file(s) match local release state`}}function H4n(t,e){return t?{id:"worker:last-update-doctor",label:"latest successful worker update doctor",level:t.last_doctor_status==="pass"&&!Number.isNaN(Date.parse(t.last_doctor_at))?"ok":"warn",detail:`${t.last_doctor_status} at ${t.last_doctor_at}`}:{id:"worker:last-update-doctor",label:"latest successful worker update doctor",level:e?"skip":"warn",detail:e?"first release activation is awaiting doctor completion":"no successful worker release update is recorded"}}function W4n(t,e,n={}){return new Promise(r=>{(0,Xnt.execFile)(t,e,{env:n.env??process.env,timeout:n.timeoutMs??8e3,windowsHide:!0},(i,s,o)=>{let a=i?.code;r({exitCode:typeof a=="number"?a:i?1:0,stdout:String(s??""),stderr:String(o??"")})})})}async function V4n(t,e){let n=await e(t,["--version"],{timeoutMs:5e3});if(n.exitCode!==0)return{id:`worker:cli:${t}`,label:`${t} CLI binary`,level:"warn",detail:`${t} --version \uC2E4\uD328 \u2014 PATH/global install \uD655\uC778 \uD544\uC694`};let r=n.stdout.split(/\r?\n/).find(Boolean)?.slice(0,120)??"version ok";return{id:`worker:cli:${t}`,label:`${t} CLI binary`,level:"ok",detail:r}}async function Y4n(t,e,n={}){let r=[];r.push(S4n(t)),r.push(Q4n()),t.kb.driver==="sqlite"&&r.push(Jnt("kb",t.kb.sqlite_path,e)),t.ops.driver==="sqlite"&&(r.push(Jnt("ops",t.ops.sqlite_path,e)),r.push(T4n(t.ops.sqlite_path))),r.push(...R4n(t.messaging.sources)),r.push(M4n(t)),r.push(N4n(t));try{let c=((await Promise.resolve().then(()=>(rs(),kA))).BUILTIN_KERNEL_SKILLS??[]).map(l=>l.id);r.push(O4n(c))}catch{r.push({id:"kernel-skills",label:"kernel skills \uBA38\uD2F0\uB9AC\uC5BC\uB77C\uC774\uC988",level:"skip",detail:"@team-semicolon/semicolony-common \uBBF8\uB85C\uB529"})}let i=[],s=t.execution.target==="ollama"?t.execution.ollama_host:t.embedding?.host;return(t.execution.target==="ollama"||t.embedding?.provider==="ollama")&&(t.execution.target==="ollama"&&t.execution.model&&i.push(t.execution.model),t.embedding?.provider==="ollama"&&t.embedding.model&&i.push(t.embedding.model),r.push(...await D4n(s,i,n.fetchImpl))),nrt(r,{strict:n.strict})}async function aT(t={}){let e=t.env??process.env,n=t.homeDir??e.HOME??trt.homedir(),r=t.surface??"semicolony",i=[],s=by(e,r),o=Ey(e,{surface:r}),a=s.value?.replace(/\/$/,""),c=o.value,l=s.envName??XE(r),u=o.envName??bx(r),d=jo(n),A=t.updateInProgress===!0;if(!a||!c){let E=[a?null:s.candidates.join(" or "),c?null:o.candidates.join(" or ")].filter(Boolean);i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"fail",detail:`\uB204\uB77D: ${E.join(", ")} \u2014 Semi\uC5D0\uAC8C worker token \uBC1C\uAE09\uC744 \uC694\uCCAD\uD558\uC138\uC694`})}else c.startsWith("wck_")?i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"ok",detail:`${a}${s.envName?` (${s.envName})`:""}`}):i.push({id:"worker:gateway-env",label:"worker KB gateway env",level:"fail",detail:`${o.envName??"worker token"} \uC740 worker-scoped \`wck_\` \uD1A0\uD070\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4`});i.push({id:"worker:direct-db",label:"worker direct DB env",level:e.DATABASE_URL?.trim()?"warn":"ok",detail:e.DATABASE_URL?.trim()?"DATABASE_URL \uC124\uC815\uB428 \u2014 worker profile\uC740 \uAE30\uBCF8\uC801\uC73C\uB85C gateway\uB9CC \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4":"DATABASE_URL unset"});let h=Uc(n,d.env,Ll(n,".env")),f=Uc(n,d.kbMcp,Ll(n,"kb-mcp.json")),g=Uc(n,d.workerState,Ll(n,"worker-state.json")),m=null;if(g.status==="rejected")i.push(HH("worker:state-file","worker local state",g));else if(g.status==="absent")i.push({id:"worker:state-file",label:"worker local state",level:"warn",detail:`${d.workerState} \uC5C6\uC74C \u2014 worker setup \uC7AC\uC2E4\uD589 \uC2DC \uC0DD\uC131`});else{let E=oT(L4n(g.filePath),g);i.push(A&&E.level==="warn"&&E.detail?.includes("capability=")?{...E,level:"ok",detail:`${E.detail}; release activation in progress`}:E);try{m=ud(g.filePath)}catch{m=null}}if(h.status==="rejected"?i.push(HH("worker:env-file","worker env file",h)):h.status==="absent"?i.push({id:"worker:env-file",label:"worker env file",level:"warn",detail:`${d.env} \uC5C6\uC74C \u2014 ${qA(r)} worker setup \uC2E4\uD589 \uD544\uC694`}):i.push(oT(P4n({filePath:h.filePath,surface:r,gatewayUrlEnv:l,tokenEnv:u}),h)),f.status==="rejected")i.push(HH("worker:mcp-config","read-only KB MCP config",f));else if(f.status==="absent"){let E=m?.tool_adapters_enabled.includes("kb-mcp")??!1;i.push({id:"worker:mcp-config",label:"read-only KB MCP config",level:E?"warn":"skip",detail:E?`${d.kbMcp} \uC5C6\uC74C \u2014 ${qA(r)} worker setup --with-kb-mcp`:"kb-mcp adapter is not enabled; config is optional"})}else i.push(oT(F4n({filePath:f.filePath,surface:r,gatewayUrlEnv:l,tokenEnv:u}),f));i.push(...fle(n).map(E=>A&&E.id==="semicolony-home-residue"&&E.level==="warn"?{...E,level:"skip",detail:`${E.detail}; historical residue is not changed by release activation`}:E));let y=U4n(n,A);i.push(y.check),i.push(q4n(n,y.state,A)),i.push(G4n(n,y.state,A)),i.push(H4n(y.state,A));let b=!!(a&&c?.startsWith("wck_")),w=[{id:"worker:kb:hive-service",label:"KB read smoke: hive-service",domain:"semicolon",key:"glossary",subKey:"hive-service"},{id:"worker:kb:setup-guide",label:"KB read smoke: worker setup guide",domain:"semicolon",key:"process",subKey:"worker-environment-setup-via-semi"}];for(let E of w){if(!b){i.push({id:E.id,label:E.label,level:"skip",detail:"worker gateway env \uBBF8\uCDA9\uC871"});continue}try{await wy({baseUrl:a,token:c},E.domain,E.key,E.subKey,t.fetchImpl),i.push({id:E.id,label:E.label,level:"ok",detail:`${E.domain}/${E.key}${E.subKey?`/${E.subKey}`:""}`})}catch(C){i.push({id:E.id,label:E.label,level:"fail",detail:C.message.slice(0,240)})}}if(t.runExternalChecks){let E=t.commandRunner??W4n;i.push(await V4n("semo",E))}return nrt(i,{strict:t.strict})}function J4n(t){return t==="ok"?Vc.default.green("\u2713"):t==="warn"?Vc.default.yellow("\u26A0"):t==="fail"?Vc.default.red("\u2717"):Vc.default.gray("\u25CB")}function WH(t){let e=[""];for(let r of t.checks)e.push(` ${J4n(r.level)} ${r.label}${r.detail?Vc.default.gray(` \u2014 ${r.detail}`):""}`);e.push("");let n=t.summary;if(e.push(` ${Vc.default.bold("\uC694\uC57D")}: ${Vc.default.green(`${n.ok} ok`)} \xB7 ${Vc.default.yellow(`${n.warn} warn`)} \xB7 ${Vc.default.red(`${n.fail} fail`)} \xB7 ${Vc.default.gray(`${n.skip} skip`)}`),t.exitCode===0&&n.fail===0){let r=t.checks.some(i=>i.id.startsWith("worker:"));e.push(" "+Vc.default.green(r?"\u2192 Worker profile \uC900\uBE44 \uC644\uB8CC":"\u2192 Personal \uC2A4\uD0DD \uC900\uBE44 \uC644\uB8CC"))}else n.fail>0&&e.push(" "+Vc.default.red("\u2192 \uBE14\uB85C\uCEE4 \uC788\uC74C \u2014 \uC704 fail \uD56D\uBAA9 \uD574\uACB0 \uD6C4 \uC7AC\uC2E4\uD589"));return e.push(""),e.join(`
|
|
2969
2969
|
`)}function irt(t){t.command("doctor").description("SemiColony \uC2A4\uD0DD \uD504\uB9AC\uD50C\uB77C\uC774\uD2B8 \uD5EC\uC2A4\uCCB4\uD06C (config/DB/migrations/Ollama/credentials)").option("--json","JSON \uC73C\uB85C \uCD9C\uB825 (\uBA38\uC2E0 \uD30C\uC2F1\uC6A9)").option("--strict","warn \uB3C4 \uC2E4\uD328\uB85C \uAC04\uC8FC (CI \uC6A9)").option("--profile <profile>","doctor profile (worker|default)","default").action(async e=>{if(e.profile==="worker"){let o=await aT({strict:e.strict,runExternalChecks:!0});e.json?console.log(JSON.stringify(o,null,2)):console.log(WH(o)),process.exitCode=o.exitCode;return}if(e.profile&&e.profile!=="default"){console.error(Vc.default.red(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 doctor profile: ${e.profile}`)),process.exitCode=1;return}let n=ln(),r=ks.resolve(__dirname,"..","migrations-sqlite"),i=Bs.existsSync(r)?r:ks.resolve(__dirname,"..","..","migrations-sqlite"),s=await Y4n(n,i,{strict:e.strict});e.json?console.log(JSON.stringify(s,null,2)):console.log(WH(s)),process.exitCode=s.exitCode})}var Vd=x(Oe());function ZUr(t,e){if(e){if(e!=="discord"&&e!=="slack")throw new Error(`--platform \uC740 discord \uB610\uB294 slack \uB9CC \uD5C8\uC6A9 (\uBC1B\uC74C: ${e})`);return e}let n=t.messaging.sources??[];if(n.includes("discord"))return"discord";if(n.includes("slack"))return"slack";throw new Error("config.toml messaging.sources \uC5D0 discord \uB610\uB294 slack \uC774 \uC5C6\uC74C \u2014 --platform \uC73C\uB85C \uBA85\uC2DC\uD558\uAC70\uB098 `semicolony init` \uC73C\uB85C \uC7AC\uC124\uC815")}async function XUr(){try{return{start:(await Promise.resolve().then(()=>(UHt(),LHt))).startDiscordRouter}}catch(t){let e=t instanceof Error?t.message:String(t);throw console.error(Vd.default.red(`
|
|
2970
2970
|
\u2717 @team-semicolon/semicolony-discord-router \uB85C\uB4DC \uC2E4\uD328`)),console.error(Vd.default.gray(` ${e}`)),console.error(Vd.default.yellow(`
|
|
2971
2971
|
\uC124\uCE58 \uC0C1\uD0DC \uD655\uC778:`)),console.error(" monorepo: packages/discord-router/ \uC874\uC7AC \uC5EC\uBD80"),console.error(" \uAE00\uB85C\uBC8C : npm list -g @team-semicolon/semicolony-discord-router"),console.error(Vd.default.gray(`
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
-- 171_worker_release_gateway_privileges.sql
|
|
2
|
+
--
|
|
3
|
+
-- The Gateway runs as sc_app. A worker release read needs only the bound
|
|
4
|
+
-- device, its profile's active release, and the immutable release manifest;
|
|
5
|
+
-- reporting needs only the six health/application columns on that device.
|
|
6
|
+
-- Keep credential issuance and all other device mutations owner-controlled.
|
|
7
|
+
|
|
8
|
+
GRANT USAGE ON SCHEMA semicolony TO sc_app;
|
|
9
|
+
|
|
10
|
+
REVOKE ALL PRIVILEGES ON TABLE
|
|
11
|
+
semicolony.worker_devices,
|
|
12
|
+
semicolony.workspace_profiles,
|
|
13
|
+
semicolony.worker_profile_releases
|
|
14
|
+
FROM PUBLIC, sc_provider;
|
|
15
|
+
|
|
16
|
+
REVOKE INSERT, DELETE, TRUNCATE, REFERENCES, TRIGGER ON TABLE
|
|
17
|
+
semicolony.worker_devices,
|
|
18
|
+
semicolony.workspace_profiles,
|
|
19
|
+
semicolony.worker_profile_releases
|
|
20
|
+
FROM sc_app;
|
|
21
|
+
|
|
22
|
+
GRANT SELECT (
|
|
23
|
+
device_id,
|
|
24
|
+
worker_id,
|
|
25
|
+
gateway_credential_id,
|
|
26
|
+
status,
|
|
27
|
+
installed_profile_id,
|
|
28
|
+
applied_release_id,
|
|
29
|
+
applied_release_version,
|
|
30
|
+
applied_at
|
|
31
|
+
) ON TABLE semicolony.worker_devices TO sc_app;
|
|
32
|
+
|
|
33
|
+
GRANT UPDATE (
|
|
34
|
+
last_seen_at,
|
|
35
|
+
last_doctor_status,
|
|
36
|
+
last_doctor_summary,
|
|
37
|
+
applied_release_id,
|
|
38
|
+
applied_release_version,
|
|
39
|
+
applied_at
|
|
40
|
+
) ON TABLE semicolony.worker_devices TO sc_app;
|
|
41
|
+
|
|
42
|
+
GRANT SELECT (profile_id, active_release_id)
|
|
43
|
+
ON TABLE semicolony.workspace_profiles TO sc_app;
|
|
44
|
+
|
|
45
|
+
GRANT SELECT (release_id, profile_id, version, status, manifest, manifest_sha256)
|
|
46
|
+
ON TABLE semicolony.worker_profile_releases TO sc_app;
|