@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,58 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{isPrivateProjectId}from"./chunk-GY7KI5E5.js";import{httpFetch}from"./chunk-J7QYPKVK.js";function describeError(res){if(res.status===null)return`transport_error=${res.transportError??"\u4E0D\u660E"}`;const body=res.json;const parts=[`http=${res.status}`];const reason=typeof body?.["reason"]==="string"?body["reason"]:"";if(reason)parts.push(`reason=${reason}`);const error=body?.["error"];const code=typeof error?.["code"]==="string"?error["code"]:"";if(code)parts.push(`code=${code}`);const message=(typeof body?.["message"]==="string"?body["message"]:"")||(typeof error?.["message"]==="\
4
+ string"?error["message"]:"");if(message)parts.push(message.slice(0,160));if(!reason&&!code&&!message)parts.push(`\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,160)}`);return parts.join(" ")}function isPermanent(res){return res.status!==null&&res.status>=400&&res.status<500}function filterByStatus(items,status){return items.filter(item=>item.status===void 0||item.status===status)}var AgentLoopApi=class{constructor(opts){this.opts=opts;const root=opts.apiUrl.replace(/\/+$/,"");this.base=isPrivateProjectId(
5
+ opts.projectId)?`${root}/api/v2/tasks/private/agent-loop`:`${root}/api/v2/projects/${opts.projectId}/agent-loop`}opts;base;get baseUrl(){return this.base}list(query){const qs=new URLSearchParams;for(const[k,v]of Object.entries(query)){if(v!==void 0&&v!=="")qs.set(k,String(v))}const suffix=qs.toString()?`?${qs.toString()}`:"";return this.request("GET",suffix)}create(body){return this.request("POST","",body)}getItem(itemId){return this.request("GET",`/${encodeURIComponent(itemId)}`)}update(itemId,body,runId){
6
+ return this.request("PUT",`/${encodeURIComponent(itemId)}`,{...body,run_id:runId})}updateUnowned(itemId,body){return this.request("PUT",`/${encodeURIComponent(itemId)}`,body)}reorder(itemIds){return this.request("PUT","/reorder",{item_ids:itemIds})}claim(runnerId,runId){return this.request("POST","/claim",{runner_id:runnerId,run_id:runId})}reclaim(){return this.request("POST","/reclaim",{})}runners(){return this.request("GET","/runners")}registerRunner(payload){return this.request("POST","/runne\
7
+ rs/register",payload)}heartbeatRunner(payload){return this.request("POST","/runners/heartbeat",payload)}deregisterRunner(payload){return this.request("POST","/runners/deregister",payload)}planStart(runnerId,runId){return this.request("POST","/plan/start",{runner_id:runnerId,run_id:runId})}planFinish(runnerId,runId,planStartedAt,result){return this.request("POST","/plan/finish",{runner_id:runnerId,run_id:runId,plan_started_at:planStartedAt,result})}consumeCounter(key,date,limit){return this.request(
8
+ "POST","/counters/consume",{key,date,limit})}async queuedSnapshot(){return this.snapshotOf(["pending","processing"])}async processingSnapshot(){return this.snapshotOf(["processing"])}async pendingSnapshot(){return this.snapshotOf(["pending"])}async completedSince(sinceMicros,maxPages=10){const all=[];let cursor=String(Math.trunc(sinceMicros));for(let page=0;page<maxPages;page++){const res=await this.list({status:"completed",limit:100,cursor});if(!res.ok)return null;const body=res.json;const items=body?.["\
9
+ items"];if(!Array.isArray(items))return null;all.push(...filterByStatus(items,"completed"));const pagination=body?.["pagination"];const hasMore=(pagination?.["has_more"]??body?.["has_more"])===true;const next=pagination?.["next_cursor"]??body?.["next_cursor"];if(!hasMore||!next)return all;cursor=next}return null}async snapshotOf(statuses){const all=[];for(const status of statuses){let cursor;for(let page=0;page<20;page++){const res=await this.list({status,limit:100,cursor});if(!res.ok)return null;
10
+ const body=res.json;const items=body?.["items"];if(!Array.isArray(items))return null;all.push(...filterByStatus(items,status));const pagination=body?.["pagination"];const hasMore=(pagination?.["has_more"]??body?.["has_more"])===true;const next=pagination?.["next_cursor"]??body?.["next_cursor"];if(!hasMore||!next)break;cursor=next;if(page===19)return null}}return all}async request(method,suffix,body){let token;try{token=await this.opts.session.getAccessToken()}catch(err){return{ok:false,status:null,
11
+ json:null,raw:"",transportError:err.message}}let res=await this.send(method,suffix,token,body);if(res.status===401){try{token=await this.opts.session.refresh(token);res=await this.send(method,suffix,token,body)}catch(err){return{ok:false,status:401,json:null,raw:res.raw,transportError:err.message}}}return res}async send(method,suffix,token,body){const fetchImpl=this.opts.fetchImpl??httpFetch;const controller=new AbortController;const timer=setTimeout(()=>controller.abort(),this.opts.timeoutMs??6e4);
12
+ try{const res=await fetchImpl(`${this.base}${suffix}`,{method,headers:{Authorization:`Bearer ${token}`,"Content-Type":"application/json",Accept:"application/json"},signal:controller.signal,...body===void 0?{}:{body:JSON.stringify(body)}});const raw=await res.text();let json=null;if(raw.trim()!==""){try{json=JSON.parse(raw)}catch{json=null}}return{ok:res.ok,status:res.status,json,raw,transportError:null}}catch(err){const reason=err.name==="AbortError"?"timeout":err.message;return{ok:false,status:null,
13
+ json:null,raw:"",transportError:reason}}finally{clearTimeout(timer)}}};function pick(json,path){let cur=json;for(const part of path.split(".")){if(cur===null||typeof cur!=="object")return void 0;cur=cur[part]}return cur===null?void 0:cur}function pickString(json,path){const v=pick(json,path);if(typeof v==="string")return v;if(typeof v==="number")return String(v);if(typeof v==="boolean")return v?"true":"false";return""}var ScheduleApi=class{constructor(api){this.api=api}api;async definitions(){const res=await this.api.request("GET","/schedules/definitions");if(!res.ok)return fetchError("\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u5B9A\u7FA9\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093",res);const body=res.json??{};const schedules=body["schedules"];if(!Array.isArray(schedules)){return{kind:"error",message:`\u5B9A\u7FA9\u306E\u5FDC\u7B54\u306B schedules \u914D\u5217\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u5FDC\u7B54\u306E\u5148\u982D: ${res.
14
+ raw.slice(0,120)}\uFF09`,status:res.status}}const gates=Array.isArray(body["gates"])?body["gates"]:[];return{kind:"ok",config:{schedules,gates,max_per_cycle:body["max_per_cycle"],warnings:Array.isArray(body["warnings"])?body["warnings"]:[]}}}async history(since){const suffix=since?`/schedules/history?since=${encodeURIComponent(since)}`:"/schedules/history";const res=await this.api.request("GET",suffix);if(!res.ok)return fetchError("\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u5C65\u6B74\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093",
15
+ res);const body=res.json??{};const rows=body["rows"];if(!Array.isArray(rows)){return{kind:"error",message:`\u5C65\u6B74\u306E\u5FDC\u7B54\u306B rows \u914D\u5217\u304C\u3042\u308A\u307E\u305B\u3093\uFF08\u5FDC\u7B54\u306E\u5148\u982D: ${res.raw.slice(0,120)}\uFF09`,status:res.status}}if(body["truncated"]===true||body["reason"]==="history_truncated"){return{kind:"error",message:"\u5C65\u6B74\u306E\u8D70\u67FB\u304C\u6253\u3061\u5207\u3089\u308C\u307E\u3057\u305F\uFF08\u5224\u5B9A\u306B\u4F7F\u3048\u307E\u305B\u3093\uFF09",
16
+ status:res.status}}const windowCounts={};const counts=body["window_counts"];if(counts&&typeof counts==="object"){for(const[k,v]of Object.entries(counts)){if(typeof v==="number"){if(Number.isInteger(v))windowCounts[k]=v}else if(/^-?\d+$/.test(String(v))){windowCounts[k]=Number(String(v))}}}const normalized=rows.map(r=>{const row=r??{};return{ts:str(row["ts"]),schedule_id:str(row["schedule_id"]),window_key:str(row["window_key"]),status:str(row["status"]),item_id:str(row["item_id"]),args:str(row["a\
17
+ rgs"])}});return{kind:"ok",history:{rows:normalized,windowCounts,timezone:str(body["timezone"])}}}async claim(scheduleId,body){const res=await this.api.request("POST",`/schedules/${encodeURIComponent(scheduleId)}/claim`,{window_key:body.windowKey,runner_id:body.runnerId,run_id:body.runId,args:body.args});if(!res.ok)return"error";const claimed=res.json?.["claimed"];return claimed===true?"claimed":"taken"}async record(scheduleId,body){const payload={status:body.status};if(body.windowKey)payload["w\
18
+ indow_key"]=body.windowKey;if(body.itemId)payload["item_id"]=body.itemId;if(body.runnerId)payload["runner_id"]=body.runnerId;const res=await this.api.request("POST",`/schedules/${encodeURIComponent(scheduleId)}/record`,payload);if(!res.ok)return{ok:false,detail:describeError(res)};const json=res.json??{};if(json["recorded"]===false&&json["reason"]!=="already_recorded"){return{ok:false,detail:`reason=${str(json["reason"])||"unknown"}`}}return{ok:true,detail:""}}async recordByItem(itemId,status,runnerId){
19
+ const payload={status,item_id:itemId};if(runnerId)payload["runner_id"]=runnerId;const res=await this.api.request("POST","/schedules/record",payload);if(!res.ok)return fetchError("\u5B9F\u884C\u7D50\u679C\u3092\u8A18\u9332\u3067\u304D\u307E\u305B\u3093",res);const json=res.json??{};if(json["recorded"]===true){const state=json["state"]??{};return{kind:"recorded",scheduleId:str(state["schedule_id"])}}if(json["reason"]==="state_not_found")return{kind:"not_scheduled"};return{kind:"error",message:`\u8A18\u9332\u3067\
20
+ \u304D\u307E\u305B\u3093\u3067\u3057\u305F\uFF08reason=${str(json["reason"])||"unknown"}\uFF09`,status:res.status}}};function fetchError(prefix,res){return{kind:"error",message:`${prefix}\uFF08${describeError(res)}\uFF09`,status:res.status}}function str(v){if(v===null||v===void 0)return"";return typeof v==="string"?v:String(v)}var DAY_KEYS=["mon","tue","wed","thu","fri","sat","sun"];function wallClock(year,month1,day,hour=0,minute=0,second=0){return new Date(Date.UTC(year,month1-1,day,hour,minute,second,0))}function nowInZone(timezone,warn,at=new Date){try{const fmt=new Intl.DateTimeFormat("en-US",{timeZone:timezone,hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"});const parts={};for(const p of fmt.formatToParts(at)){if(p.type!=="literal")parts[p.type]=p.value}
21
+ const y=Number(parts["year"]);const mo=Number(parts["month"]);const d=Number(parts["day"]);const h=Number(parts["hour"]);const mi=Number(parts["minute"]);const s=Number(parts["second"]);if([y,mo,d,h,mi,s].some(v=>!Number.isFinite(v)))throw new Error("\u5F62\u5F0F\u4E0D\u660E");return wallClock(y,mo,d,h,mi,s)}catch(err){warn?.(`\u26A0\uFE0F \u30BF\u30A4\u30E0\u30BE\u30FC\u30F3 ${timezone} \u3092\u89E3\u6C7A\u3067\u304D\u307E\u305B\u3093\uFF08${err.message}\uFF09\u3002\u30DE\u30B7\u30F3\u306E\u30ED\u30FC\u30AB\u30EB\u6642\u523B\u3067\u5224\u5B9A\u3057\u307E\u3059\u2014\u2014\u30B5\u30FC\u30D0\u306E\u5C65\u6B74\u3068\u305A\u308C\u308B\u3068\u67A0\u306E\u5224\u5B9A\u304C\u58CA\u308C\u307E\u3059`);
22
+ return wallClock(at.getFullYear(),at.getMonth()+1,at.getDate(),at.getHours(),at.getMinutes(),at.getSeconds())}}function parseTs(value){if(value===null||value===void 0||value==="")return null;const text=String(value).trim().replace(/ /g,"T");const attempts=[[19,/^(\d{4})-(\d{1,2})-(\d{1,2})T(\d{1,2}):(\d{1,2}):(\d{1,2})$/],[16,/^(\d{4})-(\d{1,2})-(\d{1,2})T(\d{1,2}):(\d{1,2})$/],[10,/^(\d{4})-(\d{1,2})-(\d{1,2})$/]];for(const[width,re]of attempts){const m=re.exec(text.slice(0,width));if(!m)continue;
23
+ const[,y,mo,d,h,mi,s]=m;const hh=Number(h??0);const mm=Number(mi??0);const ss=Number(s??0);if(hh>23||mm>59||ss>59)continue;const date=wallClock(Number(y),Number(mo),Number(d),hh,mm,ss);if(date.getUTCFullYear()!==Number(y)||date.getUTCMonth()+1!==Number(mo)||date.getUTCDate()!==Number(d)){continue}return date}return null}function num(value,fallback,cast="int"){if(value===null||value===void 0||value==="")return fallback;if(typeof value==="boolean")return value?1:0;if(typeof value==="number"){if(!Number.
24
+ isFinite(value))return cast==="float"?value:fallback;return cast==="int"?Math.trunc(value):value}if(typeof value!=="string")return fallback;const text=value.trim();if(cast==="int"){return/^[+-]?\d+$/.test(text)?Number(text):fallback}if(!/^[+-]?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i.test(text))return fallback;const n=Number(text);return Number.isFinite(n)?n:fallback}function parseHhmm(value,fallback=[0,0]){if(value===null||value===void 0||value===""||value===0||value===false){return fallback}const parts=String(
25
+ value).split(":");const h=parts[0]===void 0?NaN:intOrNaN(parts[0]);if(Number.isNaN(h))return fallback;if(parts.length<=1)return[h,0];const m=intOrNaN(parts[1]??"");if(Number.isNaN(m))return fallback;return[h,m]}function intOrNaN(text){const t=text.trim();return/^[+-]?\d+$/.test(t)?Number(t):NaN}function atTime(day,hhmm){const base=Date.UTC(day.getUTCFullYear(),day.getUTCMonth(),day.getUTCDate(),0,0,0,0);return new Date(base+hhmm[0]*36e5+hhmm[1]*6e4)}function addDays(day,days){return new Date(day.
26
+ getTime()+days*864e5)}function addHours(day,hours){return new Date(day.getTime()+hours*36e5)}function normDays(days){const out=[];if(!Array.isArray(days))return out;for(const d of days){const k=String(d).trim().toLowerCase().slice(0,3);if(DAY_KEYS.includes(k))out.push(k)}return out}function dowKey(dt){const idx=(dt.getUTCDay()+6)%7;return DAY_KEYS[idx]}function daysInMonth(year,month1){return new Date(Date.UTC(year,month1,0)).getUTCDate()}function monthDay(year,month1,daySpec){const last=daysInMonth(
27
+ year,month1);if(String(daySpec).toLowerCase()==="last")return last;const parsed=typeof daySpec==="number"?Math.trunc(daySpec):intOrNaN(String(daySpec??""));const d=Number.isNaN(parsed)?1:parsed;return Math.min(Math.max(d,1),last)}function prevMonth(year,month1){return month1===1?[year-1,12]:[year,month1-1]}function nextMonth(year,month1){return month1===12?[year+1,1]:[year,month1+1]}function priorityRank(p){const text=String(p??"").replace(/^[Pp]+/,"");const body=text===""?"2":text;return num(body,
28
+ 2,"float")}var p2=n=>String(n).padStart(2,"0");function fmtDate(d){return`${d.getUTCFullYear()}-${p2(d.getUTCMonth()+1)}-${p2(d.getUTCDate())}`}function fmtMonth(d){return`${d.getUTCFullYear()}-${p2(d.getUTCMonth()+1)}`}function fmtDateHour(d){return`${fmtDate(d)}T${p2(d.getUTCHours())}`}function fmtMonthDayTime(d){return`${p2(d.getUTCMonth()+1)}/${p2(d.getUTCDate())} ${p2(d.getUTCHours())}:${p2(d.getUTCMinutes())}`}var ACTIVE_STATUSES=["enqueued","completed"];function isActiveStatus(status){return ACTIVE_STATUSES.includes(status)}function flag(obj,key,fallback){if(!(key in obj))return fallback;const v=obj[key];if(v===null||v===void 0)return false;if(typeof v==="string")return v!=="";if(typeof v==="number")return v!==0;if(Array.isArray(v))return v.length>0;return Boolean(v)}function gateWindowsMatch(win,now){const days=normDays(win.days);if(days.length>0&&!days.includes(dowKey(now)))return false;const frm=win.from;const to=win.to;if(!frm&&!to)return true;const[fh,fm]=parseHhmm(frm,[0,0]);const[th,tm]=parseHhmm(to,[24,0]);const cur=now.getUTCHours()*60+now.getUTCMinutes();const start=fh*60+fm;const end=th*60+tm;if(end<=start)return cur>=start||cur<end;return start<=cur&&cur<end}function applicableGates(skill,gates){const out=[];for(const g of gates??[]){if(!flag(g,"\
29
+ enabled",true))continue;const skills=g.skills??[];if(skills.includes("*")||skills.includes(skill))out.push(g)}return out}function gateStatus(skill,now,gates){const applied=applicableGates(skill,gates);if(applied.length===0)return{allowed:true,reason:""};for(const g of applied){for(const win of g.deny??[]){if(gateWindowsMatch(win,now)){return{allowed:false,reason:`${g.id??"gate"}: \u9664\u5916\u6642\u9593\u5E2F\u306B\u8A72\u5F53\uFF08${describeWindow(win)}\uFF09`}}}}const allowSpecs=[];for(const g of applied){
30
+ for(const win of g.allow??[])allowSpecs.push([g,win])}if(allowSpecs.length===0)return{allowed:true,reason:""};for(const[,win]of allowSpecs){if(gateWindowsMatch(win,now))return{allowed:true,reason:""}}const descs=allowSpecs.map(([,w])=>describeWindow(w)).join(", ");const gateIds=[...new Set(allowSpecs.map(([g])=>g.id??"gate"))].sort().join("/");return{allowed:false,reason:`${gateIds}: \u8A31\u53EF\u6642\u9593\u5E2F\u5916\uFF08\u8A31\u53EF=${descs}\uFF09`}}function describeWindow(win){const days=normDays(
31
+ win.days);const d=days.length>0?days.join("/"):"\u5168\u66DC\u65E5";const frm=win.from||"00:00";const to=win.to||"24:00";return`${d} ${frm}-${to}`}function gatedSkills(config,now){const gates=config.gates??[];const skills=[];for(const g of gates){if(!flag(g,"enabled",true))continue;for(const s of g.skills??[]){if(!skills.includes(s))skills.push(s)}}const out=[];for(const s of skills){const{allowed,reason}=gateStatus(s,now,gates);if(!allowed)out.push([s,reason])}return out}function currentWindow(sch,now,warn){const when=sch.when??{};const wtype=String(when.type??"daily").toLowerCase();const after=parseHhmm(when.after,[0,0]);if(wtype==="daily"){const ws=atTime(now,after);if(now.getTime()<ws.getTime())return{key:null,start:null};return{key:`d:${fmtDate(ws)}`,start:ws}}if(wtype==="weekly"){const days=normDays(when.days);const targets=days.length>0?days:["mon"];let best=null;for(let back=0;back<8;back++){const day=addDays(now,-back);if(!targets.includes(dowKey(day)))continue;
32
+ const ws=atTime(day,after);if(ws.getTime()<=now.getTime()){best=ws;break}}if(best===null)return{key:null,start:null};return{key:`w:${fmtDate(best)}`,start:best}}if(wtype==="monthly"){let y=now.getUTCFullYear();let m=now.getUTCMonth()+1;let d=monthDay(y,m,when.day??1);let ws=atTime(wallClock(y,m,d),after);if(now.getTime()<ws.getTime()){[y,m]=prevMonth(y,m);d=monthDay(y,m,when.day??1);ws=atTime(wallClock(y,m,d),after)}return{key:`m:${fmtMonth(ws)}`,start:ws}}if(wtype==="interval"){return{key:`i:${fmtDateHour(
33
+ now)}`,start:now}}warn?.(`# \u672A\u77E5\u306E when.type=${formatRepr(when.type)}\uFF08id=${sch.id??"None"}\uFF09\u3002\u3053\u306E\u67A0\u306F\u4E00\u5EA6\u3082\u767A\u706B\u3057\u307E\u305B\u3093\u3002\u6709\u52B9\u306A\u5024: daily / weekly / monthly / interval`);return{key:null,start:null}}function pyStr(value){if(value===void 0||value===null)return"None";if(typeof value==="boolean")return value?"True":"False";return String(value)}function formatRepr(value){if(value===void 0||value===null)return"\
34
+ None";if(typeof value==="string")return`'${value}'`;if(typeof value==="boolean")return value?"True":"False";return String(value)}function nextWindowStart(sch,now,history){const when=sch.when??{};const wtype=String(when.type??"daily").toLowerCase();const after=parseHhmm(when.after,[0,0]);if(wtype==="daily"){const ws=atTime(now,after);return now.getTime()<ws.getTime()?ws:addDays(ws,1)}if(wtype==="weekly"){const days=normDays(when.days);const targets=days.length>0?days:["mon"];for(let ahead=0;ahead<
35
+ 8;ahead++){const day=addDays(now,ahead);if(!targets.includes(dowKey(day)))continue;const ws=atTime(day,after);if(ws.getTime()>now.getTime())return ws}return null}if(wtype==="monthly"){let y=now.getUTCFullYear();let m=now.getUTCMonth()+1;let d=monthDay(y,m,when.day??1);const ws=atTime(wallClock(y,m,d),after);if(ws.getTime()>now.getTime())return ws;[y,m]=nextMonth(y,m);d=monthDay(y,m,when.day??1);return atTime(wallClock(y,m,d),after)}if(wtype==="interval"){const hours=num(when.every_hours,24,"floa\
36
+ t");let last=null;for(const row of sch.id===void 0?[]:history){if(row.schedule_id!==sch.id||!isActiveStatus(row.status))continue;const ts=parseTs(row.ts);if(ts&&(last===null||ts.getTime()>last.getTime()))last=ts}if(last===null)return now;return addHours(last,hours)}return null}function describeWhen(sch){const when=sch.when??{};const wtype=String(when.type??"daily").toLowerCase();const after=when.after||"00:00";if(wtype==="daily")return`\u6BCE\u65E5 ${after}\u4EE5\u964D`;if(wtype==="weekly"){const days=normDays(
37
+ when.days);const targets=days.length>0?days:["mon"];return`\u6BCE\u9031 ${targets.join("/")} ${after}\u4EE5\u964D`}if(wtype==="monthly"){return`\u6BCE\u6708 ${pyStr("day"in when?when.day:1)}\u65E5 ${after}\u4EE5\u964D`}if(wtype==="interval"){return`\u524D\u56DE\u304B\u3089${pyStr("every_hours"in when?when.every_hours:24)}h\u7D4C\u904E`}return wtype}var REQUIRE_ZERO_STATUS={verify:"19852455-67d5-4e23-8fee-a88290c34437",merge_pending:"92ebb53c-6eab-40e6-aed9-6ab9e2d242fd",open:"default:open"};function terminalStatusByItem(rows){const out=new Map;let anon=0;for(const r of rows){let item=r.item_id||"";if(!item){anon+=1;item=`_anon${anon}`}out.set(item,r.status||"")}return out}function rotationArgs(sch,history,windowCounts,currentWindowKey=null){const rot=sch.args_rotation;if(!rot||rot.length===0)return truthyStr(sch.args);const sid=sch.id??"";
38
+ if(Object.prototype.hasOwnProperty.call(windowCounts,sid)){let n=windowCounts[sid];if(currentWindowKey&&history.some(r=>r.schedule_id===sid&&r.window_key===currentWindowKey)){n-=1}return pyStr(rot[Math.max(0,n)%rot.length])}let windows=new Set(history.filter(r=>r.schedule_id===sid&&r.window_key&&r.window_key!==currentWindowKey).map(r=>r.window_key));const hasWindow=history.some(r=>r.schedule_id===sid&&r.window_key);if(!hasWindow){windows=new Set(history.map((r,i)=>[r,i]).filter(([r])=>r.schedule_id===
39
+ sid&&r.status==="enqueued").map(([,i])=>String(i)))}return pyStr(rot[windows.size%rot.length])}function isDue(sch,now,history,safeMode=false,warn){const sid=sch.id??"";if(!flag(sch,"enabled",true)){return{due:false,reason:"\u7121\u52B9\u5316\u3055\u308C\u3066\u3044\u308B\uFF08enabled=false\uFF09",windowKey:""}}if(!sch.skill)return{due:false,reason:"skill \u304C\u672A\u8A2D\u5B9A",windowKey:""};if(safeMode&&!flag(sch,"safe_mode_ok",true)){return{due:false,reason:"\u5B89\u5168\u30E2\u30FC\u30C9\u3067\u306F\u5BFE\u8C61\u5916\uFF08safe_mode_ok=false\uFF09",
40
+ windowKey:""}}const when=sch.when??{};const wtype=String(when.type??"daily").toLowerCase();const maxAttempts=num(sch.max_attempts_per_window,2);const everyHoursText=pyStr("every_hours"in when?when.every_hours:24);const{key,start:ws}=currentWindow(sch,now,warn);if(!key)return{due:false,reason:"\u67A0\u304C\u307E\u3060\u958B\u3044\u3066\u3044\u306A\u3044",windowKey:""};if(wtype==="interval"){const hours=num(when.every_hours,24,"float");const cutoff=addHours(now,-hours);const started=new Map;const rowsByItem=new Map;
41
+ let anon=0;for(const r of history){if(r.schedule_id!==sid)continue;const ts=parseTs(r.ts);if(!ts)continue;let item=r.item_id||"";if(!item){anon+=1;item=`_anon${anon}`}const list=rowsByItem.get(item);if(list)list.push(r);else rowsByItem.set(item,[r]);if(r.status==="enqueued"||!started.has(item))started.set(item,ts)}const recent=[];for(const[item,rowsI]of rowsByItem){const st=started.get(item);if(!st||st.getTime()<cutoff.getTime())continue;recent.push(...rowsI)}const terminal2=terminalStatusByItem(
42
+ recent);let recentActive=0;let recentFailed=0;for(const st of terminal2.values()){if(isActiveStatus(st))recentActive+=1;else if(st==="failed")recentFailed+=1}if(recentActive){return{due:false,reason:`\u76F4\u8FD1${everyHoursText}h\u4EE5\u5185\u306B\u5B9F\u884C\u6E08\u307F`,windowKey:key}}if(recentFailed>=maxAttempts){return{due:false,reason:`\u76F4\u8FD1${everyHoursText}h\u4EE5\u5185\u306B${recentFailed}\u56DE\u5931\u6557\uFF08\u4E0A\u9650${maxAttempts}\uFF09`,windowKey:key}}return{due:true,reason:`\
43
+ \u524D\u56DE\u5B9F\u884C\u304B\u3089${everyHoursText}h\u4EE5\u4E0A\u7D4C\u904E`,windowKey:key}}const rows=history.filter(r=>r.schedule_id===sid&&r.window_key===key);const terminal=terminalStatusByItem(rows);for(const st of terminal.values()){if(isActiveStatus(st)){return{due:false,reason:`\u3053\u306E\u67A0\uFF08${key}\uFF09\u3067\u65E2\u306B\u5B9F\u884C\u6E08\u307F`,windowKey:key}}}let failed=0;for(const st of terminal.values())if(st==="failed")failed+=1;if(failed>=maxAttempts){return{due:false,
44
+ reason:`\u3053\u306E\u67A0\u3067${failed}\u56DE\u5931\u6557\uFF08\u4E0A\u9650${maxAttempts}\uFF09`,windowKey:key}}if(!flag(sch,"catch_up",true)){const grace=num(sch.grace_minutes,120);if(ws&&now.getTime()-ws.getTime()>grace*6e4){return{due:false,reason:`\u67A0\u958B\u59CB\u304B\u3089${grace}\u5206\u8D85\u904E\uFF08catch_up=false\uFF09`,windowKey:key}}}let label=`\u67A0 ${key} \u304C\u958B\u3044\u3066\u304A\u308A\u672A\u5B9F\u884C`;if(failed)label+=`\uFF08${failed}\u56DE\u5931\u6557\u306E\u305F\u3081\u518D\u8A66\u884C\uFF09`;
45
+ return{due:true,reason:label,windowKey:key}}function parseCounts(spec){const out={};for(const part of(spec??"").split(",")){const idx=part.indexOf("=");if(idx<0)continue;const k=part.slice(0,idx).trim();const v=part.slice(idx+1).trim();if(k&&/^\d+$/.test(v))out[k]=Number(v)}return out}async function requireZeroBlocked(sch,counts,fetchCount){const raw=sch.require_zero??[];const keys=typeof raw==="string"?[raw]:raw;const over=[];for(const k of keys){let n=Object.prototype.hasOwnProperty.call(counts,
46
+ k)?counts[k]:void 0;if(n===void 0||n===null){n=fetchCount?await fetchCount(k):null;if(n!==null&&n!==void 0)counts[k]=n}if(n===null||n===void 0||n<0)over.push(`${k}=\u5224\u5B9A\u4E0D\u80FD`);else if(n)over.push(`${k}=${n}\u4EF6`)}return over.length>0?`${over.join(" / ")} \u304C\u6B8B\u3063\u3066\u3044\u308B\u305F\u3081\u67A0\u3092\u6368\u3066\u308B`:null}var RELEASE_STALE_HOURS=4;async function fetchRunningReleases(endpoint,env=process.env,fetchImpl=httpFetch){if(!endpoint)return{ids:[],unavailable:false};
47
+ const apiKey=endpoint.apiKeyEnv?env[endpoint.apiKeyEnv]??"":"";if(endpoint.apiKeyEnv&&!apiKey)return{ids:[],unavailable:false};const headers={"Content-Type":"application/json"};if(apiKey)headers[endpoint.header]=apiKey;let rows;try{const res=await fetchImpl(`${endpoint.url}${endpoint.path}`,{headers,signal:AbortSignal.timeout(2e4)});if(!res.ok)return{ids:[],unavailable:true};rows=await res.json()}catch{return{ids:[],unavailable:true}}if(rows&&!Array.isArray(rows)&&typeof rows==="object"){const obj=rows;
48
+ if("items"in obj)rows=obj["items"];else if("data"in obj)rows=obj["data"]}if(!Array.isArray(rows))return{ids:[],unavailable:true};const limit=Date.now()-RELEASE_STALE_HOURS*36e5;const ids=[];for(const r of rows){if(!r||typeof r!=="object")continue;const row=r;if(row["status"]!=="running")continue;const started=parseAiopsUtc(String(row["created_at"]??""));if(started!==null&&started<limit)continue;ids.push(`#${String(row["id"])}`)}return{ids,unavailable:false}}function parseAiopsUtc(raw){const m=/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/.
49
+ exec(raw);if(!m)return null;const[,y,mo,d,h,mi,sec]=m;return Date.UTC(Number(y),Number(mo)-1,Number(d),Number(h),Number(mi),Number(sec))}function releaseRunningBlocked(skill,running,exclusiveSkills){if(!exclusiveSkills.has(skill))return null;if(running.unavailable)return"\u30EA\u30EA\u30FC\u30B9\u72B6\u6CC1\u3092\u5224\u5B9A\u3067\u304D\u306A\u3044\u305F\u3081\u67A0\u3092\u6368\u3066\u308B";if(running.ids.length>0)return`${running.ids.join(",")} \u304C\u5B9F\u884C\u4E2D\u306E\u305F\u3081\u67A0\u3092\u6368\u3066\u308B`;
50
+ return null}async function collectDue(input){const{config,now,history,windowCounts,safeMode,warn,verbose}=input;const gates=config.gates??[];const counts=input.counts??{};const exclusiveSkills=input.exclusiveSkills??new Set;const statusEndpoint=input.statusEndpoint??null;let running=null;const items=[];for(const sch of config.schedules??[]){const{due,reason,windowKey}=isDue(sch,now,history,safeMode,warn);const sid="id"in sch?pyStr(sch.id):"?";if(!due){verbose?.(` skip ${pad28(sid)} ${reason}`);
51
+ continue}const skill=String(sch.skill);const gate=gateStatus(skill,now,gates);if(!gate.allowed){verbose?.(` hold ${pad28(sid)} \u6642\u9593\u5E2F\u30B2\u30FC\u30C8: ${gate.reason}`);continue}const blocked=await requireZeroBlocked(sch,counts,input.fetchCount);if(blocked){verbose?.(` hold ${pad28(sid)} \u4EF6\u6570\u30B2\u30FC\u30C8: ${blocked}`);continue}if(exclusiveSkills.has(skill)){running??=await(input.fetchRunning??(()=>fetchRunningReleases(statusEndpoint)))();const held=releaseRunningBlocked(
52
+ skill,running,exclusiveSkills);if(held){verbose?.(` hold ${pad28(sid)} \u30EA\u30EA\u30FC\u30B9\u6392\u4ED6: ${held}`);continue}}items.push({scheduleId:sid,skill,args:rotationArgs(sch,history,windowCounts,windowKey),priority:truthyStr("priority"in sch?sch.priority:"P3")||"P3",label:sch.label||`\u5B9A\u671F: /twp-${skill}`,windowKey,reason,order:num(sch.order,50,"float")})}items.sort((a,b)=>{const pa=priorityRank(a.priority);const pb=priorityRank(b.priority);if(pa!==pb)return pa-pb;return a.order-
53
+ b.order});let limit=num(config.max_per_cycle,2);if(limit===0&&config.max_per_cycle!==void 0&&config.max_per_cycle!==null){warn?.("# max_per_cycle=0 \u306F\u7121\u5236\u9650\u3067\u306F\u306A\u304F\u8A2D\u5B9A\u30DF\u30B9\u3068\u307F\u306A\u3057\u65E2\u5B9A(2)\u3092\u4F7F\u3044\u307E\u3059\u3002\u7121\u5236\u9650\u306B\u3057\u305F\u3044\u5834\u5408\u306F -1 \u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");limit=2}let out=items;if(limit>0&&items.length>limit){for(const held of items.
54
+ slice(limit)){verbose?.(` hold ${pad28(held.scheduleId)} max_per_cycle=${limit} \u306E\u305F\u3081\u6B21\u30B5\u30A4\u30AF\u30EB\u3078`)}out=items.slice(0,limit)}return out.map(({order:_order,...row})=>row)}function truthyStr(v){if(v===null||v===void 0||v===false||v===0||v==="")return"";return String(v)}function pad28(s){return s.padEnd(28)}function promptSection(config,now,history,enqueuedLines,includeUpcoming=true){const blocked=gatedSkills(config,now);const upcoming=[];for(const sch of config.
55
+ schedules??[]){if(!flag(sch,"enabled",true))continue;const nxt=nextWindowStart(sch,now,history);if(!nxt)continue;upcoming.push([nxt,sch])}upcoming.sort((a,b)=>a[0].getTime()-b[0].getTime());const out=["\u3010\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\uFF08scripts/ops-schedule.json\uFF09\u3011"];if(enqueuedLines.length>0){out.push("\u4ECA\u30B5\u30A4\u30AF\u30EB\u306E\u5B9A\u671F\u5B9F\u884C\u5206\u3068\u3057\u3066\u3001\u4EE5\u4E0B\u306F**\u30B9\u30AF\u30EA\u30D7\u30C8\u304C\u65E2\u306B\u30AD\u30E5\u30FC\u3078\u6295\u5165\u6E08\u307F**\u3067\u3059\u3002steps \u306B\u91CD\u8907\u3057\u3066\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044\uFF08\u91CD\u8907\u3059\u308B\u3068\u30AD\u30E5\u30FC\u306B\u4E8C\u91CD\u767B\u9332\u3055\u308C\u307E\u3059\uFF09:");
56
+ out.push(...enqueuedLines)}else{out.push("\u4ECA\u30B5\u30A4\u30AF\u30EB\u3067\u767A\u706B\u3057\u305F\u5B9A\u671F\u30BF\u30B9\u30AF\u306F\u3042\u308A\u307E\u305B\u3093\u3002")}if(blocked.length>0){out.push("");out.push("\u73FE\u5728\u6642\u523B\u306F\u4EE5\u4E0B\u306E\u30B9\u30AD\u30EB\u306E\u5B9F\u884C\u6642\u9593\u5E2F\u5916\u3067\u3059\u3002**steps \u306B\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044**:");for(const[skill,reason]of blocked)out.push(`- ${skill} \u2014 ${reason}`)}if(includeUpcoming&&
57
+ upcoming.length>0){out.push("");out.push("\u5B9A\u671F\u30BF\u30B9\u30AF\u306E\u6B21\u56DE\u767A\u706B\u4E88\u5B9A\uFF08\u53C2\u8003\u3002\u8A08\u753B\u306B\u542B\u3081\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\uFF09:");for(const[nxt,sch]of upcoming.slice(0,8)){const whenTxt=nxt.getTime()<=now.getTime()?"\u767A\u706B\u5F85\u3061\uFF08\u6B21\u30B5\u30A4\u30AF\u30EB\u4EE5\u964D\u306B\u81EA\u52D5\u6295\u5165\uFF09":fmtMonthDayTime(nxt);out.push(`- ${whenTxt} ${sch.label||`/twp-${String(
58
+ sch.skill)}`}\uFF08${describeWhen(sch)}\uFF09`)}}out.push("");out.push("\u5B9A\u671F\u30BF\u30B9\u30AF\u306F\u6642\u9593\u30D9\u30FC\u30B9\u3067\u30B9\u30AF\u30EA\u30D7\u30C8\u304C\u7BA1\u7406\u3057\u3066\u3044\u307E\u3059\u3002\u300C\u524D\u56DE\u5B9F\u884C\u304B\u3089\u6642\u9593\u304C\u7D4C\u3063\u305F\u304B\u300D\u3092\u63A8\u6E2C\u3057\u3066\u8A08\u753B\u306B\u5165\u308C\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u3002");return out.join("\n")}export{describeError,isPermanent,filterByStatus,AgentLoopApi,pick,pickString,ScheduleApi,nowInZone,parseTs,gateStatus,REQUIRE_ZERO_STATUS,parseCounts,collectDue,promptSection};
package/dist/cli.js ADDED
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire as __twpCreateRequire } from 'node:module';
3
+ const require = __twpCreateRequire(import.meta.url);
4
+ import{isModeId,isPermissionModeId}from"./chunk-NNOYO67O.js";import{GLOBAL_OPTIONS_HELP,HELP_TOKEN,isDomainName,splitFlagToken}from"./chunk-VSQXY2VX.js";import"./chunk-VSJBJXZO.js";var BUILTIN_COMMANDS=["login","logout","whoami","update","task-loop"];var TASK_LOOP_ACTIONS=["run","status","stop","schedule","setup"];var VALUE_FLAGS=new Set(["-p","--print","--profile","--tenant","--mode","--permission-mode","--model","--project","--engine","--interval","--max-cycles","--ai","--workspace","--ai-config-file","--now","--counts","--gate","--output","--query"]);var BOOLEAN_FLAGS=new Set(["-h","--help","-v","--version","--no-tui","--doctor","--password","--token","--no-browser","--\
5
+ safe","--daemon","--force-runner","--force","--drain","--yes","-y","--no-ai-config-file","--verbose","--dry-run","--debug","--refresh"]);function dispatch(argv,limit=2){const tokens=[];const indexes=[];let truncated=false;for(let i=0;i<argv.length;i++){const arg=argv[i];if(arg===void 0)continue;if(arg.startsWith("-")&&arg!=="-"){const{name,value:inline}=splitFlagToken(arg);if(BOOLEAN_FLAGS.has(name)){if(inline!==void 0){truncated=true;break}continue}if(VALUE_FLAGS.has(name)){if(inline!==void 0)continue;
6
+ const next=argv[i+1];if(next!==void 0&&(!next.startsWith("-")||next==="-"))i++;continue}truncated=true;break}if(arg===""||arg==="-")continue;if(tokens.length>=limit)break;tokens.push(arg);indexes.push(i)}return{tokens,indexes,truncated}}function isBuiltin(token){return token!==void 0&&BUILTIN_COMMANDS.includes(token)}function isTaskLoopAction(token){return token!==void 0&&TASK_LOOP_ACTIONS.includes(token)}function resolveRoute(result){const{tokens,indexes}=result;const[first,second]=tokens;const firstIndex=indexes[0];
7
+ if(first===void 0||firstIndex===void 0)return{kind:"none",consumed:[]};const consumed=[firstIndex];const secondIndex=indexes[1];if(isBuiltin(first)){if(first==="task-loop"&&isTaskLoopAction(second)){if(secondIndex!==void 0)consumed.push(secondIndex);return{kind:"builtin",command:first,action:second,consumed}}return{kind:"builtin",command:first,...first==="task-loop"?{action:"run"}:{},consumed}}if(second!==void 0&&secondIndex!==void 0)consumed.push(secondIndex);return{kind:"domain",domain:first,...second!==
8
+ void 0?{operation:second}:{},consumed}}var GLOBAL_FLAGS=new Set(["-h","--help","-v","--version","--profile","--output","--query","--dry-run","--debug","--yes","-y","--refresh"]);function parseArgv(argv){const out={command:"tui",safe:false,daemon:false,forceRunner:false,stopForce:false,stopDrain:false,noTui:false,doctor:false,yes:false,noAiConfigFile:false,verbose:false,loginMethod:"browser",loginNoBrowser:false,promptFromStdin:false,domainArgv:[],domainHelp:false,dryRun:false,debug:false,refresh:false,unknown:[]};const route=resolveRoute(
9
+ dispatch(argv));const consumed=new Set;const[firstIndex,secondIndex]=route.consumed;if(route.kind==="builtin"){out.command=route.command;if(route.action!==void 0)out.taskLoopAction=route.action;for(const index of route.consumed)consumed.add(index)}else if(route.kind==="domain"){if(route.domain===HELP_TOKEN){if(route.operation===void 0){out.command="help";if(firstIndex!==void 0)consumed.add(firstIndex)}else if(isDomainName(route.operation)){out.command="domain";out.domain=route.operation;out.domainHelp=
10
+ true;if(firstIndex!==void 0)consumed.add(firstIndex);if(secondIndex!==void 0)consumed.add(secondIndex)}}else if(isDomainName(route.domain)){out.command="domain";out.domain=route.domain;if(route.operation!==void 0)out.operation=route.operation;for(const index of route.consumed)consumed.add(index)}}const hasSubcommandToken=route.kind==="builtin"||route.kind==="domain"&&(route.domain===HELP_TOKEN||isDomainName(route.domain));const isDomainRoute=out.command==="domain";const takeValue=(i,flag,inline)=>{
11
+ const value=inline??argv[i+1];if(value===void 0||inline===void 0&&value.startsWith("-")){out.unknown.push(flag);return{step:0}}if(value.trim()===""){out.unknown.push(inline===void 0?`${flag} `:`${flag}=${inline}`);return{step:0}}return{value,step:inline===void 0?1:0}};let optionsClosed=false;for(let i=0;i<argv.length;i++){if(consumed.has(i))continue;const raw=argv[i];if(raw===void 0)continue;if(isDomainRoute&&raw==="--")optionsClosed=true;const{name:arg,value:inline}=splitFlagToken(raw);if(isDomainRoute&&
12
+ (optionsClosed||!GLOBAL_FLAGS.has(arg))){out.domainArgv.push(raw);continue}if(inline!==void 0&&BOOLEAN_FLAGS.has(arg)){out.unknown.push(raw);continue}switch(arg){case"-h":case"--help":if(isDomainRoute)out.domainHelp=true;else out.command="help";break;case"-v":case"--version":out.command="version";break;case"--no-tui":out.noTui=true;break;case"--doctor":out.doctor=true;break;case"--password":out.loginMethod="password";break;case"--token":out.loginMethod="token";break;case"--no-browser":out.loginNoBrowser=
13
+ true;break;case"--profile":{const{value,step}=takeValue(i,"--profile",inline);if(value!==void 0){out.profile=value;i+=step}break}case"-p":case"--print":{const next=inline??argv[i+1];const step=inline===void 0?1:0;if(hasSubcommandToken){out.unknown.push(raw)}else if(next==="-"){out.command="print";out.promptFromStdin=true;out.prompt="";i+=step}else if(next!==void 0&&(inline!==void 0||!next.startsWith("-"))){out.command="print";out.prompt=next;i+=step}else{out.unknown.push(raw)}break}case"--output":{
14
+ const{value,step}=takeValue(i,"--output",inline);if(value!==void 0){out.output=value;i+=step}break}case"--query":{const{value,step}=takeValue(i,"--query",inline);if(value!==void 0){out.query=value;i+=step}break}case"--dry-run":out.dryRun=true;break;case"--debug":out.debug=true;break;case"--refresh":out.refresh=true;break;case"--tenant":{const{value,step}=takeValue(i,"--tenant",inline);if(value!==void 0){out.tenant=value;i+=step}break}case"--mode":{const next=inline??argv[i+1];const step=inline===
15
+ void 0?1:0;if(isModeId(next)){out.mode=next;i+=step}else if(next!==void 0&&(inline!==void 0||!next.startsWith("-"))){out.unknown.push(inline!==void 0?raw:`--mode ${next}`);i+=step}else{out.unknown.push("--mode")}break}case"--permission-mode":{const next=inline??argv[i+1];const step=inline===void 0?1:0;if(isPermissionModeId(next)){out.permissionMode=next;i+=step}else if(next!==void 0&&(inline!==void 0||!next.startsWith("-"))){out.unknown.push(inline!==void 0?raw:`--permission-mode ${next}`);i+=step}else{
16
+ out.unknown.push("--permission-mode")}break}case"--model":{const{value,step}=takeValue(i,"--model",inline);if(value!==void 0){out.model=value;i+=step}break}case"--safe":out.safe=true;break;case"--daemon":out.daemon=true;break;case"--force-runner":out.forceRunner=true;break;case"--force":out.stopForce=true;break;case"--drain":out.stopDrain=true;break;case"--project":{const{value,step}=takeValue(i,"--project",inline);if(value!==void 0){out.project=value;i+=step}break}case"--engine":{const{value,step}=takeValue(
17
+ i,"--engine",inline);if(value!==void 0){out.engine=value;i+=step}break}case"--interval":case"--max-cycles":{const{value,step}=takeValue(i,arg,inline);if(value!==void 0){const n=Number.parseInt(value,10);if(Number.isInteger(n)&&n>0){if(arg==="--interval")out.interval=n;else out.maxCycles=n}else{out.unknown.push(inline!==void 0?raw:`${arg} ${value}`)}i+=step}break}case"--yes":case"-y":out.yes=true;break;case"--ai":{const{value:v,step}=takeValue(i,"--ai",inline);if(v!==void 0){out.ais=[...out.ais??
18
+ [],v];i+=step}break}case"--no-ai-config-file":out.noAiConfigFile=true;break;case"--workspace":{const{value:v,step}=takeValue(i,"--workspace",inline);if(v!==void 0){out.workspace=v;i+=step}break}case"--ai-config-file":{const{value:v,step}=takeValue(i,"--ai-config-file",inline);if(v!==void 0){out.aiConfigFile=v;i+=step}break}case"--verbose":out.verbose=true;break;case"--now":{const{value:v,step}=takeValue(i,"--now",inline);if(v!==void 0){out.scheduleNow=v;i+=step}break}case"--counts":{const{value:v,
19
+ step}=takeValue(i,"--counts",inline);if(v!==void 0){out.scheduleCounts=v;i+=step}break}case"--gate":{const{value:v,step}=takeValue(i,"--gate",inline);if(v!==void 0){out.scheduleGate=v;i+=step}break}default:out.unknown.push(raw)}}if(out.command!=="login"&&out.loginMethod!=="browser"){out.unknown.push(out.loginMethod==="password"?"--password":"--token");out.loginMethod="browser"}if(out.permissionMode!==void 0&&out.command!=="tui"&&out.command!=="print"){out.unknown.push("--permission-mode");delete out.
20
+ permissionMode}if(out.loginNoBrowser&&!(out.command==="login"&&out.loginMethod==="browser")){out.unknown.push("--no-browser");out.loginNoBrowser=false}if(out.command!=="task-loop"){if(out.safe)out.unknown.push("--safe");if(out.daemon)out.unknown.push("--daemon");if(out.forceRunner)out.unknown.push("--force-runner");if(out.stopForce)out.unknown.push("--force");if(out.stopDrain)out.unknown.push("--drain");if(out.engine!==void 0)out.unknown.push("--engine");if(out.interval!==void 0)out.unknown.push(
21
+ "--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles");if(out.project!==void 0)out.unknown.push("--project");if(out.verbose)out.unknown.push("--verbose");if(out.scheduleNow!==void 0)out.unknown.push("--now");if(out.scheduleCounts!==void 0)out.unknown.push("--counts");if(out.scheduleGate!==void 0)out.unknown.push("--gate");if(out.ais!==void 0)out.unknown.push("--ai");if(out.workspace!==void 0)out.unknown.push("--workspace");if(out.aiConfigFile!==void 0)out.unknown.push("--ai-con\
22
+ fig-file");if(out.noAiConfigFile)out.unknown.push("--no-ai-config-file")}if(out.yes&&out.command!=="task-loop"&&!isDomainRoute)out.unknown.push("--yes");if(!isDomainRoute){if(out.output!==void 0)out.unknown.push("--output");if(out.query!==void 0)out.unknown.push("--query");if(out.dryRun)out.unknown.push("--dry-run");if(out.debug)out.unknown.push("--debug");if(out.refresh)out.unknown.push("--refresh")}if(out.command==="task-loop"&&out.taskLoopAction!=="schedule"){if(out.verbose)out.unknown.push("\
23
+ --verbose");if(out.scheduleNow!==void 0)out.unknown.push("--now");if(out.scheduleCounts!==void 0)out.unknown.push("--counts");if(out.scheduleGate!==void 0)out.unknown.push("--gate")}if(out.command==="task-loop"&&out.taskLoopAction!=="stop"&&out.stopForce){out.unknown.push("--force")}if(out.command==="task-loop"&&out.taskLoopAction!=="stop"&&out.stopDrain){out.unknown.push("--drain")}if(out.command==="task-loop"&&out.taskLoopAction==="stop"&&out.stopForce&&out.stopDrain){out.unknown.push("--force\
24
+ \u3068 --drain \u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u307E\u305B\u3093");out.stopForce=false;out.stopDrain=false}if(out.command==="task-loop"&&out.taskLoopAction!=="setup"){if(out.yes)out.unknown.push("--yes");if(out.ais!==void 0)out.unknown.push("--ai");if(out.workspace!==void 0)out.unknown.push("--workspace");if(out.aiConfigFile!==void 0)out.unknown.push("--ai-config-file");if(out.noAiConfigFile)out.unknown.push("--no-ai-config-file")}if(out.command==="task-loop"&&(out.taskLoopAction===
25
+ "stop"||out.taskLoopAction==="status")){if(out.safe)out.unknown.push("--safe");if(out.daemon)out.unknown.push("--daemon");if(out.forceRunner)out.unknown.push("--force-runner");if(out.engine!==void 0)out.unknown.push("--engine");if(out.interval!==void 0)out.unknown.push("--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles")}if(out.command==="task-loop"&&out.taskLoopAction==="setup"){if(out.engine!==void 0)out.unknown.push("--engine");if(out.safe)out.unknown.push("--safe");if(out.
26
+ daemon)out.unknown.push("--daemon");if(out.forceRunner)out.unknown.push("--force-runner");if(out.interval!==void 0)out.unknown.push("--interval");if(out.maxCycles!==void 0)out.unknown.push("--max-cycles")}return out}var VERSION=true?"0.10.0":"0.0.0-dev";var HELP=`twp ${VERSION} \u2014 TWP CLI
27
+
28
+ \u4F7F\u3044\u65B9:
29
+ twp \u5BFE\u8A71 TUI \u3092\u8D77\u52D5
30
+ twp -p "<\u30D7\u30ED\u30F3\u30D7\u30C8>" \u975E\u5BFE\u8A71\u3067 1 \u5F80\u5FA9\u3060\u3051\u5B9F\u884C\uFF08\u5FDC\u7B54\u306F stdout\u30FB-p - \u3067\u6A19\u6E96\u5165\u529B\uFF09
31
+ twp login \u30D6\u30E9\u30A6\u30B6\u59D4\u8B72\u30ED\u30B0\u30A4\u30F3\uFF08SSO / 2FA / \u30D1\u30B9\u30EF\u30FC\u30C9\u306B\u5BFE\u5FDC\uFF09
32
+ twp login --no-browser \u30D6\u30E9\u30A6\u30B6\u3092\u958B\u304B\u305A\u3001\u627F\u8A8D\u753B\u9762\u306B\u51FA\u305F\u8A8D\u53EF\u30B3\u30FC\u30C9\u3092\u8CBC\u308A\u4ED8\u3051\u308B
33
+ \uFF08SSH \u5148\u30FBGUI \u306A\u3057\u306E\u7AEF\u672B\u3002\u672A\u6307\u5B9A\u3067\u3082\u81EA\u52D5\u3067\u5207\u308A\u66FF\u308F\u308B\uFF09
34
+ twp login --password \u7AEF\u672B\u5185\u3067\u30D1\u30B9\u30EF\u30FC\u30C9\u30ED\u30B0\u30A4\u30F3\uFF08headless / SSH \u5411\u3051\uFF09
35
+ twp login --token \u767A\u884C\u6E08\u307F\u30C8\u30FC\u30AF\u30F3\u3067\u30ED\u30B0\u30A4\u30F3\uFF08CI \u5411\u3051\u3002TWP_TOKEN \u3067\u3082\u53EF\uFF09
36
+ twp login --tenant <code>
37
+ \u30C6\u30CA\u30F3\u30C8\u30B3\u30FC\u30C9\u3092\u5148\u306B\u6307\u5B9A\uFF08--password \u306E\u30D7\u30ED\u30F3\u30D7\u30C8\u3092 1 \u3064\u7701\u304F\uFF09
38
+ twp logout \u30ED\u30B0\u30A2\u30A6\u30C8\uFF08\u30ED\u30FC\u30AB\u30EB\u524A\u9664\uFF0B\u30B5\u30FC\u30D0\u5074\u30C8\u30FC\u30AF\u30F3\u5931\u52B9\uFF09
39
+ twp whoami \u30ED\u30B0\u30A4\u30F3\u4E2D\u306E\u30E6\u30FC\u30B6\u30FC\u30FB\u30C6\u30CA\u30F3\u30C8\u3092\u8868\u793A
40
+ twp update npm \u306E\u6700\u65B0\u7248\u3068\u3001\u30B5\u30FC\u30D0\u304C\u8981\u6C42\u3059\u308B\u6700\u5C0F\u30D0\u30FC\u30B8\u30E7\u30F3\u3092\u78BA\u8A8D
41
+ \uFF08\u66F4\u65B0\u306F\u884C\u308F\u305A\u3001\u5B9F\u884C\u3059\u3079\u304D\u30B3\u30DE\u30F3\u30C9\u3092\u8868\u793A\u3059\u308B\u3002
42
+ \u4E0B\u9650\u672A\u6E80\u306A\u3089\u7D42\u4E86\u30B3\u30FC\u30C9 1\uFF09
43
+ twp task-loop setup --project <\u30AD\u30FC|UUID>
44
+ \u5BFE\u8A71\u8A2D\u5B9A\uFF08AI CLI \u3092\u691C\u51FA \u2192 \u4F7F\u3046\u3082\u306E\u3092\u9078\u629E \u2192 \u30AB\u30C6\u30B4\u30EA\u5272\u5F53\u3092\u751F\u6210\uFF09\u3002
45
+ --yes \u3067\u5BFE\u8A71\u3092\u7701\u7565\u3001--ai claude,codex \u3067\u660E\u793A\u3001
46
+ --workspace <\u30D1\u30B9> / --ai-config-file <\u30D1\u30B9>
47
+ / --no-ai-config-file\uFF08\u65E2\u5B58\u30D5\u30A1\u30A4\u30EB\u3092\u53C2\u7167\u305B\u305A\u751F\u6210\u3059\u308B\uFF09
48
+ twp task-loop run --project <\u30AD\u30FC|UUID>
49
+ \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30EB\u30FC\u30D7\u3092\u5B9F\u884C\uFF08--daemon / --interval <\u79D2>
50
+ / --max-cycles <n> / --safe / --force-runner / --engine <\u540D\u524D>\uFF09
51
+ twp task-loop status --project <\u30AD\u30FC|UUID>
52
+ \u30E9\u30F3\u30CA\u30FC\u30FB\u30AD\u30E5\u30FC\u30FB\u8A08\u753B\u30ED\u30C3\u30AF\u306E\u73FE\u6CC1\u3092\u8868\u793A\uFF08\u8AAD\u307F\u53D6\u308A\u306E\u307F\uFF09
53
+ twp task-loop stop \u3053\u306E\u30DE\u30B7\u30F3\u3067\u7A3C\u50CD\u4E2D\u306E\u30EB\u30FC\u30D7\u3092\u505C\u6B62\uFF08\u30AD\u30E5\u30FC\u306B\u306F\u89E6\u3089\u306A\u3044\uFF09
54
+ \u505C\u6B62\u3092\u898B\u5C4A\u3051\u3066\u304B\u3089\u7D42\u4E86\u3059\u308B\u3002\u5FDC\u7B54\u3057\u306A\u3044\u3068\u304D\u306F --force \u3067\u6728\u3054\u3068\u505C\u6B62
55
+ --drain \u306F\u5B9F\u884C\u4E2D\u306E\u30A2\u30A4\u30C6\u30E0\u3092\u5B8C\u8D70\u3055\u305B\u3066\u304B\u3089\u7D42\u3048\u308B\uFF08\u4E2D\u65AD\u3057\u306A\u3044\u30FB
56
+ \u898B\u5C4A\u3051\u305A\u306B\u623B\u308B\u3002--force \u3068\u306F\u540C\u6642\u306B\u6307\u5B9A\u3067\u304D\u306A\u3044\uFF09
57
+ twp task-loop schedule --project <\u30AD\u30FC|UUID>
58
+ \u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306E\u767A\u706B\u5224\u5B9A\u3092\u8868\u793A\uFF08\u8AAD\u307F\u53D6\u308A\u306E\u307F\u30FB\u6295\u5165\u3057\u306A\u3044\u3002
59
+ --verbose \u3067\u30B9\u30AD\u30C3\u30D7\u7406\u7531 / --now <\u65E5\u6642> \u3067\u6642\u523B\u3092\u4EEE\u5B9A
60
+ / --counts verify=N / --gate <\u30B9\u30AD\u30EB> \u3067\u6642\u9593\u5E2F\u30B2\u30FC\u30C8\u3060\u3051\u5224\u5B9A\uFF09
61
+ \u203B --project __private__ \u3067\u500B\u4EBA\u30BF\u30B9\u30AF\u306E\u30AD\u30E5\u30FC\u3092\u6307\u3059
62
+ \uFF08\u5B9A\u671F\u30B9\u30B1\u30B8\u30E5\u30FC\u30EB\u306F\u6301\u305F\u306A\u3044\u305F\u3081 schedule \u306F0\u4EF6\uFF09
63
+ twp --mode <id> \u8D77\u52D5\u6642\u306E\u30E2\u30FC\u30C9\u3092\u6307\u5B9A\uFF08dev | biz | plan\uFF09
64
+ twp --permission-mode <v>
65
+ \u30C4\u30FC\u30EB\u5B9F\u884C\u306E\u65E2\u5B9A\u3092\u4E0A\u66F8\u304D\uFF08plan | acceptEdits | denyAll\uFF09\u3002
66
+ plan=\u66F8\u304D\u8FBC\u307F\u3068\u5B9F\u884C\u3092\u62D2\u5426 / acceptEdits=\u7DE8\u96C6\u3092\u81EA\u52D5\u627F\u8A8D /
67
+ denyAll=\u30C4\u30FC\u30EB\u30921\u672C\u3082\u5B9F\u884C\u3057\u306A\u3044\u3002\u30E2\u30FC\u30C9\u306E deny \u306F\u8986\u3089\u306A\u3044\u3002
68
+ plan / denyAll \u306F git \u3082\u6B62\u3081\u308B\uFF08\u30EA\u30DD\u30B8\u30C8\u30EA\u8A2D\u5B9A\u7D4C\u7531\u3067
69
+ \u4EFB\u610F\u30B3\u30DE\u30F3\u30C9\u304C\u8D70\u308A\u3046\u308B\u305F\u3081\uFF09\u3002
70
+ \u975E\u5BFE\u8A71\uFF08-p / \u30D1\u30A4\u30D7\uFF09\u3067\u306F\u627F\u8A8D\u3067\u304D\u306A\u3044\u305F\u3081 ask \u306F\u62D2\u5426\u306B\u306A\u308B
71
+ twp --model <id> \u8D77\u52D5\u6642\u306E\u30E2\u30C7\u30EB\u3092\u6307\u5B9A
72
+ twp --profile <name> \u63A5\u7D9A\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\uFF08TWP_PROFILE \u3067\u3082\u53EF\uFF09
73
+ twp --no-tui \u7D20\u306E\u30B9\u30C8\u30EA\u30FC\u30E0\u51FA\u529B\u3067\u8D77\u52D5\uFF08VT \u975E\u5BFE\u5FDC\u7AEF\u672B\u30FB\u30D1\u30A4\u30D7\u5411\u3051\uFF09
74
+ twp --doctor \u7AEF\u672B\u30AD\u30FC\u5165\u529B\u306E\u5B9F\u6E2C\u753B\u9762\u3092\u76F4\u63A5\u958B\u304F
75
+ twp --version \u30D0\u30FC\u30B8\u30E7\u30F3
76
+ twp --help \u3053\u306E\u30D8\u30EB\u30D7
77
+
78
+ \u30C9\u30E1\u30A4\u30F3\u30B3\u30DE\u30F3\u30C9\uFF08TWP \u306E\u30C7\u30FC\u30BF\u3092\u64CD\u4F5C\u3059\u308B\uFF09:
79
+ twp project list \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u4E00\u89A7\u3059\u308B
80
+ twp project get <\u53C2\u7167> \u30D7\u30ED\u30B8\u30A7\u30AF\u30C81\u4EF6\u306E\u8A73\u7D30\u3092\u8868\u793A\u3059\u308B
81
+ twp project members \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u30E1\u30F3\u30D0\u30FC\u3092\u4E00\u89A7\u3059\u308B
82
+ twp task list \u30BF\u30B9\u30AF\u3092\u4E00\u89A7\u3059\u308B\uFF08--status / --assignee \u306F\u540D\u524D\u3067\u6307\u5B9A\u3067\u304D\u308B\uFF09
83
+ twp task get <\u30AD\u30FC> \u30BF\u30B9\u30AF1\u4EF6\u306E\u8A73\u7D30\u3092\u8868\u793A\u3059\u308B\uFF08--project \u4E0D\u8981\uFF09
84
+ twp task subtasks <\u30AD\u30FC>
85
+ \u30BF\u30B9\u30AF\u306E\u30B5\u30D6\u30BF\u30B9\u30AF\u3092\u4E00\u89A7\u3059\u308B
86
+ twp task create \u30BF\u30B9\u30AF\u3092\u4F5C\u6210\u3059\u308B\uFF08--subject \u5FC5\u9808\uFF09
87
+ twp task update <\u30AD\u30FC> \u30BF\u30B9\u30AF\u3092\u66F4\u65B0\u3059\u308B\uFF08--status / --assignee \u7B49\uFF09
88
+ twp task delete <\u30AD\u30FC> \u30BF\u30B9\u30AF\u3092\u524A\u9664\u3059\u308B\uFF08--yes \u304C\u5FC5\u8981\uFF09
89
+ twp task comment list <\u30AD\u30FC>
90
+ \u30BF\u30B9\u30AF\u306E\u30B3\u30E1\u30F3\u30C8\u3092\u4E00\u89A7\u3059\u308B
91
+ twp task comment create <\u30AD\u30FC>
92
+ \u30BF\u30B9\u30AF\u306B\u30B3\u30E1\u30F3\u30C8\u3092\u6295\u7A3F\u3059\u308B\uFF08--body-file / --body\uFF09
93
+ twp task comment update <\u30B3\u30E1\u30F3\u30C8ID>
94
+ \u30B3\u30E1\u30F3\u30C8\u306E\u672C\u6587\u3092\u66F8\u304D\u63DB\u3048\u308B\uFF08--task \u304C\u8981\u308B\uFF09
95
+ twp task comment delete <\u30B3\u30E1\u30F3\u30C8ID>
96
+ \u30B3\u30E1\u30F3\u30C8\u3092\u524A\u9664\u3059\u308B\uFF08--task \u3068 --yes \u304C\u8981\u308B\uFF09
97
+ twp <\u30C9\u30E1\u30A4\u30F3> help \u305D\u306E\u30C9\u30E1\u30A4\u30F3\u306E\u30D8\u30EB\u30D7
98
+ twp <\u30C9\u30E1\u30A4\u30F3> <\u64CD\u4F5C> help
99
+ \u305D\u306E\u64CD\u4F5C\u306E\u30D8\u30EB\u30D7
100
+
101
+ ${GLOBAL_OPTIONS_HELP}
102
+
103
+ \u63A5\u7D9A\u5148\uFF08\u65E2\u5B9A\u306F\u672C\u756A\uFF09:
104
+ TWP_API_URL TWP API\uFF08\u4F8B https://backend.tocca.systems\uFF09
105
+ TWP_RELAY_URL \u30E2\u30C7\u30EB\u53D6\u6B21\uFF08\u4F8B https://ai-api.tocca.systems\uFF09
106
+ ~/.twp/config.json \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u3054\u3068\u306B api_url / relay_url / model \u3092\u8A2D\u5B9A
107
+
108
+ TUI \u5185:
109
+ Shift+Tab / Alt+M \u30E2\u30FC\u30C9\u5DE1\u56DE\uFF08dev \u2192 biz \u2192 plan\uFF09
110
+ / \u30B9\u30E9\u30C3\u30B7\u30E5\u30B3\u30DE\u30F3\u30C9\u30D1\u30EC\u30C3\u30C8\uFF08/exit \u3067\u7D42\u4E86\u30FB/quit \u3082\u53EF\uFF09
111
+ Shift+Enter / Ctrl+J \u6539\u884C\uFF08\\ \u3092\u6253\u3063\u3066\u304B\u3089 Enter \u3067\u3082\u53EF\uFF09
112
+ Ctrl+R \u76F4\u524D\u306E\u30C4\u30FC\u30EB\u51FA\u529B\u3092\u5168\u6587\u5C55\u958B
113
+ Ctrl+C \u4E2D\u65AD\uFF08\u5165\u529B\u304C\u7A7A\u306A\u3089 2 \u56DE\u3067\u7D42\u4E86\uFF09 \xB7 Ctrl+D \u7D42\u4E86
114
+
115
+ \u76E3\u67FB\u30ED\u30B0:
116
+ ~/.twp/logs/session-*.jsonl
117
+ \u30C4\u30FC\u30EB\u540D\u30FB\u6A29\u9650\u5224\u65AD\u3068\u305D\u306E\u6839\u62E0\u30921\u884C1\u4EF6\u3067\u6B8B\u3059\uFF0814\u65E5\u30FB200\u672C\u3067
118
+ \u81EA\u52D5\u524A\u9664\u3002POSIX \u3067\u306F 0600 / Windows \u306F OS \u65E2\u5B9A\u306E ACL\uFF09\u3002
119
+ \u672C\u6587\u30FB\u5DEE\u5206\u306F\u66F8\u304B\u306A\u3044\u3002TWP_NO_AUDIT=1 \u3067\u7121\u52B9\u5316
120
+
121
+ \u26A0 **\u30E2\u30C7\u30EB\u304C\u4F1A\u8A71\u4E2D\u306B\u547C\u3076**\u30C4\u30FC\u30EB\uFF08twp_*\uFF09\u306F\u307E\u3060\u3042\u308A\u307E\u305B\u3093\u3002
122
+ \u4E0A\u306E\u300C\u30C9\u30E1\u30A4\u30F3\u30B3\u30DE\u30F3\u30C9\u300D\u306F\u5229\u7528\u8005\u304C\u76F4\u63A5\u6253\u3064\u3082\u306E\u3067\u3001\u3053\u3061\u3089\u306F\u5B9F\u7269\u3068\u3057\u3066\u52D5\u304D\u307E\u3059\u3002
123
+ \u4F1A\u8A71\u30FB\u30ED\u30FC\u30AB\u30EB\u30C4\u30FC\u30EB\uFF08\u30D5\u30A1\u30A4\u30EB\u30FB\u30B3\u30DE\u30F3\u30C9\u30FBgit\uFF09\u306F\u30C6\u30CA\u30F3\u30C8\u306E\u30AF\u30EC\u30B8\u30C3\u30C8\u3067\u5B9F\u969B\u306B\u52D5\u304D\u307E\u3059\u3002
124
+ `;function ignoreEpipe(stream){stream.on("error",err=>{if(err.code==="EPIPE")process.exit(0);throw err})}async function main(){const nodeMajor=Number(process.versions.node.split(".")[0]);if(nodeMajor<22){process.stderr.write(`twp-cli \u306B\u306F Node.js 22 \u4EE5\u4E0A\u304C\u5FC5\u8981\u3067\u3059\uFF08\u73FE\u5728: ${process.versions.node}\uFF09
125
+ `);process.exit(1)}ignoreEpipe(process.stdout);ignoreEpipe(process.stderr);const args=parseArgv(process.argv.slice(2));if(args.command==="version"){process.stdout.write(`${VERSION}
126
+ `);return}if(args.command==="help"){process.stdout.write(HELP);return}if(args.unknown.length>0){process.stderr.write(`\u4E0D\u660E\u306A\u5F15\u6570: ${args.unknown.join(" ")}
127
+
128
+ ${HELP}`);process.exitCode=2;return}if(args.command==="domain"&&args.domain!==void 0){const{runDomain}=await import("./run-EDV5273K.js");process.exitCode=await runDomain({domain:args.domain,...args.operation!==void 0?{operation:args.operation}:{},argv:args.domainArgv,help:args.domainHelp,globals:{...args.profile!==void 0?{profile:args.profile}:{},...args.output!==void 0?{output:args.output}:{},...args.query!==void 0?{query:args.query}:{},dryRun:args.dryRun,debug:args.debug,yes:args.yes,refresh:args.
129
+ refresh},version:VERSION});return}if(args.command==="update"){const{runUpdate}=await import("./update-WDWUECN7.js");process.exitCode=await runUpdate({...args.profile!==void 0?{profile:args.profile}:{},version:VERSION});return}if(args.command==="login"||args.command==="logout"||args.command==="whoami"){const{runLogin,runLogout,runWhoami}=await import("./commands-QKNOQRWT.js");const options={profile:args.profile,method:args.loginMethod,tenant:args.tenant,noBrowser:args.loginNoBrowser,cliVersion:VERSION};
130
+ const runner=args.command==="login"?runLogin:args.command==="logout"?runLogout:runWhoami;process.exitCode=await runner(options);return}if(args.command==="task-loop"){const{runTaskLoop}=await import("./commands-T47RY6EH.js");process.exitCode=await runTaskLoop({action:args.taskLoopAction??"run",project:args.project,profile:args.profile,safe:args.safe,daemon:args.daemon,interval:args.interval,maxCycles:args.maxCycles,forceRunner:args.forceRunner,force:args.stopForce,drain:args.stopDrain,engine:args.
131
+ engine,version:VERSION,verbose:args.verbose,scheduleNow:args.scheduleNow,scheduleCounts:args.scheduleCounts,scheduleGate:args.scheduleGate,yes:args.yes,ais:args.ais,workspace:args.workspace,aiConfigFile:args.aiConfigFile,noAiConfigFile:args.noAiConfigFile});return}if(args.command==="print"){const{runOneShot}=await import("./oneshot-JD5LINMX.js");process.exitCode=await runOneShot({prompt:args.prompt??"",fromStdin:args.promptFromStdin,mode:args.mode??"dev",...args.permissionMode!==void 0?{permissionMode:args.
132
+ permissionMode}:{},...args.model!==void 0?{model:args.model}:{},...args.profile!==void 0?{profile:args.profile}:{},version:VERSION});return}const{startTui}=await import("./app-S33SNSH5.js");await startTui({mode:args.mode,permissionMode:args.permissionMode,model:args.model,profile:args.profile,noTui:args.noTui||!process.stdout.isTTY,doctor:args.doctor,version:VERSION})}await main();
@@ -0,0 +1,60 @@
1
+ import { createRequire as __twpCreateRequire } from 'node:module';
2
+ const require = __twpCreateRequire(import.meta.url);
3
+ import{PromptAbortedError,promptHidden,promptText}from"./chunk-L37NS5L2.js";import{system32}from"./chunk-N2UVRM3Z.js";import{ApiError,TwpApiClient}from"./chunk-7ZVTACQS.js";import{isWindowsDriveAbsolute}from"./chunk-PMOUHEJQ.js";import{AuthSession,NotLoggedInError,SessionExpiredError,deleteCredentials,loadCredentials,maskToken,saveCredentials}from"./chunk-63LDNYGW.js";import{effectiveApiUrl,resolveProfile}from"./chunk-NERYSBA4.js";import"./chunk-RZVI6PMW.js";
4
+ import{httpFetch}from"./chunk-J7QYPKVK.js";import{stripTerminalControls}from"./chunk-NHYMHCAT.js";import"./chunk-VSJBJXZO.js";import os from"os";import{createHash,randomBytes}from"crypto";function generatePkcePair(){const verifier=randomBytes(32).toString("base64url");return{verifier,challenge:computeChallenge(verifier),method:"S256"}}function computeChallenge(verifier){return createHash("sha256").update(verifier,"ascii").digest("base64url")}function generateState(){return randomBytes(16).toString("base64url")}import http from"http";import crypto from"crypto";function safeEqual(a,b){const x=Buffer.from(a,"utf8");const y=Buffer.from(b,"utf8");const len=Math.max(x.length,y.length,1);const px=Buffer.alloc(len);const py=Buffer.alloc(len);x.copy(px);y.copy(py);return crypto.timingSafeEqual(px,py)&&x.length===y.length}var LoginTimeoutError=class extends Error{constructor(timeoutMs){super(`\u30D6\u30E9\u30A6\u30B6\u3067\u306E\u627F\u8A8D\u3092 ${Math.round(timeoutMs/1e3)} \u79D2\u5F85\u3061\u307E\u3057\u305F\u304C\u5B8C\u4E86\u3057\u307E\u305B\u3093\u3067\u3057\u305F\u3002twp login \u3092\u3084\u308A\u76F4\u3057\u3066\u304F\u3060\u3055\
5
+ \u3044\u3002`)}};var SUCCESS_HTML=`<!doctype html><html lang="ja"><head><meta charset="utf-8"><title>TWP CLI \u30ED\u30B0\u30A4\u30F3\u5B8C\u4E86</title></head>
6
+ <body style="font-family: sans-serif; text-align: center; padding-top: 4rem; background:#f7f9fc; color:#1b2559">
7
+ <h1 style="font-size:1.4rem">\u2705 \u30ED\u30B0\u30A4\u30F3\u304C\u5B8C\u4E86\u3057\u307E\u3057\u305F</h1>
8
+ <p>\u3053\u306E\u753B\u9762\u3092\u9589\u3058\u3066\u3001\u30BF\u30FC\u30DF\u30CA\u30EB\u306B\u623B\u3063\u3066\u304F\u3060\u3055\u3044\u3002</p>
9
+ </body></html>`;var ERROR_HTML=msg=>`<!doctype html><html lang="ja"><head><meta charset="utf-8"><title>TWP CLI \u30ED\u30B0\u30A4\u30F3\u30A8\u30E9\u30FC</title></head>
10
+ <body style="font-family: sans-serif; text-align: center; padding-top: 4rem; background:#f7f9fc; color:#1b2559">
11
+ <h1 style="font-size:1.4rem">\u26A0 \u30ED\u30B0\u30A4\u30F3\u3092\u5B8C\u4E86\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F</h1>
12
+ <p>${msg}</p>
13
+ <p>\u30BF\u30FC\u30DF\u30CA\u30EB\u3067 <code>twp login</code> \u3092\u3084\u308A\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002</p>
14
+ </body></html>`;function startLoopbackListener(expectedState,timeoutMs=3e5){return new Promise((resolveListener,rejectListener)=>{let resolveCode=null;let rejectCode=null;let settled=false;const codePromise=new Promise((resolve,reject)=>{resolveCode=resolve;rejectCode=reject});let closed=false;let succeeded=false;const release=force=>{if(!closed){closed=true;server.close()}if(force)server.closeAllConnections();else server.closeIdleConnections()};const respond=(res,status,html,onFlush)=>{const body=Buffer.
15
+ from(html,"utf8");res.writeHead(status,{"Content-Type":"text/html; charset=utf-8","Content-Length":String(body.byteLength),Connection:"close"});res.end(body,onFlush)};const server=http.createServer((req,res)=>{let url;try{url=new URL(req.url??"/","http://127.0.0.1")}catch{respond(res,400,ERROR_HTML("\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u4E0D\u6B63\u3067\u3059\u3002"));return}if(url.pathname!=="/callback"){respond(res,404,ERROR_HTML("\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002"));return}const code=url.
16
+ searchParams.get("code");const state=url.searchParams.get("state");if(!code||state===null||!safeEqual(state,expectedState)){respond(res,400,ERROR_HTML("\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u4E0D\u6B63\u3067\u3059\uFF08state \u4E0D\u4E00\u81F4\uFF09\u3002"));return}if(succeeded){respond(res,200,SUCCESS_HTML);return}if(settled){respond(res,400,ERROR_HTML("\u30ED\u30B0\u30A4\u30F3\u306F\u65E2\u306B\u4E2D\u65AD\u3055\u308C\u3066\u3044\u307E\u3059\u3002"));return}settled=true;succeeded=true;clearTimeout(
17
+ timer);res.on("close",()=>release(true));respond(res,200,SUCCESS_HTML,()=>release(true));resolveCode?.(code)});const timer=setTimeout(()=>{if(!settled){settled=true;release(true);rejectCode?.(new LoginTimeoutError(timeoutMs))}},timeoutMs);timer.unref();server.once("error",err=>rejectListener(err));server.listen(0,"127.0.0.1",()=>{const address=server.address();if(!address||typeof address==="string"){rejectListener(new Error("loopback listener \u306E\u30DD\u30FC\u30C8\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"));
18
+ return}const port=address.port;resolveListener({port,redirectUri:`http://127.0.0.1:${port}/callback`,waitForCode:()=>codePromise,close:()=>{settled=true;clearTimeout(timer);release(!succeeded)}})})})}import{spawn}from"child_process";import fs from"fs";function isWsl(env=process.env){if(env.WSL_DISTRO_NAME||env.WSL_INTEROP)return true;try{return fs.readFileSync("/proc/version","utf8").toLowerCase().includes("microsoft")}catch{return false}}function isHeadless(env=process.env,platform=process.platform){if(platform!=="linux")return false;if(env.DISPLAY||env.WAYLAND_DISPLAY)return false;if(env.BROWSER&&env.BROWSER.trim()!=="")return false;if(isWsl(env))return false;return true}function escapeForCmd(url){return url.replace(/[&|^<>()]/g,c=>`^${c}`)}
19
+ function browserCandidates(url,env=process.env,platform=process.platform,wsl=isWsl(env)){const candidates=[];if(env.BROWSER&&env.BROWSER.trim()!==""){const browser=env.BROWSER.trim();if(platform!=="win32"||isWindowsDriveAbsolute(browser)){candidates.push({cmd:browser,args:[url]})}}if(platform==="darwin"){candidates.push({cmd:"open",args:[url]})}else if(platform==="win32"){const cmdExe=system32(env,"cmd.exe");if(cmdExe!==null){candidates.push({cmd:cmdExe,args:["/c","start",'""',escapeForCmd(url)]})}
20
+ const powershellExe=system32(env,"WindowsPowerShell","v1.0","powershell.exe");if(powershellExe!==null){candidates.push({cmd:powershellExe,args:["-NoProfile","-NonInteractive","-Command",`Start-Process '${url.replace(/'/g,"''")}'`]})}}else{candidates.push({cmd:"xdg-open",args:[url]});if(wsl){candidates.push({cmd:"wslview",args:[url]});candidates.push({cmd:"cmd.exe",args:["/c","start",'""',escapeForCmd(url)]});candidates.push({cmd:"powershell.exe",args:["-NoProfile","-NonInteractive","-Command",`S\
21
+ tart-Process '${url.replace(/'/g,"''")}'`]})}}return candidates}function tryCandidate(candidate,settleMs){return new Promise(resolve=>{let child;try{child=spawn(candidate.cmd,candidate.args,{stdio:"ignore",detached:process.platform!=="win32",shell:false})}catch{resolve(false);return}const timer=setTimeout(()=>{child.unref();resolve(true)},settleMs);child.once("error",()=>{clearTimeout(timer);resolve(false)});child.once("exit",code=>{clearTimeout(timer);resolve(code===0)})})}async function openBrowser(url,env=process.
22
+ env,platform=process.platform,settleMs=1500){for(const candidate of browserCandidates(url,env,platform)){if(await tryCandidate(candidate,settleMs))return true}return false}var LoginError=class extends Error{};var OOB_REDIRECT_URI="urn:ietf:wg:oauth:2.0:oob";var defaultIo=cliVersion=>({out:text=>process.stdout.write(stripTerminalControls(text)),fetchImpl:httpFetch,cliVersion});function defaultDeviceName(){let user="unknown";try{user=os.userInfo().username}catch{}return`${user}@${os.hostname()} (${process.platform})`.slice(0,100)}async function parseJson(res){try{return await res.json()}catch{return null}}function describeHttpError(status,body){const pick=()=>{if(body?.
23
+ error_description)return body.error_description;if(body?.errors){const first=Object.values(body.errors).flat()[0];if(first)return first}if(body?.message)return body.message;return`HTTP ${status}`};return stripTerminalControls(pick())}function toStoredCredentials(body,method,profile){if(typeof body.token!=="string"||body.token===""){throw new LoginError("\u30B5\u30FC\u30D0\u5FDC\u7B54\u306B\u30C8\u30FC\u30AF\u30F3\u304C\u542B\u307E\u308C\u3066\u3044\u307E\u305B\u3093\u3002")}const user=body.user;
24
+ return{token:body.token,token_expires_at:body.token_expires_at??null,refresh_token:body.refresh_token??null,refresh_token_expires_at:body.refresh_token_expires_at??null,api_url:profile.apiUrl,frontend_url:profile.frontendUrl,relay_url:profile.relayUrl,tenant_code:user?.tenant_code??null,user:user?{id:user.id,name:user.name,email:user.email}:null,method,saved_at:new Date().toISOString()}}function reportLoggedIn(io,profile,creds){const safe=value=>stripTerminalControls(value??"");const who=creds.user?
25
+ `${safe(creds.user.name)}\uFF08${safe(creds.user.email)}\uFF09`:"(\u30E6\u30FC\u30B6\u30FC\u60C5\u5831\u306A\u3057)";const tenant=creds.tenant_code?` / \u30C6\u30CA\u30F3\u30C8: ${safe(creds.tenant_code)}`:"";io.out(`
26
+ \u2705 \u30ED\u30B0\u30A4\u30F3\u3057\u307E\u3057\u305F: ${who}${tenant}
27
+ `);io.out(` \u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${profile.name} \u2192 ${profile.apiUrl}
28
+ `);if(!creds.refresh_token){io.out(" \u26A0 refresh token \u304C\u3042\u308A\u307E\u305B\u3093\u3002\u30C8\u30FC\u30AF\u30F3\u5931\u52B9\u6642\u306F\u518D\u30ED\u30B0\u30A4\u30F3\u304C\u5FC5\u8981\u3067\u3059\u3002\n")}}function consentUrl(profile,io,challenge,redirectUri,state){const params=new URLSearchParams({code_challenge:challenge,redirect_uri:redirectUri,device:defaultDeviceName(),cli_version:io.cliVersion});if(state)params.set("state",state);return`${profile.frontendUrl}/auth/cli?${params.
29
+ toString()}`}async function exchangeCode(profile,io,code,verifier){const res=await io.fetchImpl(`${profile.apiUrl}/api/v2/auth/cli/exchange`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({code,code_verifier:verifier})});const body=await parseJson(res);if(!res.ok||!body?.result){throw new LoginError(`\u30C8\u30FC\u30AF\u30F3\u4EA4\u63DB\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${describeHttpError(res.status,body)}`)}return body}async function finishBrowserLogin(profile,env,io,body){
30
+ const creds=toStoredCredentials(body,"browser",profile);await saveCredentials(profile.name,creds,env);reportLoggedIn(io,profile,creds);return creds}async function oobLogin(profile,env=process.env,io=defaultIo("0.0.0-dev")){const pkce=generatePkcePair();const url=consentUrl(profile,io,pkce.challenge,OOB_REDIRECT_URI);io.out("\u3053\u306E\u74B0\u5883\u3067\u306F\u30D6\u30E9\u30A6\u30B6\u306E\u30B3\u30FC\u30EB\u30D0\u30C3\u30AF\u3092\u53D7\u3051\u53D6\u308C\u307E\u305B\u3093\u3002\u30B3\u30FC\u30C9\u306E\u8CBC\u308A\u4ED8\u3051\u3067\u9032\u3081\u307E\u3059\u3002\n\n");
31
+ io.out(` 1. \u6B21\u306E URL \u3092\u624B\u5143\u306E PC \u306E\u30D6\u30E9\u30A6\u30B6\u3067\u958B\u3044\u3066\u627F\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044:
32
+ ${url}
33
+ `);io.out(" 2. \u753B\u9762\u306B\u8868\u793A\u3055\u308C\u305F\u8A8D\u53EF\u30B3\u30FC\u30C9\u3092\u8CBC\u308A\u4ED8\u3051\u3066\u304F\u3060\u3055\u3044\uFF08Ctrl+C \u3067\u4E2D\u6B62\uFF09:\n\n");const code=(await promptText("\u8A8D\u53EF\u30B3\u30FC\u30C9 > ")).trim();if(!code)throw new LoginError("\u8A8D\u53EF\u30B3\u30FC\u30C9\u304C\u5165\u529B\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002twp login \u3092\u3084\u308A\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\u3002");const body=await exchangeCode(
34
+ profile,io,code,pkce.verifier);return finishBrowserLogin(profile,env,io,body)}async function browserLogin(profile,env=process.env,io=defaultIo("0.0.0-dev"),options={}){if(options.noBrowser||isHeadless(env)){return oobLogin(profile,env,io)}const pkce=generatePkcePair();const state=generateState();const listener=await startLoopbackListener(state);try{const url=consentUrl(profile,io,pkce.challenge,listener.redirectUri,state);io.out("\u30D6\u30E9\u30A6\u30B6\u3067 TWP \u306E\u30ED\u30B0\u30A4\u30F3\u30FB\u627F\u8A8D\u753B\u9762\u3092\u958B\u304D\u307E\u3059\u2026\n");
35
+ const opened=await openBrowser(url,env);if(!opened){io.out("\u26A0 \u30D6\u30E9\u30A6\u30B6\u3092\u81EA\u52D5\u3067\u958B\u3051\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u30B3\u30FC\u30C9\u306E\u8CBC\u308A\u4ED8\u3051\u306B\u5207\u308A\u66FF\u3048\u307E\u3059\u3002\n\n");listener.close();return await oobLogin(profile,env,io)}io.out(`\u958B\u304B\u306A\u3044\u5834\u5408\u306F\u6B21\u306E URL \u3092\u624B\u52D5\u3067\u958B\u3044\u3066\u304F\u3060\u3055\u3044:
36
+ ${url}
37
+
38
+ `);io.out("\u30D6\u30E9\u30A6\u30B6\u3067\u306E\u627F\u8A8D\u3092\u5F85\u3063\u3066\u3044\u307E\u3059\u2026\uFF08Ctrl+C \u3067\u4E2D\u6B62\uFF09\n");const code=await listener.waitForCode();const body=await exchangeCode(profile,io,code,pkce.verifier);return await finishBrowserLogin(profile,env,io,body)}finally{listener.close()}}async function passwordLogin(profile,options={},env=process.env,io=defaultIo("0.0.0-dev")){const tenantCode=options.tenantCode??profile.tenantCode??await promptText("\u30C6\u30CA\u30F3\u30C8\u30B3\
39
+ \u30FC\u30C9: ");if(!tenantCode)throw new LoginError("\u30C6\u30CA\u30F3\u30C8\u30B3\u30FC\u30C9\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002");const tenantRes=await io.fetchImpl(`${profile.apiUrl}/api/v2/auth/tenants/${encodeURIComponent(tenantCode)}`,{headers:{Accept:"application/json"}});const tenantInfo=await parseJson(tenantRes);if(!tenantRes.ok||!tenantInfo?.result){throw new LoginError(`\u30C6\u30CA\u30F3\u30C8\u300C${tenantCode}\u300D\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F: ${describeHttpError(
40
+ tenantRes.status,tenantInfo)}`)}if(tenantInfo.password_auth_enabled===false){throw new LoginError(`\u30C6\u30CA\u30F3\u30C8\u300C${tenantCode}\u300D\u306F\u30D1\u30B9\u30EF\u30FC\u30C9\u8A8D\u8A3C\u304C\u7121\u52B9\u3067\u3059\uFF08SSO \u5C02\u7528\uFF09\u3002\u30D6\u30E9\u30A6\u30B6\u7D4C\u7531\u306E \`twp login\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`)}const loginId=options.loginId??await promptText("\u30ED\u30B0\u30A4\u30F3ID\uFF08\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9\uFF09: ");
41
+ const password=options.password??await promptHidden("\u30D1\u30B9\u30EF\u30FC\u30C9: ");const res=await io.fetchImpl(`${profile.apiUrl}/api/v2/auth/cli/login`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({tenant_code:tenantCode,login_id:loginId,password,keep_login:true,device_name:defaultDeviceName(),cli_version:io.cliVersion})});let body=await parseJson(res);if(!res.ok||!body?.result){throw new LoginError(`\u30ED\u30B0\u30A4\u30F3\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${describeHttpError(
42
+ res.status,body)}`)}if(body.is_two_factor_authentication){if(!body.two_factor_token){throw new LoginError("2\u6BB5\u968E\u8A8D\u8A3C\u30C8\u30FC\u30AF\u30F3\u304C\u30B5\u30FC\u30D0\u5FDC\u7B54\u306B\u542B\u307E\u308C\u3066\u3044\u307E\u305B\u3093\u3002")}io.out(`\u8A8D\u8A3C\u30B3\u30FC\u30C9\u3092\u9001\u4FE1\u3057\u307E\u3057\u305F\uFF08${body.two_factor_type??"email"}\uFF09\u3002
43
+ `);const code=await promptText("\u8A8D\u8A3C\u30B3\u30FC\u30C9\uFF086\u6841\uFF09: ");const verifyRes=await io.fetchImpl(`${profile.apiUrl}/api/v2/auth/two-factor/verify`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({token:body.two_factor_token,code})});body=await parseJson(verifyRes);if(!verifyRes.ok||!body?.result){throw new LoginError(`2\u6BB5\u968E\u8A8D\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F: ${describeHttpError(verifyRes.
44
+ status,body)}`)}}const creds=toStoredCredentials(body,"password",profile);await saveCredentials(profile.name,creds,env);reportLoggedIn(io,profile,creds);return creds}async function tokenLogin(profile,env=process.env,io=defaultIo("0.0.0-dev")){const token=env.TWP_TOKEN?.trim()||await promptHidden("\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3: ");if(!token)throw new LoginError("\u30C8\u30FC\u30AF\u30F3\u304C\u5165\u529B\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002");const res=await io.fetchImpl(
45
+ `${profile.apiUrl}/api/v2/user`,{headers:{Accept:"application/json",Authorization:`Bearer ${token}`}});if(!res.ok){throw new LoginError(`\u30C8\u30FC\u30AF\u30F3\u306E\u691C\u8A3C\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08GET /api/v2/user -> ${res.status}\uFF09\u3002\u5024\u3068\u63A5\u7D9A\u5148\uFF08${profile.apiUrl}\uFF09\u3092\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002`)}const me=(await parseJson(res))?.user;const creds={token,token_expires_at:null,refresh_token:null,refresh_token_expires_at:null,
46
+ api_url:profile.apiUrl,frontend_url:profile.frontendUrl,relay_url:profile.relayUrl,tenant_code:me?.tenant_code??null,user:me?.id?{id:me.id,name:me.name??"",email:me.email??""}:null,method:"token",saved_at:new Date().toISOString()};await saveCredentials(profile.name,creds,env);reportLoggedIn(io,profile,creds);io.out(" \u26A0 \u30E2\u30C7\u30EB\u53D6\u6B21\uFF08\u4F1A\u8A71\uFF09\u306B\u306F `cli` \u6A29\u9650\u4ED8\u304D\u30C8\u30FC\u30AF\u30F3\u304C\u5FC5\u8981\u3067\u3059\u3002\u3053\u3053\u3067\u4FDD\u5B58\u3057\u305F\u30C8\u30FC\u30AF\u30F3\u304C\n `twp login` / `twp login --password` \u7531\u6765\u3067\u306A\u3044\u5834\u5408\u3001\u4F1A\u8A71\u306F 401 \u306B\u306A\u308A\u307E\u3059\u3002\n");
47
+ return creds}function writeOut(text){process.stdout.write(stripTerminalControls(text))}function writeErr(text){process.stderr.write(stripTerminalControls(text))}function makeIo(cliVersion){return{out:writeOut,fetchImpl:httpFetch,cliVersion}}async function run(fn){try{await fn();return 0}catch(err){if(err instanceof PromptAbortedError){writeErr("\n\u4E2D\u6B62\u3057\u307E\u3057\u305F\u3002\n");return 130}if(err instanceof LoginError||err instanceof LoginTimeoutError||err instanceof NotLoggedInError||err instanceof
48
+ SessionExpiredError||err instanceof ApiError){writeErr(`${err.message}
49
+ `);return 1}writeErr(`\u30A8\u30E9\u30FC: ${err.message}
50
+ `);return 1}}async function runLogin(options){return run(async()=>{const profile=resolveProfile(options.profile);const io=makeIo(options.cliVersion);if(options.method==="password"){await passwordLogin(profile,{tenantCode:options.tenant??void 0},process.env,io)}else if(options.method==="token"){await tokenLogin(profile,process.env,io)}else{await browserLogin(profile,process.env,io,{noBrowser:options.noBrowser})}})}async function runLogout(options){return run(async()=>{const profile=resolveProfile(
51
+ options.profile);const creds=loadCredentials(profile.name);if(!creds){writeOut(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB\u300C${profile.name}\u300D\u306F\u30ED\u30B0\u30A4\u30F3\u3057\u3066\u3044\u307E\u305B\u3093\u3002
52
+ `);return}const apiUrl=effectiveApiUrl(profile,creds.api_url);const revoked=await httpFetch(`${apiUrl}/api/v2/auth/logout`,{method:"POST",headers:{Accept:"application/json",Authorization:`Bearer ${creds.token}`}}).then(res=>res.ok,()=>false);await deleteCredentials(profile.name);writeOut(`\u2705 \u30ED\u30B0\u30A2\u30A6\u30C8\u3057\u307E\u3057\u305F\uFF08\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${profile.name} / \u30C8\u30FC\u30AF\u30F3: ${maskToken(creds.token)}\uFF09
53
+ `);if(!revoked){writeOut("\u26A0 \u30B5\u30FC\u30D0\u5074\u306E\u30C8\u30FC\u30AF\u30F3\u5931\u52B9\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08\u30AA\u30D5\u30E9\u30A4\u30F3\u7B49\uFF09\u3002TWP \u306E\u300C\u8A2D\u5B9A > CLI\u7AEF\u672B\u300D\u304B\u3089\u3082\u5931\u52B9\u3067\u304D\u307E\u3059\u3002\n")}})}async function runWhoami(options){return run(async()=>{const profile=resolveProfile(options.profile);const stored=loadCredentials(profile.name);const apiUrl=effectiveApiUrl(profile,stored?.
54
+ api_url);const session=new AuthSession(profile.name,apiUrl);const client=new TwpApiClient(apiUrl,session,httpFetch,options.cliVersion);const me=await client.get("/api/v2/user");const user=me.user;const creds=loadCredentials(profile.name);writeOut(`\u30E6\u30FC\u30B6\u30FC: ${user?.name??"?"}\uFF08${user?.email??"?"}\uFF09
55
+ `);writeOut(`\u30C6\u30CA\u30F3\u30C8: ${user?.tenant_code??"?"}
56
+ `);writeOut(`\u30ED\u30FC\u30EB: ${user?.role??"?"}${user?.is_admin?"\uFF08\u7BA1\u7406\u8005\uFF09":""}
57
+ `);writeOut(`\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB: ${profile.name}
58
+ `);writeOut(`API: ${apiUrl}
59
+ `);if(creds?.token_expires_at){writeOut(`\u30C8\u30FC\u30AF\u30F3\u671F\u9650: ${creds.token_expires_at}
60
+ `)}})}export{runLogin,runLogout,runWhoami};