@tocca-systems/twp-cli 0.10.0

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.
Files changed (47) hide show
  1. package/CHANGELOG.public.md +80 -0
  2. package/LICENSE +47 -0
  3. package/README.md +279 -0
  4. package/dist/THIRD-PARTY-NOTICES.md +1239 -0
  5. package/dist/ai-dispatch-T6PJ4DUG.js +82 -0
  6. package/dist/app-S33SNSH5.js +1370 -0
  7. package/dist/chunk-3WJHTPOZ.js +48 -0
  8. package/dist/chunk-4QI5NX4C.js +6 -0
  9. package/dist/chunk-5QCAIKFE.js +9 -0
  10. package/dist/chunk-63LDNYGW.js +23 -0
  11. package/dist/chunk-7ZVTACQS.js +8 -0
  12. package/dist/chunk-DIMZRTLE.js +37 -0
  13. package/dist/chunk-DXXFUNYN.js +7 -0
  14. package/dist/chunk-FQDYLZV3.js +6 -0
  15. package/dist/chunk-GY7KI5E5.js +4 -0
  16. package/dist/chunk-II5RVJQN.js +3 -0
  17. package/dist/chunk-IM4H52FC.js +109 -0
  18. package/dist/chunk-J7QYPKVK.js +18 -0
  19. package/dist/chunk-KCXVV45F.js +16 -0
  20. package/dist/chunk-L37NS5L2.js +8 -0
  21. package/dist/chunk-N2UVRM3Z.js +5 -0
  22. package/dist/chunk-N3B737KO.js +57 -0
  23. package/dist/chunk-NERYSBA4.js +9 -0
  24. package/dist/chunk-NHYMHCAT.js +4 -0
  25. package/dist/chunk-NNOYO67O.js +7 -0
  26. package/dist/chunk-PMOUHEJQ.js +5 -0
  27. package/dist/chunk-Q7YSSWTR.js +33 -0
  28. package/dist/chunk-RQFG3OUL.js +41 -0
  29. package/dist/chunk-RZVI6PMW.js +5 -0
  30. package/dist/chunk-VSJBJXZO.js +3 -0
  31. package/dist/chunk-VSQXY2VX.js +42 -0
  32. package/dist/chunk-WVS4W5FY.js +16 -0
  33. package/dist/chunk-ZZ5EYKCK.js +58 -0
  34. package/dist/cli.js +132 -0
  35. package/dist/commands-QKNOQRWT.js +60 -0
  36. package/dist/commands-T47RY6EH.js +365 -0
  37. package/dist/devtools-VZW7JDIG.js +131 -0
  38. package/dist/dist-HZIZTJ4O.js +93 -0
  39. package/dist/fuzzysort-DFVKV4B4.js +3 -0
  40. package/dist/oneshot-JD5LINMX.js +18 -0
  41. package/dist/project-BEY4CNSF.js +13 -0
  42. package/dist/run-EDV5273K.js +58 -0
  43. package/dist/schedule-command-LWUBXHBQ.js +13 -0
  44. package/dist/setup-GY674TII.js +74 -0
  45. package/dist/task-MQYRE4QC.js +135 -0
  46. package/dist/update-WDWUECN7.js +21 -0
  47. package/package.json +73 -0
@@ -0,0 +1,48 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{defaultIsExecutableFile,findExecutable,findOnPath,isWindowsDriveAbsolute,joinFor}from"./chunk-PMOUHEJQ.js";import{spawnSync as spawnSync2}from"child_process";import{spawnSync}from"child_process";import fs from"fs";import path from"path";function resolveDeps(d){return{platform:d.platform??process.platform,env:d.env??process.env,findExecutable:d.findExecutable??((name,env,platform)=>findExecutable(name,{env,platform})),readFileSync:d.readFileSync??(p=>fs.readFileSync(p,"utf8")),existsSync:d.existsSync??fs.existsSync,sizeOf:d.sizeOf??(p=>fs.statSync(p).size),nodePath:d.nodePath??process.execPath}}var MAX_SHIM_BYTES=64*1024;var DENIED_NODE_FLAGS=["--require","-r","--import","--loader","--experimental-loader","--env-file","--eval","\
4
+ -e","--print","-p","--inspect"];function deniedNodeFlag(arg){const name=arg.split("=")[0]??arg;if(name.startsWith("--inspect"))return true;return DENIED_NODE_FLAGS.includes(name)}function escapeRegExp(v){return v.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function parseCmdShim(text){const paths=[];const re=/"%~?dp0%?[\\/]*([^"]+)"/gi;for(let m=re.exec(text);m!==null;m=re.exec(text))paths.push(m[1]??"");for(const script of paths.filter(v=>/\.[cm]?js$/i.test(v))){const esc=escapeRegExp(script);const adjacent=new RegExp(
5
+ `"%_prog%"([^"]*)"%~?dp0%?[\\\\/]*${esc}"`,"i").exec(text)??new RegExp(`"%~?dp0%?[\\\\/]*node\\.exe"([^"]*)"%~?dp0%?[\\\\/]*${esc}"`,"i").exec(text);if(adjacent===null)continue;const middle=adjacent[1]??"";return{target:script,viaNode:true,nodeArgs:middle.trim().split(/\s+/).filter(a=>a!=="")}}const exe=paths.find(v=>/\.(exe|com)$/i.test(v)&&!/(^|[\\/])node\.exe$/i.test(v));if(exe!==void 0)return{target:exe,viaNode:false,nodeArgs:[]};return null}function resolveSpawnTarget(file,args,deps={}){const d=resolveDeps(
6
+ deps);if(d.platform!=="win32")return{ok:true,file,args:[...args],note:null};const hasSeparator=/[\\/]/.test(file);const isAbsolute=isWindowsDriveAbsolute(file);if(hasSeparator&&!isAbsolute){return{ok:false,reason:`${file} \u306F\u76F8\u5BFE\u30D1\u30B9\u3067\u3059\u3002bare name \u304B\u7D76\u5BFE\u30D1\u30B9\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`}}const resolved=isAbsolute?file:d.findExecutable(file,d.env,d.platform);if(resolved===null||resolved===""){return{ok:false,reason:`${file}\
7
+ \u304C PATH \u4E0A\u306B\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF08PATHEXT \u306E\u62E1\u5F35\u5B50\u3082\u542B\u3081\u3066\u63A2\u3057\u307E\u3057\u305F\uFF09`}}const describe=to=>file===to?null:`${file} \u2192 ${to}`;const ext=path.win32.extname(resolved).toLowerCase();if(ext===".exe"||ext===".com"){return{ok:true,file:resolved,args:[...args],note:describe(resolved)}}if(ext!==".cmd"&&ext!==".bat"){return{ok:false,reason:`${resolved} \u306F Windows \u306E spawn \u3067\u8D77\u52D5\u3067\u304D\u306A\u3044\u5F62\u3067\u3059\uFF08\u62E1\u5F35\u5B50 ${ext===
8
+ ""?"\u306A\u3057":ext}\uFF09\u3002native \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\uFF08.exe\uFF09\u304B npm \u30B0\u30ED\u30FC\u30D0\u30EB\uFF08.cmd\uFF09\u3067\u5165\u308C\u76F4\u3057\u3066\u304F\u3060\u3055\u3044`}}let text;try{const size=d.sizeOf(resolved);if(size>MAX_SHIM_BYTES){return{ok:false,reason:`${resolved} \u304C\u5927\u304D\u3059\u304E\u307E\u3059\uFF08${size} \u30D0\u30A4\u30C8\uFF09\u3002npm \u306E cmd \u30B7\u30E0\u3067\u306F\u3042\u308A\u307E\u305B\u3093`}}text=d.readFileSync(resolved)}catch(e){
9
+ return{ok:false,reason:`${resolved} \u3092\u8AAD\u3081\u307E\u305B\u3093\u3067\u3057\u305F: ${e.message}`}}const shim=parseCmdShim(text);if(shim===null){return{ok:false,reason:`${resolved} \u306F npm \u306E cmd \u30B7\u30E0\u306E\u5F62\u3067\u306F\u306A\u3044\u305F\u3081\u3001\u5B9F\u4F53\u3092\u7279\u5B9A\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002cmd.exe \u7D4C\u7531\u306E\u8D77\u52D5\u306F\u5F15\u6570\u3092\u6700\u521D\u306E\u6539\u884C\u3067\u5207\u308A\u6368\u3066\u308B\u305F\u3081\u4F7F\u3044\u307E\u305B\u3093\u3002native \u30A4\u30F3\u30B9\u30C8\u30FC\u30E9\uFF08.exe\uFF09\u3067\u5165\u308C\u76F4\u3059\u304B\u3001npm \u3067\u30B0\u30ED\u30FC\u30D0\u30EB\u306B\u5165\u308C\u76F4\u3057\u3066\u304F\u3060\u3055\u3044`}}
10
+ const dir=path.win32.dirname(resolved);if(path.win32.isAbsolute(shim.target)||/^[\\/]{2}/.test(shim.target)){return{ok:false,reason:`${resolved} \u304C\u7D76\u5BFE\u30D1\u30B9\uFF08${shim.target}\uFF09\u3092\u6307\u3057\u3066\u3044\u307E\u3059\u3002npm \u306E cmd \u30B7\u30E0\u3067\u306F\u3042\u308A\u307E\u305B\u3093`}}const target=path.win32.resolve(dir,shim.target);if(!d.existsSync(target)){return{ok:false,reason:`${resolved} \u304C\u6307\u3059 ${target} \u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF08\u5C0E\u5165\u304C\u58CA\u308C\u3066\u3044\u307E\u3059\uFF09`}}
11
+ if(!shim.viaNode){return{ok:true,file:target,args:[...args],note:`${file} \u2192 ${resolved} \u2192 ${target}`}}const bad=shim.nodeArgs.filter(a=>!a.startsWith("-")||deniedNodeFlag(a));if(bad.length>0){return{ok:false,reason:`${resolved} \u304C node \u3078\u6E21\u305D\u3046\u3068\u3057\u3066\u3044\u308B\u5F15\u6570\u3092\u8A31\u53EF\u3067\u304D\u307E\u305B\u3093\uFF08${bad.join(" ")}\uFF09`}}const colocated=path.win32.join(dir,"node.exe");const prog=d.existsSync(colocated)?colocated:d.nodePath;return{
12
+ ok:true,file:prog,args:[...shim.nodeArgs,target,...args],note:`${file} \u2192 ${resolved}\uFF08cmd \u30B7\u30E0\u3092\u89E3\u6C7A: ${prog} ${target}\uFF09`}}function spawnSyncResolved(file,args,options,deps={},run=spawnSync){const target=resolveSpawnTarget(file,args,deps);if(!target.ok){return{pid:0,output:[],stdout:"",stderr:"",status:null,signal:null,error:new Error(target.reason)}}return run(target.file,target.args,options)}var DEFAULT_CLAUDE_LAUNCHER={bin:"claude-auto-switch",probe:["--help"],probeMatch:"^\\s*exec\\s",execArgs:["exec","--"],activeArgs:["active","--path"]};function detectClaudeAutoSwitch(bin=DEFAULT_CLAUDE_LAUNCHER.bin,run=spawnSync2,lookup={}){const r=spawnSyncResolved(bin,[...DEFAULT_CLAUDE_LAUNCHER.probe],{encoding:"utf8",timeout:1e4},lookup,run);if(r.error!==void 0||r.status!==0)return null;const help=`${r.stdout??""}${r.stderr??""}`;return{bin,hasExec:new RegExp(DEFAULT_CLAUDE_LAUNCHER.probeMatch,
13
+ "m").test(help)}}function wrapWithAutoSwitch(cas,file,args){if(cas===null||!cas.hasExec)return{file,args:[...args]};return{file:cas.bin,args:[...DEFAULT_CLAUDE_LAUNCHER.execArgs,file,...args]}}function activeSlotPath(cas,run=spawnSync2,lookup={}){if(cas===null)return null;const r=spawnSyncResolved(cas.bin,[...DEFAULT_CLAUDE_LAUNCHER.activeArgs],{encoding:"utf8",timeout:1e4},lookup,run);if(r.error!==void 0||r.status!==0)return null;const out=(r.stdout??"").trim();return out===""?null:out}function isClaudeAi(ai){
14
+ return ai==="claude"||!["gemini","codex","copilot"].includes(ai)}import{createHash}from"crypto";import fs2 from"fs";var FALSY=new Set(["0","false","no","off"]);function isBoolishTrue(raw){const v=(raw??"").trim();if(v==="")return false;return!FALSY.has(v.toLowerCase())}var EXCLUSIVE_SKILL_FLOOR=["support-triage"];function normalizeSkillName(skill){return skill.trim().replace(/^twp-/,"")}var stripPrefix=normalizeSkillName;function skillOfItem(item){const explicit=(item.ai_skill??"").trim();if(explicit)return stripPrefix(explicit);const m=/\/twp-([a-z0-9-]+)/.exec(item.prompt??"");return m?.[1]??""}function ageMinutesOf(item,now){for(const raw of[item.started_at,item.updated_at,item.dequeued_at,item.created_at]){if(!raw)continue;const ts=Date.parse(raw);if(Number.
15
+ isNaN(ts))continue;return Math.floor((now.getTime()-ts)/6e4)}return null}function exclusiveInflightEntries(groups,opts){const now=opts.now??new Date;const staleMinutes=opts.staleHours*60;const bySkill=new Map;for(const group of groups){for(const item of group.items){const skill=skillOfItem(item);if(!skill)continue;const status=group.status==="mixed"?item.status??"unknown":group.status;const ageMinutes=ageMinutesOf(item,now);if(status==="processing"&&ageMinutes!==null&&ageMinutes>staleMinutes)continue;
16
+ const entry={skill,status,runner:item.runner_id??"-",ageMinutes};const prev=bySkill.get(skill);if(!prev||(entry.ageMinutes??-1)>(prev.ageMinutes??-1))bySkill.set(skill,entry)}}return[...bySkill.values()].sort((a,b)=>a.skill.localeCompare(b.skill))}function formatExclusiveEntry(entry){const age=entry.ageMinutes===null?"\u4E0D\u660E":`${entry.ageMinutes}\u5206`;return`${entry.skill} status=${entry.status} runner=${entry.runner} \u7D4C\u904E=${age}`}import path2 from"path";var BUILTIN={primary_rotation:{complex:["claude"],search:["claude"],simple:["claude"]},fallback_chains:{complex:["claude","codex"],search:["codex","gemini","copilot","claude"],simple:["codex","gemini","copilot","claude"]}};function usesBedrock(env){return isBoolishTrue(env.CLAUDE_CODE_USE_BEDROCK)}var DEFAULT_CATEGORY="complex";var EFFORTS=new Set(["low","medium","high","xhigh","max"]);var MAX_COOLDOWN_SEC=3600;var DEFAULT_COOLDOWN_SEC=300;var AI_UNUSABLE_COOLDOWN_SEC=1800;
17
+ function loadAiConfig(inline,file,workspace){const warnings=[];let fromFile=null;if(file!==void 0&&file.trim()!==""){const resolved=path2.isAbsolute(file)?file:path2.resolve(workspace,file);try{const parsed=JSON.parse(fs2.readFileSync(resolved,"utf8"));if(parsed===null||typeof parsed!=="object"||Array.isArray(parsed)){warnings.push(`ai_config_file \u304C\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u3067\u306F\u3042\u308A\u307E\u305B\u3093: ${resolved}`)}else{fromFile=parsed}}catch(err){warnings.push(`ai\
18
+ _config_file \u3092\u8AAD\u3081\u307E\u305B\u3093: ${resolved}\uFF08${err.message}\uFF09
19
+ \u3053\u306E\u72B6\u614B\u3067\u306F\u5168\u30B9\u30AD\u30EB\u304C\u65E2\u5B9A\u30AB\u30C6\u30B4\u30EA\u3067\u8D70\u308A\u307E\u3059\u3002\u78BA\u8A8D: python3 -m json.tool <file>`)}}const merged={...fromFile??{},...inline??{}};return{config:new AiConfig(merged),warnings}}var CHAIN_KEYS=["primary_rotation","fallback_chains"];var AiConfig=class{constructor(raw){this.raw=raw;this.highRiskSkills=new Set((raw.high_risk_skills??[]).filter(v=>typeof v==="string"&&v!==""))}raw;rotation=new Map;limitedUntil=new Map;unusableUntil=new Map;highRiskSkills;hash(){
20
+ const significant=Object.fromEntries(Object.entries(this.raw).filter(([k])=>!k.startsWith("_")&&!CHAIN_KEYS.includes(k)).sort(([a],[b])=>a.localeCompare(b)));return createHash("sha256").update(JSON.stringify(significant)).digest("hex").slice(0,16)}categoryForSkill(skill){const name=stripPrefix2(skill);return this.raw.skill_category?.[name]??DEFAULT_CATEGORY}usesAi(ai){const rotations=this.raw.primary_rotation??BUILTIN.primary_rotation;const chains=this.raw.fallback_chains??BUILTIN.fallback_chains;
21
+ const categories=new Set([DEFAULT_CATEGORY,...Object.keys(rotations),...Object.keys(chains),...Object.values(this.raw.skill_category??{})]);const matches=name=>isClaudeAi(ai)?isClaudeAi(name):name===ai;for(const category of categories){const rotation=rotations[category]??rotations[DEFAULT_CATEGORY]??BUILTIN.primary_rotation[DEFAULT_CATEGORY]??[];const chain=chains[category]??chains[DEFAULT_CATEGORY]??BUILTIN.fallback_chains[DEFAULT_CATEGORY]??["claude"];for(const name of[...rotation,...chain]){if(matches(
22
+ name))return true}}return false}chainFor(category){const chains=this.raw.fallback_chains??BUILTIN.fallback_chains;return chains[category]??chains[DEFAULT_CATEGORY]??BUILTIN.fallback_chains[DEFAULT_CATEGORY]??["claude"]}primaryFor(category,skill){const rotations=this.raw.primary_rotation??BUILTIN.primary_rotation;const entries=rotations[category]??rotations[DEFAULT_CATEGORY]??BUILTIN.primary_rotation[DEFAULT_CATEGORY]??[];if(entries.length===0)return"";const start=this.rotation.get(category)??0;for(let i=0;i<
23
+ entries.length;i+=1){const ai=entries[(start+i)%entries.length];if(ai!==void 0&&this.isAllowed(ai,category,skill)){this.rotation.set(category,(start+i+1)%entries.length);return ai}}return""}isHighRisk(category,skill,priority,label){if(["verify","security","support"].includes(category))return true;if(priority==="P0"||priority==="P0.5")return true;const name=stripPrefix2(skill);if(this.highRiskSkills.has(name))return true;return HIGH_RISK_LABEL.test(label)}selectPrimary(category,skill,priority,label){
24
+ if(this.isHighRisk(category,skill,priority,label)&&this.chainFor(category).includes("claude")){return"claude"}return this.primaryFor(category,skill)}isAllowed(ai,category,skill){if(ai!=="gemini")return true;if(["complex","verify","security","support"].includes(category))return false;return!this.requiresGitRemote(skill)}requiresGitRemote(skill){return(this.raw.git_remote_skills??[]).includes(stripPrefix2(skill))}exclusiveSkills(){const configured=(this.raw.exclusive_skills??[]).map(s=>stripPrefix2(
25
+ (s??"").trim())).filter(s=>s!=="");return new Set([...configured,...EXCLUSIVE_SKILL_FLOOR])}isExclusiveSkill(skill){const name=stripPrefix2(skill.trim());return name!==""&&this.exclusiveSkills().has(name)}modelFor(ai,category,env=process.env){switch(ai){case"gemini":return this.raw.gemini_models?.[category]??"";case"codex":return this.raw.codex_models?.[category]??this.raw.codex_models?.[DEFAULT_CATEGORY]??"";case"claude":return this.claudeModelFor(category,env);default:return isClaudeAi(ai)?this.
26
+ claudeModelFor(category,env):""}}claudeModelFor(category,env){const table=usesBedrock(env)?this.raw.claude_models_bedrock:this.raw.claude_models;return table?.[category]??env.CLAUDE_MODEL??""}maxTurnsFor(category,env=process.env){const fallback=Number.parseInt(env.CLAUDE_MAX_TURNS??"",10);const base=Number.isInteger(fallback)&&fallback>0?fallback:200;const configured=this.raw.claude_max_turns?.[category];return Number.isInteger(configured)&&(configured??0)>0?configured:base}effortFor(category,skill,env=process.
27
+ env,explicit){const name=stripPrefix2(skill);const item=(explicit??"").trim();if(item!==""&&EFFORTS.has(item))return{value:item,warning:null};const itemWarning=item!==""?`\u4E0D\u6B63\u306A ai_effort '${item}'\uFF08\u30A2\u30A4\u30C6\u30E0\u6307\u5B9A\uFF09\u2192 \u30B9\u30AD\u30EB\uFF0F\u30AB\u30C6\u30B4\u30EA\u65E2\u5B9A\u3092\u4F7F\u3044\u307E\u3059`:null;const raw=(name!==""?this.raw.claude_effort_by_skill?.[name]:void 0)??this.raw.claude_effort?.[category]??env.CLAUDE_EFFORT??"";if(raw==="")
28
+ return{value:"",warning:itemWarning};if(EFFORTS.has(raw))return{value:raw,warning:itemWarning};return{value:"",warning:`\u4E0D\u6B63\u306A effort \u5024 '${raw}'\uFF08category=${category}, skill=${name||"none"}\uFF09\u2192 \u672A\u6307\u5B9A\u3068\u3057\u3066\u6271\u3044\u307E\u3059`}}fallbackDelaySec(ai,env=process.env){const fromEnv=Number.parseInt(env[`AI_FALLBACK_DELAY_${ai.toUpperCase()}`]??"",10);if(Number.isInteger(fromEnv)&&fromEnv>=0)return fromEnv;const cfg=this.raw.fallback_delay?.[ai];
29
+ return Number.isInteger(cfg)&&(cfg??0)>=0?cfg:0}cooldownDefaultSec(ai,env=process.env){const fromEnv=Number.parseInt(env[`AI_COOLDOWN_${ai.toUpperCase()}`]??"",10);if(Number.isInteger(fromEnv)&&fromEnv>0)return fromEnv;const cfg=this.raw.cooldown?.[ai];if(Number.isInteger(cfg)&&(cfg??0)>0)return cfg;const backoff=Number.parseInt(env.RATE_LIMIT_BACKOFF??"",10);return Number.isInteger(backoff)&&backoff>0?backoff:DEFAULT_COOLDOWN_SEC}limitKey(ai,slot){return slot===null||slot===void 0||slot===""?ai:
30
+ `${ai}@${slot}`}hasCooldownFor(ai,now=Date.now()){for(const[key,until]of this.limitedUntil){if(until<=now)continue;if(key===ai||key.startsWith(`${ai}@`))return true}return false}isRateLimited(ai,now=Date.now(),slot=null){return(this.limitedUntil.get(this.limitKey(ai,slot))??0)>now}markRateLimited(ai,seconds,now=Date.now(),slot=null){const capped=Math.min(Math.max(Math.trunc(seconds),1),MAX_COOLDOWN_SEC);this.limitedUntil.set(this.limitKey(ai,slot),now+capped*1e3);return capped}markAiUnusable(ai,now=Date.
31
+ now()){this.unusableUntil.set(ai,now+AI_UNUSABLE_COOLDOWN_SEC*1e3);return AI_UNUSABLE_COOLDOWN_SEC}isAiUnusable(ai,now=Date.now()){return(this.unusableUntil.get(ai)??0)>now}minCooldownRemainingSec(now=Date.now()){let min=null;for(const until of this.limitedUntil.values()){if(until<=now)continue;const remaining=Math.ceil((until-now)/1e3);if(min===null||remaining<min)min=remaining}return min}};var HIGH_RISK_LABEL=/本番|リリース|認証|認可|権限|セキュリティ|課金|給与|勤怠計算/;
32
+ var TIER_ALIASES=new Set(["opus","sonnet","haiku","default"]);function modelFitsRoute(model,env=process.env){if(TIER_ALIASES.has(model.trim().toLowerCase()))return true;if(model.startsWith("arn:aws:bedrock:"))return usesBedrock(env);const bedrockShaped=/(^|[./])anthropic\./.test(model);return usesBedrock(env)?bedrockShaped:!bedrockShaped}function isUsableModelId(value){return value!==""&&!value.startsWith("-")&&/^[A-Za-z0-9._:\-/[\]]+$/.test(value)}function stripPrefix2(skill){return skill.startsWith(
33
+ "twp-")?skill.slice(4):skill}import{spawnSync as spawnSync3}from"child_process";import{createHash as createHash2}from"crypto";import fs3 from"fs";import os from"os";import path3 from"path";var DETECTABLE_AIS=["claude","codex","gemini","copilot"];function isDetectableAi(value){return DETECTABLE_AIS.includes(value)}function isSelectable(d){return d.installed&&d.blockedReason===null&&d.auth!=="unauthenticated"}function resolveDetectDeps(deps={}){return resolve(deps)}function resolve(deps){const platform=deps.platform??process.platform;return{run:deps.run??spawnSync3,env:deps.env??process.env,homedir:deps.homedir??os.homedir,isExecutableFile:deps.isExecutableFile??(p=>defaultIsExecutableFile(p,platform)),existsSync:deps.existsSync??fs3.existsSync,readFileSync:deps.readFileSync??(p=>fs3.readFileSync(p,"utf8")),
34
+ platform,now:deps.now??Date.now,launcherBin:nonEmptyBin(deps.launcherBin)??DEFAULT_CLAUDE_LAUNCHER.bin}}function nonEmptyBin(value){const t=value?.trim();return t===void 0||t===""?void 0:t}var PROBE_TIMEOUT_MS=1e4;function oneLine(text){return text.replace(/\s+/g," ").trim()}function claudeConfigDir(d){const lookup={env:d.env,platform:d.platform};const bin=nonEmptyBin(d.launcherBin)??DEFAULT_CLAUDE_LAUNCHER.bin;const cas=detectClaudeAutoSwitch(bin,d.run,lookup);if(cas!==null){const active=activeSlotPath(
35
+ cas,d.run,lookup);if(active!==null){return{dir:active,via:`${bin} ${DEFAULT_CLAUDE_LAUNCHER.activeArgs.join(" ")}`}}}const explicit=d.env.CLAUDE_CONFIG_DIR?.trim();if(explicit!==void 0&&explicit!=="")return{dir:explicit,via:"CLAUDE_CONFIG_DIR"};return{dir:joinFor(d.platform)(d.homedir(),".claude"),via:"\u65E2\u5B9A\uFF08~/.claude\uFF09"}}var CLAUDE_AUTH_ENV=[{key:"ANTHROPIC_API_KEY",label:"ANTHROPIC_API_KEY",boolish:false},{key:"ANTHROPIC_AUTH_TOKEN",label:"ANTHROPIC_AUTH_TOKEN",boolish:false},{
36
+ key:"CLAUDE_CODE_OAUTH_TOKEN",label:"CLAUDE_CODE_OAUTH_TOKEN",boolish:false},{key:"AWS_BEARER_TOKEN_BEDROCK",label:"AWS_BEARER_TOKEN_BEDROCK",boolish:false},{key:"CLAUDE_CODE_USE_BEDROCK",label:"CLAUDE_CODE_USE_BEDROCK\uFF08AWS \u8CC7\u683C\u60C5\u5831\u3067\u52D5\u304D\u307E\u3059\uFF09",boolish:true},{key:"CLAUDE_CODE_USE_VERTEX",label:"CLAUDE_CODE_USE_VERTEX\uFF08GCP \u8CC7\u683C\u60C5\u5831\u3067\u52D5\u304D\u307E\u3059\uFF09",boolish:true}];function envEnabled(raw,boolish){if(boolish)return isBoolishTrue(
37
+ raw);return(raw??"").trim()!==""}function keychainService(configDir,homedir){const norm=configDir.normalize("NFC");if(norm===path3.posix.join(homedir,".claude").normalize("NFC"))return"Claude Code-credentials";return`Claude Code-credentials-${createHash2("sha256").update(norm,"utf8").digest("hex").slice(0,8)}`}function probeMacKeychain(d,configDir){const account=d.env.USER?.trim()??"";const args=["find-generic-password","-s",keychainService(configDir,d.homedir())];if(account!=="")args.push("-a",
38
+ account);try{const r=d.run("/usr/bin/security",args,{encoding:"utf8",timeout:PROBE_TIMEOUT_MS,stdio:"ignore"});return r.error===void 0&&r.status===0}catch{return false}}function detectClaude(d){for(const e of CLAUDE_AUTH_ENV){if(envEnabled(d.env[e.key],e.boolish)){return{auth:"authenticated",detail:`${e.label} \u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059`,blockedReason:null}}}const{dir,via}=claudeConfigDir(d);const file=joinFor(d.platform)(dir,".credentials.json");let raw;try{if(!d.existsSync(
39
+ file))throw new Error("ENOENT");raw=d.readFileSync(file)}catch{if(d.platform==="darwin"){if(probeMacKeychain(d,dir)){return{auth:"authenticated",detail:oneLine(`macOS Keychain \u306B\u8CC7\u683C\u60C5\u5831\u304C\u3042\u308A\u307E\u3059\uFF08${dir}\uFF09`),blockedReason:null}}return{auth:"unknown",detail:oneLine(`\u8CC7\u683C\u60C5\u5831\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF08${dir}\uFF0F${via}\uFF09\u3002macOS \u306F Keychain \u306B\u4FDD\u5B58\u3059\u308B\u305F\u3081\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u306F\u5224\u5B9A\u3067\u304D\u307E\u305B\u3093`),
40
+ blockedReason:null}}return{auth:"unauthenticated",detail:oneLine(`\u8CC7\u683C\u60C5\u5831\u304C\u3042\u308A\u307E\u305B\u3093\uFF08${file}\uFF0F${via}\uFF09\u3002'claude' \u3092\u4E00\u5EA6\u8D77\u52D5\u3057\u3066\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u304F\u3060\u3055\u3044`),blockedReason:null}}let expiresAt;let hasToken;try{const parsed=JSON.parse(raw);hasToken=typeof parsed.claudeAiOauth?.accessToken==="string"&&parsed.claudeAiOauth.accessToken!=="";expiresAt=parsed.claudeAiOauth?.refreshTokenExpiresAt}catch{
41
+ return{auth:"unknown",detail:oneLine(`\u8CC7\u683C\u60C5\u5831\u3092\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\uFF08${file}\uFF09\u3002\u30D5\u30A1\u30A4\u30EB\u304C\u58CA\u308C\u3066\u3044\u308B\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059`),blockedReason:null}}if(!hasToken){return{auth:"unauthenticated",detail:oneLine(`\u8CC7\u683C\u60C5\u5831\u306B\u30C8\u30FC\u30AF\u30F3\u304C\u3042\u308A\u307E\u305B\u3093\uFF08${file}\uFF09`),blockedReason:null}}if(typeof expiresAt==="number"&&expiresAt>
42
+ 0&&expiresAt<d.now()){return{auth:"unauthenticated",detail:oneLine(`\u30EA\u30D5\u30EC\u30C3\u30B7\u30E5\u30C8\u30FC\u30AF\u30F3\u304C\u5931\u52B9\u3057\u3066\u3044\u307E\u3059\uFF08${dir}\uFF09\u3002\u518D\u30ED\u30B0\u30A4\u30F3\u304C\u5FC5\u8981\u3067\u3059`),blockedReason:null}}return{auth:"authenticated",detail:oneLine(`\u8CC7\u683C\u60C5\u5831\u304C\u3042\u308A\u307E\u3059\uFF08${dir}\uFF0F${via}\uFF09`),blockedReason:null}}function detectCodex(d,binPath){let r;try{r=spawnSyncResolved(binPath,
43
+ ["login","status"],{encoding:"utf8",timeout:PROBE_TIMEOUT_MS},{env:d.env,platform:d.platform},d.run)}catch(err){return{auth:"unknown",detail:oneLine(`codex login status \u3092\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\uFF08${err.message}\uFF09`),blockedReason:null}}if(r.error!==void 0){return{auth:"unknown",detail:oneLine(`codex login status \u3092\u5B9F\u884C\u3067\u304D\u307E\u305B\u3093\uFF08${r.error.message}\uFF09`),blockedReason:null}}if(r.status===null){return{auth:"unknown",detail:`codex\
44
+ login status \u304C ${PROBE_TIMEOUT_MS/1e3} \u79D2\u4EE5\u5185\u306B\u7D42\u308F\u308A\u307E\u305B\u3093\u3067\u3057\u305F`,blockedReason:null}}if(r.status===0)return{auth:"authenticated",detail:"codex login status: \u30ED\u30B0\u30A4\u30F3\u6E08\u307F",blockedReason:null};return{auth:"unauthenticated",detail:`codex login status \u304C\u7D42\u4E86\u30B3\u30FC\u30C9 ${r.status} \u3092\u8FD4\u3057\u307E\u3057\u305F\u3002'codex login' \u3067\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u304F\u3060\u3055\u3044`,
45
+ blockedReason:null}}function detectPending(ai){return{auth:"unknown",detail:"\u30ED\u30B0\u30A4\u30F3\u5224\u5B9A\u306E\u65B9\u6CD5\u304C\u672A\u78BA\u5B9A\u3067\u3059",blockedReason:`${ai} \u306F\u7121\u4EBA\u5B9F\u884C\u3067\u306E\u8A8D\u8A3C\u72B6\u614B\u3092\u5224\u5B9A\u3059\u308B\u65B9\u6CD5\u304C\u672A\u78BA\u5B9A\u306E\u305F\u3081\u9078\u629E\u3067\u304D\u307E\u305B\u3093`}}function detectAiClis(deps={}){const d=resolve(deps);return DETECTABLE_AIS.map(ai=>{const binPath=findOnPath(ai,d);
46
+ if(binPath===null){return{ai,installed:false,binPath:null,auth:"unknown",detail:"PATH \u306B\u898B\u3064\u304B\u308A\u307E\u305B\u3093\uFF08\u672A\u5C0E\u5165\uFF09",blockedReason:null}}const state=ai==="claude"?detectClaude(d):ai==="codex"?detectCodex(d,binPath):detectPending(ai);return{ai,installed:true,binPath,...state}})}function formatDetection(d,index){const selectable=isSelectable(d);const mark=selectable?d.auth==="authenticated"?"\u2705":"\u2754":" ";const num=index===null?" ":`${String(
47
+ index).padStart(2)}.`;const state=!d.installed?"\u672A\u5C0E\u5165":d.auth==="authenticated"?"\u30ED\u30B0\u30A4\u30F3\u6E08\u307F":d.auth==="unauthenticated"?"\u672A\u30ED\u30B0\u30A4\u30F3":"\u672A\u5224\u5B9A";const blocked=d.blockedReason===null?"":`
48
+ \u9078\u629E\u3067\u304D\u307E\u305B\u3093: ${oneLine(d.blockedReason)}`;return`${num} ${mark} ${d.ai.padEnd(8)} ${state.padEnd(8)} ${oneLine(d.detail)}${blocked}`}export{isBoolishTrue,resolveSpawnTarget,spawnSyncResolved,DEFAULT_CLAUDE_LAUNCHER,detectClaudeAutoSwitch,wrapWithAutoSwitch,activeSlotPath,isClaudeAi,normalizeSkillName,skillOfItem,exclusiveInflightEntries,formatExclusiveEntry,usesBedrock,loadAiConfig,AiConfig,modelFitsRoute,isUsableModelId,isDetectableAi,isSelectable,resolveDetectDeps,claudeConfigDir,detectAiClis,formatDetection};
@@ -0,0 +1,6 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ function isAiUnavailable(outcome){return outcome==="unavailable"||outcome==="rate-limited"||outcome==="network-down"}function needsHumanToRestoreAi(outcome){return outcome==="unavailable"}function aiUnavailableLabel(outcome){if(outcome==="rate-limited")return"\u5168AI\u30EC\u30FC\u30C8\u30EA\u30DF\u30C3\u30C8";if(outcome==="network-down")return"\u30DB\u30B9\u30C8\u5074\u306E\u30CD\u30C3\u30C8\u30EF\u30FC\u30AF\u969C\u5BB3";return"AI \u304C1\u3064\u3082\u4F7F\u3048\u306A\u3044\uFF08\u672A\u30ED\u30B0\u30A4\u30F3\u7B49\uFF09"}
4
+ var SERVER_AI_TYPES=["claude","gemini","codex","copilot"];function isServerAiType(value){return SERVER_AI_TYPES.includes(value)}var NoopEngine=class{constructor(note="\uFF08noop \u30A8\u30F3\u30B8\u30F3: AI \u306F\u8D77\u52D5\u3057\u3066\u3044\u307E\u305B\u3093\uFF09"){this.note=note}note;name="noop";run(req){const output=[`[noop] prompt: ${req.prompt.split("\n").slice(-1)[0]??""}`,`[noop] cwd: ${req.cwd}`,`[noop] ai_type=${req.aiType??"(\u672A\u6307\u5B9A)"} ai_model=${req.aiModel??"(\u672A\u6307\u5B9A)"}`,
5
+ this.note].join("\n");return Promise.resolve({outcome:"ok",usedAi:"noop",serverAiType:null,output})}};var UnknownEngineError=class extends Error{constructor(name,available){super(`\u672A\u77E5\u306E\u30A8\u30F3\u30B8\u30F3\u3067\u3059: ${name}\uFF08\u5229\u7528\u3067\u304D\u308B\u306E\u306F ${available.join(" / ")}\uFF09`)}};var ENGINE_NAMES=["cli","noop"];function assertKnownEngine(name){if(!ENGINE_NAMES.includes(name)){throw new UnknownEngineError(name,ENGINE_NAMES)}}var EngineNotConfiguredError=class extends Error{constructor(){
6
+ super('\u5B9F\u884C\u30A8\u30F3\u30B8\u30F3\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002\n \u5B9F AI \u3092\u8D77\u52D5\u3059\u308B\u306A\u3089 --engine cli\uFF08\u8A2D\u5B9A\u306A\u3089 "engine": "cli"\uFF09\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n \u9AA8\u683C\u3060\u3051\u3092\u691C\u8A3C\u3057\u305F\u3044\u5834\u5408\u306F --engine noop \u3092**\u660E\u793A**\u3057\u3066\u304F\u3060\u3055\u3044\u3002\n \u26A0\uFE0F noop \u306F AI \u30921\u3064\u3082\u8D77\u52D5\u305B\u305A\u30A2\u30A4\u30C6\u30E0\u3092 completed \u306B\u3057\u307E\u3059\u3002**\u5B9F\u30AD\u30E5\u30FC\uFF08\u672C\u756A\u306E TWP \u7B49\uFF09\u3078\u5411\u3051\u306A\u3044\u3053\u3068**\n \u5B9A\u671F\u7531\u6765\u306E\u30A2\u30A4\u30C6\u30E0\u306A\u3089\u67A0\u307E\u3067\u6D88\u5316\u3055\u308C\u3001\u305D\u306E\u7A93\u306E release-deploy / develop-merge \u304C\u767A\u706B\u3057\u306A\u304F\u306A\u308A\u307E\u3059\u3002')}};export{isAiUnavailable,needsHumanToRestoreAi,aiUnavailableLabel,isServerAiType,NoopEngine,UnknownEngineError,assertKnownEngine,EngineNotConfiguredError};
@@ -0,0 +1,9 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ var ResolveError=class extends Error{constructor(message,status=null){super(message);this.status=status;this.name="ResolveError"}status};var UUID_RE=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;var ULID_RE=/^[0-7][0-9A-HJKMNP-TV-Z]{25}$/;var SAFE_ID_RE=/^[A-Za-z0-9._-]{1,128}$/;var uuidProjectIdPolicy={isDirectId:ref=>UUID_RE.test(ref),assertId(id){if(typeof id!=="string"||!UUID_RE.test(id)){throw new ResolveError(`\u30B5\u30FC\u30D0\u304C\u8FD4\u3057\u305F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID\u304C UUID \u3067\u306F\u3042\u308A\u307E\u305B\u3093\uFF08${String(id).slice(0,60)}\uFF09\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}}};
4
+ var safeProjectIdPolicy={isDirectId:ref=>UUID_RE.test(ref)||ULID_RE.test(ref),assertId(id){if(!isSafePathSegment(id)){throw new ResolveError(`\u30B5\u30FC\u30D0\u304C\u8FD4\u3057\u305F\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID\u3092\u305D\u306E\u307E\u307E\u4F7F\u3048\u307E\u305B\u3093\uFF08${String(id).slice(0,60)}\uFF09\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}}};function isSafePathSegment(value){return typeof value==="string"&&SAFE_ID_RE.test(value)&&!/^\.+$/.
5
+ test(value)}function collapsesInUrlPath(value){return/^\.+$/.test(value)}async function resolveByCode(ref,get,policy){const res=await get(`/api/v2/projects/by-code/${encodeURIComponent(ref)}`);if(res.status===404){const error=res.json?.error;return error==="project_code_not_found"?{kind:"absent"}:{kind:"unsupported"}}if(!res.ok)return{kind:"unsupported"};const project=res.json?.project;if(!project||typeof project.id!=="string")return{kind:"unsupported"};policy.assertId(project.id);return{kind:"h\
6
+ it",project:{id:project.id,code:project.code??ref,name:project.name??ref}}}async function resolveByListScan(ref,get,policy){let cursor;for(let page=0;page<20;page++){const qs=new URLSearchParams({limit:"100"});if(cursor)qs.set("cursor",cursor);const res=await get(`/api/v2/projects?${qs.toString()}`);if(!res.ok){throw new ResolveError(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08HTTP ${res.status}\uFF09\u3002--project \u306B\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306EUUID\u3092\
7
+ \u76F4\u63A5\u6307\u5B9A\u3059\u308B\u304B\u3001\u63A5\u7D9A\u5148\u3068\u30ED\u30B0\u30A4\u30F3\u72B6\u614B\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,res.status)}const body=res.json;const items=body?.items??[];const hit=items.find(p=>(p.code??"").toLowerCase()===ref.toLowerCase());if(hit){policy.assertId(hit.id);return hit}const hasMore=body?.pagination?.has_more??body?.has_more??false;const next=body?.pagination?.next_cursor??body?.next_cursor;if(!hasMore||!next)break;cursor=
8
+ next}throw new ResolveError(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: ${ref}\uFF08\u30B3\u30FC\u30C9\u306E\u5B8C\u5168\u4E00\u81F4\u3067\u63A2\u3057\u3066\u3044\u307E\u3059\uFF09`,404)}async function resolveProjectRef(ref,get,policy){if(policy.isDirectId(ref))return{id:ref,code:ref,name:ref};if(collapsesInUrlPath(ref)){throw new ResolveError(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30B3\u30FC\u30C9\u3068\u3057\u3066\u4F7F\u3048\u306A\u3044\u5024\u3067\u3059: ${ref}`,
9
+ 404)}const point=await resolveByCode(ref,get,policy);if(point.kind==="hit")return point.project;if(point.kind==="absent"){throw new ResolveError(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093: ${ref}\uFF08\u30B3\u30FC\u30C9\u3067\u691C\u7D22\u3057\u3066\u3044\u307E\u3059\uFF09`,404)}return resolveByListScan(ref,get,policy)}export{ResolveError,uuidProjectIdPolicy,safeProjectIdPolicy,isSafePathSegment,collapsesInUrlPath,resolveProjectRef};
@@ -0,0 +1,23 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{ensureTwpHome,twpHomeDir}from"./chunk-RZVI6PMW.js";import{httpFetch}from"./chunk-J7QYPKVK.js";import fs2 from"fs";import path from"path";import fs from"fs";import{setTimeout as sleep}from"timers/promises";var POLL_MS=100;var STALE_MS=3e4;var DEFAULT_TIMEOUT_MS=STALE_MS+5e3;var LockTimeoutError=class extends Error{};async function withFileLock(lockPath,fn,timeoutMs=DEFAULT_TIMEOUT_MS){const deadline=Date.now()+timeoutMs;for(;;){try{const fd=fs.openSync(lockPath,"wx");fs.writeSync(fd,`${process.pid}
4
+ `);fs.closeSync(fd);break}catch(err){if(err.code!=="EEXIST")throw err;let stale=false;try{stale=Date.now()-fs.statSync(lockPath).mtimeMs>STALE_MS}catch{}if(stale){fs.rmSync(lockPath,{force:true});continue}if(Date.now()>=deadline){throw new LockTimeoutError(`\u30ED\u30C3\u30AF\u306E\u53D6\u5F97\u304C\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F: ${lockPath}
5
+ \u5225\u306E twp \u30D7\u30ED\u30BB\u30B9\u304C\u8A8D\u8A3C\u60C5\u5831\u3092\u66F4\u65B0\u4E2D\u306E\u53EF\u80FD\u6027\u304C\u3042\u308A\u307E\u3059\u3002\u6B8B\u9AB8\u306A\u3089\u524A\u9664\u3057\u3066\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}await sleep(POLL_MS)}}try{return await fn()}finally{fs.rmSync(lockPath,{force:true})}}var CredentialPermissionError=class extends Error{};function credentialsPath(env=process.env){return path.join(twpHomeDir(env),"credentials.json")}function credentialsLockPath(env=process.env){return path.join(twpHomeDir(env),"credentials.lock")}async function withCredentialsLock(env,fn){ensureTwpHome(env);return withFileLock(credentialsLockPath(env),fn)}function assertDirPrivate(dir){if(process.platform==="win32")return;let st;try{st=fs2.lstatSync(dir)}catch{return}if(st.isSymbolicLink()){throw new CredentialPermissionError(
6
+ `${dir} \u304C\u30B7\u30F3\u30DC\u30EA\u30C3\u30AF\u30EA\u30F3\u30AF\u3067\u3059\u3002\u8A8D\u8A3C\u60C5\u5831\u306E\u7F6E\u304D\u5834\u6240\u306F\u30EA\u30F3\u30AF\u306B\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
7
+ \u5B89\u5168\u306E\u305F\u3081\u8AAD\u307F\u8FBC\u307F\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002`)}assertOwnedByUs(dir,st);const mode=st.mode&511;if((mode&18)!==0){throw new CredentialPermissionError(`${dir} \u304C\u4ED6\u30E6\u30FC\u30B6\u30FC\u304B\u3089\u66F8\u3051\u308B\u72B6\u614B\u3067\u3059\uFF08mode=${mode.toString(8)}\uFF09\u3002
8
+ chmod 700 ${dir}
9
+ \u3092\u5B9F\u884C\u3057\u3066\u304B\u3089\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5B89\u5168\u306E\u305F\u3081\u8AAD\u307F\u8FBC\u307F\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002`)}}function assertOwnedByUs(target,st){const uid=process.getuid?.();if(uid===void 0)return;if(st.uid!==uid){throw new CredentialPermissionError(`${target} \u306E\u6240\u6709\u8005\u304C\u5225\u306E\u30E6\u30FC\u30B6\u30FC\u3067\u3059\uFF08uid=${st.uid}\uFF09\u3002
10
+ \u7B2C\u4E09\u8005\u304C\u7F6E\u3044\u305F\u30D5\u30A1\u30A4\u30EB\u3092\u8A8D\u8A3C\u60C5\u5831\u3068\u3057\u3066\u8AAD\u307E\u306A\u3044\u3088\u3046\u3001\u5B89\u5168\u306E\u305F\u3081\u8AAD\u307F\u8FBC\u307F\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002`)}}function assertFilePrivate(file){if(process.platform==="win32")return;const st=fs2.lstatSync(file);if(st.isSymbolicLink()){throw new CredentialPermissionError(`${file} \u304C\u30B7\u30F3\u30DC\u30EA\u30C3\u30AF\u30EA\u30F3\u30AF\u3067\u3059\u3002\u5B89\u5168\u306E\u305F\u3081\u8AAD\u307F\u8FBC\u307F\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002`)}
11
+ assertOwnedByUs(file,st);const mode=st.mode&511;if((mode&36)!==0){throw new CredentialPermissionError(`${file} \u304C\u4ED6\u30E6\u30FC\u30B6\u30FC\u304B\u3089\u8AAD\u3081\u308B\u72B6\u614B\u3067\u3059\uFF08mode=${mode.toString(8)}\uFF09\u3002
12
+ chmod 600 ${file}
13
+ \u3092\u5B9F\u884C\u3057\u3066\u304B\u3089\u518D\u8A66\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5B89\u5168\u306E\u305F\u3081\u8AAD\u307F\u8FBC\u307F\u3092\u62D2\u5426\u3057\u307E\u3057\u305F\u3002`)}}function readFile(env){const file=credentialsPath(env);assertDirPrivate(twpHomeDir(env));try{assertFilePrivate(file)}catch(err){if(err.code==="ENOENT")return{version:1,profiles:{}};throw err}let raw;try{raw=fs2.readFileSync(file,"utf8")}catch(err){if(err.code==="ENOENT")return{version:1,profiles:{}};
14
+ throw err}try{const parsed=JSON.parse(raw);if(!parsed||typeof parsed!=="object"||typeof parsed.profiles!=="object"){return{version:1,profiles:{}}}return parsed}catch{throw new Error(`${file} \u306E\u5185\u5BB9\u304C\u58CA\u308C\u3066\u3044\u307E\u3059\u3002twp login \u3067\u30ED\u30B0\u30A4\u30F3\u3057\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}}function writeFile(data,env){ensureTwpHome(env);const file=credentialsPath(env);const tmp=`${file}.${process.pid}.tmp`;fs2.writeFileSync(tmp,`${JSON.
15
+ stringify(data,null,2)}
16
+ `,{mode:384});try{fs2.renameSync(tmp,file)}catch(err){fs2.rmSync(tmp,{force:true});throw err}if(process.platform!=="win32"){try{fs2.chmodSync(file,384)}catch{}}}function loadCredentials(profile,env=process.env){return readFile(env).profiles[profile]??null}function saveCredentialsUnlocked(profile,creds,env=process.env){const data=readFile(env);data.profiles[profile]=creds;writeFile(data,env)}async function saveCredentials(profile,creds,env=process.env){await withCredentialsLock(env,async()=>{saveCredentialsUnlocked(
17
+ profile,creds,env)})}async function deleteCredentials(profile,env=process.env){if(!fs2.existsSync(credentialsPath(env)))return false;return withCredentialsLock(env,async()=>{const data=readFile(env);if(!(profile in data.profiles))return false;delete data.profiles[profile];writeFile(data,env);return true})}function maskToken(token){return token.length<=8?"********":`${token.slice(0,8)}\u2026`}var NotLoggedInError=class extends Error{constructor(profile){super(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u300C${profile}\u300D\u306F\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u3044\u307E\u305B\u3093\u3002twp login \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}};var SessionExpiredError=class extends Error{constructor(profile){super(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u300C${profile}\u300D\u306E\u30BB\u30C3\u30B7\u30E7\u30F3\u304C\u5931\u52B9\u3057\u307E\u3057\u305F\uFF08refresh token \u304C\u7121\u52B9\uFF09\u3002twp login \u3067\u30ED\u30B0\u30A4\u30F3\u3057\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}};
18
+ var EXPIRY_MARGIN_MS=6e4;var AuthSession=class{constructor(profile,apiUrl,env=process.env,fetchImpl=httpFetch,now=Date.now){this.profile=profile;this.apiUrl=apiUrl;this.env=env;this.fetchImpl=fetchImpl;this.now=now}profile;apiUrl;env;fetchImpl;now;refreshInFlight=null;loadOrThrow(){const creds=loadCredentials(this.profile,this.env);if(!creds)throw new NotLoggedInError(this.profile);return creds}async getAccessToken(){const creds=this.loadOrThrow();if(!this.isExpiring(creds))return creds.token;if(!creds.
19
+ refresh_token){if(this.isExpired(creds))throw new SessionExpiredError(this.profile);return creds.token}return this.refresh(creds.token)}refresh(usedToken){if(this.refreshInFlight)return this.refreshInFlight;this.refreshInFlight=this.refreshLocked(usedToken).finally(()=>{this.refreshInFlight=null});return this.refreshInFlight}async refreshLocked(usedToken){return withCredentialsLock(this.env,async()=>{const onDisk=this.loadOrThrow();if(onDisk.token!==usedToken&&!this.isExpiring(onDisk))return onDisk.
20
+ token;if(!onDisk.refresh_token)throw new SessionExpiredError(this.profile);const result=await this.callRefreshApi(onDisk.refresh_token);if(result.ok){this.persist(onDisk,result.body);return result.body.token}const reread=this.loadOrThrow();if(reread.refresh_token&&reread.refresh_token!==onDisk.refresh_token){const retry=await this.callRefreshApi(reread.refresh_token);if(retry.ok){this.persist(reread,retry.body);return retry.body.token}}throw new SessionExpiredError(this.profile)})}async callRefreshApi(refreshToken){
21
+ const res=await this.fetchImpl(`${this.apiUrl}/api/v2/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({refresh_token:refreshToken})});const body=await res.json().then(parsed=>parsed,()=>null);if(res.ok&&body?.result&&typeof body.token==="string"){return{ok:true,body}}return{ok:false}}persist(prev,body){saveCredentialsUnlocked(this.profile,{...prev,token:body.token,token_expires_at:body.token_expires_at??null,refresh_token:body.
22
+ refresh_token??prev.refresh_token,refresh_token_expires_at:body.refresh_token_expires_at??prev.refresh_token_expires_at,user:body.user??prev.user,saved_at:new Date(this.now()).toISOString()},this.env)}isExpiring(creds){if(!creds.token_expires_at)return false;const at=Date.parse(creds.token_expires_at);return Number.isFinite(at)&&at-this.now()<EXPIRY_MARGIN_MS}isExpired(creds){if(!creds.token_expires_at)return false;const at=Date.parse(creds.token_expires_at);return Number.isFinite(at)&&at<=this.
23
+ now()}};export{withFileLock,loadCredentials,saveCredentials,deleteCredentials,maskToken,NotLoggedInError,SessionExpiredError,AuthSession};
@@ -0,0 +1,8 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{httpFetch}from"./chunk-J7QYPKVK.js";function encodeScalar(key,value,inArray){if(typeof value==="boolean")return value?"true":"false";if(typeof value==="number"){if(!Number.isFinite(value)){throw new TypeError(`\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF ${key} \u306B\u6709\u9650\u3067\u306A\u3044\u6570\u5024\u306F\u6E21\u305B\u307E\u305B\u3093: ${String(value)}`)}return String(value)}if(inArray&&value.includes(",")){throw new TypeError(`\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF ${key} \u306E\u914D\u5217\u8981\u7D20\u306B\u30AB\u30F3\u30DE\u306F\u542B\u3081\u3089\u308C\u307E\u305B\u3093: ${value}`)}
4
+ return value}function buildQuery(params){if(!params)return"";const search=new URLSearchParams;for(const[key,value]of Object.entries(params)){if(value===null||value===void 0)continue;if(Array.isArray(value)){if(value.length===0)continue;search.append(key,value.map(v=>encodeScalar(key,v,true)).join(","));continue}search.append(key,encodeScalar(key,value,false))}return search.toString()}function appendQuery(path,params){const qs=buildQuery(params);if(qs==="")return path;if(path.endsWith("?")||path.
5
+ endsWith("&"))return`${path}${qs}`;return`${path}${path.includes("?")?"&":"?"}${qs}`}var ApiError=class extends Error{constructor(status,body,method,path){super(`${method} ${path} -> ${status}${body?.error_description?` (${body.error_description})`:body?.message?` (${body.message})`:""}`);this.status=status;this.body=body}status;body};var TwpApiClient=class{constructor(apiUrl,session,fetchImpl=httpFetch,cliVersion="0.0.0-dev"){this.apiUrl=apiUrl;this.session=session;this.fetchImpl=fetchImpl;this.cliVersion=cliVersion}apiUrl;session;fetchImpl;cliVersion;async get(path,query){return this.
6
+ request("GET",appendQuery(path,query))}async post(path,body,query){return this.request("POST",appendQuery(path,query),body)}async put(path,body,query){return this.request("PUT",appendQuery(path,query),body)}async patch(path,body,query){return this.request("PATCH",appendQuery(path,query),body)}async delete(path,query){return this.request("DELETE",appendQuery(path,query))}async request(method,path,body){let token=await this.session.getAccessToken();let res=await this.send(method,path,token,body);if(res.
7
+ status===401){token=await this.session.refresh(token);res=await this.send(method,path,token,body)}if(!res.ok){const errBody=await res.json().then(parsed=>parsed,()=>null);throw new ApiError(res.status,errBody,method,path)}if(res.status===204||res.headers.get("content-length")==="0"){return null}const raw=await res.text();if(raw.trim()==="")return null;try{return JSON.parse(raw)}catch{throw new ApiError(res.status,null,method,path)}}send(method,path,token,body){return this.fetchImpl(`${this.apiUrl}${path}`,
8
+ {method,headers:{Accept:"application/json",Authorization:`Bearer ${token}`,"User-Agent":`twp-cli/${this.cliVersion}`,...body!==void 0?{"Content-Type":"application/json"}:{}},...body!==void 0?{body:JSON.stringify(body)}:{}})}};export{appendQuery,ApiError,TwpApiClient};
@@ -0,0 +1,37 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{__commonJS}from"./chunk-VSJBJXZO.js";var require_fuzzysort=__commonJS({"node_modules/fuzzysort/fuzzysort.js"(exports,module){((root,UMD)=>{if(typeof define==="function"&&define.amd)define([],UMD);else if(typeof module==="object"&&module.exports)module.exports=UMD();else root["fuzzysort"]=UMD()})(exports,_=>{"use strict";var single=(search,target)=>{if(!search||!target)return NULL;var preparedSearch=getPreparedSearch(search);if(!isPrepared(target))target=getPrepared(target);var searchBitflags=preparedSearch.bitflags;if((searchBitflags&
4
+ target._bitflags)!==searchBitflags)return NULL;return algorithm(preparedSearch,target)};var go=(search,targets,options)=>{if(!search)return options?.all?all(targets,options):noResults;var preparedSearch=getPreparedSearch(search);var searchBitflags=preparedSearch.bitflags;var containsSpace=preparedSearch.containsSpace;var threshold=denormalizeScore(options?.threshold||0);var limit=options?.limit||INFINITY;var resultsLen=0;var limitedCount=0;var targetsLen=targets.length;function push_result(result2){
5
+ if(resultsLen<limit){q.add(result2);++resultsLen}else{++limitedCount;if(result2._score>q.peek()._score)q.replaceTop(result2)}}if(options?.key){var key=options.key;for(var i=0;i<targetsLen;++i){var obj=targets[i];var target=getValue(obj,key);if(!target)continue;if(!isPrepared(target))target=getPrepared(target);if((searchBitflags&target._bitflags)!==searchBitflags)continue;var result=algorithm(preparedSearch,target);if(result===NULL)continue;if(result._score<threshold)continue;result.obj=obj;push_result(
6
+ result)}}else if(options?.keys){var keys=options.keys;var keysLen=keys.length;outer:for(var i=0;i<targetsLen;++i){var obj=targets[i];{var keysBitflags=0;for(var keyI=0;keyI<keysLen;++keyI){var key=keys[keyI];var target=getValue(obj,key);if(!target){tmpTargets[keyI]=noTarget;continue}if(!isPrepared(target))target=getPrepared(target);tmpTargets[keyI]=target;keysBitflags|=target._bitflags}if((searchBitflags&keysBitflags)!==searchBitflags)continue}if(containsSpace)for(let i2=0;i2<preparedSearch.spaceSearches.
7
+ length;i2++)keysSpacesBestScores[i2]=NEGATIVE_INFINITY;for(var keyI=0;keyI<keysLen;++keyI){target=tmpTargets[keyI];if(target===noTarget){tmpResults[keyI]=noTarget;continue}tmpResults[keyI]=algorithm(preparedSearch,target,false,containsSpace);if(tmpResults[keyI]===NULL){tmpResults[keyI]=noTarget;continue}if(containsSpace)for(let i2=0;i2<preparedSearch.spaceSearches.length;i2++){if(allowPartialMatchScores[i2]>-1e3){if(keysSpacesBestScores[i2]>NEGATIVE_INFINITY){var tmp=(keysSpacesBestScores[i2]+allowPartialMatchScores[i2])/
8
+ 4;if(tmp>keysSpacesBestScores[i2])keysSpacesBestScores[i2]=tmp}}if(allowPartialMatchScores[i2]>keysSpacesBestScores[i2])keysSpacesBestScores[i2]=allowPartialMatchScores[i2]}}if(containsSpace){for(let i2=0;i2<preparedSearch.spaceSearches.length;i2++){if(keysSpacesBestScores[i2]===NEGATIVE_INFINITY)continue outer}}else{var hasAtLeast1Match=false;for(let i2=0;i2<keysLen;i2++){if(tmpResults[i2]._score!==NEGATIVE_INFINITY){hasAtLeast1Match=true;break}}if(!hasAtLeast1Match)continue}var objResults=new KeysResult(
9
+ keysLen);for(let i2=0;i2<keysLen;i2++){objResults[i2]=tmpResults[i2]}if(containsSpace){var score=0;for(let i2=0;i2<preparedSearch.spaceSearches.length;i2++)score+=keysSpacesBestScores[i2]}else{var score=NEGATIVE_INFINITY;for(let i2=0;i2<keysLen;i2++){var result=objResults[i2];if(result._score>-1e3){if(score>NEGATIVE_INFINITY){var tmp=(score+result._score)/4;if(tmp>score)score=tmp}}if(result._score>score)score=result._score}}objResults.obj=obj;objResults._score=score;if(options?.scoreFn){score=options.
10
+ scoreFn(objResults);if(!score)continue;score=denormalizeScore(score);objResults._score=score}if(score<threshold)continue;push_result(objResults)}}else{for(var i=0;i<targetsLen;++i){var target=targets[i];if(!target)continue;if(!isPrepared(target))target=getPrepared(target);if((searchBitflags&target._bitflags)!==searchBitflags)continue;var result=algorithm(preparedSearch,target);if(result===NULL)continue;if(result._score<threshold)continue;push_result(result)}}if(resultsLen===0)return noResults;var results=new Array(
11
+ resultsLen);for(var i=resultsLen-1;i>=0;--i)results[i]=q.poll();results.total=resultsLen+limitedCount;return results};var highlight=(result,open="<b>",close="</b>")=>{var callback=typeof open==="function"?open:void 0;var target=result.target;var targetLen=target.length;var indexes=result.indexes;var highlighted="";var matchI=0;var indexesI=0;var opened=false;var parts=[];for(var i=0;i<targetLen;++i){var char=target[i];if(indexes[indexesI]===i){++indexesI;if(!opened){opened=true;if(callback){parts.
12
+ push(highlighted);highlighted=""}else{highlighted+=open}}if(indexesI===indexes.length){if(callback){highlighted+=char;parts.push(callback(highlighted,matchI++));highlighted="";parts.push(target.substr(i+1))}else{highlighted+=char+close+target.substr(i+1)}break}}else{if(opened){opened=false;if(callback){parts.push(callback(highlighted,matchI++));highlighted=""}else{highlighted+=close}}}highlighted+=char}return callback?parts:highlighted};var prepare=target=>{if(typeof target==="number")target=""+
13
+ target;else if(typeof target!=="string")target="";var info=prepareLowerInfo(target);return new_result(target,{_targetLower:info._lower,_targetLowerCodes:info.lowerCodes,_bitflags:info.bitflags})};var cleanup=()=>{preparedCache.clear();preparedSearchCache.clear()};class Result{get["indexes"](){return this._indexes.slice(0,this._indexes.len).sort((a,b)=>a-b)}set["indexes"](indexes){return this._indexes=indexes}["highlight"](open,close){return highlight(this,open,close)}get["score"](){return normalizeScore(
14
+ this._score)}set["score"](score){this._score=denormalizeScore(score)}}class KeysResult extends Array{get["score"](){return normalizeScore(this._score)}set["score"](score){this._score=denormalizeScore(score)}}var new_result=(target,options)=>{const result=new Result;result["target"]=target;result["obj"]=options.obj??NULL;result._score=options._score??NEGATIVE_INFINITY;result._indexes=options._indexes??[];result._targetLower=options._targetLower??"";result._targetLowerCodes=options._targetLowerCodes??
15
+ NULL;result._nextBeginningIndexes=options._nextBeginningIndexes??NULL;result._bitflags=options._bitflags??0;return result};var normalizeScore=score=>{if(score===NEGATIVE_INFINITY)return 0;if(score>1)return score;return Math.E**(((-score+1)**.04307-1)*-2)};var denormalizeScore=normalizedScore=>{if(normalizedScore===0)return NEGATIVE_INFINITY;if(normalizedScore>1)return normalizedScore;return 1-Math.pow(Math.log(normalizedScore)/-2+1,1/.04307)};var prepareSearch=search=>{if(typeof search==="number")
16
+ search=""+search;else if(typeof search!=="string")search="";search=search.trim();var info=prepareLowerInfo(search);var spaceSearches=[];if(info.containsSpace){var searches=search.split(/\s+/);searches=[...new Set(searches)];for(var i=0;i<searches.length;i++){if(searches[i]==="")continue;var _info=prepareLowerInfo(searches[i]);spaceSearches.push({lowerCodes:_info.lowerCodes,_lower:searches[i].toLowerCase(),containsSpace:false})}}return{lowerCodes:info.lowerCodes,_lower:info._lower,containsSpace:info.
17
+ containsSpace,bitflags:info.bitflags,spaceSearches}};var getPrepared=target=>{if(target.length>999)return prepare(target);var targetPrepared=preparedCache.get(target);if(targetPrepared!==void 0)return targetPrepared;targetPrepared=prepare(target);preparedCache.set(target,targetPrepared);return targetPrepared};var getPreparedSearch=search=>{if(search.length>999)return prepareSearch(search);var searchPrepared=preparedSearchCache.get(search);if(searchPrepared!==void 0)return searchPrepared;searchPrepared=
18
+ prepareSearch(search);preparedSearchCache.set(search,searchPrepared);return searchPrepared};var all=(targets,options)=>{var results=[];results.total=targets.length;var limit=options?.limit||INFINITY;if(options?.key){for(var i=0;i<targets.length;i++){var obj=targets[i];var target=getValue(obj,options.key);if(target==NULL)continue;if(!isPrepared(target))target=getPrepared(target);var result=new_result(target.target,{_score:target._score,obj});results.push(result);if(results.length>=limit)return results}}else if(options?.
19
+ keys){for(var i=0;i<targets.length;i++){var obj=targets[i];var objResults=new KeysResult(options.keys.length);for(var keyI=options.keys.length-1;keyI>=0;--keyI){var target=getValue(obj,options.keys[keyI]);if(!target){objResults[keyI]=noTarget;continue}if(!isPrepared(target))target=getPrepared(target);target._score=NEGATIVE_INFINITY;target._indexes.len=0;objResults[keyI]=target}objResults.obj=obj;objResults._score=NEGATIVE_INFINITY;results.push(objResults);if(results.length>=limit)return results}}else{
20
+ for(var i=0;i<targets.length;i++){var target=targets[i];if(target==NULL)continue;if(!isPrepared(target))target=getPrepared(target);target._score=NEGATIVE_INFINITY;target._indexes.len=0;results.push(target);if(results.length>=limit)return results}}return results};var algorithm=(preparedSearch,prepared,allowSpaces=false,allowPartialMatch=false)=>{if(allowSpaces===false&&preparedSearch.containsSpace)return algorithmSpaces(preparedSearch,prepared,allowPartialMatch);var searchLower=preparedSearch._lower;
21
+ var searchLowerCodes=preparedSearch.lowerCodes;var searchLowerCode=searchLowerCodes[0];var targetLowerCodes=prepared._targetLowerCodes;var searchLen=searchLowerCodes.length;var targetLen=targetLowerCodes.length;var searchI=0;var targetI=0;var matchesSimpleLen=0;for(;;){var isMatch=searchLowerCode===targetLowerCodes[targetI];if(isMatch){matchesSimple[matchesSimpleLen++]=targetI;++searchI;if(searchI===searchLen)break;searchLowerCode=searchLowerCodes[searchI]}++targetI;if(targetI>=targetLen)return NULL}
22
+ var searchI=0;var successStrict=false;var matchesStrictLen=0;var nextBeginningIndexes=prepared._nextBeginningIndexes;if(nextBeginningIndexes===NULL)nextBeginningIndexes=prepared._nextBeginningIndexes=prepareNextBeginningIndexes(prepared.target);targetI=matchesSimple[0]===0?0:nextBeginningIndexes[matchesSimple[0]-1];var backtrackCount=0;if(targetI!==targetLen)for(;;){if(targetI>=targetLen){if(searchI<=0)break;++backtrackCount;if(backtrackCount>200)break;--searchI;var lastMatch=matchesStrict[--matchesStrictLen];
23
+ targetI=nextBeginningIndexes[lastMatch]}else{var isMatch=searchLowerCodes[searchI]===targetLowerCodes[targetI];if(isMatch){matchesStrict[matchesStrictLen++]=targetI;++searchI;if(searchI===searchLen){successStrict=true;break}++targetI}else{targetI=nextBeginningIndexes[targetI]}}}var substringIndex=searchLen<=1?-1:prepared._targetLower.indexOf(searchLower,matchesSimple[0]);var isSubstring=!!~substringIndex;var isSubstringBeginning=!isSubstring?false:substringIndex===0||prepared._nextBeginningIndexes[substringIndex-
24
+ 1]===substringIndex;if(isSubstring&&!isSubstringBeginning){for(var i=0;i<nextBeginningIndexes.length;i=nextBeginningIndexes[i]){if(i<=substringIndex)continue;for(var s=0;s<searchLen;s++)if(searchLowerCodes[s]!==prepared._targetLowerCodes[i+s])break;if(s===searchLen){substringIndex=i;isSubstringBeginning=true;break}}}var calculateScore=matches=>{var score2=0;var extraMatchGroupCount=0;for(var i2=1;i2<searchLen;++i2){if(matches[i2]-matches[i2-1]!==1){score2-=matches[i2];++extraMatchGroupCount}}var unmatchedDistance=matches[searchLen-
25
+ 1]-matches[0]-(searchLen-1);score2-=(12+unmatchedDistance)*extraMatchGroupCount;if(matches[0]!==0)score2-=matches[0]*matches[0]*.2;if(!successStrict){score2*=1e3}else{var uniqueBeginningIndexes=1;for(var i2=nextBeginningIndexes[0];i2<targetLen;i2=nextBeginningIndexes[i2])++uniqueBeginningIndexes;if(uniqueBeginningIndexes>24)score2*=(uniqueBeginningIndexes-24)*10}score2-=(targetLen-searchLen)/2;if(isSubstring)score2/=1+searchLen*searchLen*1;if(isSubstringBeginning)score2/=1+searchLen*searchLen*1;
26
+ score2-=(targetLen-searchLen)/2;return score2};if(!successStrict){if(isSubstring)for(var i=0;i<searchLen;++i)matchesSimple[i]=substringIndex+i;var matchesBest=matchesSimple;var score=calculateScore(matchesBest)}else{if(isSubstringBeginning){for(var i=0;i<searchLen;++i)matchesSimple[i]=substringIndex+i;var matchesBest=matchesSimple;var score=calculateScore(matchesSimple)}else{var matchesBest=matchesStrict;var score=calculateScore(matchesStrict)}}prepared._score=score;for(var i=0;i<searchLen;++i)prepared.
27
+ _indexes[i]=matchesBest[i];prepared._indexes.len=searchLen;const result=new Result;result.target=prepared.target;result._score=prepared._score;result._indexes=prepared._indexes;return result};var algorithmSpaces=(preparedSearch,target,allowPartialMatch)=>{var seen_indexes=new Set;var score=0;var result=NULL;var first_seen_index_last_search=0;var searches=preparedSearch.spaceSearches;var searchesLen=searches.length;var changeslen=0;var resetNextBeginningIndexes=()=>{for(let i2=changeslen-1;i2>=0;i2--)
28
+ target._nextBeginningIndexes[nextBeginningIndexesChanges[i2*2+0]]=nextBeginningIndexesChanges[i2*2+1]};var hasAtLeast1Match=false;for(var i=0;i<searchesLen;++i){allowPartialMatchScores[i]=NEGATIVE_INFINITY;var search=searches[i];result=algorithm(search,target);if(allowPartialMatch){if(result===NULL)continue;hasAtLeast1Match=true}else{if(result===NULL){resetNextBeginningIndexes();return NULL}}var isTheLastSearch=i===searchesLen-1;if(!isTheLastSearch){var indexes=result._indexes;var indexesIsConsecutiveSubstring=true;
29
+ for(let i2=0;i2<indexes.len-1;i2++){if(indexes[i2+1]-indexes[i2]!==1){indexesIsConsecutiveSubstring=false;break}}if(indexesIsConsecutiveSubstring){var newBeginningIndex=indexes[indexes.len-1]+1;var toReplace=target._nextBeginningIndexes[newBeginningIndex-1];for(let i2=newBeginningIndex-1;i2>=0;i2--){if(toReplace!==target._nextBeginningIndexes[i2])break;target._nextBeginningIndexes[i2]=newBeginningIndex;nextBeginningIndexesChanges[changeslen*2+0]=i2;nextBeginningIndexesChanges[changeslen*2+1]=toReplace;
30
+ changeslen++}}}score+=result._score/searchesLen;allowPartialMatchScores[i]=result._score/searchesLen;if(result._indexes[0]<first_seen_index_last_search){score-=(first_seen_index_last_search-result._indexes[0])*2}first_seen_index_last_search=result._indexes[0];for(var j=0;j<result._indexes.len;++j)seen_indexes.add(result._indexes[j])}if(allowPartialMatch&&!hasAtLeast1Match)return NULL;resetNextBeginningIndexes();var allowSpacesResult=algorithm(preparedSearch,target,true);if(allowSpacesResult!==NULL&&
31
+ allowSpacesResult._score>score){if(allowPartialMatch){for(var i=0;i<searchesLen;++i){allowPartialMatchScores[i]=allowSpacesResult._score/searchesLen}}return allowSpacesResult}if(allowPartialMatch)result=target;result._score=score;var i=0;for(let index of seen_indexes)result._indexes[i++]=index;result._indexes.len=i;return result};var remove_accents=str=>str.replace(new RegExp("\\p{Script=Latin}+","gu"),match=>match.normalize("NFD")).replace(/[\u0300-\u036f]/g,"");var prepareLowerInfo=str=>{str=remove_accents(
32
+ str);var strLen=str.length;var lower=str.toLowerCase();var lowerCodes=[];var bitflags=0;var containsSpace=false;for(var i=0;i<strLen;++i){var lowerCode=lowerCodes[i]=lower.charCodeAt(i);if(lowerCode===32){containsSpace=true;continue}var bit=lowerCode>=97&&lowerCode<=122?lowerCode-97:lowerCode>=48&&lowerCode<=57?26:lowerCode<=127?30:31;bitflags|=1<<bit}return{lowerCodes,bitflags,containsSpace,_lower:lower}};var prepareBeginningIndexes=target=>{var targetLen=target.length;var beginningIndexes=[];var beginningIndexesLen=0;
33
+ var wasUpper=false;var wasAlphanum=false;for(var i=0;i<targetLen;++i){var targetCode=target.charCodeAt(i);var isUpper=targetCode>=65&&targetCode<=90;var isAlphanum=isUpper||targetCode>=97&&targetCode<=122||targetCode>=48&&targetCode<=57;var isBeginning=isUpper&&!wasUpper||!wasAlphanum||!isAlphanum;wasUpper=isUpper;wasAlphanum=isAlphanum;if(isBeginning)beginningIndexes[beginningIndexesLen++]=i}return beginningIndexes};var prepareNextBeginningIndexes=target=>{target=remove_accents(target);var targetLen=target.
34
+ length;var beginningIndexes=prepareBeginningIndexes(target);var nextBeginningIndexes=[];var lastIsBeginning=beginningIndexes[0];var lastIsBeginningI=0;for(var i=0;i<targetLen;++i){if(lastIsBeginning>i){nextBeginningIndexes[i]=lastIsBeginning}else{lastIsBeginning=beginningIndexes[++lastIsBeginningI];nextBeginningIndexes[i]=lastIsBeginning===void 0?targetLen:lastIsBeginning}}return nextBeginningIndexes};var preparedCache=new Map;var preparedSearchCache=new Map;var matchesSimple=[];var matchesStrict=[];
35
+ var nextBeginningIndexesChanges=[];var keysSpacesBestScores=[];var allowPartialMatchScores=[];var tmpTargets=[];var tmpResults=[];var getValue=(obj,prop)=>{var tmp=obj[prop];if(tmp!==void 0)return tmp;if(typeof prop==="function")return prop(obj);var segs=prop;if(!Array.isArray(prop))segs=prop.split(".");var len=segs.length;var i=-1;while(obj&&++i<len)obj=obj[segs[i]];return obj};var isPrepared=x=>{return typeof x==="object"&&typeof x._bitflags==="number"};var INFINITY=Infinity;var NEGATIVE_INFINITY=-INFINITY;
36
+ var noResults=[];noResults.total=0;var NULL=null;var noTarget=prepare("");var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r2=>{for(var a2=0,v2=e[a2],c=1;c<o;){var s=c+1;a2=c,s<o&&e[s]._score<e[c]._score&&(a2=s),e[a2-1>>1]=e[a2],c=1+(a2<<1)}for(var f=a2-1>>1;a2>0&&v2._score<e[f]._score;f=(a2=f)-1>>1)e[a2]=e[f];e[a2]=v2};return a.add=(r2=>{var a2=o;e[o++]=r2;for(var v2=a2-1>>1;a2>0&&r2._score<e[v2]._score;v2=(a2=v2)-1>>1)e[a2]=e[v2];e[a2]=r2}),a.poll=(r2=>{if(0!==o){var a2=e[0];return e[0]=e[--o],v(),
37
+ a2}}),a.peek=(r2=>{if(0!==o)return e[0]}),a.replaceTop=(r2=>{e[0]=r2,v()}),a};var q=fastpriorityqueue();return{"single":single,"go":go,"prepare":prepare,"cleanup":cleanup}})}});export{require_fuzzysort};
@@ -0,0 +1,7 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ var PACKAGE_NAME="@tocca-systems/twp-cli";var UPDATE_COMMAND=`npm i -g ${PACKAGE_NAME}@latest`;var SEMVER_RE=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;var MAX_VERSION_LENGTH=64;function parseVersionCore(raw){if(typeof raw!=="string")return null;const trimmed=raw.trim();if(trimmed.length>MAX_VERSION_LENGTH)return null;const m=SEMVER_RE.exec(trimmed);if(m===null)return null;return[Number(m[1]),Number(m[2]),Number(m[3])]}function compareVersionCores(a,b){
4
+ for(let i=0;i<3;i++){const diff=(a[i]??0)-(b[i]??0);if(diff!==0)return diff}return 0}function isBelowMinSupported(current,floor){const floorCore=parseVersionCore(floor);if(floorCore===null)return false;const currentCore=parseVersionCore(current);if(currentCore===null)return false;if(currentCore[0]===0&&currentCore[1]===0&&currentCore[2]===0)return false;return compareVersionCores(currentCore,floorCore)<0}function minSupportedBlockMessage(current,floor){return[`\u3053\u306E\u30D0\u30FC\u30B8\u30E7\u30F3\u306E twp\uFF08${current}\
5
+ \uFF09\u306F\u3001\u63A5\u7D9A\u5148\u306E\u30B5\u30FC\u30D0\u304C\u8981\u6C42\u3059\u308B\u6700\u5C0F\u30D0\u30FC\u30B8\u30E7\u30F3 ${floor} \u3092\u6E80\u305F\u3057\u3066\u3044\u307E\u305B\u3093\u3002`,"\u8D77\u52D5\u3092\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\u6B21\u306E\u30B3\u30DE\u30F3\u30C9\u3067\u66F4\u65B0\u3057\u3066\u304F\u3060\u3055\u3044\u3002","",` ${UPDATE_COMMAND}`,"","\u66F4\u65B0\u306E\u53EF\u5426\u30FB\u63A5\u7D9A\u5148\u304C\u8981\u6C42\u3057\u3066\u3044\u308B\u7248\u306F `twp update` \u3067\u78BA\u8A8D\u3067\u304D\u307E\u3059\u3002",
6
+ ""].join("\n")}function enforceMinSupportedVersion(args){if(!isBelowMinSupported(args.current,args.floor))return false;args.write(minSupportedBlockMessage(args.current,(args.floor??"").trim()));return true}async function checkMinSupportedVersion(args){if(!isBelowMinSupported(args.current,args.cachedFloor))return false;const fresh=await args.refresh();return enforceMinSupportedVersion({current:args.current,floor:fresh,write:args.write})}var FLOOR_MAX_AGE_MS=6*60*60*1e3;function floorNeedsRefresh(fetchedAt,now=Date.
7
+ now(),maxAgeMs=FLOOR_MAX_AGE_MS){if(typeof fetchedAt!=="string")return true;const at=Date.parse(fetchedAt);if(!Number.isFinite(at))return true;return now-at>=maxAgeMs||at>now}export{PACKAGE_NAME,UPDATE_COMMAND,parseVersionCore,compareVersionCores,isBelowMinSupported,minSupportedBlockMessage,enforceMinSupportedVersion,checkMinSupportedVersion,floorNeedsRefresh};
@@ -0,0 +1,6 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{ApiResponseError,UsageError}from"./chunk-KCXVV45F.js";function singleRef(input,options){const fromFlag=input.flags.get(options.flag);const[fromArg,...rest]=input.args;if(rest.length>0){throw new UsageError(`\u53D7\u3051\u53D6\u308C\u308B${options.label}\u306F1\u3064\u3060\u3051\u3067\u3059: ${rest.join(" ")}`,options.usage)}if(fromArg!==void 0&&fromFlag!==void 0){throw new UsageError(`${options.label}\u304C\u4F4D\u7F6E\u5F15\u6570\uFF08${fromArg}\uFF09\u3068 ${options.flag} ${fromFlag} \u306E\u4E21\u65B9\u3067\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059`,
4
+ `\u3069\u3061\u3089\u304B\u4E00\u65B9\u3060\u3051\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u3069\u3061\u3089\u3067\u3082\u540C\u3058\u610F\u5473\u3067\u3059\uFF09\u3002`)}const value=fromArg??fromFlag;if(value===void 0||value.trim()===""){if(options.required===false)return void 0;throw new UsageError(`${options.label}\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044`,options.usage)}return value.trim()}function requireResolved(input,key){const value=input.resolved?.[key];if(value===
5
+ void 0||value===""){throw new Error(`\u5185\u90E8\u30A8\u30E9\u30FC: ${key} \u304C\u89E3\u6C7A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\uFF08prepare() \u306E\u914D\u7DDA\u6F0F\u308C\uFF09`)}return value}function withResolved(input,values){return{...input,resolved:{...input.resolved,...values}}}function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function pick(row,columns){const source=isRecord(row)?row:{};const out={};for(const column of columns)out[column]=source[column]??null;return out}function acknowledgement(body,label){if(!isRecord(body)||body["result"]!==true){throw new ApiResponseError(`${label}\u306E\u5FDC\u7B54\u304C\u60F3\u5B9A\u306E\u5F62\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}
6
+ return{result:true,message:body["message"]??null}}export{singleRef,requireResolved,withResolved,isRecord,pick,acknowledgement};
@@ -0,0 +1,4 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ var PRIVATE_PROJECT_REF="__private__";var PRIVATE_PROJECT_PREFIX="private:";function isPrivateProjectRef(ref){return ref.trim().toLowerCase()===PRIVATE_PROJECT_REF}function isPrivateProjectId(projectId){return projectId.startsWith(PRIVATE_PROJECT_PREFIX)}function privateProjectId(userId){return`${PRIVATE_PROJECT_PREFIX}${userId}`}function projectFileKey(projectId){const key=isPrivateProjectId(projectId)?`private-${projectId.slice(PRIVATE_PROJECT_PREFIX.length)}`:projectId;if(!/^[A-Za-z0-9._-]+$/.
4
+ test(key)||key.includes("..")){throw new Error(`\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8ID\u3092\u30D5\u30A1\u30A4\u30EB\u540D\u306B\u4F7F\u3048\u307E\u305B\u3093\uFF08${projectId.slice(0,60)}\uFF09\u3002\u63A5\u7D9A\u5148\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}return key}export{PRIVATE_PROJECT_REF,isPrivateProjectRef,isPrivateProjectId,privateProjectId,projectFileKey};
@@ -0,0 +1,3 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ var TASK_KEY_RE=/^[^/]+-[0-9]+$/;var LEADING_TASK_KEY_RE=/^([^/]+?-[0-9]+)(?:\s|$)/;function isTaskKey(value){return TASK_KEY_RE.test(value.trim())}function extractLeadingTaskKey(value){return LEADING_TASK_KEY_RE.exec(value.trim())?.[1]??""}var PRIVATE_TASK_KEY_PREFIX="PRIVATE";function isPrivateTaskKey(value){return new RegExp(`^${PRIVATE_TASK_KEY_PREFIX}-[0-9]+$`).test(value.trim())}export{isTaskKey,extractLeadingTaskKey,PRIVATE_TASK_KEY_PREFIX,isPrivateTaskKey};
@@ -0,0 +1,109 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{applyPermissionMode,checkPermission}from"./chunk-NNOYO67O.js";import{DEFAULT_MAX_TOKENS,emptyUsage}from"./chunk-RQFG3OUL.js";import{isForceOnly,killProcessTree,system32}from"./chunk-N2UVRM3Z.js";import{findExecutable,isWindowsDriveAbsolute}from"./chunk-PMOUHEJQ.js";import{configReadDirs,ensureTwpHome,twpHomeDir}from"./chunk-RZVI6PMW.js";import{sep as sep2}from"path";import{realpathSync}from"fs";import{homedir}from"os";import{dirname,isAbsolute,relative,resolve,sep}from"path";var PathDeniedError=class extends Error{constructor(message){super(message);this.name="PathDeniedError"}};function resolveToolPath(input,cwd,home=homedir()){if(typeof input!=="string"||input.trim()===""){throw new PathDeniedError("path must be a non-empty string")}const expanded=expandHome(input,home);const abs=isAbsolute(expanded)?resolve(expanded):resolve(cwd,expanded);const root=realOrSelf(resolve(cwd));assertInside(abs,resolve(cwd),abs);assertNotSecret(abs,home);const real=realOrSelf(abs);if(real!==
4
+ abs){assertInside(real,root,abs);assertNotSecret(real,home)}return abs}function realToolPath(input,cwd,home=homedir()){return realOrSelf(resolveToolPath(input,cwd,home))}function assertInside(target,root,reported){const rel=relative(root,target);const outside=rel===".."||rel.startsWith(`..${sep}`)||isAbsolute(rel);if(outside){throw new PathDeniedError(`path escapes the working directory (${reported}). Only paths under ${root} can be accessed.`)}}function realOrSelf(target){let current=target;const rest=[];
5
+ for(;;){try{const real=realpathSync(current);return rest.length===0?real:resolve(real,...rest.reverse())}catch{const parent=dirname(current);if(parent===current)return target;rest.push(current.slice(parent.length+1));current=parent}}}function assertNotSecret(absPath,home=homedir(),env=process.env){const reason=secretReason(absPath,home,env);if(reason!==null)throw new PathDeniedError(`refusing to access ${absPath}: ${reason}`)}function secretReason(absPath,_home=homedir(),env=process.env){const lower=absPath.
6
+ toLowerCase();const segments=lower.split(sep);const base=segments[segments.length-1]??"";const parent=segments[segments.length-2]??"";if(base===".env"||base.startsWith(".env."))return".env files are denied (design \xA77)";if(segments.includes(".ssh"))return"SSH key material is denied (design \xA77)";if(parent===".git"&&base==="config"){return".git/config is denied (it can hold a GitHub token in the remote URL)"}if(base===".netrc"||base==="_netrc"||base===".npmrc")return"credential files are deni\
7
+ ed";if(parent===".aws"&&(base==="credentials"||base==="config"))return"AWS credentials are denied";for(const dir of configReadDirs(env)){if(lower===resolve(dir,"credentials.json").toLowerCase()){return"TWP credentials are denied (design \xA77)"}}if(parent===".twp"&&base==="credentials.json")return"TWP credentials are denied (design \xA77)";if(parent==="logs"&&base.startsWith("session-")&&base.endsWith(".jsonl")){const grandparent=segments[segments.length-3]??"";if(grandparent===".twp")return"TWP\
8
+ audit logs are denied (design \xA77)";for(const dir of configReadDirs(env)){if(lower.startsWith(resolve(dir,"logs").toLowerCase()+sep)){return"TWP audit logs are denied (design \xA77)"}}}return null}function toolRelative(cwd,absPath){const rel=relative(cwd,absPath);return sep==="\\"?rel.split("\\").join("/"):rel}function isInsideCwd(absPath,cwd){const root=resolve(cwd);if(!withinLexically(absPath,root))return false;const real=realOrSelf(absPath);return real===absPath||withinLexically(real,realOrSelf(
9
+ root))}function withinLexically(target,root){const rel=relative(root,target);return!(rel===".."||rel.startsWith(`..${sep}`)||isAbsolute(rel))}function expandHome(input,home){if(input==="~")return home;if(input.startsWith("~/")||input.startsWith(`~${sep}`))return resolve(home,input.slice(2));return input}function isSingleCommand(command){let quote=null;for(let i=0;i<command.length;i++){const ch=command[i];const next=command[i+1];if(quote==="'"){if(ch==="'")quote=null;continue}if(quote==='"'){if(ch==="\\"){i++;continue}if(ch==="`")return false;if(ch==="$"&&next==="(")return false;if(ch==='"')quote=null;continue}switch(ch){case'"':case"'":quote=ch;continue;case"\\":i++;continue;case";":case"&":case"|":case"\n":case"`":case">":case"<":return false;case"$":if(next==="(")return false;continue;default:
10
+ continue}}return true}function isRecursiveForceRemove(command){const re=/(^|[^\w.-])(rm|rmdir)([^\w.-]|$)/g;for(;;){const m=re.exec(command);if(m===null)return false;const tail=command.slice(m.index+m[0].length);const segment=tail.split(/[;&|\n]/)[0]??"";const tokens=segment.split(/\s+/).filter(t=>t.startsWith("-"));let recursive=false;let force=false;for(const flag of tokens){if(flag==="--recursive")recursive=true;if(flag==="--force")force=true;if(!flag.startsWith("--")){if(flag.includes("r")||
11
+ flag.includes("R"))recursive=true;if(flag.includes("f"))force=true}}if(recursive&&force)return true}}function neverAutoAllowReason(toolName,input){if(toolName!=="bash"&&toolName!=="shell")return null;const command=typeof input["command"]==="string"?input["command"]:"";if(isRecursiveForceRemove(command))return"rm -rf \u3092\u542B\u3080\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059";if(!isSingleCommand(command)){return"\u8907\u6570\u306E\u30B3\u30DE\u30F3\u30C9\u306B\u5206\u5C90\u3057\u3066\u3044\u308B\u305F\u3081\uFF08&& ; | $() \u306A\u3069\uFF09\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059"}
12
+ return null}function autoApproveExemptReason(tool,input,cwd){if(tool.risk!=="write")return null;const raw=input["path"]??input["file_path"]??input["dest"]??input["target"]??input["filename"];if(typeof raw!=="string"||raw==="")return"\u66F8\u304D\u8FBC\u307F\u5148\u3092\u5224\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059";let absolute;try{absolute=realToolPath(raw,cwd)}catch{return"\u66F8\u304D\u8FBC\u307F\u5148\u3092\u89E3\u6C7A\u3067\u304D\u306A\u3044\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059"}
13
+ const segments=absolute.toLowerCase().split(sep2);const base=segments[segments.length-1]??"";if(segments.includes(".git"))return".git/ \u914D\u4E0B\u306F\u6B21\u306E git \u64CD\u4F5C\u3067\u5B9F\u884C\u3055\u308C\u308B\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059";if(segments.includes(".github"))return".github/ \u914D\u4E0B\u306F CI \u304C\u5B9F\u884C\u3059\u308B\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059";if(segments.includes(".claude"))return".claude/ \u914D\u4E0B\u306F\u30D5\u30C3\u30AF\u5B9A\u7FA9\u3092\u542B\
14
+ \u3080\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059";if(segments.includes(".husky")||segments.includes(".githooks")){return"git hook \u306E\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u306A\u306E\u3067\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059"}if(base==="package.json"||base==="makefile"||base===".envrc"||base===".mcp.json"){return`${base} \u306F\u5F8C\u7D9A\u306E\u5B9F\u884C\u306B\u5F71\u97FF\u3059\u308B\u305F\u3081\u3001\u6BCE\u56DE\u78BA\u8A8D\u3057\u307E\u3059`}return null}function validateInput(schema,input){const errors=[];if(typeof input!=="object"||input===null||Array.isArray(input)){return{ok:false,errors:["input must be a JSON object"],value:{}}}const value={...input};const props=schema.properties??{};for(const key of schema.required??[]){if(value[key]===void 0||value[key]===null)errors.push(`missing required property: ${key}`)}if(schema.additionalProperties===false){for(const key of Object.keys(value)){if(!(key in props))errors.push(`unknown property: ${key}`)}}
15
+ for(const[key,sub]of Object.entries(props)){if(value[key]===void 0){if(sub.default!==void 0)value[key]=sub.default;continue}checkValue(`${key}`,sub,value[key],errors)}return{ok:errors.length===0,errors,value}}function checkValue(path4,schema,value,errors){switch(schema.type){case"string":if(typeof value!=="string")errors.push(`${path4} must be a string`);break;case"boolean":if(typeof value!=="boolean")errors.push(`${path4} must be a boolean`);break;case"integer":if(typeof value!=="number"||!Number.
16
+ isInteger(value))errors.push(`${path4} must be an integer`);break;case"number":if(typeof value!=="number"||!Number.isFinite(value))errors.push(`${path4} must be a number`);break;case"array":if(!Array.isArray(value)){errors.push(`${path4} must be an array`);break}if(schema.items){value.forEach((item,i)=>checkValue(`${path4}[${i}]`,schema.items,item,errors))}break;case"object":if(typeof value!=="object"||value===null||Array.isArray(value)){errors.push(`${path4} must be an object`)}break;default:break}
17
+ if(schema.enum&&!schema.enum.some(v=>v===value)){errors.push(`${path4} must be one of: ${schema.enum.join(", ")}`)}if(typeof value==="number"){if(schema.minimum!==void 0&&value<schema.minimum)errors.push(`${path4} must be >= ${schema.minimum}`);if(schema.maximum!==void 0&&value>schema.maximum)errors.push(`${path4} must be <= ${schema.maximum}`)}}async function executeTool(tool,rawInput,deps){const validated=validateInput(tool.inputSchema,rawInput);if(!validated.ok){const content=`Invalid input for ${tool.name}:
18
+ - ${validated.errors.join("\n- ")}`;deps.audit.record({event:"result",tool:tool.name,risk:tool.risk,outcome:"error",bytes:Buffer.byteLength(content),mode:deps.mode.id,reasonCode:"invalid_input"});return{content,isError:true,summary:`${tool.name} \xB7 \u5165\u529B\u304C\u4E0D\u6B63`}}const input=validated.value;const recordDecision=(decision,reasonCode,reason)=>{deps.audit.record({event:"decision",tool:tool.name,risk:tool.risk,decision,reasonCode,reason,mode:deps.mode.id,rawInput:input})};const modePolicy=checkPermission(
19
+ tool.name,deps.mode);const overlay=applyPermissionMode(modePolicy,tool.risk,deps.permissionMode);const policy=overlay.decision;if(policy==="deny"){recordDecision("deny",overlay.reason===null?"mode_policy":"permission_mode",overlay.reason??`mode=${deps.mode.id} \u306E\u65B9\u91DD`);return{content:overlay.reason===null?`permission denied: ${tool.name} is not available in ${deps.mode.id} mode.`:`permission denied: ${tool.name} is blocked by --permission-mode=${deps.permissionMode??""}.`,isError:true,
20
+ denied:true,summary:overlay.reason===null?`${tool.name} \xB7 deny\uFF08${deps.mode.label}\u30E2\u30FC\u30C9\uFF09`:`${tool.name} \xB7 deny\uFF08--permission-mode=${deps.permissionMode??""}\uFF09`}}const preview=safePreview(tool,input);const noAlwaysReason=neverAutoAllowReason(tool.name,input)??autoApproveExemptReason(tool,input,deps.ctx.cwd);const needsAsk=policy==="ask"||noAlwaysReason!==null;if(needsAsk){const skip=noAlwaysReason===null&&deps.sessionAllow.has(tool.name);if(skip)recordDecision(
21
+ "allow","session_allow","\u30BB\u30C3\u30B7\u30E7\u30F3\u5185\u306E\u300C\u4ECA\u5F8C\u805E\u304B\u306A\u3044\u300D");if(!skip){if(!deps.askPermission){recordDecision("deny",noAlwaysReason===null?"non_interactive":"guard",noAlwaysReason??"\u975E\u5BFE\u8A71\u30BB\u30C3\u30B7\u30E7\u30F3\u3067\u627F\u8A8D\u304C\u5FC5\u8981\uFF08deny-and-continue\uFF09");return{content:`permission denied: ${tool.name} requires approval, and this session is non-interactive. `+(noAlwaysReason===null?"":`Reason: ${noAlwaysReason}\
22
+ `)+"Explain what you would run instead of running it.",isError:true,denied:true,summary:`${tool.name} \xB7 \u975E\u5BFE\u8A71\u306E\u305F\u3081\u62D2\u5426`}}let diff;try{diff=await tool.prepare?.(input,deps.ctx)??void 0}catch(err){diff=void 0;if(err instanceof PathDeniedError){recordDecision("deny","path_denied","\u4FDD\u8B77\u3055\u308C\u305F\u30D1\u30B9\uFF08paths.ts\uFF09");return{content:err.message,isError:true,denied:true,summary:`${tool.name} \xB7 deny\uFF08\u4FDD\u8B77\u3055\u308C\u305F\u30D1\u30B9\uFF09`}}}
23
+ const answer=await deps.askPermission({tool,input,preview,...diff?{diff}:{},noAlwaysReason});if(answer==="no"){recordDecision("deny","user_declined","\u5229\u7528\u8005\u304C\u62D2\u5426");return{content:`permission denied: the user declined to run ${tool.name}.`,isError:true,denied:true,summary:`${tool.name} \xB7 \u5229\u7528\u8005\u304C\u62D2\u5426`}}if(answer==="always"&&noAlwaysReason===null)deps.sessionAllow.add(tool.name);recordDecision("allow","user_approved",answer==="always"?"\u5229\u7528\u8005\u304C\u627F\u8A8D\uFF08\u4ECA\u5F8C\u805E\
24
+ \u304B\u306A\u3044\uFF09":"\u5229\u7528\u8005\u304C\u627F\u8A8D")}}else{recordDecision("allow",overlay.reason===null?"mode_policy":"permission_mode",overlay.reason??`mode=${deps.mode.id} \u306E\u65B9\u91DD`)}deps.onStart?.(tool,preview);try{const result=await tool.run(input,deps.ctx);deps.audit.record({event:"result",tool:tool.name,risk:tool.risk,outcome:result.isError===true?"error":"ok",bytes:Buffer.byteLength(result.content),mode:deps.mode.id});return{summary:preview,...result}}catch(err){if(err instanceof
25
+ PathDeniedError){deps.audit.record({event:"result",tool:tool.name,risk:tool.risk,outcome:"denied",bytes:Buffer.byteLength(err.message),mode:deps.mode.id,reasonCode:"path_denied"});return{content:err.message,isError:true,denied:true,summary:`${tool.name} \xB7 deny\uFF08\u4FDD\u8B77\u3055\u308C\u305F\u30D1\u30B9\uFF09`}}const message=`${tool.name} failed: ${err.message}`;deps.audit.record({event:"result",tool:tool.name,risk:tool.risk,outcome:"error",bytes:Buffer.byteLength(message),mode:deps.mode.
26
+ id});return{content:message,isError:true,summary:`${tool.name} \xB7 \u30A8\u30E9\u30FC`}}}function safePreview(tool,input){try{return tool.preview(input)}catch{return tool.name}}function toWireTool(def){return{name:def.name,description:def.description,input_schema:def.inputSchema}}var DEFAULT_MAX_STEPS=24;function buildSystemPrompt(ctx){const tools=ctx.toolNames??[];const capability=tools.length===0?["- **\u30C4\u30FC\u30EB\u5B9F\u884C\u306F\u307E\u3060\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002** \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u307F\u66F8\u304D\u30FB\u30B3\u30DE\u30F3\u30C9\u5B9F\u884C\u30FBTWP API \u64CD\u4F5C\u30FBWeb \u691C\u7D22\u306F\u3044\u305A\u308C\u3082\u884C\u3048\u307E\u305B\u3093","- \u5B9F\u884C\u304C\u5FC5\u8981\u306A\u3053\u3068\u306F\u3001\u5229\u7528\u8005\u304C\u81EA\u5206\u3067\u5B9F\u884C\u3067\u304D\u308B\u30B3\u30DE\u30F3\u30C9\u3084\u624B\u9806\u3068\u3057\u3066\u63D0\u793A\u3057\u3066\u304F\u3060\u3055\u3044"]:
27
+ [`- \u4F7F\u3048\u308B\u30C4\u30FC\u30EB: ${tools.join(" / ")}`,"- **\u63A8\u6E2C\u3067\u7B54\u3048\u305A\u3001\u307E\u305A\u30C4\u30FC\u30EB\u3067\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002** \u30D5\u30A1\u30A4\u30EB\u306E\u5185\u5BB9\u30FB\u30B3\u30DE\u30F3\u30C9\u306E\u7D50\u679C\u30FB\u73FE\u5728\u306E\u72B6\u614B\u306F\u3059\u3079\u3066\u5B9F\u969B\u306B\u8AAD\u3093\u3067\u304B\u3089\u7B54\u3048\u307E\u3059","- \u4E00\u5EA6\u306B1\u3064\u305A\u3064\u78BA\u304B\u3081\u3001\u7D50\u679C\u3092\u898B\u3066\u304B\u3089\u6B21\u3092\u6C7A\u3081\u3066\u304F\u3060\u3055\u3044",
28
+ "- \u30C4\u30FC\u30EB\u304C\u62D2\u5426\u3055\u308C\u305F\uFF08permission denied\uFF09\u3068\u304D\u306F\u3001\u540C\u3058\u547C\u3073\u51FA\u3057\u3092\u7E70\u308A\u8FD4\u3055\u305A\u3001\u4F55\u3092\u3057\u305F\u3044\u306E\u304B\u3092\u5229\u7528\u8005\u306B\u8AAC\u660E\u3057\u3066\u304F\u3060\u3055\u3044"];return[`\u3042\u306A\u305F\u306F TWP\uFF08Tocca Working Platform\uFF09\u306E CLI\u300Ctwp\u300D${ctx.cliVersion} \u306E\u4E2D\u3067\u52D5\u304F\u30A2\u30B7\u30B9\u30BF\u30F3\u30C8\u3067\u3059\u3002`,
29
+ "\u51FA\u529B\u306F\u7AEF\u672B\u306B\u8868\u793A\u3055\u308C\u307E\u3059\u3002\u65E5\u672C\u8A9E\u3067\u3001\u7D50\u8AD6\u3092\u5148\u306B\u3001\u7C21\u6F54\u306B\u7B54\u3048\u3066\u304F\u3060\u3055\u3044\u3002","","## \u3044\u307E\u3067\u304D\u308B\u3053\u3068\u30FB\u3067\u304D\u306A\u3044\u3053\u3068","",...capability,"- \u898B\u3066\u3044\u306A\u3044\u30D5\u30A1\u30A4\u30EB\u306E\u5185\u5BB9\u3084\u5B9F\u884C\u3057\u3066\u3044\u306A\u3044\u30B3\u30DE\u30F3\u30C9\u306E\u7D50\u679C\u3092\u3001\u898B\u305F\u30FB\u5B9F\u884C\u3057\u305F\u304B\u306E\u3088\u3046\u306B\u66F8\u304B\u306A\u3044\u3067\u304F\u3060\u3055\u3044",
30
+ "","## \u5229\u7528\u8005\u306E\u74B0\u5883","",`- \u4F5C\u696D\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA: ${ctx.cwd}`,...ctx.branch?[`- git \u30D6\u30E9\u30F3\u30C1: ${ctx.branch}`]:[],`- \u30E2\u30FC\u30C9: ${ctx.modeLabel}\uFF08\u30E2\u30FC\u30C9\u304C\u30C4\u30FC\u30EB\u306E\u8A31\u53EF\u7BC4\u56F2\u3092\u6C7A\u3081\u307E\u3059\uFF09`].join("\n")}async function runTurn(client,context,request){const maxTokens=request.maxTokens??DEFAULT_MAX_TOKENS;const maxSteps=request.maxSteps??DEFAULT_MAX_STEPS;const tools=request.
31
+ tools??[];const wire=tools.map(toWireTool);context.addUser(request.input);let droppedMessages=context.trimToFit(maxTokens);const totals=emptyUsage();let lastText="";let toolCalls=0;for(let step=0;step<maxSteps;step++){let outcome;try{outcome=await client.stream({model:request.model,maxTokens,...request.system!==void 0?{system:request.system}:{},...wire.length>0?{tools:wire}:{},messages:context.history()},{onTextDelta:request.onTextDelta,...request.signal?{signal:request.signal}:{}})}catch(err){context.
32
+ completeTurn("");err.usage=totals;throw err}add(totals,outcome.usage);context.applyUsage(outcome.usage);lastText=outcome.text;if(outcome.aborted||outcome.upstreamError!==null||outcome.toolUses.length===0){const kept=context.completeTurn(outcome.text);return{text:outcome.text,usage:totals,aborted:outcome.aborted,upstreamError:outcome.upstreamError,stopReason:outcome.stopReason,droppedMessages,emptyResponse:!kept,toolCalls,maxStepsReached:false}}const results=await runToolUses(outcome.toolUses,tools,
33
+ request);toolCalls+=results.length;context.addToolExchange(outcome.text,outcome.toolUses,results);if(request.signal?.aborted===true){return{text:outcome.text,usage:totals,aborted:true,upstreamError:null,stopReason:outcome.stopReason,droppedMessages,emptyResponse:false,toolCalls,maxStepsReached:false}}droppedMessages+=context.trimToFit(maxTokens)}return{text:lastText,usage:totals,aborted:false,upstreamError:null,stopReason:"max_steps",droppedMessages,emptyResponse:false,toolCalls,maxStepsReached:true}}
34
+ async function runToolUses(toolUses,tools,request){const results=[];for(const call of toolUses){request.onToolUse?.({name:call.name,input:call.input});const result=await runOne(call,tools,request);request.onToolResult?.({name:call.name,input:call.input},result);results.push({type:"tool_result",tool_use_id:call.id,content:result.content===""?"(no output)":result.content,...result.isError===true?{is_error:true}:{}})}return results}async function runOne(call,tools,request){const auditUnexecuted=(reasonCode,reason)=>{
35
+ if(!request.execute)return;request.execute.audit.record({event:"decision",tool:call.name,risk:"unknown",decision:"deny",reasonCode,reason,mode:request.execute.mode.id,rawInput:typeof call.input==="object"&&call.input!==null?call.input:{}})};if(request.signal?.aborted===true){auditUnexecuted("interrupted","\u5229\u7528\u8005\u304C\u4E2D\u65AD\u3057\u305F\u305F\u3081\u5B9F\u884C\u3057\u306A\u3044");return{content:"interrupted by the user before this tool ran",isError:true,summary:`${call.name} \xB7 \u4E2D\
36
+ \u65AD`}}const tool=tools.find(t=>t.name===call.name);if(!tool){auditUnexecuted("unknown_tool","\u30E2\u30C7\u30EB\u306B\u6E21\u3057\u3066\u3044\u306A\u3044\u30C4\u30FC\u30EB\u540D\uFF08\u5E38\u99D0\u30BB\u30C3\u30C8\u306B\u7121\u3044\uFF09");return{content:`Unknown tool: ${call.name}. Available tools: ${tools.map(t=>t.name).join(", ")||"(none)"}`,isError:true,summary:`${call.name} \xB7 \u672A\u77E5\u306E\u30C4\u30FC\u30EB`}}if(!request.execute){return{content:`Tool ${call.name} cannot run: this\
37
+ session has no tool execution context.`,isError:true,summary:`${call.name} \xB7 \u5B9F\u884C\u74B0\u5883\u306A\u3057`}}return executeTool(tool,call.input,{...request.execute,ctx:{...request.execute.ctx,...request.signal?{signal:request.signal}:{}}})}function add(target,source){target.inputTokens+=source.inputTokens;target.cacheReadTokens+=source.cacheReadTokens;target.cacheWriteTokens+=source.cacheWriteTokens;target.outputTokens+=source.outputTokens}import fs from"fs";import path from"path";import crypto from"crypto";var MAX_LINE_BYTES=4096;var MAX_FILE_BYTES=5*1024*1024;var MAX_AGE_DAYS=14;var MAX_FILES=200;var PRUNE_GRACE_MS=6*60*60*1e3;var MAX_STRING_BYTES=200;var MAX_TOOL_NAME_BYTES=120;var REDACT_KEYS=new Set(["content","contents","new_string","old_string","body","text","patch","diff","data","stdin","password","passwd","pwd","secret","secret_key","token","access_token","refresh_token","id_token","session_token","api_key","apikey","api-key","key","private_key","client_secret","authorization","auth","cook\
38
+ ie","headers","signature","credential","credentials"]);var SECRET_PATTERNS=[/(?:bearer|basic)\s+[A-Za-z0-9._~+/=-]{8,}/gi,/\b(?:sk|pk|rk)-[A-Za-z0-9_-]{8,}/g,/\bgh[pousr]_[A-Za-z0-9]{8,}/g,/\bAKIA[0-9A-Z]{12,}/g,/-----BEGIN[^-]*PRIVATE KEY-----/g,/\b(?:password|passwd|pwd|token|secret|api[_-]?key)\s*[:=]\s*[^\s;&|<>'"`]+/gi,/\b[A-Fa-f0-9]{40,}\b/g,/\b[A-Za-z0-9+_-]{40,}={0,2}\b/g];function scrubSecrets(value){let out=value;for(const re of SECRET_PATTERNS)out=out.replace(re,"[REDACTED]");return out}
39
+ var TOKEN_RE=/[^\s=:,;&|<>'"`()[\]{}/\\]+/g;var SEPARATOR_RE=/[\s=:,;&|<>'"`()[\]{}/\\]/;var SecretRegistry=class _SecretRegistry{static MAX_HASHES=4096;static MAX_PHRASES=64;static MIN_LENGTH=12;static MAX_LENGTH=512;hashes=new Set;phrases=[];saturated=false;learn(value,depth=0){if(value!==null&&typeof value==="object"&&depth<8){const children=Array.isArray(value)?value:Object.values(value);for(const child of children)this.learn(child,depth+1);return}const text=typeof value==="string"?value:safeStringify(
40
+ value);if(text==="")return;for(const line of text.split(/\r?\n/)){const trimmed=line.trim();if(trimmed==="")continue;const eq=trimmed.indexOf("=");if(eq>0)this.add(unquote(trimmed.slice(eq+1).trim()),true);if(!/\s/.test(trimmed))this.add(unquote(trimmed),false)}}add(candidate,fromEnv){if(candidate.length<_SecretRegistry.MIN_LENGTH)return;if(candidate.length>_SecretRegistry.MAX_LENGTH)return;const hasSeparator=SEPARATOR_RE.test(candidate);if(hasSeparator&&!fromEnv)return;if(hasSeparator){if(this.
41
+ phrases.includes(candidate))return;if(this.phrases.length>=_SecretRegistry.MAX_PHRASES){this.saturated=true;return}this.phrases.push(candidate);return}const hash=digest(candidate);if(this.hashes.has(hash))return;if(this.hashes.size>=_SecretRegistry.MAX_HASHES){this.saturated=true;return}this.hashes.add(hash)}scrub(text){let out=text;for(const phrase of this.phrases){if(out.includes(phrase))out=out.split(phrase).join("[REDACTED]")}if(this.hashes.size===0)return out;return out.replace(TOKEN_RE,token=>token.
42
+ length>=_SecretRegistry.MIN_LENGTH&&this.hashes.has(digest(token))?"[REDACTED]":token)}};function digest(value){return crypto.createHash("sha256").update(value,"utf8").digest("hex").slice(0,24)}function unquote(value){const first=value[0];if((first==='"'||first==="'")&&value.endsWith(first)&&value.length>1)return value.slice(1,-1);return value}function safeStringify(value){try{return JSON.stringify(value)??""}catch{return""}}function nullAuditLogger(){return{path:null,sessionId:"",record:()=>void 0}}
43
+ function createAuditLogger(ctx){const env=ctx.env??process.env;if(env.TWP_NO_AUDIT==="1")return nullAuditLogger();const sessionId=newSessionId();const file=path.join(twpHomeDir(env),"logs",`session-${sessionId}.jsonl`);let fd=null;let written=0;let stopped=false;const registry=new SecretRegistry;let reportedSaturation=false;const open=()=>{if(fd!==null)return true;if(stopped)return false;try{const dir=path.join(ensureTwpHome(env),"logs");const link=lstatOrNull(dir);if(link!==null&&link.isSymbolicLink()){
44
+ stopped=true;return false}fs.mkdirSync(dir,{recursive:true,mode:448});if(process.platform!=="win32"){try{fs.chmodSync(dir,448)}catch{}}prune(dir);const handle=fs.openSync(file,"a",384);if(process.platform!=="win32"){try{fs.fchmodSync(handle,384)}catch{fs.closeSync(handle);try{fs.unlinkSync(file)}catch{}stopped=true;return false}}fd=handle;ctx.onOpen?.(file);return true}catch{stopped=true;return false}};const writeAll=(handle,text)=>{const buf=Buffer.from(text,"utf8");let offset=0;while(offset<buf.
45
+ length){const n=fs.writeSync(handle,buf,offset,buf.length-offset);if(n<=0)throw new Error("writeSync made no progress");offset+=n}written+=buf.length};const writeLine=payload=>{if(stopped||!open()||fd===null)return;try{let line=`${JSON.stringify(payload)}
46
+ `;if(Buffer.byteLength(line)>MAX_LINE_BYTES&&"input"in payload){const rest={...payload};delete rest["input"];line=`${JSON.stringify({...rest,_dropped:"line_too_long"})}
47
+ `}if(Buffer.byteLength(line)>MAX_LINE_BYTES){line=`${JSON.stringify({ts:now(),v:1,session:sessionId,event:payload["event"],tool:clamp(String(payload["tool"]??""),40),_dropped:"line_too_long"})}
48
+ `}if(written+Buffer.byteLength(line)>MAX_FILE_BYTES){stopped=true;writeAll(fd,`${JSON.stringify({ts:now(),v:1,session:sessionId,event:"truncated"})}
49
+ `);return}writeAll(fd,line)}catch{stopped=true}};const common={v:1,session:sessionId,permission_mode:ctx.permissionMode??null};let wroteHeader=false;const header=()=>{if(wroteHeader)return;writeLine({ts:now(),...common,event:"session_start",mode:ctx.mode,model:ctx.model,cwd:ctx.cwd,cli_version:ctx.cliVersion,interactive:ctx.interactive,pid:process.pid});if(fd!==null&&!stopped)wroteHeader=true};const reportSaturation=()=>{if(!registry.saturated||reportedSaturation)return;reportedSaturation=true;writeLine(
50
+ {ts:now(),...common,event:"registry_saturated"})};return{path:file,sessionId,record(event){header();const tool=clamp(event.tool,MAX_TOOL_NAME_BYTES);if(event.event==="decision"){const input=sanitizeInput(event.rawInput,registry);writeLine({ts:now(),...common,event:"decision",tool,risk:event.risk,decision:event.decision,reason_code:event.reasonCode,reason:event.reason,mode:event.mode,input});reportSaturation();return}writeLine({ts:now(),...common,event:"result",tool,risk:event.risk,outcome:event.
51
+ outcome,bytes:event.bytes,mode:event.mode,...event.reasonCode!==void 0?{reason_code:event.reasonCode}:{}})}}}function now(){return new Date().toISOString()}function lstatOrNull(target){try{return fs.lstatSync(target)}catch{return null}}function clamp(value,maxBytes){const total=Buffer.byteLength(value);if(total<=maxBytes)return value;let out=value;while(out.length>0&&Buffer.byteLength(out)>maxBytes)out=out.slice(0,-1);return`${out}\u2026(+${total-Buffer.byteLength(out)})`}function sanitizeInput(rawInput,registry){
52
+ learnSecrets(rawInput,0,registry);return sanitizeObject(rawInput,0,registry)}function learnSecrets(value,depth,registry){if(depth>8||value===null||typeof value!=="object")return;if(Array.isArray(value)){for(const item of value)learnSecrets(item,depth+1,registry);return}for(const[key,child]of Object.entries(value)){if(REDACT_KEYS.has(key.toLowerCase()))registry.learn(child);else learnSecrets(child,depth+1,registry)}}function sanitizeObject(obj,depth,registry){const out={};let keys=0;for(const[key,
53
+ value]of Object.entries(obj)){if(keys>=20){out["_twp_more_keys"]=true;break}keys++;if(REDACT_KEYS.has(key.toLowerCase())){out[key]=`<redacted ${byteLengthOf(value)} bytes>`;continue}out[key]=sanitizeValue(value,depth+1,registry)}return out}function sanitizeValue(value,depth,registry){if(value===null||typeof value==="number"||typeof value==="boolean")return value;if(typeof value==="string"){return clamp(registry.scrub(scrubSecrets(value)),MAX_STRING_BYTES)}if(depth>=3)return"<depth>";if(Array.isArray(
54
+ value)){const head=value.slice(0,10).map(v=>sanitizeValue(v,depth+1,registry));return value.length>10?[...head,`\u2026(+${value.length-10})`]:head}if(typeof value==="object")return sanitizeObject(value,depth,registry);return`<${typeof value}>`}function byteLengthOf(value){if(typeof value==="string")return Buffer.byteLength(value);try{return Buffer.byteLength(JSON.stringify(value)??"")}catch{return 0}}function prune(dir,nowMs=Date.now()){let entries;try{entries=fs.readdirSync(dir).filter(n=>/^session-.*\.jsonl$/.
55
+ test(n))}catch{return}const stats=[];for(const name of entries){try{stats.push({name,mtime:fs.statSync(path.join(dir,name)).mtimeMs})}catch{}}stats.sort((a,b)=>b.mtime-a.mtime);const cutoff=nowMs-MAX_AGE_DAYS*24*60*60*1e3;stats.forEach((entry,index)=>{const overCount=index>=MAX_FILES-1;const tooOld=entry.mtime<cutoff;if(!tooOld&&!overCount)return;if(!tooOld&&nowMs-entry.mtime<PRUNE_GRACE_MS)return;try{fs.unlinkSync(path.join(dir,entry.name))}catch{}})}var CROCKFORD="0123456789ABCDEFGHJKMNPQRSTVW\
56
+ XYZ";function newSessionId(nowMs=Date.now()){let time="";let remaining=nowMs;for(let i=0;i<10;i++){time=`${CROCKFORD[remaining%32]??"0"}${time}`;remaining=Math.floor(remaining/32)}const bytes=crypto.randomBytes(16);let rand="";for(const byte of bytes)rand+=CROCKFORD[byte%32]??"0";return`${time}${rand}`}import{readFileSync}from"fs";import{dirname as dirname2,join,resolve as resolve2,sep as sep3}from"path";function currentBranch(cwd=process.cwd()){let dir=cwd;for(;;){const gitPath=join(dir,".git");const head=readHead(gitPath);if(head!==null)return head;const parent=dirname2(dir);if(parent===dir)return null;dir=parent}}function readHead(gitPath){let headFile=join(gitPath,"HEAD");try{const stat2=readFileSync(gitPath,"utf8");const m=/^gitdir:\s*(.+)$/m.exec(stat2);if(m?.[1])headFile=join(resolve2(dirname2(
57
+ gitPath),m[1].trim()),"HEAD")}catch{}try{const head=readFileSync(headFile,"utf8").trim();const ref=/^ref:\s*refs\/heads\/(.+)$/.exec(head);if(ref?.[1])return ref[1];return head.slice(0,7)}catch{return null}}function displayCwd(cwd=process.cwd(),home=process.env["HOME"]??process.env["USERPROFILE"]??""){if(!home)return cwd;const stripped=home.replace(new RegExp(`${escapeSep()}+$`),"");if(stripped==="")return cwd;const normalize=p=>process.platform==="win32"?p.toLowerCase():p;const h=normalize(stripped);
58
+ const c=normalize(cwd);if(c===h)return"~";if(c.startsWith(h+sep3))return`~${cwd.slice(stripped.length)}`;return cwd}function escapeSep(){return sep3==="\\"?"\\\\":sep3}import{spawn}from"child_process";function keepTailBytes(buf,maxBytes){if(buf.length<=maxBytes)return{text:buf.toString("utf8"),droppedBytes:0};const start=buf.length-maxBytes;let cut=start;while(cut<buf.length&&(buf[cut]&192)===128)cut++;return{text:buf.subarray(cut).toString("utf8"),droppedBytes:cut}}function keepHeadBytes(text,maxBytes){const buf=Buffer.from(text,"utf8");if(buf.length<=maxBytes)return{text,truncated:false};let cut=maxBytes;while(cut>0&&(buf[cut]&192)===128)cut--;return{text:buf.subarray(0,cut).toString("utf8"),
59
+ truncated:true}}import{existsSync}from"fs";import path2 from"path";var GIT_BASH_CANDIDATES=["C:\\Program Files\\Git\\bin\\bash.exe","C:\\Program Files (x86)\\Git\\bin\\bash.exe","C:\\Program Files\\Git\\usr\\bin\\bash.exe"];function system32Path(env,...rest){return system32(env,...rest)??path2.win32.join("C:\\Windows\\System32",...rest)}function defaultProbe(filePath){try{return existsSync(filePath)}catch{return false}}function selectShell(platform=process.platform,probe=defaultProbe,env=process.env){if(platform!=="win32"){return{toolName:"bash",command:"/bin/b\
60
+ ash",args:["-c"],kind:"bash",note:null}}const sys={wsl:system32Path(env,"wsl.exe"),powershell:system32Path(env,"WindowsPowerShell","v1.0","powershell.exe"),cmd:system32Path(env,"cmd.exe")};for(const candidate of gitBashCandidates(env)){if(probe(candidate)){return{toolName:"bash",command:candidate,args:["-c"],kind:"git-bash",note:null}}}if(probe(sys.wsl)){return{toolName:"bash",command:sys.wsl,args:["-e","bash","-c"],kind:"wsl",note:"WSL \u306E bash \u3067\u5B9F\u884C\u3057\u307E\u3059\uFF08Windows \u306E\u30D1\u30B9\u306F /mnt/c/... \u5F62\u5F0F\u306B\u306A\u308A\u307E\u3059\uFF09"}}
61
+ const pwsh=pwshPath(probe,env);if(pwsh!==null){return{toolName:"shell",command:pwsh,args:["-NoProfile","-NonInteractive","-Command"],kind:"pwsh",note:"\u3053\u306E\u74B0\u5883\u306B bash \u304C\u306A\u3044\u305F\u3081 PowerShell \u3067\u5B9F\u884C\u3057\u307E\u3059\u3002**bash \u69CB\u6587\u306F\u4F7F\u3048\u307E\u305B\u3093**\uFF08`&&` \u306E\u9023\u7D50\u30FB`grep` / `rm` \u306A\u3069\u306E POSIX \u30B3\u30DE\u30F3\u30C9\u306F PowerShell \u306E\u69CB\u6587\u3068\u30B3\u30DE\u30F3\u30C9\u30EC\u30C3\u30C8\u306B\u7F6E\u304D\u63DB\u3048\u3066\u304F\u3060\u3055\u3044\uFF09"}}
62
+ if(probe(sys.powershell)){return{toolName:"shell",command:sys.powershell,args:["-NoProfile","-NonInteractive","-Command"],kind:"powershell",note:"\u3053\u306E\u74B0\u5883\u306B bash \u304C\u306A\u3044\u305F\u3081 Windows PowerShell 5.1 \u3067\u5B9F\u884C\u3057\u307E\u3059\u3002**bash \u69CB\u6587\u306F\u4F7F\u3048\u307E\u305B\u3093**\uFF08`&&` \u306F\u4F7F\u3048\u305A `;` \u306B\u306A\u308A\u307E\u3059\uFF09"}}return{toolName:"shell",command:sys.cmd,args:["/d","/s","/c"],kind:"cmd",note:"\u3053\u306E\u74B0\u5883\u306B b\
63
+ ash \u3082 PowerShell \u3082\u306A\u3044\u305F\u3081 cmd.exe \u3067\u5B9F\u884C\u3057\u307E\u3059\u3002**bash \u69CB\u6587\u306F\u4F7F\u3048\u307E\u305B\u3093**\uFF08cmd \u306E\u30D0\u30C3\u30C1\u69CB\u6587\u3067\u66F8\u3044\u3066\u304F\u3060\u3055\u3044\uFF09"}}function trustedBase(base){return typeof base==="string"&&isWindowsDriveAbsolute(base)}function gitBashCandidates(env){const fromEnv=[];for(const key of["ProgramFiles","ProgramFiles(x86)","ProgramW6432"]){const base=env[key];if(trustedBase(
64
+ base))fromEnv.push(`${base}\\Git\\bin\\bash.exe`,`${base}\\Git\\usr\\bin\\bash.exe`)}return[...fromEnv,...GIT_BASH_CANDIDATES]}function pwshPath(probe,env){const bases=[env["ProgramFiles"],env["ProgramW6432"],"C:\\Program Files"].filter(trustedBase);for(const base of bases){for(const major of["7","6"]){const candidate=`${base}\\PowerShell\\${major}\\pwsh.exe`;if(probe(candidate))return candidate}}return null}var DEFAULT_TIMEOUT_MS=12e4;var MAX_TIMEOUT_MS=6e5;var MAX_OUTPUT_BYTES=1e5;function createBashTool(choice=selectShell()){const base=choice.toolName==="bash"?"Run a shell command with bash. Prefer specific tools (read_file / glob / grep) when they fit \u2014 they are cheaper and safer.":"Run a shell command. NOTE: bash is not available in this environment.";return{name:choice.toolName,domain:"local",risk:"exec",description:choice.note===null?base:`${base}
65
+ ${choice.note}`,inputSchema:{type:"object",additionalProperties:false,properties:{command:{type:"string",description:"The command line to run"},timeout_ms:{type:"integer",description:`Timeout in milliseconds (default ${DEFAULT_TIMEOUT_MS}, max ${MAX_TIMEOUT_MS})`,minimum:1e3,maximum:MAX_TIMEOUT_MS}},required:["command"]},preview(input){const command=typeof input["command"]==="string"?input["command"]:"";const line=command.split("\n")[0]??"";return`${choice.toolName} \xB7 ${line.slice(0,80)}${line.
66
+ length>80||command.includes("\n")?"\u2026":""}`},async run(input,ctx){const command=String(input["command"]);const timeout=clampTimeout(input["timeout_ms"]);return runCommand(choice,command,timeout,ctx.cwd,ctx.signal,ctx.env)}}}function clampTimeout(value){if(typeof value!=="number"||!Number.isFinite(value))return DEFAULT_TIMEOUT_MS;return Math.min(MAX_TIMEOUT_MS,Math.max(1e3,Math.floor(value)))}function runCommand(choice,command,timeoutMs,cwd,signal,env=process.env){return new Promise(resolve5=>{
67
+ const child=spawn(choice.command,[...choice.args,command],{cwd,env,shell:false,detached:process.platform!=="win32",stdio:["ignore","pipe","pipe"]});const chunks=[];let bytes=0;const collect=buf=>{chunks.push(buf);bytes+=buf.length;while(bytes-(chunks[0]?.length??0)>MAX_OUTPUT_BYTES*2&&chunks.length>1){const dropped=chunks.shift();if(!dropped)break;bytes-=dropped.length}};child.stdout.on("data",collect);child.stderr.on("data",collect);let outcome="ok";const kill=()=>{if(child.killed||child.exitCode!==
68
+ null)return;if(isForceOnly()){killProcessTree(child,"SIGKILL");return}killProcessTree(child,"SIGTERM");setTimeout(()=>killProcessTree(child,"SIGKILL"),2e3).unref()};const timer=setTimeout(()=>{outcome="timeout";kill()},timeoutMs);const onAbort=()=>{outcome="aborted";kill()};if(signal){if(signal.aborted)onAbort();else signal.addEventListener("abort",onAbort,{once:true})}const finish=(exitCode,spawnError)=>{clearTimeout(timer);signal?.removeEventListener("abort",onAbort);const raw=Buffer.concat(chunks);
69
+ const kept=keepTailBytes(raw,MAX_OUTPUT_BYTES);const body=kept.text;const head=kept.droppedBytes>0?`[output truncated: dropped the first ${kept.droppedBytes} bytes, showing the last ${Buffer.byteLength(body,"utf8")}]
70
+ `:"";if(spawnError){resolve5({content:`Failed to start ${choice.command}: ${spawnError.message}`,isError:true,summary:`${choice.toolName} \xB7 \u8D77\u52D5\u3067\u304D\u307E\u305B\u3093`});return}if(outcome==="timeout"){resolve5({content:`${head}${body}
71
+ [timed out after ${timeoutMs}ms and was killed]`,isError:true,summary:`${choice.toolName} \xB7 \u30BF\u30A4\u30E0\u30A2\u30A6\u30C8 (${timeoutMs}ms)`});return}if(outcome==="aborted"){resolve5({content:`${head}${body}
72
+ [interrupted by the user]`,isError:true,summary:`${choice.toolName} \xB7 \u4E2D\u65AD`});return}resolve5({content:body===""?`(no output, exit code ${exitCode??0})`:`${head}${body}`,...exitCode!==0?{isError:true}:{},summary:`${choice.toolName} \xB7 exit ${exitCode??0}`})};child.on("error",err=>finish(null,err));child.on("close",code=>finish(code))})}import{readFile,writeFile}from"fs/promises";function detectEol(text){let crlf=0;let lf=0;for(let i=0;i<text.length;i++){if(text.charCodeAt(i)!==10)continue;if(i>0&&text.charCodeAt(i-1)===13)crlf++;else lf++}return crlf>lf?"\r\n":"\n"}function toLf(text){return text.replace(/\r\n/g,"\n")}function applyEol(text,eol){if(eol==="\n")return toLf(text);return toLf(text).replace(/\n/g,"\r\n")}var editFileTool={name:"edit_file",domain:"local",risk:"write",description:"Replace an exact string in a file. old_string must match exactly and be unique unless replace_all is true. Read the file first \u2014 the match includes indentation. Line endings of the file are preserved.",inputSchema:{type:"object",additionalProperties:false,properties:{path:{type:"string",description:"File path, relative to the working directory"},old_string:{type:"string",description:"Exact text to replace (without l\
73
+ ine-number prefixes)"},new_string:{type:"string",description:"Replacement text"},replace_all:{type:"boolean",description:"Replace every occurrence instead of requiring uniqueness",default:false}},required:["path","old_string","new_string"]},preview(input){const old=typeof input["old_string"]==="string"?input["old_string"]:"";const head=old.split("\n")[0]??"";return`edit_file \xB7 ${String(input["path"]??"")} \xB7 ${head.slice(0,48)}${head.length>48?"\u2026":""}`},async prepare(input,ctx){const abs=resolveToolPath(
74
+ String(input["path"]),ctx.cwd);const before=await readFile(abs,"utf8").catch(()=>null);if(before===null)return null;const applied=apply(before,input);if(!applied.ok)return null;return{path:toolRelative(ctx.cwd,abs),before,after:applied.after}},async run(input,ctx){const abs=resolveToolPath(String(input["path"]),ctx.cwd);const before=await readFile(abs,"utf8").catch(()=>null);if(before===null)return{content:`File not found: ${input["path"]}`,isError:true};const applied=apply(before,input);if(!applied.
75
+ ok)return{content:applied.error,isError:true};await writeFile(abs,applied.after,"utf8");const rel=toolRelative(ctx.cwd,abs);return{content:`Edited ${rel} (${applied.count} replacement${applied.count===1?"":"s"}).`,summary:`edit_file \xB7 ${rel}`,diff:{path:rel,before,after:applied.after}}}};function apply(before,input){const eol=detectEol(before);const oldRaw=String(input["old_string"]);const newRaw=String(input["new_string"]);const replaceAll=input["replace_all"]===true;if(oldRaw==="")return{ok:false,
76
+ error:"old_string must not be empty"};if(oldRaw===newRaw)return{ok:false,error:"old_string and new_string are identical"};const candidates=eol==="\r\n"?[applyEol(oldRaw,eol),oldRaw]:[oldRaw];for(const needle of candidates){const count=countOccurrences(before,needle);if(count===0)continue;if(count>1&&!replaceAll){return{ok:false,error:`old_string occurs ${count} times. Provide more surrounding context to make it unique, or set replace_all: true.`}}const replacement=applyEol(newRaw,eol);const after=replaceAll?
77
+ before.split(needle).join(replacement):replaceOnce(before,needle,replacement);return{ok:true,after,count}}return{ok:false,error:"old_string not found in the file. Read the file again \u2014 whitespace and indentation must match exactly."}}function countOccurrences(haystack,needle){let count=0;let from=0;for(;;){const at=haystack.indexOf(needle,from);if(at===-1)return count;count+=1;from=at+needle.length}}function replaceOnce(haystack,needle,replacement){const at=haystack.indexOf(needle);return haystack.
78
+ slice(0,at)+replacement+haystack.slice(at+needle.length)}import{spawn as spawn2}from"child_process";import path3 from"path";var GIT_TIMEOUT_MS=6e4;var MAX_GIT_OUTPUT_BYTES=1e5;var READ_ONLY_SUBCOMMANDS=["blame","branch","describe","diff","log","ls-files","rev-parse","shortlog","show","status","tag"];var DENIED_ARGS=new Set(["--no-index","-c","--config-env","--upload-pack","--receive-pack","--exec","--output"]);var LIST_ONLY_SUBCOMMANDS=new Set(["branch","tag"]);var gitTool={name:"git",domain:"local",risk:"exec",description:`Run a read-only git command. Allowed subcommands: ${READ_ONLY_SUBCOMMANDS.join(", ")}. Writing\
79
+ operations (commit, push, checkout, add, ...) are not available here \u2014 use bash for those, which goes through the permission prompt.`,inputSchema:{type:"object",additionalProperties:false,properties:{subcommand:{type:"string",description:'The git subcommand, e.g. "log"',enum:[...READ_ONLY_SUBCOMMANDS]},args:{type:"array",description:'Arguments, e.g. ["--oneline", "-20"]. Each element is passed as a separate argv entry.',items:{type:"string"}}},required:["subcommand"]},preview(input){const args=Array.
80
+ isArray(input["args"])?input["args"].map(String):[];return`git \xB7 ${String(input["subcommand"]??"")} ${args.join(" ")}`.trim()},async run(input,ctx){const sub=String(input["subcommand"]);if(!READ_ONLY_SUBCOMMANDS.includes(sub)){return{content:`git ${sub} is not available (read-only subcommands only: ${READ_ONLY_SUBCOMMANDS.join(", ")}). Use bash for write operations.`,isError:true}}const args=Array.isArray(input["args"])?input["args"].map(String):[];for(const arg of args){const head=arg.split(
81
+ "=")[0]??arg;if(DENIED_ARGS.has(head)){return{content:`Argument ${arg} is not allowed for the git tool.`,isError:true}}}const argv=LIST_ONLY_SUBCOMMANDS.has(sub)?[sub,"--list",...args]:[sub,...args];const env=ctx.env??process.env;const exe=resolveGitExecutable({env});if(exe===null){return{content:'git executable was not found on PATH. On Windows the git tool resolves the executable to an absolute path from PATH (it never runs a bare "git", because Windows searches the current directory before PA\
82
+ TH). Install Git for Windows or add its bin directory to PATH.',isError:true,summary:"git \xB7 \u5B9F\u884C\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093"}}return runGit(exe,argv,ctx.cwd,env,ctx.signal)}};function resolveGitExecutable(deps={}){const platform=deps.platform??process.platform;if(platform!=="win32")return"git";const env=deps.env??process.env;const common={platform,...deps.isExecutableFile!==void 0?{isExecutableFile:deps.isExecutableFile}:{}};const spawnable=findExecutable(
83
+ "git",{...common,env:{...env,PATHEXT:".EXE;.COM"}});return spawnable??findExecutable("git",{...common,env})}function runGit(exe,argv,cwd,baseEnv,signal){return new Promise(resolve5=>{let child;try{child=spawn2(exe,["--no-pager",...argv],{cwd,shell:false,env:{...baseEnv,GIT_PAGER:"cat",PAGER:"cat",GIT_TERMINAL_PROMPT:"0",GIT_EDITOR:"true",EDITOR:"true"},detached:process.platform!=="win32",stdio:["ignore","pipe","pipe"]})}catch(e){const err=e;const name=path3.basename(exe);resolve5({content:err.code===
84
+ "EINVAL"?`Failed to start git: the resolved executable (${name}) is a .cmd/.bat shim, which Node refuses to spawn without a shell. Install Git for Windows (which provides git.exe) or put its bin directory earlier on PATH.`:`Failed to start git (${name}): ${err.code??"unknown error"}`,isError:true,summary:"git \xB7 \u8D77\u52D5\u3067\u304D\u307E\u305B\u3093"});return}const chunks=[];let bytes=0;const collect=buf=>{chunks.push(buf);bytes+=buf.length;while(bytes-(chunks[0]?.length??0)>MAX_GIT_OUTPUT_BYTES*
85
+ 2&&chunks.length>1){const dropped=chunks.shift();if(!dropped)break;bytes-=dropped.length}};child.stdout?.on("data",collect);child.stderr?.on("data",collect);let timedOut=false;const timer=setTimeout(()=>{timedOut=true;killProcessTree(child,"SIGKILL")},GIT_TIMEOUT_MS);const onAbort=()=>{killProcessTree(child,"SIGKILL")};if(signal){if(signal.aborted)onAbort();else signal.addEventListener("abort",onAbort,{once:true})}const finish=(code,err)=>{clearTimeout(timer);signal?.removeEventListener("abort",
86
+ onAbort);const kept=keepTailBytes(Buffer.concat(chunks),MAX_GIT_OUTPUT_BYTES);const body=kept.text;const note=kept.droppedBytes>0?`
87
+ [output truncated: dropped the first ${kept.droppedBytes} bytes]`:"";if(err){resolve5({content:`Failed to run git (${path3.basename(exe)}): ${err.code??err.message}`,isError:true,summary:"git \xB7 \u8D77\u52D5\u3067\u304D\u307E\u305B\u3093"});return}if(timedOut){resolve5({content:`${body}${note}
88
+ [timed out after ${GIT_TIMEOUT_MS}ms]`,isError:true,summary:"git \xB7 \u30BF\u30A4\u30E0\u30A2\u30A6\u30C8"});return}resolve5({content:body===""?`(no output, exit code ${code??0})`:`${body}${note}`,...code!==0?{isError:true}:{},summary:`git ${argv[0]??""} \xB7 exit ${code??0}`})};child.on("error",e=>finish(null,e));child.on("close",code=>finish(code))})}import{glob}from"fs/promises";import{resolve as resolve3}from"path";var MAX_GLOB_RESULTS=500;var DEFAULT_EXCLUDES=["**/node_modules/**","**/.git/**","**/dist/**","**/.next/**","**/vendor/**"];var globTool={name:"glob",domain:"local",risk:"read",description:'Find files by glob pattern (e.g. "src/**/*.ts"). Returns paths relative to the working directory, sorted. node_modules, .git, dist, .next and vendor are excluded by default.',inputSchema:{type:"object",additionalProperties:false,properties:{pattern:{type:"string",description:'Glob pattern, e.g. "**/*.test.ts"'},
89
+ path:{type:"string",description:"Directory to search in (default: the working directory)"},include_ignored:{type:"boolean",description:"Include node_modules / dist / vendor etc.",default:false}},required:["pattern"]},preview(input){return`glob \xB7 ${String(input["pattern"]??"")}`},async run(input,ctx){const root=input["path"]===void 0?resolve3(ctx.cwd):resolveToolPath(String(input["path"]),ctx.cwd);const pattern=String(input["pattern"]);const exclude=input["include_ignored"]===true?[]:DEFAULT_EXCLUDES;
90
+ const found=[];let hardStop=false;let skipped=0;try{for await(const entry of glob(pattern,{cwd:root,exclude})){const abs=resolve3(root,typeof entry==="string"?entry:String(entry));if(!isInsideCwd(abs,ctx.cwd)||secretReason(abs)!==null){skipped+=1;continue}found.push(abs);if(found.length>=MAX_GLOB_RESULTS*4){hardStop=true;break}}}catch(err){return{content:`glob failed: ${err.message}`,isError:true}}const sorted=found.map(abs=>toolRelative(ctx.cwd,abs)).sort();const shown=sorted.slice(0,MAX_GLOB_RESULTS);
91
+ const note=hardStop?`
92
+ [stopped scanning after ${found.length} matches \u2014 there may be many more. Narrow the pattern.]`:sorted.length>shown.length?`
93
+ [${sorted.length-shown.length} more matches not shown \u2014 narrow the pattern]`:"";const denied=skipped>0?`
94
+ [${skipped} path(s) outside the working directory or denied were omitted]`:"";return{content:shown.length===0?`No files matched ${pattern}${denied}`:shown.join("\n")+note+denied,summary:`glob \xB7 ${pattern} \u2192 ${shown.length}\u4EF6`}}};import{glob as glob2}from"fs/promises";import{readFile as readFile2}from"fs/promises";import{resolve as resolve4}from"path";var MAX_GREP_MATCHES=200;var MAX_GREP_RESULTS_LIMIT=2e3;var MAX_LINE_LENGTH=2e4;var GREP_DEADLINE_MS=2e4;var MAX_FILE_BYTES2=2e6;var DEFAULT_EXCLUDES2=["**/node_modules/**","**/.git/**","**/dist/**","**/.next/**","**/vendor/**"];var grepTool={name:"grep",domain:"local",risk:"read",description:'Search file contents with a JavaScript regular expression. Returns "path:line: text" for each match. Use the glob parameter to limit which files are searched.',inputSchema:{type:"object",additionalProperties:false,
95
+ properties:{pattern:{type:"string",description:"JavaScript regular expression"},path:{type:"string",description:"Directory to search in (default: the working directory)"},glob:{type:"string",description:'Limit to files matching this glob, e.g. "**/*.ts"',default:"**/*"},ignore_case:{type:"boolean",description:"Case-insensitive match",default:false},max_results:{type:"integer",description:`Maximum matches (default ${MAX_GREP_MATCHES}, max ${MAX_GREP_RESULTS_LIMIT})`,minimum:1,maximum:MAX_GREP_RESULTS_LIMIT}},
96
+ required:["pattern"]},preview(input){return`grep \xB7 /${String(input["pattern"]??"")}/ ${String(input["glob"]??"")}`.trim()},async run(input,ctx){let re;try{re=new RegExp(String(input["pattern"]),input["ignore_case"]===true?"i":"")}catch(err){return{content:`Invalid regular expression: ${err.message}`,isError:true}}const root=input["path"]===void 0?resolve4(ctx.cwd):resolveToolPath(String(input["path"]),ctx.cwd);const filePattern=typeof input["glob"]==="string"?input["glob"]:"**/*";const limit=typeof input["\
97
+ max_results"]==="number"?Math.min(MAX_GREP_RESULTS_LIMIT,Math.max(1,Math.floor(input["max_results"]))):MAX_GREP_MATCHES;const matches=[];let scanned=0;let skipped=0;let longLines=0;let hitLimit=false;let timedOut=false;const deadline=Date.now()+GREP_DEADLINE_MS;const aborted=()=>ctx.signal?.aborted===true;try{for await(const entry of glob2(filePattern,{cwd:root,exclude:DEFAULT_EXCLUDES2})){if(aborted())break;const abs=resolve4(root,typeof entry==="string"?entry:String(entry));if(!isInsideCwd(abs,
98
+ ctx.cwd)||secretReason(abs)!==null){skipped+=1;continue}const buf=await readFile2(abs).catch(()=>null);if(buf===null||buf.length>MAX_FILE_BYTES2||buf.includes(0))continue;scanned+=1;const rel=toolRelative(ctx.cwd,abs);const lines=toLf(buf.toString("utf8")).split("\n");for(let i=0;i<lines.length;i++){if(aborted())break;if(Date.now()>deadline){timedOut=true;break}const line=lines[i]??"";if(line.length>MAX_LINE_LENGTH){longLines+=1;continue}if(!re.test(line))continue;matches.push(`${rel}:${i+1}: ${line.
99
+ slice(0,400)}`);if(matches.length>=limit){hitLimit=true;break}}if(hitLimit||timedOut||aborted())break}}catch(err){return{content:`grep failed: ${err.message}`,isError:true}}const notes=[hitLimit?`[stopped at ${limit} matches \u2014 narrow the pattern or the glob]`:"",timedOut?`[stopped after ${GREP_DEADLINE_MS}ms \u2014 narrow the glob]`:"",longLines>0?`[${longLines} line(s) longer than ${MAX_LINE_LENGTH} chars were not searched]`:"",skipped>0?`[${skipped} path(s) outside the working directory o\
100
+ r denied were omitted]`:""].filter(n=>n!=="");const suffix=notes.length>0?`
101
+ ${notes.join("\n")}`:"";return{content:matches.length===0?`No matches in ${scanned} files.${suffix}`:matches.join("\n")+suffix,summary:`grep \xB7 ${matches.length}\u4EF6 / ${scanned}\u30D5\u30A1\u30A4\u30EB`}}};import{readFile as readFile3,stat}from"fs/promises";var MAX_READ_BYTES=2e5;var DEFAULT_LIMIT_LINES=2e3;var readFileTool={name:"read_file",domain:"local",risk:"read",description:"Read a UTF-8 text file from the working directory. Returns the content with 1-based line numbers. Use offset/limit for large files. Binary files are not returned.",inputSchema:{type:"object",additionalProperties:false,properties:{path:{type:"string",description:"File path, relative to the working directory"},offset:{type:"integer",description:"1-based line to start from",
102
+ minimum:1},limit:{type:"integer",description:`Maximum lines to return (default ${DEFAULT_LIMIT_LINES})`,minimum:1}},required:["path"]},preview(input){return`read_file \xB7 ${String(input["path"]??"")}`},async run(input,ctx){const abs=resolveToolPath(String(input["path"]),ctx.cwd);const info=await stat(abs).catch(()=>null);if(info===null)return{content:`File not found: ${input["path"]}`,isError:true};if(info.isDirectory()){return{content:`${input["path"]} is a directory. Use glob to list its cont\
103
+ ents.`,isError:true}}const buf=await readFile3(abs);if(buf.includes(0)){return{content:`Binary file (${info.size} bytes) \u2014 not returned. Use bash if you need to inspect it.`,isError:true,summary:`read_file \xB7 ${toolRelative(ctx.cwd,abs)} (binary)`}}const raw=buf.toString("utf8");const eol=detectEol(raw);const lines=toLf(raw).split("\n");if(lines[lines.length-1]==="")lines.pop();const offset=typeof input["offset"]==="number"?input["offset"]:1;const limit=typeof input["limit"]==="number"?input["\
104
+ limit"]:DEFAULT_LIMIT_LINES;const slice=lines.slice(offset-1,offset-1+limit);let body=slice.map((line,i)=>`${offset+i} ${line}`).join("\n");let truncated=offset-1+slice.length<lines.length;const clipped=keepHeadBytes(body,MAX_READ_BYTES);body=clipped.text;if(clipped.truncated)truncated=true;const note=truncated?`
105
+
106
+ [truncated: file has ${lines.length} lines; re-read with offset/limit for the rest]`:"";if(body===""){const reason=lines.length===0?"(empty file)":`(no lines at offset ${offset}; the file has ${lines.length} lines)`;return{content:reason,summary:`read_file \xB7 ${toolRelative(ctx.cwd,abs)} (0 \u884C)`}}return{content:body+note,summary:`read_file \xB7 ${toolRelative(ctx.cwd,abs)} (${slice.length} \u884C${eol==="\r\n"?" \xB7 CRLF":""})`}}};import{mkdir,readFile as readFile4,writeFile as writeFile2}from"fs/promises";import{dirname as dirname3}from"path";var writeFileTool={name:"write_file",domain:"local",risk:"write",description:"Write the full content of a file, creating it (and parent directories) if needed. Overwrites the whole file \u2014 prefer edit_file for partial changes. The existing line ending style (LF/CRLF) is preserved.",inputSchema:{type:"object",additionalProperties:false,properties:{path:{type:"string",description:"File path, relative to the working directory"},content:{type:"string",description:"Full new content. Use \\n for li\
107
+ ne breaks."}},required:["path","content"]},preview(input){const content=typeof input["content"]==="string"?input["content"]:"";return`write_file \xB7 ${String(input["path"]??"")} (${content.split("\n").length} \u884C)`},async prepare(input,ctx){const abs=resolveToolPath(String(input["path"]),ctx.cwd);const before=await readFile4(abs,"utf8").catch(()=>"");return{path:toolRelative(ctx.cwd,abs),before,after:String(input["content"]??"")}},async run(input,ctx){const abs=resolveToolPath(String(input["\
108
+ path"]),ctx.cwd);const existing=await readFile4(abs,"utf8").catch(()=>null);const eol=existing===null?"\n":detectEol(existing);const body=applyEol(String(input["content"]),eol);await mkdir(dirname3(abs),{recursive:true});await writeFile2(abs,body,"utf8");const rel=toolRelative(ctx.cwd,abs);return{content:`Wrote ${rel} (${body.split(eol).length} lines${eol==="\r\n"?", CRLF preserved":""}).`,summary:`write_file \xB7 ${rel}`,diff:{path:rel,before:existing??"",after:String(input["content"])}}}};var RESIDENT_TOKEN_CAP=8e3;function localTools(choice=selectShell()){return[readFileTool,writeFileTool,editFileTool,createBashTool(choice),globTool,grepTool,gitTool]}function buildResidentSet(mode,opts={}){const all=opts.tools??localTools();const cap=opts.cap??RESIDENT_TOKEN_CAP;const eligible=all.filter(tool=>matchesAnyGlob(tool.name,mode.tools)&&applyPermissionMode(checkPermission(tool.name,mode),tool.risk,opts.permissionMode).decision!=="deny");const tools=[];const dropped=[];let tokens=0;for(const tool of eligible){const cost=estimateToolTokens(
109
+ tool);if(tokens+cost>cap){dropped.push(tool.name);continue}tools.push(tool);tokens+=cost}return{tools,wire:tools.map(toWireTool),tokens,dropped}}function estimateToolTokens(tool){return Math.ceil(JSON.stringify(toWireTool(tool)).length/4)}function matchesAnyGlob(name,patterns){return patterns.some(pattern=>globToRegExp(pattern).test(name))}function globToRegExp(pattern){const escaped=pattern.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");return new RegExp(`^${escaped}$`)}export{buildSystemPrompt,runTurn,createAuditLogger,currentBranch,displayCwd,RESIDENT_TOKEN_CAP,buildResidentSet};
@@ -0,0 +1,18 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import{createRequire}from"module";import fs from"fs";function readProxyEnv(env=process.env){const pick=(lower,upper)=>{for(const name of[lower,upper]){const raw=env[name];if(raw!==void 0&&raw.trim()!=="")return{value:raw.trim(),source:name}}return{value:null,source:null}};const https=pick("https_proxy","HTTPS_PROXY");const http=pick("http_proxy","HTTP_PROXY");const no=pick("no_proxy","NO_PROXY");return{httpsProxy:https.value,httpProxy:http.value,noProxy:no.value,sources:{httpsProxy:https.source,httpProxy:http.source,noProxy:no.source}}}var LOOPBACK_NO_PROXY=[
4
+ "localhost","127.0.0.1","::1"];function effectiveNoProxy(proxy){const given=(proxy.noProxy??"").split(",").map(e=>e.trim()).filter(e=>e!=="");const merged=[...given];for(const entry of LOOPBACK_NO_PROXY){if(!merged.some(e=>e.toLowerCase()===entry))merged.push(entry)}return merged.join(",")}function hasProxyConfig(env=process.env){const proxy=readProxyEnv(env);return proxy.httpsProxy!==null||proxy.httpProxy!==null}var PROXY_SCHEMES=["http:","https:","socks:","socks4:","socks4a:","socks5:","socks5\
5
+ h:"];function redactProxyUrl(raw){try{const url=new URL(raw);if(!PROXY_SCHEMES.includes(url.protocol))return"(\u89E3\u6790\u3067\u304D\u306A\u3044\u5024)";if(url.username!==""||url.password!==""){url.username="***";url.password=""}url.search="";url.hash="";return url.toString()}catch{return"(\u89E3\u6790\u3067\u304D\u306A\u3044\u5024)"}}var UNDICI_MIN_NODE="22.19.0";var activeAgent=null;var resolved=null;var resolving=null;async function resolveFetch(env){if(resolved!==null)return resolved;if(resolving!==null)return resolving;resolving=(async()=>{if(!hasProxyConfig(env)){return((input,init)=>globalThis.fetch(input,init))}const proxy=readProxyEnv(env);let undici;try{undici=await import("undici")}catch(err){const reason=err instanceof Error?err.message:String(err);throw new Error(`\u30D7\u30ED\u30AD\u30B7\u8A2D\u5B9A\uFF08${proxy.sources.httpsProxy??proxy.sources.httpProxy??"HTTP\
6
+ S_PROXY"}\uFF09\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u306E\u901A\u4FE1\u306B\u5FC5\u8981\u306A undici \u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F: ${reason}
7
+ undici \u306F Node ${UNDICI_MIN_NODE} \u4EE5\u4E0A\u3092\u8981\u6C42\u3057\u307E\u3059\uFF08\u73FE\u5728: ${process.versions.node}\uFF09\u3002\u53E4\u3044\u5834\u5408\u306F Node \u3092\u4E0A\u3052\u3066\u304F\u3060\u3055\u3044\u3002\u305D\u3046\u3067\u306A\u3051\u308C\u3070 npm i -g @tocca-systems/twp-cli@latest \u3067\u518D\u30A4\u30F3\u30B9\u30C8\u30FC\u30EB\u3057\u3066\u304F\u3060\u3055\u3044\u3002`,{cause:err})}let agent;try{agent=new undici.EnvHttpProxyAgent({...proxy.httpProxy!==null?{httpProxy:proxy.
8
+ httpProxy}:{},...proxy.httpsProxy!==null?{httpsProxy:proxy.httpsProxy}:{},noProxy:effectiveNoProxy(proxy)});activeAgent=agent}catch(err){const reason=err instanceof Error?err.message:String(err);const name=proxy.sources.httpsProxy??proxy.sources.httpProxy??"HTTPS_PROXY";throw new Error(`\u30D7\u30ED\u30AD\u30B7\u8A2D\u5B9A ${name} \u306E\u5024\u3092\u30D7\u30ED\u30AD\u30B7 URL \u3068\u3057\u3066\u89E3\u91C8\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${reason}
9
+ http://\u30DB\u30B9\u30C8:\u30DD\u30FC\u30C8 \u306E\u5F62\uFF08scheme \u304B\u3089\uFF09\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u5024\u306F twp --doctor \u3067\u78BA\u8A8D\u3067\u304D\u307E\u3059\u3002`,{cause:err})}return(input,init)=>undici.fetch(input,{...init??{},dispatcher:agent})})();try{resolved=await resolving;return resolved}finally{resolving=null}}var httpFetch=async(input,init)=>(await resolveFetch(process.env))(input,init);var MAX_CA_BYTES=1024*1024;function defaultCanLoadUndici(){
10
+ try{createRequire(import.meta.url).resolve("undici");return true}catch{return false}}function proxyDiagnostics(env=process.env,deps={}){const proxy=readProxyEnv(env);const lines=[];const proxied=proxy.httpsProxy!==null||proxy.httpProxy!==null;const clean=text=>stripTerminalControls(text);const proxyLine=(label,value,source)=>{if(value===null)return{label,value:"(\u672A\u8A2D\u5B9A)"};const shown=redactProxyUrl(value);const line={label:clean(source??label),value:clean(shown)};if(shown==="(\u89E3\u6790\u3067\u304D\u306A\u3044\u5024\
11
+ )"){line.value="(\u89E3\u6790\u3067\u304D\u306A\u3044\u5024 \u2014 http://\u30DB\u30B9\u30C8:\u30DD\u30FC\u30C8 \u306E\u5F62\u3067\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044)";line.warn=true}return line};lines.push(proxyLine("HTTPS_PROXY",proxy.httpsProxy,proxy.sources.httpsProxy));lines.push(proxyLine("HTTP_PROXY",proxy.httpProxy,proxy.sources.httpProxy));lines.push({label:clean(proxy.sources.noProxy??"NO_PROXY"),value:proxy.noProxy!==null?clean(proxy.noProxy):"(\u672A\u8A2D\u5B9A)"});lines.
12
+ push({label:"NO_PROXY\uFF08\u5B9F\u52B9\uFF09",value:clean(effectiveNoProxy(proxy))});const canLoadUndici=(deps.canLoadUndici??defaultCanLoadUndici)();if(proxied){lines.push(canLoadUndici?{label:"\u3053\u306E CLI \u306E\u7D4C\u8DEF",value:"undici EnvHttpProxyAgent \u7D4C\u7531"}:{label:"\u3053\u306E CLI \u306E\u7D4C\u8DEF",value:`undici \u3092\u8AAD\u307F\u8FBC\u3081\u306A\u3044\uFF08Node ${UNDICI_MIN_NODE} \u4EE5\u4E0A\u304C\u5FC5\u8981\u30FB\u73FE\u5728 ${deps.nodeVersion??process.versions.node}\
13
+ \uFF09\u3002\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u306E\u901A\u4FE1\u306F\u5931\u6557\u3057\u307E\u3059`,warn:true});if(proxy.httpsProxy===null&&proxy.httpProxy!==null){lines.push({label:"https \u306E\u5B9B\u5148",value:`${proxy.sources.httpProxy} \u3092\u4F7F\u3046\uFF08HTTPS_PROXY \u672A\u8A2D\u5B9A\u306E\u305F\u3081\uFF09`})}}else{lines.push({label:"\u3053\u306E CLI \u306E\u7D4C\u8DEF",value:"\u7D20\u306E fetch\uFF08\u76F4\u7D50\uFF09"})}const caPath=env["NODE_EXTRA_CA_CERTS"]?.trim();if(caPath===
14
+ void 0||caPath===""){lines.push({label:"NODE_EXTRA_CA_CERTS",value:"(\u672A\u8A2D\u5B9A)",...proxied?{warn:true}:{}})}else{const readFile=deps.readFile??(p=>fs.readFileSync(p,"utf8"));const statFile=deps.statFile??(p=>{const st=fs.statSync(p);return{isFile:st.isFile(),size:st.size}});try{const st=statFile(caPath);if(!st.isFile){lines.push({label:"NODE_EXTRA_CA_CERTS",value:`${clean(caPath)}\uFF08\u901A\u5E38\u30D5\u30A1\u30A4\u30EB\u3067\u306F\u306A\u3044\uFF09`,warn:true})}else if(st.size>MAX_CA_BYTES){
15
+ lines.push({label:"NODE_EXTRA_CA_CERTS",value:`${clean(caPath)}\uFF08${Math.round(st.size/1024)}KB \u2014 \u5927\u304D\u3059\u304E\u308B\u305F\u3081\u4EF6\u6570\u3092\u6570\u3048\u3066\u3044\u306A\u3044\uFF09`})}else{const pem=readFile(caPath);const count=(pem.match(/-----BEGIN CERTIFICATE-----/g)??[]).length;lines.push({label:"NODE_EXTRA_CA_CERTS",value:count>0?`${clean(caPath)}\uFF08\u8A3C\u660E\u66F8 ${count} \u4EF6\uFF09`:`${clean(caPath)}\uFF08\u8A3C\u660E\u66F8\u304C\u898B\u3064\u304B\u3089\u306A\u3044\uFF09`,
16
+ ...count>0?{}:{warn:true}})}}catch(err){lines.push({label:"NODE_EXTRA_CA_CERTS",value:clean(`${caPath}\uFF08\u8AAD\u3081\u306A\u3044: ${err instanceof Error?err.message:String(err)}\uFF09`),warn:true})}}const execArgv=deps.execArgv??process.execArgv;const nodeVersion=deps.nodeVersion??process.versions.node;const builtinRequested=execArgv.includes("--use-env-proxy")||(env["NODE_OPTIONS"]??"").includes("--use-env-proxy")||(env["NODE_USE_ENV_PROXY"]?.trim()??"")!=="";if(builtinRequested){const major=Number(
17
+ nodeVersion.split(".")[0]);lines.push({label:"Node \u7D44\u8FBC\u307F\u30D7\u30ED\u30AD\u30B7",value:major>=24?`\u6709\u52B9\uFF08Node ${nodeVersion}\uFF09\u3002\u3053\u306E CLI \u306F undici \u7D4C\u7531\u306A\u306E\u3067\u4E8C\u91CD\u306B\u306F\u901A\u3089\u306A\u3044`:`\u6307\u5B9A\u3055\u308C\u3066\u3044\u308B\u304C Node ${nodeVersion} \u3067\u306F\u52B9\u304B\u306A\u3044\uFF0824 \u4EE5\u4E0A\u304C\u5FC5\u8981\uFF09\u3002\u3053\u306E CLI \u306F undici \u7D4C\u7531\u3067\u901A\u3059`,...major>=
18
+ 24?{}:{warn:true}})}return lines}export{httpFetch,proxyDiagnostics};