
    #j                   ~   d Z ddlmZ ddlZddlZddlZddlZddlZddlZddl	Z	ddl
mZ ddlmZmZ ddlmZ ddlmZ ddlmZmZmZ d	d
ddddddZdbdZdcdZdddZdedZdfd!Zdgd#Zdhd%Zdid)Z djd+Z!dkd,Z"djd-Z#dld0Z$djd1Z%djd2Z&djd3Z'djd4Z(djd5Z)djd6Z*djd7Z+dmd8Z,djd9Z-djd:Z.djd;Z/djd<Z0djd=Z1djd>Z2djd?Z3djd@Z4djdAZ5djdBZ6djdCZ7djdDZ8djdEZ9djdFZ:djdGZ;dndIZ<djdJZ=djdKZ>djdLZ?djdMZ@djdNZAdjdOZBdjdPZCdjdQZDdjdRZEdjdSZFdjdTZGdjdUZHdjdVZIdjdWZJdjdXZKdjdYZLdjdZZMdjd[ZNdjd\ZOdjd]ZPdjd^ZQd_ZRdodaZSdS )pu)  CLI for the Hermes Kanban board — ``hermes kanban …`` subcommand.

Exposes the full Kanban command surface documented in the design spec
(``docs/hermes-kanban-v1-spec.pdf``).  All DB work is delegated to
``kanban_db``.  This module adds:

  * Argparse subcommand construction (``build_parser``).
  * Argument dispatch (``kanban_command``).
  * Output formatting (plain text + ``--json``).
  * A short shared helper that parses a single slash-style string
    (used by ``/kanban …`` in CLI and gateway) and forwards it to the
    argparse surface.
    )annotationsN)Path)AnyOptional)	kanban_db)kanban_swarm)get_active_profile_nameget_profile_dirseed_profile_skillsu   ◻u   ▶   ●u   ⏱u   ⊘u   ✓u   —)todoreadyrunning	scheduledblockeddonearchivedtsOptional[int]returnstrc                X    | sdS t          j        dt          j        |                     S )N z%Y-%m-%d %H:%M)timestrftime	localtime)r   s    6/home/ubuntu/.hermes/hermes-agent/hermes_cli/kanban.py_fmt_tsr   /   s,     r=)4>"+=+=>>>    tkb.Taskc           
         t                               | j        d          }| j        pd}| j        rd| j         dnd}| d| j         d| j        dd|d	| d| j         
S )
N?(unassigned) []r      8s20s)_STATUS_ICONSgetstatusassigneetenantidtitle)r    iconr.   r/   s       r   _fmt_task_liner3   5   s    QXs++Dz+^H!"1!(rFMMQTMMQXMMMHMM&MMAGMMMr   dict[str, Any]c                l   i d| j         d| j        d| j        d| j        d| j        d| j        d| j        d| j        d	| j        d
| j	        d| j
        d| j        d| j        d| j        d| j        d| j        rt!          | j                  ng d| j        | j        | j        | j        dS )Nr0   r1   bodyr.   r-   priorityr/   workspace_kindworkspace_pathbranch_name
created_by
created_at
started_atcompleted_atresultskillsmax_retries)
session_idworkflow_template_idcurrent_step_key)r0   r1   r6   r.   r-   r7   r/   r8   r9   r:   r;   r<   r=   r>   r?   r@   listrA   rB   rC   rD   )r    s    r   _task_to_dictrF   <   s+   ad 	 	AJ	
 	!( 	AJ 	!( 	!* 	!* 	q} 	al 	al 	al 	 	!(  	AH4$qx..."!" 	q}#$ l ! 6.)   r   argsargparse.NamespaceOptional[dict[str, str]]c                p    t          | dd           }t          | dd           }|d u |d u k    rd S |i S ||dS )N
state_type
state_name)rK   rL   )getattr)rG   stsns      r   _run_state_kwargsrP   U   sT    	|T	*	*B	|T	*	*B
d
d
##t	z	B///r   valuetuple[str, Optional[str]]c                x   | sdS |                                  }|dv r|dfS dD ]\  }}|                    |          s|t          |          d                                          }|st          j        d| d          |t
          j                            |          fc S t          j        d| d          )	zParse ``--workspace`` into ``(kind, path|None)``.

    Accepts: ``scratch``, ``worktree``, ``worktree:<path>``, ``dir:<path>``.
    )scratchN>   rT   worktreeN))zdir:dir)z	worktree:rU   z--workspace z  requires a path after the colonzunknown --workspace value z7: use scratch, worktree, worktree:<path>, or dir:<path>)strip
startswithlenargparseArgumentTypeErrorospath
expanduser)rQ   vprefixkindr]   s        r   _parse_workspace_flagrb   _   s    
  !  A###4yD 0 0||F## 	V$$&& 	,GvGGG   bg((..////

$	)U 	) 	) 	)  r   Optional[str]c                   | dS |                                  }|st          j        d          |                    d          rt          j        d          t	          d |D                       rt          j        d          |S )zBNormalize an optional branch name from ``kanban create --branch``.Nz"--branch requires a non-empty name-z --branch must not start with '-'c              3  >   K   | ]}|                                 V  d S N)isspace).0chs     r   	<genexpr>z%_parse_branch_flag.<locals>.<genexpr>   s*      
)
)B2::<<
)
)
)
)
)
)r   z$--branch must not contain whitespace)rW   rZ   r[   rX   any)rQ   branchs     r   _parse_branch_flagrn   x   s    }t[[]]F O()MNNN M()KLLL

)
)&
)
)
))) Q()OPPPMr   tuple[bool, str]c                 L   	 ddl m}  n# t          $ r Y dS w xY w	  |             }n# t          $ r Y dS w xY w	 ddlm}  |            }t          |                    di                               dd                    }n# t          $ r d}Y nw xY w|r
|rdd| d	fS |r|sd
S dS )u  Return ``(running, message)``.

    - ``running=True``: a gateway is alive for this HERMES_HOME and its
      config has ``kanban.dispatch_in_gateway`` on (default). Message
      is a short status line.
    - ``running=False``: either no gateway is running, or the gateway
      is running but the config flag is off. Message is human guidance
      explaining the next step.

    Used by ``hermes kanban create`` (and callers) to warn when a task
    will sit in ``ready`` because nothing is there to pick it up.
    Defensive against import failures and config-read errors — if the
    probe itself errors, we return ``(True, "")`` so we don't spam
    false warnings (better to miss a warning than to cry wolf).
    r   )get_running_pid)Tr   load_configkanbandispatch_in_gatewayTzgateway pid=z, dispatch enabled)Fu   Gateway is running but kanban.dispatch_in_gateway=false in config.yaml — the task will sit in 'ready' until you flip it back on and restart the gateway, OR run the legacy standalone daemon (`hermes kanban daemon --force`).)Fu   No gateway is running — the task will sit in 'ready' until you start it. Run:
    hermes gateway start
The gateway hosts an embedded dispatcher (tick interval 60s by default); your task will be picked up on the next tick after the gateway comes up.)gateway.statusrq   	Exceptionhermes_cli.configrs   boolr,   )rq   pidrs   cfgdispatch_ons        r   _check_dispatcher_presencer}      s3    2222222   zzo   zz111111kmm3778R00445JDQQRR     >{ ><S<<<==
 
; 

 
 s*   	 

& 
44AB   BBparent_subparsersargparse._SubParsersActionargparse.ArgumentParserc           	     '   |                      ddd          }|                    dddd	           |                    d
          }|                     dd           |                     ddd          }|                    d          }|                     ddgd          }|                    dd           |                    ddd           |                     ddgd          }|                    d d!           |                    d"dd#$           |                    d%dd&$           |                    d'dd($           |                    d)dd*$           |                    d+dd,           |                    d-dd.$           |                     d/d0d1gd2          }|                    d            |                    d3dd4           |                     d5d6gd7          }|                    d            |                     d8d9gd:           |                     d;d<          }	|	                    d            |	                    d=d>           |                     d?d@          }
|
                    d            |
                    dAdBddCD           |                     ddE          }|                    dFdG           |                    dHddI$           |                    dJddK$           |                    dLdMg dNO           |                    dPdQdR$           |                    dSddT$           |                    dUddV$           |                    dWt          dXdYZ           |                    d[dd\           |                    d]dd^$           |                    d_dd`$           |                    dadbdc$           |                    dddMg dedfg           |                    dht          ddidjt          j         dkl           |                    dmddndop           |                    dqt          ddidrdst           |                    dut          t          j                  dvdwx           |                    dddy           |                     dzd{          }|                    d|d}           |                    d~dMg dd           |                    ddd           |                    ddd           |                    dUddV$           |                    dWt          dXdYZ           |                    dadd$           |                    d]dd$           |                    dddy           |                     ddgd          }|                    ddd           |                    dJd           |                    ddt          t          j                             |                    dUd           |                    ddd$           |                    ddd           |                    dd           |                    ddt          t          j	        
                                          d           |                    dddd	           |                    ddddd           |                     d8d          }|                    d           |                    dd           |                    ddddx           |                    dddd	           |                     dd          }|                    d           |                    dd           |                     dd          }|                    d           |                    ddd$           |                     dd          }|                    d           |                    dd           |                    ddd           |                    ddd$           |                     ddgd          }|                    dg dddx           |                    ddd$           |                    ddd           |                     dd          }|                    d           |                    d           |                     dd¬          }|                    d           |                    d           |                     ddĬ          }|                    d           |                    dt          t          j        dƬZ           |                     ddȬ          }|                    d           |                    dddˬ̦           |                    dddά$           |                    dt          ddЬZ           |                     ddҬ          }|                    dddԬ̦           |                    ddd֬$           |                    dddج$           |                    dddڬ$           |                     ddܬ          }|                    d           |                    dddݬ           |                    dddެ$           |                    ddd߬$           |                     dd          }|                    d           |                    ddd̦           |                    ddddD           |                     dd          }|                    d           |                    ddd̦           |                    ddddD           |                     dd          }|                    ddd$           |                    ddʬ           |                     dd          }|                    d           |                    ddd̦           |                    ddddD           |                    ddd           |                    ddd           |                    dddd           |                     dd          }|                    ddd̦           |                    ddddd            |                     dd          }|                    d           |                    dt          d           |                     dd          }|                    ddd           |                    d	t          dd
Z           |                    dt          t          j        dt          j         dZ           |                    dd           |                     dd          } |                     dt          ddZ           |                     d	t          ddZ           |                     dt          t          j                   |                     ddd$           |                     dddd           |                     ddt          j                   |                     dd          }!|!                    dJdd$           |!                    dUdd$           |!                    ddd$           |!                    dt          ddZ           |                     d d!          }"|"                    dd           |                     d"d#          }#|#                    d           |#                    d$d%           |#                    d&d%           |#                    d'd           |#                    d(d           |#                    d)dd*$           |                     d+d,          }$|$                    ddBd-           |$                    dd           |                     d.d/          }%|%                    d           |%                    d$d%           |%                    d&d%           |%                    d'd           |                     d0d1          }&|&                    d           |&                    d2t          dd3Z           |                     d4d5          }'|'                    d           |'                    dd           |'                    dddd6x           |'                    dddd	           |                     d7d8          }(|(                    d           |(                    d9dd:$           |                     d;d<          })|)                    dd           |                     d=d>          }*|*                    d           |                     d?d@          }+|+                    ddBddAD           |+                    ddBddC           |+                    dUddD$           |+                    dddE$           |+                    dddF           |                     dGdH          },|,                    ddBddID           |,                    ddBddJ           |,                    dUddD$           |,                    dddK$           |,                    dddF           |                     dLdM          }-|-                    dNt          dOdPZ           |-                    dQt          dOdRZ           |                    |S           |S (T  zAttach the ``kanban`` subcommand tree under an existing subparsers.

    Returns the top-level ``kanban`` parser so caller can ``set_defaults``.
    rt   z:Multi-profile collaboration board (tasks, links, comments)a7  Durable SQLite-backed task board shared across Hermes profiles. Tasks are claimed atomically, can depend on other tasks, and are executed by a named profile in an isolated workspace. See https://hermes-agent.nousresearch.com/docs/user-guide/features/kanban or docs/hermes-kanban-v1-spec.pdf for the full design.)helpdescriptionz--boardNz<slug>zBoard slug to operate on. Defaults to the current board (set via `hermes kanban boards switch <slug>` or the HERMES_KANBAN_BOARD env var). Use `hermes kanban boards list` to see all boards.)defaultmetavarr   kanban_actiondestinitz(Create kanban.db if missing (idempotent))r   boardsz9Manage kanban boards (one board per project / workstream)u  Boards let you separate unrelated streams of work (projects, repos, domains) into isolated queues. Each board has its own DB, workspaces directory, and dispatcher loop — tasks on one board cannot collide with tasks on another. The first board is 'default' and always exists.boards_actionrE   lsz List all boards with task counts)aliasesr   z--json
store_true)actionz--allzInclude archived boards too)r   r   createnewzCreate a new boardslugz*Board slug (kebab-case, e.g. atm10-server)z--namez<Human-readable display name (defaults to Title Case of slug))r   r   z--descriptionzOptional descriptionz--iconz9Optional emoji or single-character icon for the dashboardz--colorz5Optional hex color (e.g. '#8b5cf6') for the dashboardz--switchz)Switch to the new board after creating itz--default-workdirz6Default workspace path for tasks created on this boardrmremovedeletez#Archive (default) or delete a boardz--deletezxHard-delete the board directory instead of archiving it. Default is to move it to boards/_archived/ so it's recoverable.switchusez-Set the active board for subsequent CLI callsshowcurrentz%Print the currently-active board slugrenamez@Change a board's human-readable display name (slug is immutable)namezNew display nameset-default-workdirz3Set the default workspace path for tasks on a boardr]   r#   z7Absolute path to use as default workdir. Omit to clear.)nargsr   r   zCreate a new taskr1   z
Task titlez--bodyzOptional opening postz
--assigneezProfile name to assignz--parentappendzParent task id (repeatable))r   r   r   z--workspacerT   zDscratch | worktree | worktree:<path> | dir:<path> (default: scratch)z--branchz/Branch name for worktree tasks, e.g. wt/t6-wirez--tenantzTenant namespacez
--priorityr   zPriority tiebreaker)typer   r   z--triageuJ   Park in triage — a specifier will flesh out the spec and promote to todoz--idempotency-keyzkDedup key. If a non-archived task with this key exists, its id is returned instead of creating a duplicate.z--max-runtimezPer-task runtime cap. Accepts seconds (300) or durations (90s, 30m, 2h, 1d). When exceeded, the dispatcher SIGTERMs (then SIGKILLs) the worker and re-queues the task.z--created-byuserz0Author name recorded on the task (default: user)z--skillr@   zSkill to force-load into the worker (repeatable). Appended to the built-in kanban-worker skill. Example: --skill translation --skill github-code-review)r   r   r   r   z--max-retriesNu   Per-task override for the consecutive-failure circuit breaker. Trip on the Nth failure — e.g. --max-retries 1 blocks on the first failure (no retries), --max-retries 3 allows two retries. Omit to use the dispatcher's kanban.failure_limit config (default z).)r   r   r   r   z--goal	goal_modea=  Run the worker in a goal loop: after each turn a judge checks the response against the card title/body and, if not done, the worker keeps going in the same session until the judge agrees it's complete (or the turn budget runs out, which blocks the card for review). Best for open-ended cards one shot rarely finishes.)r   r   r   z--goal-max-turnsgoal_max_turnszDTurn budget for --goal workers (default 20). Ignored without --goal.)r   r   r   r   r   z--initial-statusr   zInitial card status. Use 'blocked' for cards that require immediate human ops (R3 gate) to skip the brief running-to-blocked transition.)choicesr   r   zEmit JSON outputswarmuN   Create a Kanban Swarm v1 graph (parallel workers → verifier → synthesizer)goalzSwarm goal / final outcomez--workerzPROFILE:TITLE[:SKILL,SKILL]z!Parallel worker card (repeatable))r   r   r   r   z
--verifierTzVerifier profile)requiredr   z--synthesizerzSynthesizer/writer profilezCreator/anchor profilezDedup key for the root cardz
List tasksz--minez%Filter by $HERMES_PROFILE as assignee)r   z--status)r   r   z	--sessionzZFilter by originating chat/agent session id (set on tasks created from inside an ACP loop)z
--archivedzInclude archived tasksz--sortz/Sort order for listed tasks (default: priority))r   r   r   z--workflow-template-idIDz0Restrict to tasks with this workflow_template_idz
--step-keyrD   KEYz,Restrict to tasks with this current_step_key)r   r   r   r   z"Show a task with comments + eventstask_idz--state-type)r-   outcomez9With --state-name: filter listed runs by task_runs columnz--state-nameVALUEz;With --state-type: keep runs whose column equals this valueassignzAssign or reassign a taskprofilez$Profile name (or 'none' to unassign)reclaimz0Release an active worker claim on a running taskz--reasonz7Human-readable reason (recorded on the reclaimed event)reassignzCReassign a task to a different profile, optionally reclaiming firstz(New profile name (or 'none' to unassign)z	--reclaimzIRelease any active claim before reassigning (required if task is running)diagnosticsdiagz,List active diagnostics on the current boardz
--severitywarningerrorcriticalz/Only show diagnostics at or above this severityz--taskz%Only show diagnostics for one task idz9Emit JSON (structured) instead of the default human tablelinkzAdd a parent->child dependency	parent_idchild_idunlinkz!Remove a parent->child dependencyclaimz>Atomically claim a ready task (prints resolved workspace path)z--ttlz#Claim TTL in seconds (default: 900)commentzAppend a commenttext+zComment body)r   r   z--authorz0Author name (default: $HERMES_PROFILE or 'user')z	--max-lenz4Trim the stored comment body to this many characterscompletezMark one or more tasks donetask_idsz;One or more task ids (only --result applies to all of them)z--resultzResult summaryz	--summaryzSStructured handoff summary for downstream tasks. Falls back to --result if omitted.z
--metadatazlJSON dict of structured facts (e.g. '{"changed_files": [...], "tests_run": 12}'). Stored on the closing run.editz1Edit recovery fields on an already-completed taskz+Backfilled task result text for a done taskz>Structured handoff summary. Falls back to --result if omitted.zCJSON dict of structured facts to store on the latest completed run.blockzMark one or more tasks blockedreason*z#Reason (also appended as a comment)z--idsz=Additional task ids to block with the same reason (bulk mode)schedulezFPark one or more tasks in Scheduled (waiting on time, not human input)z/Reason/timing note (also appended as a comment)z@Additional task ids to schedule with the same reason (bulk mode)unblockz3Return one or more blocked/scheduled tasks to readyu[   Optional reason/note — recorded as a comment before unblocking. Quote multi-word reasons.)r   promotezEManually move one or more todo/blocked tasks to ready (recovery path)z4Audit-trail reason (recorded on the task_events row)z?Additional task ids to promote with the same reason (bulk mode)z--forcez=Promote even if parent dependencies are not yet done/archivedz	--dry-runz-Validate the promotion without mutating statejsonz!Emit machine-readable JSON result)r   r   r   archivezArchive one or more tasksz"Task ids to archive (default mode)z--rm	purge_idsz;Permanently delete already-archived task ids from the board)r   r   r   r   tailzFollow a task's event streamz
--intervalg      ?)r   r   dispatchz@One dispatcher pass: reclaim stale, promote ready, spawn workersz<Don't actually spawn processes; just print what would happenz--maxzCap number of spawns this passz--failure-limitzrAuto-block a task after this many consecutive non-success attempts (spawn_failed, timed_out, or crashed; default: )daemonuN   DEPRECATED — dispatcher now runs in the gateway. Use `hermes gateway start`.g      N@z,Seconds between dispatch ticks (default: 60)zCap number of spawns per tickz	--pidfilez,Write the daemon's PID to this file on startz	--verbosez-vz!Log each tick's outcome to stdoutwatchz8Live-stream task_events to the terminal (Ctrl+C to exit)z3Only show events for tasks assigned to this profilez*Only show events from tasks in this tenantz--kindsz[Comma-separated event kinds to include (e.g. 'completed,blocked,gave_up,crashed,timed_out')g      ?z'Poll interval in seconds (default: 0.5)statsz3Per-status + per-assignee counts + oldest-ready agenotify-subscribeziSubscribe a gateway source to a task's terminal events (used by /kanban subscribe in the gateway adapter)z
--platform)r   z	--chat-idz--thread-idz	--user-idz--notifier-profilezNProfile gateway that owns/delivers this subscription (default: active profile)notify-listz>List notification subscriptions (optionally for a single task))r   r   notify-unsubscribez)Remove a gateway subscription from a tasklogzAPrint the worker log for a task (from <kanban-root>/kanban/logs/)z--tailzOnly print the last N bytesrunszUShow attempt history for a task (one row per run: profile, outcome, elapsed, summary)z2With --state-name: filter runs by task_runs column	heartbeatzBEmit a heartbeat event for a running task (worker liveness signal)z--notez3Optional short note attached to the heartbeat event	assigneeszoList known profiles + per-profile task counts (union of ~/.hermes/profiles/ and current assignees on the board)contextz[Print the full context a worker sees for a task (title + body + parent results + comments).specifyzFlesh out a triage-column task into a concrete spec (title + body) and promote it to todo. Uses the auxiliary LLM configured under auxiliary.triage_specifier.z3Task id to specify (required unless --all is given)
all_triagez1Specify every task currently in the triage columnz7When used with --all, restrict the sweep to this tenantzSAuthor name recorded on the audit comment (default: $HERMES_PROFILE or 'specifier')z'Emit one JSON object per task on stdout	decomposezDecompose a triage-column task into a graph of child tasks routed to specialist profiles by description. Falls back to specify-style single-task promotion when the task doesn't benefit from fan-out. Uses auxiliary.kanban_decomposer.z5Task id to decompose (required unless --all is given)z3Decompose every task currently in the triage columnzTAuthor name recorded on the audit comment (default: $HERMES_PROFILE or 'decomposer')gczBGarbage-collect archived-task workspaces, old events, and old logsz--event-retention-days   zEDelete task_events older than N days for terminal tasks (default: 30)z--log-retention-daysz7Delete worker log files older than N days (default: 30))_kanban_parser)
add_parseradd_argumentadd_subparsersintkbDEFAULT_FAILURE_LIMITsortedVALID_INITIAL_STATUSESVALID_STATUSESVALID_SORT_ORDERSkeysDEFAULT_CLAIM_TTL_SECONDSfloatDEFAULT_SPAWN_FAILURE_LIMITrZ   SUPPRESSset_defaults).r~   kanban_parsersubp_boards
boards_subb_listb_createb_rmb_switchb_renameb_set_wdp_createp_swarmp_listp_showp_assign	p_reclaim
p_reassignp_diagp_linkp_unlinkp_claim	p_comment
p_completep_editp_block
p_schedule	p_unblock	p_promote	p_archivep_tailp_dispp_daemonp_watchp_statsp_nsubp_nlistp_nrmp_logp_runsp_hbp_asgp_ctx	p_specifyp_decomposep_gcs.                                                 r   build_parserr     s   
 &00IE	 1 
 
M  !  
 
 
 
&
&O
&
<
<C NN6 JNKKK ~~HG	  
 
H ((o(>>J""/ #  F 666
:  < < < $$5'! %  H &K  M M M(D]  _ _ _/45  7 7 7(DZ  \ \ \)TV  X X X*\J  L L L-tW  Y Y Y   x*2 !  D 	fj]  ^ ^ ^ $$5'< %  H &!!!4    
 $$O %  H &!!!&'9:::$$B %  H &!!!&TX  Z Z Z ~~h-@~AAH'555(D7NOOO,;STTT*Xr<  > > >- 4  5 5 5 *dP  R R R*d9KLLL,S!BWXXX*\k  m m m-t U  V V V /4 9  : : :
 .&Q  S S S)Hbx P  Q Q Q
 /T"% H ,.+C H  H  H  I I I (<k 2  3 3 3 ,3"%,< 9  : : : ,"()B"C"C"+ R  S S S (<>PQQQ nn]   G &BCCC-0     ;MNNN4>Z[[[T8JKKKCAVWWW<TUUU,dA^___,=OPPP ^^FTF^FFF
D  F F F
d333

D &r'8 9 9  ; ; ;

D111
TN  O O O \5  7 7 7
666
r+002233>	      ?	     ;     ^^F)M^NNF
	"""
666
%H	     J	     ~~h-H~IIH)$$$)*PQQQ ?   I 9%%%DF    
 R    J I&&&7     LX     DF     ^^;   F
 000>	     4    
 H     ^^F)I^JJF
$$$

###~~h-P~QQH+&&&*%%% nnM   G ###sB4PC  E E E y/ABBI9%%%6>BBB:t R  T T T;S$ V  X X X 
1NOOJJc!^  ` ` `J;KLLLK"F  G G G L$"S  T T T ^^@   F 	"""
:    
 M    
 R     nnW+KnLLG###3XYYYT]  _ _ _ 
1yzzJI&&&HC6ghhhG3!c  e e e y/deeIj    
 :S111T   I 9%%%C    
 N	     L    
 <    
 0	     y/JKKI:S D  F F FJ     ^^F)G^HHF
	"""
5#>>> ^^O   F L[  ] ] ]
c4=  ? ? ?
) " >qOQOmq q q  r r r 666 ~~]   H ,UDM  O O O'T>  @ @ @+#"$"@  B B B+tM  O O O+tLB  D D D
 )L'0  2 2 2 nnG   G tS  U U UTJ  L L LDU  V V V E3G  I I I nnK   G ,777 ^^B   F
 	"""
t444
d333
t444
T222
d]    
 nnM   G #t<<<,777NN8   E 
y!!!	|d333	{T222	}d333 NNP   E 
y!!!	xc49  ; ; ; ^^*   F
 	"""
666
%A	     J	     >>Q   D 	i   hP  R R R NNQ   E
 
x555 NN;   E
 
y!!! @   I B	     @	     F    
 9     6     ..G !  K D	     B	     F    
 :     6     >>W   D 	.S"b  d d d,3T  V V V m<<<r   r   c                D   t          | dd          }|sEt          | dd          }||                                 nt          dt          j                   dS |dk    rt          |           S t          | dd          }t          j                    }|r	 t          j	        |          }n6# t          $ r)}t          d	| t          j                   Y d}~d
S d}~ww xY w|st          dt          j                   d
S |t          j        k    r8t          j        |          s$t          d|d| dt          j                   dS t          j        |          }|5  	 t          j                     nA# t          $ r4}t          d| t          j                   Y d}~ddd           dS d}~ww xY wi dt           dt"          dt$          dt&          dt&          dt(          dt*          dt,          dt.          dt0          dt0          dt2          dt4          dt6          dt8          d t:          d!t<          i d"t>          d#t@          d$tB          d%tD          d&tF          d'tH          d(tJ          d)tL          d*tN          d+tP          d,tR          d-tT          d.tV          d/tX          d0tZ          d1t\          d2t^          t`          tb          td          tf          d3}|4                    |          }|s,t          d4|t          j                   	 ddd           d
S 	 tk           ||           pd          cddd           S # t          tl          f$ r4}t          d	| t          j                   Y d}~ddd           dS d}~ww xY w# 1 swxY w Y   dS )5u   Entry point from ``hermes kanban …`` argparse dispatch.

    Returns a shell-style exit code (0 on success, non-zero on error).
    r   Nr   z`usage: hermes kanban <action> [options]
Run 'hermes kanban --help' for the full list of actions.filer   r   boardkanban:    zkanban: --board requires a slugzkanban: board = does not exist. Create it with `hermes kanban boards create `.   z'kanban: could not initialize database: r   r   r   rE   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r   zkanban: unknown action )7rM   
print_helpprintsysstderr_dispatch_boards
contextlibnullcontextr   _normalize_board_slug
ValueErrorDEFAULT_BOARDboard_existsscoped_current_boardinit_dbrw   	_cmd_init_cmd_create
_cmd_swarm	_cmd_list	_cmd_show_cmd_assign_cmd_reclaim_cmd_reassign_cmd_diagnostics	_cmd_link_cmd_unlink
_cmd_claim_cmd_comment_cmd_complete	_cmd_edit
_cmd_block_cmd_schedule_cmd_unblock_cmd_promote_cmd_archive	_cmd_tail_cmd_dispatch_cmd_daemon
_cmd_watch
_cmd_stats_cmd_log	_cmd_runs_cmd_heartbeat_cmd_assignees_cmd_notify_subscribe_cmd_notify_list_cmd_notify_unsubscribe_cmd_context_cmd_specify_cmd_decompose_cmd_gcr,   r   RuntimeError)	rG   r   parserboard_overrideboard_scopenormedexchandlershandlers	            r   kanban_commandr_  W  sq   
 T?D11F /66KZ   
 q %%% T7D11N(**K 6	-n==FF 	 	 	"S""444411111	  	3#*EEEE1 R%%%bof.E.E%J J J?EJ J JZ   
 1-f55 
 7 7	JLLLL 	 	 	ACAA
SSSS1117 7 7 7 7 7 7 7	'
	'
'
 
'
 		'

 	'
 	'
 '
 '
 '
 +'
 ('
 	'
 '
 
'
 '
  !'
" 	#'
 '
$ 
%'
& ''
( )'
* +'
, -'
. 	/'
0 1'
2 3'
4 
5'
6 
7'
8 9'
: 	;'
< ='
> ?'
@ "7A'
B "2C'
D !"9E'
 '
F %$(M'
 '
 '
P ,,v&& 	6F66SZHHHHe7 7 7 7 7 7 7 7f	wwt}})**i7 7 7 7 7 7 7 7j L) 	 	 	"S""4444111o7 7 7 7 7 7 7 7j	k7 7 7 7 7 7 7 7 7 7sy   B* *
C4CCNE32N3
F1=F,N,F11E(N'MNN<NNNNNc                     dD ]'} t           j                            |           }|r|c S (	 ddlm}  |            pdS # t
          $ r Y dS w xY w)z4Best-effort author name for an interactive CLI call.)HERMES_PROFILE_NAMEHERMES_PROFILEr   )r	   r   )r\   environr,   hermes_cli.profilesr	   rw   )envr_   r	   s      r   _profile_authorrf    s    8  JNN3 	HHH	??????&&((2F2   vvs   > 
AAc                z   t          | dd          pd}|dv rt          |           S |dv rt          |           S |dv rt          |           S |dv rt	          |           S |dv rt          |           S |d	k    rt          |           S |d
k    rt          |           S t          d|t          j
                   dS )at  Handle ``hermes kanban boards <action>``.

    Boards management is deliberately separate from the task-level
    commands: it operates on the filesystem (board directories,
    ``current`` pointer, ``board.json``), not on the per-board SQLite
    DB, so a fresh HERMES_HOME that has never called ``kanban init``
    can still run ``boards create`` / ``boards list``.
    r   NrE   >   r   rE   >   r   r   >   r   r   r   >   r   r   >   r   r   r   r   zkanban boards: unknown action r  r"  )rM   _cmd_boards_list_cmd_boards_create_cmd_boards_rm_cmd_boards_switch_cmd_boards_show_cmd_boards_rename_cmd_boards_set_default_workdirr'  r(  r)  )rG   r   s     r   r*  r*    s     $
.
.
8&C
n%%%
!$'''
(((d###
!$'''
!!!%%%
h!$'''
###.t444	
23
2
2DDDD1r   r   dict[str, int]c                >   	 t          j        |           }|                                si S t          j        |           5 }|                    d                                          }ddd           n# 1 swxY w Y   d |D             S # t          $ r i cY S w xY w)zDReturn ``{status: count}`` for a board. Safe to call on an empty DB.)r   z7SELECT status, COUNT(*) AS n FROM tasks GROUP BY statusNc                F    i | ]}|d          t          |d                   S )r-   n)r   ri   rs     r   
<dictcomp>z&_board_task_counts.<locals>.<dictcomp>	  s(    777Q(S3[[777r   )r   kanban_db_pathexistsconnect_closingexecutefetchallrw   )r   r]   connrowss       r   _board_task_countsr}    s    
 t,,,{{}} 	Id+++ 	t<<I hjj 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 87$7777   			s:   *B B (A6*B 6A::B =A:>B BBc           
        t          t          | dd                    }t          j        |          }t          j                    }|D ]S}|d         |k    |d<   t          |d                   |d<   t          |d                                                   |d<   Tt          | dd          r&t          t          j
        |d	d
                     dS |st          d           dS t          ddddddddd           |D ]}|d         rdnd}|d         pi }d                    d t          |                                          D                       pd}|                    d          pd}|                    d          r|dz  }t          |dd|d         dd|dd|            t                       t          d|            t          |          dk    rt          d           dS ) NallFinclude_archivedr   
is_currentcountstotalr   r"  indentensure_asciir   uD   (no boards — create one with `hermes kanban boards create <slug>`)r   2sr(   SLUG24sNAME28s  COUNTSr   r'   , c              3  *   K   | ]\  }}| d | V  dS =N ri   kr_   s      r   rk   z#_cmd_boards_list.<locals>.<genexpr>#  s0      DDTQjjQjjDDDDDDr   z(empty)r   r   z [archived]Current board: r%  z8Switch boards with `hermes kanban boards switch <slug>`.)ry   rM   r   list_boardsget_current_boardr}  sumvaluesr'  r   dumpsjoinr   itemsr,   rY   )	rG   r  r   r   bmarkerr  
counts_strr   s	            r   rh  rh    s9   GD%7788^-=>>>F"$$G / /V9/,(633(8++--..'

tVU## dj>>>???q TUUUq	R
8
8
8f
8
8
8F
8
8
8
8999 
I 
IL/2s8"IIDDVFLLNN-C-CDDDDD  	 uuV}}"55 	"M!DGGGaiGGGtGGG:GGHHHH	GGG	
%G
%
%&&&
6{{QHIII1r   c                   	 t          j        | j                  }n6# t          $ r)}t	          d| t
          j                   Y d }~dS d }~ww xY w|st	          dt
          j                   dS t          j        |          o|t           j        k    }t          j	        || j
        | j        | j        | j        | j                  }|rdnd}t	          d|d	         d
| d           t	          d|                    dd                      t	          d|d                     t!          | dd          r4t          j        |d	                    t	          d|d	         d           nt	          d|d	          d           dS )Nzkanban boards create: r  r"  z&kanban boards create: slug is required)r   r   r2   colordefault_workdirzalready existscreatedBoard r   r'   .  Display name: r   r     DB path:      db_pathr   Fz  Switched to z#  Use `hermes kanban boards switch z` to make it current.r   )r   r-  r   r.  r'  r(  r)  r0  r/  create_boardr   r   r2   r  r  r,   rM   set_current_board)rG   r[  r\  alreadymetaverbs         r   ri  ri  1  s   )$)44   ,s,,3:>>>>qqqqq  6SZHHHHqof%%D&B4D*DG?Y$Yj,  D  '5ID	
+4<
+
+D
+
+
+,,,	
3TXXfb11
3
3444	
.T)_
.
.///tXu%% Y
T&\***0tF|0001111WDLWWWXXX1    
AA

Ac                   t          | dd          pt          | dd          dk    }	 t          j        | j        |           }n6# t          $ r)}t          d| t          j                   Y d }~dS d }~ww xY w|d	         d
k    r1t          d|d         d|d                     t          d           nt          d|d         d           dS )Nr   Fr   r   )r   zkanban boards rm: r  r%  r   r   r  r   u    archived → new_pathzERecover by moving the directory back to <root>/kanban/boards/<slug>/.z	 deleted.r   )rM   r   remove_boardr   r.  r'  r(  r)  )rG   force_deleteresr\  s       r   rj  rj  O  s   
 4511cWT?TV5W5W[c5cLodi\1ABBB   (3((sz::::qqqqq 8}
""Es6{EEC
OEEFFF . 	/ 	/ 	/ 	/ 	/s6{///0001s   A 
A8A33A8c                   	 t          j        | j                  }n6# t          $ r)}t	          d| t
          j                   Y d }~dS d }~ww xY w|st	          dt
          j                   dS t          j        |          s$t	          d|d| dt
          j                   dS t          j        |           t	          d	|d
           dS )Nzkanban boards switch: r  r"  z&kanban boards switch: slug is requiredzkanban boards switch: board r#  r$  r%  zActive board is now r  r   )	r   r-  r   r.  r'  r(  r)  r0  r  )rG   r[  r\  s      r   rk  rk  c  s   )$)44   ,s,,3:>>>>qqqqq  6SZHHHHq?6"" F6 F F;AF F F	
 	
 	
 	

 q   	
,
,
,
,---1r  c                b   t          j                    }t          j        |          }t          |          }t	          |                                          }t          d|            t          d|                    dd                      |                    d          rt          d|d                     t          d|d                     t          d	| d
|rBdd                    d t          |
                                          D                        dndz              dS )Nr  r  r   r   r   z  Description:  r  r  z  Tasks:        z total (r  c              3  *   K   | ]\  }}| d | V  dS r  r  r  s      r   rk   z#_cmd_boards_show.<locals>.<genexpr>  s0      JJ41aqJJ1JJJJJJJJr   r   r   )r   r  read_board_metadatar}  r  r  r'  r,   r  r   r  )rG   r   r  r  r  s        r   rl  rl  x  s<   "$$G!'**D((F  E	
%G
%
%&&&	
3TXXfb11
3
3444xx 86m!466777	
.T)_
.
.///	
*U
*
*
*M$))JJ6&,,..3I3IJJJJJMMMM  ! ! ! 1r   c                   	 t          j        | j                  }n6# t          $ r)}t	          d| t
          j                   Y d }~dS d }~ww xY w|rt          j        |          s&t	          d| j        dt
          j                   dS t          j        || j	                  }t	          d|d	|d
         d           dS )Nzkanban boards rename: r  r"  zkanban boards rename: board  does not existr%  )r   r  z renamed to r   r  r   )
r   r-  r   r.  r'  r(  r)  r0  write_board_metadatar   )rG   r[  r\  r  s       r   rm  rm    s    )$)44   ,s,,3:>>>>qqqqq  00 ITYIII:	 	 	 	q"6	:::D	
:6
:
:f
:
:
:;;;1r  c                   	 t          j        | j                  }n6# t          $ r)}t	          d| t
          j                   Y d }~dS d }~ww xY w|rt          j        |          s&t	          d| j        dt
          j                   dS t          j        || j	                  }|
                    d          }|rt	          d	|d
|d           nt	          d	|d           dS )Nz#kanban boards set-default-workdir: r  r"  z)kanban boards set-default-workdir: board r  r%  )r  r  r  z default workdir set to r  z default workdir cleared.r   )r   r-  r   r.  r'  r(  r)  r0  r  r]   r,   )rG   r[  r\  r  new_vals        r   rn  rn    s&   )$)44   9C99
KKKKqqqqq  00 V$)VVV:	 	 	 	q"649EEEDhh())G <EvEEEEEFFFF:v:::;;;1r  c                   | | dk    rdS t          |                                                                           }	 t          |          S # t          $ r Y nw xY wddddd}|rf|d         |v r\	 t          |dd                   }n%# t          $ r}t	          d	|           |d}~ww xY wt          |||d                  z            S t	          d	| d
          )u   Parse ``30s`` / ``5m`` / ``2h`` / ``1d`` or a raw integer → seconds.

    Returns None for empty input. Raises ValueError on malformed input so
    the CLI can surface a usage error cleanly.
    Nr   r%  <     iQ )smhdzmalformed duration z( (expected 30s, 5m, 2h, 1d, or a number))r   rW   lowerr   r.  r   )valr  unitsrr  r\  s        r   _parse_durationr    s    {cRiitC  A1vv    "4e44E %QrUe^^	EafAA 	E 	E 	E:3::;;D	E1uQrU|#$$$
Z3ZZZ
[
[[s)   A 
AA2B
 

B,B''B,c                   t          j                    }t          d|            	 t                      pd}t	          |          }t          |d          }|r@|                    dg           }|r(t          d| dd                    |                      n# t          $ r Y nw xY wt                       	 t          j	                    }n# t          $ r g }Y nw xY w|r8t          d	t          |           d
           |D ]}t          d|            nt          d           t          d           t                       t          d           t          d           t                       t          d           dS )NzKanban DB initialized at r   T)quietcopiedzSeeded skill(s) into profile : r  zDiscovered z7 profile(s) on disk; any of these can be an --assignee:r(   z,No profiles found under ~/.hermes/profiles/.z@Create one with `hermes -p <name> setup` before assigning tasks.zCNext step: start the gateway so ready tasks actually get picked up.z  hermes gateway startzThe gateway hosts an embedded dispatcher that ticks every 60 seconds
by default (config: kanban.dispatch_interval_seconds). Without a
running gateway, tasks stay in 'ready' forever.r   )r   r2  r'  r	   r
   r   r,   r  rw   list_profiles_on_diskrY   )rG   r]   profile_nameprofile_dirr?   r  profilesr   s           r   r3  r3    s   :<<D	
,d
,
,---	.00=I%l33$[=== 	[ZZ"--F [YlYYdiiPVFWFWYYZZZ    
GGG+--    R #CMM # # # 	$ 	$ 	$ 	 	D+t++	 	<===PQQQ	GGG	
OPPP	
"###	GGG		:  
 1s$   A2B 
B'&B'9C CCc           
     V   t          j                    5 }t          j        || j        t	          | dd           t          | j                            }d d d            n# 1 swxY w Y   |s&t          d| j         dt          j                   dS t          d| j                    dS )	Nnote)r  expected_run_idzcannot heartbeat z (not running?)r  r%  zHeartbeat recorded for r   )	r   rx  heartbeat_workerr   rM   _worker_run_id_forr'  r(  r)  rG   r{  oks      r   rN  rN    s    				 
 Lvt,,.t|<<	
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
  ?$,???cjQQQQq	
2DL
2
23331s   ?AA#&A#c                :   t          j                    5 }t          j        |          }d d d            n# 1 swxY w Y   t          | dd          r&t	          t          j        |dd                     dS |st	          d           dS t	          ddd	d
dd           |D ]w}|d         rdnd}|d         pi }d                    d t          |	                                          D                       pd}t	          |d         dd	|dd	|            xdS )Nr   Fr"  r  r   uA   (no assignees — create a profile with `hermes -p <name> setup`)r  r*   r(   zON DISKr)   r  on_diskyesnor  r  c              3  *   K   | ]\  }}| d | V  dS r  r  r  s      r   rk   z!_cmd_assignees.<locals>.<genexpr>  0      LLTQjjQjjLLLLLLr   z(idle)r   )
r   rx  known_assigneesrM   r'  r   r  r  r   r  )rG   r{  dataentryr  r  	count_strs          r   rO  rO    s   				 (!$''( ( ( ( ( ( ( ( ( ( ( ( ( ( (tVU## djae<<<===q QRRRq	V
1
1
19
1
1
1
1222 A A +5%%x&BIILLVFLLNN5K5KLLLLLXPX	v???g???I??@@@@1   599c                &   	 t          | j                  \  }}t          t          | dd                     }n;# t          j        $ r)}t          d| t          j                   Y d }~dS d }~ww xY w|r#|dk    rt          dt          j                   dS 	 t          t          | dd                     }n6# t          $ r)}t          d| t          j                   Y d }~dS d }~ww xY wt          | d	d           }|'|d
k     r!t          d| dt          j                   dS t          j                    5 }t          j        |fi d| j        d| j        d| j        d| j        pt%                      d|d|d|d| j        d| j        dt+          | j        pd          dt/          t          | dd                    dt          | dd           d|dt          | dd           pd d	|dt/          t          | dd                    dt          | dd           dt          | dd           }t          j        ||          }	d d d            n# 1 swxY w Y   t          | d!d          r2t          t3          j        t7          |	          dd"                     njt          d#| d$|	j         d%|	j        pd& d'           |	j        d(k    r:|	j        r3t;                      \  }
}|
s |rt          d)| t          j                   d*S )+Nrm   r!  r  r"  rU   z8kanban: --branch is only valid with --workspace worktreemax_runtimezkanban: --max-runtime: rA   r%  z(kanban: --max-retries must be >= 1 (got z&); use 1 to trip on the first failure.r1   r6   r.   r;   r8   r9   r:   r/   r7   parentsr  triageFidempotency_keymax_runtime_secondsr@   r   r   initial_statusr   r   r  zCreated z  (z, assignee=re   r   r   u   
⚠  r   )rb   	workspacern   rM   rZ   r[   r'  r(  r)  r  r.  r   rx  create_taskr1   r6   r.   r;   rf  r/   r7   tupleparentry   get_taskr   r  rF   r-   r}   )rG   ws_kindws_pathr:   r\  r  rA   r{  r   taskr   messages               r   r4  r4    s.   0@@(x)F)FGG%   SZ0000qqqqq  w*,,HszZZZZq%gdM4&H&HII   ---CJ????qqqqq $t44K;??2{ 2 2 2	
 	
 	
 	

 q				 *.
 
 
**
 
 ]]	

 ;/*;*;
 #7
 #7
 $
 ;;
 ]]
 $++,,,
 h66777
 $D*;TBBB
 !,
 44008D
  $!
" 74e<<===#
$ #4)94@@@%
& #4)99EEE'
* {4))-* * * * * * * * * * * * * * *. tVU## <djt,,QUKKKLLLLTTTT[TTT]=QcTTTUUU ;'!!dm!9;;GW <w <)))
;;;;1s@   58 A0A++A0B8 8
C+C&&C+;DII Ic                N   	 d | j         pg D             }n6# t          $ r)}t          d| t          j                   Y d }~dS d }~ww xY w|st          dt          j                   dS t          j                    5 }t          j        || j	        || j
        | j        | j        | j        pt                      | j        t!          | dd           	  	        }d d d            n# 1 swxY w Y   t!          | dd	          r7t          t#          j        |                                dd	
                     not          d|j                    t          dd                    |j                  z              t          d|j                    t          d|j                    dS )Nc                6    g | ]}t          j        |          S r  )ksparse_worker_arg)ri   raws     r   
<listcomp>z_cmd_swarm.<locals>.<listcomp>\  s#    KKK2&s++KKKr   zkanban swarm: r  r"  z/kanban swarm: at least one --worker is requiredr  )r   workersverifier_assigneesynthesizer_assigneer/   r;   r7   r  r   Fr  zSwarm root: z	Workers: r  z
Verifier: zSynthesizer: r   )workerr.  r'  r(  r)  r   rx  r  create_swarmr   verifiersynthesizerr/   r;   rf  r7   rM   r   r  as_dictroot_idr  
worker_idsverifier_idsynthesizer_id)rG   r  r\  r{  r  s        r   r5  r5  Z  s   KK8IrKKK   $s$$3:6666qqqqq  ?cjQQQQq				 
/"m!%!1;;/*;*;]#D*;TBB

 

 


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 tVU## 8dj**15IIIJJJJ.W_..///kDIIg&8999:::07.001116g4667771s'    
A	AA	>AC##C'*C'c                B   | j         }| j        r|st                      }t          j                    5 }t          j        |           t          j        ||| j        | j        | j	        | j
        t          | dd           | j        | j        	  	        }d d d            n# 1 swxY w Y   t          | dd          r0t          t          j        d |D             dd                     dS 	 t          j        d	          }n# t$          $ r g }Y nw xY wt'          |          d
k    rFt          j                    }t'          |          d
z
  }t          d| d| d|d
k    rdnd d           |st          d           dS |D ]}t          t+          |                     dS )Nsort)r.   r-   r/   rB   r  order_byrC   rD   r   Fc                ,    g | ]}t          |          S r  )rF   )ri   r    s     r   r  z_cmd_list.<locals>.<listcomp>  s     :::q-**:::r   r"  r  r   r  r%  zBoard: r  z other boardr  r   u"    — `hermes kanban boards list`)
z(no matching tasks))r.   minerf  r   rx  recompute_ready
list_tasksr-   r/   sessionr   rM   rC   rD   r'  r   r  r  rw   rY   r  r3   )rG   r.   r{  tasks
all_boardsr   other_countr    s           r   r6  r6  y  s5   }Hy % %"$$				 
 	4   ;;|!]T6400!%!:!2

 

 

	
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 tVU## dj::E:::1SXYYYZZZq^U;;;

   



:&((*oo).g . .. .0;q0@0@b. . .	
 	
 	

  #$$$q ! !nQ    1s$   ABB!$B!*D   DDc                   t          |           }|t          dt          j                   dS t	          j                    5 }t	          j        || j                  }|s1t          d| j         t          j                   	 d d d            dS t	          j        || j                  }t	          j	        || j                  }t	          j
        || j                  }t	          j        || j                  }t	          j        || j        fi |}t	          j        || j                  }	d d d            n# 1 swxY w Y   t          | dd          r[t          |          |	||d |D             d	 |D             d
 |D             d}
t          t!          j        |
dd                     dS t          d|j         d|j                    t          d|j                    t          d|j        pd            |j        rt          d|j                    t          d|j         |j        r
d|j         ndz              |j        rt          d|j                    |j        r*t          dd                    |j                              |j        rt          d|j                    |j        t          d|j         d           n	 ddlm}  |            }|                     di           pi                      d          }n# tB          $ r d }Y nw xY w|>tE          |          t          j#        k    r!t          dtE          |           d            nt          dt          j#         d!           t          d"tI          |j%                   d#|j&        pd            dd$l'm(} |)                    |||          }|rFd%d&d'd(}t          d)tU          |           d*           |D ]}t          d+|                     |j+        d,           d-|j+         d.|j                    |j,        rg }|j,        -                                D ]l\  }}t]          |t^                    r8|0                    | d/d0                    d1 |D                                   R|0                    | d/|            m|r%t          d2d3                    |                      |j1        D ] }|j2        rt          d4|j3                    !|j4        r$t          d5tI          |j4                              |j5        r$t          d6tI          |j5                              |r%t          d7d                    |                      |r%t          d8d                    |                      |j6        r1t                       t          d9           t          |j6                   |j7        r2t                       t          d:           t          |j7                   n.|	r,t                       t          d;           t          |	           |rgt                       t          d<tU          |           d*           |D ]6}t          d=tI          |j%                   d.|j8         d|j6                    7|rt                       t          d>tU          |           d*           |d?d          D ]Z}|j9        r
d@|j9         nd}|j:        rdA|j:         dBnd}t          d=tI          |j%                   dB| d@|j;         |            [|r,t                       t          dCtU          |           d*           |D ]}|j<        rt{          d|j<        |j4        z
            nd }|| dDndE}|j>        p|j        pdE}t          dF|j        dGd@|dHdI|j?        pd dJ| dJtI          |j4                   
           |j@        r7t          dK|j@        A                                d         d dL                     |jB        r7t          dM|jB        A                                d         d dL                     dS )NNzBkanban show: pass both --state-type and --state-name, or omit bothr  r"  no such task: r%  r   Fc                8    g | ]}|j         |j        |j        d S )authorr6   r<   r  )ri   cs     r   r  z_cmd_show.<locals>.<listcomp>  s8        8QV1<PP  r   c                D    g | ]}|j         |j        |j        |j        d S )ra   payloadr<   run_idr  )ri   es     r   r  z_cmd_show.<locals>.<listcomp>  sE         F y"#,h	   r   c                    g | ]G}|j         |j        |j        |j        |j        |j        |j        |j        |j        |j	        |j
        d HS )r0   r   step_keyr-   r   summaryr   metadata
worker_pidr=   ended_atr  rs  s     r   r  z_cmd_show.<locals>.<listcomp>  sh         $ y !
h y yW !
"#,"#, !
   r   )r  latest_summaryr  childrencommentseventsr   r  r   zTask r  z  status:    z  assignee:  re   z  tenant:    z  workspace: z @ r   z  branch:    z  skills:    r  z  model:     z  max-retries: z (task)rr   rt   failure_limitz (config kanban.failure_limit)z
 (default)z  created:   z by kanban_diagnostics   ⚠!!!!!r   z
  Diagnostics (z):    r#   r%   ] r  ,c              3  4   K   | ]}t          |          V  d S rg   r   ri   xs     r   rk   z_cmd_show.<locals>.<genexpr>  (      3F3FqCFF3F3F3F3F3F3Fr          data:  |           → z  started:   z  completed: z  parents:   z  children:  zBody:zResult:zLatest summary:z
Comments (z  [zEvents (ir'   z [run r&   zRuns (r  activez  #z<3z<12z @r(   u           →    z
        ! )CrP   r'  r(  r)  r   rx  r  r   list_commentslist_events
parent_ids	child_ids	list_runsr#  rM   rF   r   r  r0   r1   r-   r.   r/   r8   r9   r:   r@   r  model_overriderA   rx   rs   r,   rw   r   r   r   r<   r;   
hermes_clir)  compute_task_diagnosticsrY   severityr  r  
isinstancerE   r   actions	suggestedlabelr=   r>   r6   r?   r  r  r  ra   r"  maxr   r   r  
splitlinesr   )rG   rskr{  r  r%  r&  r  r$  r   r#  r  rs   r{   cfg_valkddiags
sev_markerr  bitsr  r_   ar  r  plrun_tagrt  elapsedelr   s                                 r   r7  r7    s@
   
D
!
!C
{P	
 	
 	
 	
 q				 ?{4.. 	14<11
CCCC	? ? ? ? ? ? ? ?
 #D$,77dl33-dl33<dl33|D$,66#66
 *4>>? ? ? ? ? ? ? ? ? ? ? ? ? ? ?  tVU## %!$'',  !           %"
 "
F 	dj???@@@q	
)$'
)
)TZ
)
)***	
'$+
'
'(((	
0$-.3
0
0111{ -+dk++,,,	
/$-
/
/*.*=E&$&&&2G H H H 20d.00111{ 86dii4466777 53d133444
 #9 0999::::	555555+--Cwwx,,277HHGG 	 	 	GGG	3w<<23K#K#KPCLLPPPQQQQHB$<HHHIII	
P'$/22
P
P8N3
P
PQQQ
 433333''fd;;E 3!&5II
0#e**000111 	3 	3AS
C88SSAJSS!'SSTTTv >FLLNN 0 0DAq!!T** 0q$H$H3883F3FA3F3F3F+F+F$H$HIIIIqJJ1JJ//// ><%**T*:*:<<=== Y 3 3; 31112223  :8gdo6688999 <:gd&788::;;; 42dii0022333 53dii1133444y gdi{ 
idk	  	   n G,3x==,,,--- 	G 	GAE--EEEEQVEEFFFF H(V((())) 	H 	HA$%I5QY2B./h>*qx****BGF--FFFF!&F"FFGGGG D$s4yy$$$%%% 	D 	DA */s1aj1<7888*. ")"5G8Bi7187xG -K - -'K - -1Ac - -R - -Q\**- - . . .y HFQY%9%9%;%;A%>tt%DFFGGGw DB17#5#5#7#7#:4C4#@BBCCC1s,   AD6BD66D:=D:;L LLc                `   | j                                         dv rd n| j         }t          j                    5 }t          j        || j        |          }d d d            n# 1 swxY w Y   |s%t          d| j         t          j                   dS t          d| j         d|pd            dS )	N>   nonenullre   r  r  r%  z	Assigned  to r$   r   )	r   r  r   rx  assign_taskr   r'  r(  r)  rG   r   r{  r  s       r   r8  r8  R  s    l((**.CCCddG				 9^D$,889 9 9 9 9 9 9 9 9 9 9 9 9 9 9 -t|--CJ????q	
Cdl
C
C(A>
C
CDDD1s   A  A$'A$c           
     0   t          j                    5 }t          j        || j        t	          | dd                     }d d d            n# 1 swxY w Y   |s&t          d| j         dt          j                   dS t          d| j                    dS )	Nr   )r   zcannot reclaim z (not running or unknown id)r  r%  z
Reclaimed r   )r   rx  reclaim_taskr   rM   r'  r(  r)  r  s      r   r9  r9  ]  s    				 
_$,4400
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 

  HdlHHH	
 	
 	
 	
 q	
%t|
%
%&&&1s   ,AAAc                   | j                                         dv rd n| j         }t          j                    5 }t          j        || j        |t          t          | dd                    t          | dd                     }d d d            n# 1 swxY w Y   |s&t          d| j         dt          j
                   d	S t          d
| j         d|pd t          | dd          rdndz              dS )N>   rU  rV  re   r   Fr   )reclaim_firstr   zcannot reassign uC    (unknown id, or still running — pass --reclaim to release first)r  r%  zReassigned rW  r$   z (claim reclaimed)r   r   )r   r  r   rx  reassign_taskr   ry   rM   r'  r(  r)  rY  s       r   r:  r:  m  st   l((**.CCCddG				 
$,wtY>>??4400
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
  Rt| R R R	
 	
 	
 	

 q		'dl 	' 	'$n	' 	'#*4E#B#BJ	L  
 1s   A
BBBc                   ddl m ddlm}                      |                      }t          j                    5 }t          | dd          rt          j        || j	                  }|1t          d| j	         t          j                   	 ddd           dS | j	                            |t          j        || j	                  t          j        || j	                  |	          i}nt!          |                    d
                                                    }d |D             }|si }nGd                    dgt)          |          z            }d |D             }	|                    d| dt+          |                    D ]1}
|	                    |
d         g                               |
           2d |D             }|                    d| dt+          |                    D ]1}
|                    |
d         g                               |
           2i }|D ]R}|d         }                    ||	                    |g           |                    |g           |	          }|r|||<   St          | dd          rDt!          |                                          D ]"}fd||         D             }|r|||<   ||= #i |rd                    dgt)          |          z            }|                    d| dt+          |                                                    D ]#}|d         |d         |d         d|d         <   $ddd           n# 1 swxY w Y   t          | dd          rFfd|                                D             }t          t7          j        |d d!                     dS |st          d"           dS d#d$d%d&}t;          d' |                                D                       }t          | d(t)          |           d)           |                                D ]\  }}                    |i           }|                    d          pd*}|                    d          pd}|                    d          pd+}t          d,| d,|d-d.|d/d,|            |D ]$}t          d0|                    |j        d           d1|j         d2|j          d3|j!                    |j"        rg }|j"                                        D ]l\  }}tG          |t                     r8|                    | d4d                    d5 |D                                   R|                    | d4|            m|r%t          d6d7                    |                      |j$        D ] }|j%        rt          d8|j&                    !&t                       dS )9zList active diagnostics on the board. Wraps the same rule engine
    the dashboard uses, so CLI output matches what the UI shows.
    r   r(  rr   r  Nr  r  r%  )configz.SELECT * FROM tasks WHERE status != 'archived'c                    g | ]
}|d          S )r0   r  rs  s     r   r  z$_cmd_diagnostics.<locals>.<listcomp>  s    )))q1T7)))r   r/  r#   c                    i | ]}|g S r  r  ri   is     r   ru  z$_cmd_diagnostics.<locals>.<dictcomp>  s    ,,,1B,,,r   z,SELECT * FROM task_events WHERE task_id IN (z) ORDER BY idr   c                    i | ]}|g S r  r  rc  s     r   ru  z$_cmd_diagnostics.<locals>.<dictcomp>  s    ---A!R---r   z*SELECT * FROM task_runs WHERE task_id IN (r0   rB  c                    g | ]?}j                             |j                  j                                       k    =|@S r  )SEVERITY_ORDERindexrB  )ri   r  rK  sevs     r   r  z$_cmd_diagnostics.<locals>.<listcomp>  sK    }}}a9J9P9PQRQ[9\9\`b`q`w`wx{`|`|9|9|9|9|9|r   z;SELECT id, title, status, assignee FROM tasks WHERE id IN (r   r1   r-   r.   )r1   r-   r.   r   Fc                f    g | ]-\  }}d |i                     |i           dd |D             i.S )r   r   c                6    g | ]}|                                 S r  )to_dict)ri   r  s     r   r  z/_cmd_diagnostics.<locals>.<listcomp>.<listcomp>  s     888		888r   )r,   )ri   tiddlr  s      r   r  z$_cmd_diagnostics.<locals>.<listcomp>  sl     
 
 
 R	 3((3## 88R888 
 
 
r   r"  r  z$No active diagnostics on this board.r*  r+  r,  r   c              3  4   K   | ]}t          |          V  d S rg   )rY   )ri   rn  s     r   rk   z#_cmd_diagnostics.<locals>.<genexpr>  s(      99BB999999r   z active diagnostic(s) across z
 task(s):
z
(untitled)r$   r(   r)   z  @18sr-  r%   r.  r  r  c              3  4   K   | ]}t          |          V  d S rg   r1  r2  s     r   rk   z#_cmd_diagnostics.<locals>.<genexpr>  r4  r   r5  r6  r7  )'r@  r)  rx   rs   config_from_runtime_configr   rx  rM   r  r  r'  r(  r)  rA  r;  r>  rE   ry  rz  r  rY   r  
setdefaultr   r,   r   r  r   r  r  r  rB  ra   r1   r  rC  rD  rE  rF  )rG   rs   diag_configr{  r  diags_by_taskr|  idsplaceholdersev_byrowrun_byrt  rm  rn  keptout_jsonrM  r  r  r1   r-   r.   r  rN  r  r_   rO  rK  r  ri  s                               @@@r   r;  r;    s    433333------//>>K				 F4&& -	0;tTY//D|2ty22DDDDF F F F F F F F 	266N433Lty11&	 7  MM @ hjj D *)D)))C 0 ""xxC(899,,,,,<<^<^^^#JJ  E EC $$S^R88??DDDD-----<<\\\\#JJ  F FC %%c)nb99@@EEEE " 	0 	0AD'C44		#r**

3++*	 5  B  0-/c* dJ-- 	+M..0011 + +}}}}}=#5}}} +)-M#&&%c** !# 		88SEC,>,>$>??L\\]l]]]m((**++   
 wZ1X; !*! !QtWGF F F F F F F F F F F F F F FP tVU## 

 
 
 
 )..00
 
 
 	dj!%@@@AAAq 4555q #TuEEJ99-"6"6"8"899999E	 	+ 	+}	+ 	+ 	+   !&&((  RHHS"g.,x'C55$$6?3??&????????@@@ 	3 	3A]
C88]]AJ]]!&]]TUT[]]^^^v 	>FLLNN 0 0DAq!!T** 0q$H$H3883F3FA3F3F3F+F+F$H$HIIIIqJJ1JJ//// ><%**T*:*:<<===Y 3 3; 31112223 	1s    AM(J=M((M,/M,c                    t          j                    5 }t          j        || j        | j                   d d d            n# 1 swxY w Y   t          d| j         d| j                    dS )NzLinked  -> r   )r   rx  
link_tasksr   r   r'  rG   r{  s     r   r<  r<    s    				 ;
dDNDM:::; ; ; ; ; ; ; ; ; ; ; ; ; ; ;	
7DN
7
7
7
78881   !AAAc                8   t          j                    5 }t          j        || j        | j                  }d d d            n# 1 swxY w Y   |s-t          d| j         d| j         t          j                   dS t          d| j         d| j                    dS )NzNo such link: r~  r  r%  z	Unlinked r   )r   rx  unlink_tasksr   r   r'  r(  r)  r  s      r   r=  r=    s    				 B_T4>4=AAB B B B B B B B B B B B B B B Bt~BB4=BBTTTTq	
9dn
9
9$-
9
9:::1r  c           	        t          j                    5 }t          j        || j        | j                  }|t          j        || j                  }|1t          d| j         t          j                   	 d d d            dS t          d| j         d|j	         d|j
        pd t          j                   	 d d d            dS t          j        |          }t          j        ||j        t          |                     d d d            n# 1 swxY w Y   t          d	|j                    t          d
|            dS )N)ttl_secondsr  r  r%  zcannot claim z	: status=z lock=z(none)zClaimed zWorkspace: r   )r   rx  
claim_taskr   ttlr  r'  r(  r)  r-   
claim_lockresolve_workspaceset_workspace_pathr0   r   )rG   r{  r  existingr  s        r   r>  r>    s   				 =}T4<TXFFF<{466H5t|55CJGGGG= = = = = = = = : : :x : : +7x: :Z   
 = = = = = = = = (..	
dDGS^^<<<= = = = = = = = = = = = = = =  

TW

	
#	
#
#$$$1s   A$D6D<DDDc           	     l   d                     | j                                                  }| j        | j        dk     rt	          dt
          j                   dS t          |          | j        k    rMd| j         d}|d t          d| j        t          |          z
                     	                                |z   }| j
        pt                      }t          j                    5 }t          j        || j        ||           d d d            n# 1 swxY w Y   t	          d	| j                    dS )
Nr'   r%  z"kanban: --max-len must be positiver  r"  z

[trimmed to z chars by --max-len]r   zComment added to )r  r   rW   max_lenr'  r(  r)  rY   rG  rstripr  rf  r   rx  add_commentr   )rG   r6   suffixr  r{  s        r   r?  r?  .  sW   88DI$$&&D|<!6SZHHHH1t99t|##JJJJF<#aF!;<<<=DDFFOD[-O--F				 9
tT\648889 9 9 9 9 9 9 9 9 9 9 9 9 9 9	
,dl
,
,---1s   )DDDr   c                    t           j                            d          | k    rd S t           j                            d          }|sd S 	 t          |          S # t          $ r Y d S w xY w)NHERMES_KANBAN_TASKHERMES_KANBAN_RUN_ID)r\   rc  r,   r   r.  )r   r  s     r   r  r  >  st    	z~~*++w66t
*../
0
0C t3xx   tts   
A 
A'&A'c                p   t          | j        pg           }|st          dt          j                   dS t          | dd          }t          | dd          }t          |          dk    r!|s|rt          dt          j                   dS d}|r|	 t          j        |          }t          |t                    st          d	          nB# t          t          j        f$ r)}t          d
| t          j                   Y d}~dS d}~ww xY wg }t          j                    5 }|D ]u}t          j        ||| j        ||t#          |                    s5|                    |           t          d| dt          j                   ct          d|            v	 ddd           n# 1 swxY w Y   |sdndS )z<Mark one or more tasks done. Supports a single id or a list. at least one task_id is requiredr  r%  r  Nr   zkanban: --summary / --metadata are per-task and can't be used with multiple ids (would apply the same handoff to every task). Complete tasks one at a time, or drop the flags for the bulk close.r"  must be a JSON objectkanban: --metadata: )r?   r  r   r  zcannot complete z (unknown id or terminal state)z
Completed r   )rE   r   r'  r(  r)  rM   rY   r   loadsrC  dictr.  JSONDecodeErrorr   rx  complete_taskr?   r  r   )	rG   rv  r  raw_metar   r\  failedr{  rm  s	            r   r@  r@  J  sN   
t}"
#
#C 0szBBBBqdIt,,GtZ..H 3xx!|||H|R 		
 	
 	
 	
 qH 	z(++Hh-- : !8999:D01 	 	 	...SZ@@@@11111	 F				 * 	* 	*C#c{! 23 7 7   
* c"""MMMMTWT^_____(3(())))	** * * * * * * * * * * * * * * !11!s+   8C
 
D	 DD	!A9F''F+.F+c                v   t          | dd           }d }|r|	 t          j        |          }t          |t                    st          d          nB# t
          t          j        f$ r)}t          d| t          j	                   Y d }~dS d }~ww xY wt          j                    5 }t          j        || j        | j        t          | dd           |          s2t          d| j         d	t          j	                   	 d d d            d
S 	 d d d            n# 1 swxY w Y   t          d| j                    dS )Nr   r  r  r  r"  r  )r?   r  r   zcannot edit z! (unknown id or task is not done)r%  zEdited r   )rM   r   r  rC  r  r.  r  r'  r(  r)  r   rx  edit_completed_task_resultr   r?   )rG   r  r   r\  r{  s        r   rA  rA  w  s   tZ..HH 	z(++Hh-- : !8999:D01 	 	 	...SZ@@@@11111	 
			 ,L;D)T22
 
 
 	 Nt|NNNZ           	               

"DL
"
"###1s*   8A B&B

B%ADDDc           
     n   | j         r,d                    | j                                                   nd }t                      }| j        gt          t          | dd           pg           z   }g }t          j                    5 }|D ]}|rt          j	        |||d|            t          j
        |||t          |                    s4|                    |           t          d| t          j                   wt          d| |rd| nd	z              	 d d d            n# 1 swxY w Y   |sd
ndS )Nr'   rv  z	BLOCKED: r   r  zcannot block r  zBlocked r  r   r   r%  )r   r  rW   rf  r   rE   rM   r   rx  r  
block_taskr  r   r'  r(  r)  rG   r   r  rv  r  r{  rm  s          r   rB  rB    s   .2kCSXXdk""((***tFF<.4eT : : @bAA
ACF				 L 	L 	LC HtS&2Ff2F2FGGG= 23 7 7	   	L c"""+c++#*=====&&&6*I-v---rJKKKK	LL L L L L L L L L L L L L L L !11!   BD&&D*-D*c           
     n   | j         r,d                    | j                                                   nd }t                      }| j        gt          t          | dd           pg           z   }g }t          j                    5 }|D ]}|rt          j	        |||d|            t          j
        |||t          |                    s4|                    |           t          d| t          j                   wt          d| |rd| nd	z              	 d d d            n# 1 swxY w Y   |sd
ndS )Nr'   rv  zSCHEDULED: r  zcannot schedule r  z
Scheduled r  r   r   r%  )r   r  rW   rf  r   rE   rM   r   rx  r  schedule_taskr  r   r'  r(  r)  r  s          r   rC  rC    s   .2kCSXXdk""((***tFF<.4eT : : @bAA
ACF				 N 	N 	NC JtS&2H2H2HIII# 23 7 7	   	N c"""...SZ@@@@@(3((V,KMMMMLMMMM	NN N N N N N N N N N N N N N N !11!r  c           	     X   t          | j        pg           }|st          dt          j                   dS t          | dd           }||                                pd }|rt                      nd }g }t          j	                    5 }|D ]}|rt          j
        |||d|            t          j        ||          s5|                    |           t          d| dt          j                   ht          d| |rd	| nd
z              	 d d d            n# 1 swxY w Y   |sdndS )Nr  r  r%  r   z	UNBLOCK: zcannot unblock z (not blocked/scheduled?)z
Unblocked r  r   r   )rE   r   r'  r(  r)  rM   rW   rf  r   rx  r  unblock_taskr   )rG   rv  r   r  r  r{  rm  s          r   rD  rD    s   
t}"
#
#C 0szBBBBqT8T**F'4"(2_dFF				 N 	N 	NC HtS&2Ff2F2FGGG?4-- Nc"""FFFFSZXXXXX(3((V,KMMMMLMMMM	NN N N N N N N N N N N N N N N !11!s   BDD"Dc                   | j         r,d                    | j                                                   nd }t                      }t	          | dd          }t          t	          | dd           pg           }g }t                      }| j        g|D ]0}||vr*|                    |           |	                    |           1g }t          j                    5 }	|D ]}t          j        |	|||t          | j                  t          | j                            \  }
}|                    ||
t          | j                  t          | j                  ||d           	 d d d            n# 1 swxY w Y   d |D             }|rGt!          |          dk    r|d	         n|}t#          t%          j        |d
d                     |sd	ndS | j        rdnd}| j        rdnd}|D ]`}|d         r)|rd| nd}t#          | d|d          d| |            3t#          d|d          d|d          t(          j                   a|sd	ndS )Nr'   r   Frv  )actorr   forcedry_run)r   promotedr  forcedr   r   c                "    g | ]}|d          
|S )r  r  rs  s     r   r  z _cmd_promote.<locals>.<listcomp>  s!    666A*6a666r   r%  r   r"  r   (dry)r   zWould promotePromotedr  r  r   z	 -> readyzcannot promote r   r  )r   r  rW   rf  rM   rE   setr   r   addr   rx  promote_taskry   r  r  rY   r'  r   r  r(  r)  )rG   r   r  as_json	extra_idsrv  seenrm  resultsr{  r  errr  r  tagrF  rt  r  s                     r   rE  rE    s   .2kCSXXdk""((***tFFdFE**GWT5$//5266ICUUD)y)  d??JJsOOOHHSMMM')G				  	 	Co4:&&T\**  GB NN--tz**      	              & 76666F &(+G(9(9'!**wdj???@@@%qqA%l
*((C#|;OOE S SZ= 	S&,4]&]]]"FUAAQy\AACAAABBBB@AiL@@AgJ@@szRRRRR!11!s   BE))E-0E-c                   t          | j        pg           }t          t          | dd           pg           }|r|rt          dt          j                   dS |s|st          dt          j                   dS g }t          j                    5 }|rs|D ]^}t          j        ||          s5|	                    |           t          d| dt          j                   Lt          d|            _|sd	ndcd d d            S |D ]]}t          j
        ||          s4|	                    |           t          d
| t          j                   Kt          d|            ^	 d d d            n# 1 swxY w Y   |sd	ndS )Nr   z;choose either task_ids to archive or --rm archived task_idsr  r%  r  zcannot delete z (must already be archived)zDeleted r   zcannot archive z	Archived )rE   r   rM   r'  r(  r)  r   rx  delete_archived_taskr   archive_task)rG   rv  r   r  r{  rm  s         r   rF  rF    s*   
t}"
#
#CWT;55;<<I
 y KRUR\]]]]q y 0szBBBBqF				 ) 	*  , ,.tS99 ,MM#&&&K3KKKRUR\]]]]]*S**++++")11) ) ) ) ) ) ) )  	) 	)C?4-- )c"""---CJ?????'#''((((	)) ) ) ) ) ) ) ) ) ) ) ) ) ) ) !11!s   A)E1A E11E58E5c                   d}t          d| j         d           	 	 t          j                    5 }t          j        || j                  }d d d            n# 1 swxY w Y   |D ]W}|j        |k    rJ|j        r
d|j         nd}t          dt          |j                   d|j	         | d	           |j        }Xt          j        t          d
| j                             # t          $ r t          d           Y dS w xY w)Nr   zTailing events for z. Ctrl-C to stop.Tr'   r   [r.  flush皙?

(stopped))r'  r   r   rx  r;  r0   r  r   r<   ra   r   sleeprG  intervalKeyboardInterrupt)rG   last_idr{  r&  r  rP  s         r   rG  rG  $  sc   G	
?
?
?
?@@@	0#%% <dl;;< < < < < < < < < < < < < < < # #4'>>,-I=QY2BCgal33CCqvCrCC4PPPPdGJs3..///	0    mqqs5   C$ AC$ AC$ ABC$ $D Dc                *	   	 ddl m}  |            }t          |t                    r|                    di           ni }|                    d          pd                                pd }d } ||                    d                    } ||                    d                    }t          | d	d           }||n ||                    d
                    }	n'# t          $ r d }d }d }t          | d	d           }	Y nw xY wt          j	                    5 }
t          j
        |
| j        |	|t          | dt          j                  ||          }d d d            n# 1 swxY w Y   t          | dd          r|t          t          j        |j        |j        |j        |j        |j        |j        d |j        D             |j        |j        d |j        D             |j        dd                     dS t          d|j                    t          dt7          |j                              |j        r*t          dd                    |j                              t          dt7          |j                              |j        r*t          dd                    |j                              t          dt7          |j                              |j        r*t          dd                    |j                              t          dt7          |j                              |j        r*t          dd                    |j                              t          d|j                    t          dt7          |j                              |j        D ]-\  }}}| j        rdnd}t          d| d| d |pd! |            .|j        r-t          d"|d#d                    |j                              |j        r*t          d$d                    |j                              |j        r&|j        D ]\  }}}t          d%| d&| d'|            |j        r*t          d(d                    |j                              dS ))Nr   rr   rt   default_assigneer   c                p    | d S 	 t          |           }n# t          t          f$ r Y d S w xY w|dk    r|nd S )Nr%  )r   	TypeErrorr.  )rQ   ivals     r   _coerce_positive_intz+_cmd_dispatch.<locals>._coerce_positive_intD  sW    }t5zzz*   tt19944$.s    ++max_in_progress_per_profilemax_in_progressrG  	max_spawnr'  )r  r  r  r'  r  r  r   Fc                "    g | ]\  }}}|||d S ))r   r.   r  r  )ri   rm  whowss       r   r  z!_cmd_dispatch.<locals>.<listcomp>n  s8       "S#r  SrBB  r   c                "    g | ]\  }}}|||d S ))r   r.   r   r  )ri   rm  r  r   s       r   r  z!_cmd_dispatch.<locals>.<listcomp>t  s8     + + +'S#w  SWEE+ + +r   )	reclaimedcrashed	timed_outstaleauto_blockedr  spawnedskipped_unassignedskipped_nonspawnableskipped_per_profile_cappedauto_assigned_defaultr"  )r  zReclaimed:    zCrashed:      r(   r  zTimed out:    zStale:        zAuto-blocked: zPromoted:     zSpawned:      r  z  - z  ->  z  @ re   z)Auto-assigned to kanban.default_assignee=r  zSkipped (unassigned): z
Deferred (z at per-profile cap, z running): u8   Skipped (non-spawnable assignee — terminal lane, OK): )rx   rs   rC  r  r,   rW   rM   rw   r   rx  dispatch_oncer  r   r'  r   r  r  r  r  r  r  r  r  r  r  r  r  rY   r  )rG   rs   _cfg_kanban_cfgr  r  r  r  cli_maxr  r{  r  rm  r  r  r  r   s                    r   rH  rH  6  s   /111111{}}0:40F0FNdhhx,,,B'OO,>??E2LLNNVRV	/ 	/ 	/ ';&:OO9::'
 '
# /.{?P/Q/QRR $t,,&2GG8L8LOOK((9
 9
		  / / /&*#D%..				/
 
			 	
L+!$9WXX-(C
 
 
	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 tVU## dj{Y, &)k   #&"8$'$<+ ++.+I+ + + &)%>#
 
$ %   	 	 	& q	
*3=
*
*+++	
-3s{++
-
-...
{ -+499S[))++,,,	
/3s}--
/
/000
} /-499S]++--...	
+3sy>>
+
+,,,
y +)499SY''))***	
23s/00
2
2333
 20499S-..00111	
)3<
)
)***	
-3s{++
-
-... ; ;S",.hhB9S9999s9C99::::
  
68H 6 6yy2336 6	
 	
 	
  LJtyy1G'H'HJJKKK
% !$!? 	 	CgPSPPwPP3PP     
5yy1225 5	
 	
 	
 1s$   CC !D D:EE!$E!c           	     H   t          | dd          st          dt          j                   dS t	          j                     t          | dd          }|r	 t          |          j                            dd	           t          |          	                    t          t          j                              d
           n8# t          $ r+}t          d| d| t          j                   Y d}~nd}~ww xY wt          t          | dd                    t          d| j         dt          j                     dt          j                   ddddfd}dd	 t	          j        | j        | j        t          | dt          j                  |           |r3	 t          |                                           nK# t          $ r Y n?w xY wn:# |r3	 t          |                                           w # t          $ r Y w w xY ww xY wt          d           dS )u:  Deprecated — the dispatcher now runs inside the gateway.

    Left in as a stub so users with the old command in scripts/systemd
    units get a clear migration message instead of a cryptic
    "no such command" error. A ``--force`` escape hatch keeps the old
    standalone daemon alive for the rare edge case where someone truly
    cannot run the gateway (e.g. running on a host that forbids
    long-lived background services), but the default path exits 2
    with guidance so nobody accidentally keeps running two dispatchers
    against the same kanban.db.
    r  Fuy  hermes kanban daemon: DEPRECATED — the dispatcher now runs
inside the gateway. To use kanban:

    hermes gateway start       # starts the gateway + embedded dispatcher

Ready tasks will be picked up on the next dispatcher tick
(default: every 60 seconds). Configure via config.yaml:

    kanban:
      dispatch_in_gateway: true      # default
      dispatch_interval_seconds: 60
      failure_limit: 2              # consecutive non-success attempts before auto-block

Running both the gateway AND this standalone daemon will
race for claims. If you truly need the old standalone
daemon (no gateway available), rerun with --force.r  r"  pidfileNT)r  exist_okzutf-8)encodingz!warning: could not write pidfile r  verbosez;Kanban dispatcher running STANDALONE via --force (interval=zs, pid=z). Ctrl-C to stop. NOTE: if a gateway is also running with dispatch_in_gateway=true (default), you have two dispatchers racing for claims.   r   )	bad_tickslast_warn_atc                n   t          | j                  p	             }t          | j                  }|r|sdxx         dz  cc<   ndd<   d         k    rjt          t	          j                              }|d         z
  dk    r;t          dt          |           dd          dt          j        d	
           |d<   sd S | j	        p)| j
        p"| j        p| j        p| j        p| j        p| j        }|rt          dt          t          t	          j                                         d| j	         dt          | j
                   dt          | j                   dt          | j                   d| j         dt          | j                   dt          | j                   d	           d S d S )Nr  r%  r   r  i,  r  z3] WARN dispatcher stuck: ready queue non-empty for z consecutive ticks but 0 workers spawned successfully. Check profile health (venv, PATH, credentials) and `hermes kanban list --status ready` / `hermes kanban list --status blocked` for recent spawn_failed tasks.T)r  r  z] reclaimed=z	 crashed=z timed_out=z stale=z
 promoted=z	 spawned=z auto_blocked=r  )ry   r  r  r   r   r'  r   r(  r)  r  r  r  r  r  r  rY   )	r  ready_pendingspawned_anynowdid_workHEALTH_WINDOW_ready_queue_nonemptyhealth_stater  s	        r   _on_tickz_cmd_daemon.<locals>._on_tick  sE   S344O8M8M8O8O3;'' 	* 	*%%%*%%%%()L% $55dikk""C\.11S88+ + +1=k1J+ + + 4	 	 	 	 03^, 	FM <S[ <CM <S\ <{<!.<25) 	  	8GC	,,-- 8 8 ]8 8585E5E8 8 //8 88;CI8 8  L8 8 47s{3C3C8 8 !$C$4 5 5	8 8
      	 	r   r   ry   c                     	 t          j                    5 } t          j        |           cddd           S # 1 swxY w Y   dS # t          $ r Y dS w xY w)u  Cheap probe — is there at least one ready+assigned+unclaimed
        task whose assignee maps to a real Hermes profile (i.e. one the
        dispatcher would actually try to spawn for)?

        Filters out tasks assigned to control-plane lanes
        (e.g. ``orion-cc``, ``orion-research``) that are pulled by
        terminals via ``claim_task`` directly — those are correctly idle
        from the dispatcher's perspective, not stuck.
        NF)r   rx  has_spawnable_readyrw   )r{  s    r   r  z*_cmd_daemon.<locals>._ready_queue_nonempty	  s    	#%% 4-d334 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 	 	 	55	s,   A 6A :A :A 
AAr'  )r  r  r'  on_tickz(dispatcher stopped))r   ry   )rM   r'  r(  r)  r   r2  r   r  mkdir
write_textr   r\   getpidOSErrorry   r  
run_daemonrG  r   r   )rG   r  r\  r  r  r  r  r  s       @@@@r   rI  rI    s    4%(( A  #	
 	
 	
 	
& q
 JLLLdIt,,G Y	YMM &&td&CCCMM$$S%5%5$HHHH 	Y 	Y 	YFgFFFFSZXXXXXXXXX	Y 74E2233G		]	 	+-9;;	 	 	
 Z    M!"A66L& & & & & & & &P    
]h!$9WXX		
 	
 	
 	
  	W$$&&&&   	7 	W$$&&&&   	
 

 !!!1s[   A+C 
C;!C66C;(;G &!G 
GGH!G?>H?
H	HHHc                p   | j         r$d | j                             d          D             nd}d}t          dd           t          j                    5 }|                    d                                          }t          |d	                   }ddd           n# 1 swxY w Y   	 	 t          j                    5 }|                    d
|f                                          }ddd           n# 1 swxY w Y   |D ]}t          |t          |d                             }|r|d         |vr2| j
        r|d         | j
        k    rK| j        r|d         | j        k    rd	 |d         rt          j        |d                   nd}n# t          $ r d}Y nw xY w|rd| nd}t          dt          |d                    d|d         dd|d         dd|d         pd d| 
d           t!          j        t          d| j                             n# t&          $ r t          d           Y dS w xY w)z(Live-stream task_events to the terminal.c                ^    h | ]*}|                                 |                                 +S r  )rW   )ri   r  s     r   	<setcomp>z_cmd_watch.<locals>.<setcomp>1	  s-    ???qQWWYY????r   r/  Nr   z'Watching kanban events. Ctrl-C to stop.Tr  z1SELECT COALESCE(MAX(id), 0) AS m FROM task_eventsr  zSELECT e.id, e.task_id, e.kind, e.payload, e.created_at,        t.assignee, t.tenant FROM task_events e LEFT JOIN tasks t ON t.id = e.task_id WHERE e.id > ? ORDER BY e.id ASC LIMIT 200r0   ra   r.   r/   r  r'   r   r  r<   r.  r   10srp  z (@re   r   r  r  )kindssplitr'  r   rx  ry  fetchoner   rz  rG  r.   r/   r   r  rw   r   r   r  r  r  )	rG   r   cursorr{  ry  r|  rt  r  rP  s	            r   rJ  rJ  .	  sE    :	 ??DJ,,S11???? 
 F	
34@@@@				 ll?
 

(** 	 SX	              	0#%% ||A I  (**                  VS4\\22 QvYe33= Qz]dm%C%C; 1X;$+#=#=#:;I,Pdj9666DGG  # # #"GGG#&-5]]]]2E,00 E EAiLG E EyDE E)*:)=#E E@BE E    
 Js3..///7	08    mqqsn   =BB!$B!)H =*C3'H 3C77H :C7;A)H %$F
	H 
FH FA?H H54H5c           
        t          j                    5 }t          j        |          }d d d            n# 1 swxY w Y   t          | dd          r&t	          t          j        |dd                     dS t	          d           dD ]2}t	          d|d	d|d
                             |d                      3|d         rt	          d           t          |d         	                                          D ]Y\  }}d
                    d t          |	                                          D                       }t	          d|dd|            Z|d         }| t	          dt          |           d           dS )Nr   Fr"  r  r   z
By status:)r  r   r   r   r   r   r   r(   r)   	by_statusby_assigneez
By assignee:r  c              3  *   K   | ]\  }}| d | V  dS r  r  r  s      r   rk   z_cmd_stats.<locals>.<genexpr>k	  r  r   r*   oldest_ready_age_secondsz
Oldest ready task age: r  )r   rx  board_statsrM   r'  r   r  r,   r   r  r  r   )rG   r{  r   r  r  r  partsages           r   rK  rK  _	  s   				 %t$$% % % % % % % % % % % % % % %tVU## djqu===>>>q	,S ; ;919995-11!Q7799::::] +!%"6"<"<">">?? 	+ 	+KCIILLVFLLNN5K5KLLLLLE)s)))%))****
*
+C
5#c((5556661r  c                   t          j                    5 }t          j        || j                  1t	          d| j         t
          j                   	 d d d            dS t          j        || j        | j        | j	        | j
        | j        | j        pt                                 d d d            n# 1 swxY w Y   t	          d| j         d| j	         | j
        r
d| j
         ndz   d| j         z              d	S )
Nr  r  r%  )r   platformchat_id	thread_iduser_idnotifier_profilezSubscribed :r   rW  r   )r   rx  r  r   r'  r(  r)  add_notify_subr  r  r  r  r  rf  r  s     r   rP  rP  s	  sk   				 	
;tT\**214<11
CCCC	
 	
 	
 	
 	
 	
 	
 	
 	$,]DLndl!2Go6G6G		
 	
 	
 	
		
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 	
 

6
6
6
6
6%)^;!!!!=!4<!!" # # # 1s   ?B3 AB33B7:B7c                (   t          j                    5 }t          j        || j                  }d d d            n# 1 swxY w Y   t	          | dd          r&t          t          j        |dd                     dS |st          d           dS |D ]}|                    d          rd|d          nd	}|                    d
          rd|d
          nd	}t          d|d         dd|d          d|d          | d|d          d|            dS )Nr   Fr"  r  r   z(no subscriptions)r  r  r   r  z  owner=r(   r   r  r  r  z  (since event last_event_idr   )	r   rx  list_notify_subsr   rM   r'  r   r  r,   )rG   r{  subsr  throwners         r   rQ  rQ  	  s   				 7"4667 7 7 7 7 7 7 7 7 7 7 7 7 7 7tVU## djae<<<===q "###q > >&'eeK&8&8@"!K."""b67ee<N6O6OW21/0222UW =1Y<J = =q} = =q| =S = = !/ 2= =5:= = 	> 	> 	> 	>1   ;??c                "   t          j                    5 }t          j        || j        | j        | j        | j                  }d d d            n# 1 swxY w Y   |st          dt          j	                   dS t          d| j                    dS )N)r   r  r  r  z(no such subscription)r  r%  zUnsubscribed from r   )
r   rx  remove_notify_subr   r  r  r  r'  r(  r)  r  s      r   rR  rR  	  s    				 
!$,]DLn
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
  &SZ8888q	
-t|
-
-...1s   .AAAc                <   t          j        | j        | j                  }|&t	          d| j         dt
          j                   dS t
          j                            |           |	                    d          st
          j                            d           dS )N)
tail_bytesz(no log for u#    — task may not have spawned yet)r  r%  
r   )
r   read_worker_logr   r   r'  r(  r)  stdoutwriteendswith)rG   contents     r   rL  rL  	  s     $)DDDGNT\NNN:	 	 	 	qJWD!! 
1r   c                D   t          |           }|t          dt          j                   dS t	          j                    5 }t	          j        || j        fi |}ddd           n# 1 swxY w Y   t          | dd          r0t          t          j
        d |D             dd                     d	S |st          d
| j         d           d	S t          dddddddddddd           t          |d          D ] \  }}|j        pt          t          j                              }t          d	||j        z
            }|dk     r| d}n|dk     r	|dz   d}n	|dz  dd}|j        p|j        sdn|j        }	t          |dd|	dd|j        pddd|ddt)          |j                   	           |j        r9|j                                        d	         dd          }
t          d!|
            |j        rt          d"|j        dd                      "d	S )#z Show attempt history for a task.NzBkanban runs: pass both --state-type and --state-name, or omit bothr  r"  r   Fc                    g | ]G}|j         |j        |j        |j        |j        |j        |j        |j        |j        |j	        |j
        d HS )r0   r   r-   r   r=   r"  r  r   r   r!  r  r'  rs  s     r   r  z_cmd_runs.<locals>.<listcomp>	  sb     
 
 
  dqyAH9ALJ19ajl
 
 
 
r   r  r   z(no runs yet for r   #3sr(   OUTCOME12sPROFILE16sELAPSEDz>8sz	  STARTEDr%  r  r  r  r  z.1fr  z	(running)3dre   d   u	        → u	        ✖ )rP   r'  r(  r)  r   rx  r>  r   rM   r   r  	enumerater"  r   r   rG  r=   r   r-   r   r   r  rH  r   )rG   rI  r{  r   rd  rt  endrR  rS  r   r  s              r   rM  rM  	  s   
D
!
!C
{P	
 	
 	
 	
 q				 7|D$,66#667 7 7 7 7 7 7 7 7 7 7 7 7 7 7tVU## 
dj 
 
 
 
 
 %) ) ) 	* 	* 	* q 1$,111222q	S
Q
Q
Qy
Q
Q
Q	
Q
Q
Q
Q
Q
Q
QRRR$"" / /1j,C	,,aq|+,,R<<BBt^^rM$$$BBdN))))B)L1: K18cccccc)9cccc"cccGTUT`LaLaccddd9 	)i**,,Q/5G'g''(((7 	/-agdsdm--...1s   A''A+.A+c                    t          j                    5 }t          j        || j                  }d d d            n# 1 swxY w Y   t	          |           dS Nr   )r   rx  build_worker_contextr   r'  )rG   r{  r   s      r   rS  rS  	  s    				 ;&tT\::; ; ; ; ; ; ; ; ; ; ; ; ; ; ;	$KKK1r  c           
        ddl m} t          t          | dd                    }t          | dd          }t          | dd          pt	                      }t          t          | dd                    }| j        r|rt          d	t          j        
           dS |r`|	                    |          }|sGd|rd|ndz   dz   }|r%t          t          j        ddd                     nt          |           dS n-| j        r	| j        g}nt          dt          j        
           dS d}d}	|D ]}
|                    |
|          }|j        r|dz  }n|	dz  }	|r;t          t          j        |j        |j        |j        |j        d                     h|j        r.|j        r
d|j        nd}t          d|j         d|            t          d|j         d|j         t          j        
           |s
|dk    rdndS |dk    s|sdndS )z{Flesh out a triage task (or all of them) via auxiliary LLM,
    then promote to todo. Thin wrapper over ``kanban_specify``.r   )kanban_specifyr   Fr/   Nr  r   0kanban: pass either a task id OR --all, not bothr  r"  r/   No triage tasks for tenant r   r  )	specifiedr  z+kanban: specify requires a task id or --allr  r%  )r   r  r   	new_title    — retitled: 
Specified u	    → todozkanban: specify r  )r@  r7  ry   rM   rf  r   r'  r(  r)  list_triage_idsr   r  specify_taskr  r   r>  )rG   specall_flagr/   r  	want_jsonrv  msgok_count
fail_countrm  r   title_suffixs                r   rT  rT  	  s    211111GD,6677HT8T**FT8T**?o.?.?FWT651122I|  >	
 	
 	
 	
 q ""&"11 
	!06>,&,,,B@ 
  djq1!=!=>>????c


1
	 
 |n9	
 	
 	
 	
 qHJ  ##C#77: 	MHH!OJ 	$*"?j!.$.	        Z 	 $7'"3777 
 GwGGGGHHHHF7?FFgnFFZ      )MMqqq( AS11q0r   c                   ddl m} t          t          | dd                    }t          | dd          }t          | dd          pt	                      }t          t          | dd                    }| j        r|rt          d	t          j        
           dS |r`|	                    |          }|sGd|rd|ndz   dz   }|r%t          t          j        ddd                     nt          |           dS n-| j        r	| j        g}nt          dt          j        
           dS d}|D ](}	|                    |	|          }
|
j        r|dz  }|rGt          t          j        |
j        |
j        |
j        |
j        |
j        |
j        d                     o|
j        r|
j        rR|
j        rKd                    |
j                  }t          d|
j         dt'          |
j                   d| d           |
j        r
d|
j        nd}t          d|
j         d|            t          d|
j         d|
j         t          j        
           *|s
|dk    rdndS |dk    s|sdndS ) zFan a triage task (or all of them) out into a graph of child
    tasks via the auxiliary LLM, routed to specialist profiles by
    description. Thin wrapper over ``kanban_decompose``.r   )kanban_decomposer   Fr/   Nr  r   r8  r  r"  r9  r:  r;  r   r  )
decomposedr  z-kanban: decompose requires a task id or --allr=  r%  )r   r  r   fanoutr=  r>  r  zDecomposed u    → z children (z); root promoted to todor?  r@  u    → todo (no fanout)zkanban: decompose r  )r@  rK  ry   rM   rf  r   r'  r(  r)  rA  r   r  decompose_taskr  r   rM  r=  r>  r  rY   )rG   decomprD  r/   r  rE  rv  rF  rG  rm  r   child_summaryrI  s                r   rU  rU  .
  sm    655555GD,6677HT8T**FT8T**?o.?.?FWT651122I|  >	
 	
 	
 	
 q $$F$33 
	!06>,&,,,B@ 
  djA!>!>??@@@@c


1
	 
 |n;	
 	
 	
 	
 qH " "''F';;: 	MH 	$*"?j!.!.$.$.        Z 	~ '"3  $		'*; < <I'/ I IG<M8N8N I I!.I I I    (;g&7;;; 
 1 1 1".1 1   
 HW_HHHHZ      )MMqqq(AS11q0r   c           	        ddl }t          j                    }d}t          j                    5 }|                    d                                          }ddd           n# 1 swxY w Y   |D ]}|d         dk    rt          |d         p
||d         z            }	 |                                }n# t          $ r Y Qw xY w	 |	                    |                                           n# t          $ r Y w xY w|                                r0|                                r|                    |d	           |d
z  }t          | dd          }t          | dd          }	t          j                    5 }t          j        ||dz  dz            }
ddd           n# 1 swxY w Y   t          j        |	dz  dz            }t#          d| d|
 d| d           dS )z^Remove scratch workspaces of archived tasks, prune old events, and
    delete old worker logs.r   NzNSELECT id, workspace_kind, workspace_path FROM tasks WHERE status = 'archived'r8   rT   r9   r0   T)ignore_errorsr%  event_retention_daysr   log_retention_days   r  )older_than_secondszGC complete: z workspace(s), z event row(s), z log file(s) removed)shutilr   workspaces_rootrx  ry  rz  r   resolver  relative_tor.  rw  is_dirrmtreerM   	gc_eventsgc_worker_logsr'  )rG   rW  scratch_root
removed_wsr{  r|  ry  r]   
event_dayslog_daysremoved_eventsremoved_logss               r   rV  rV  
  s    MMM%''LJ				 ||\
 

(** 	                  I--C()GlSY.FHH	<<>>DD 	 	 	H		\11334444 	 	 	H	 ;;== 	T[[]] 	MM$dM333!OJ5r::Jt1266H				 
Z"_t%;
 
 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 $#b=4/  L 
 O* O OO O,8O O O P P P1sG   (A!!A%(A%B33
C ?C 'C,,
C98C96FF#&F#uU  **/kanban** — manage the shared task board.

Common subcommands:
  `list` (alias `ls`)   List tasks on the current board
  `show <id>`           Task details + comments + events
  `stats`               Per-status / per-assignee counts
  `create <title>…`     Create a task (auto-subscribes you to events)
  `comment <id> <msg>`  Append a comment
  `complete <id>…`      Mark task(s) done
  `block <id> [reason]` Mark blocked; `schedule <id> [reason]` parks time-delay work; `unblock <id>` to revive
  `assign <id> <profile>`  Reassign
  `boards list`         Show all boards
  `assignees`           Known profiles + counts
  `context <id>`        Full worker-context dump
  `runs <id>`           Attempt history
  `log <id>`            Worker log

Run `/kanban <subcommand> -h` for arguments. Read-only commands are safe while an agent is running.restc                Z   ddl }ddl}| r(|                                 rt          j        |           ng r
d         dv rt
          S t          j        dd          }d|_        |	                    d          }t          |          d	_        d_        j        D ]L}t          |t          j                  r0|j                                        D ]\  }}d
| |_        d|_        Mdfd}|                                }	|                                }
	  |j        |	          5   |j        |
          5                                }ddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   n# t*          $ ru}|	                                                                }|
                                                                }|j        dv r	|r|cY d}~S |p|}|rd| ndcY d}~S d}~wt          j        $ r}d |             d| cY d}~S d}~ww xY w |j        |	          5   |j        |
          5  	 t5          |           n@# t*          $ r Y n4t6          $ r(}t9          d| t:          j                   Y d}~nd}~ww xY wddd           n# 1 swxY w Y   ddd           n# 1 swxY w Y   |	                                                                }|
                                                                }|r	|r| d| S |r|n|pdS )u  Execute a ``/kanban …`` string and return captured stdout/stderr.

    ``rest`` is everything after ``/kanban`` (may be empty).  Used from
    both the interactive CLI (``self._handle_kanban_command``) and the
    gateway (``_handle_kanban_command``) so formatting is identical.
    r   N>   -h--helpr   r#   z/kanban-wrapF)progadd_help_topr   z/kanbanz/kanban r   r   c                 0   rnj         D ]f} t          | t          j                  rJ| j                            d                   }|(|                                                                c S g                                                                S r4  )_actionsrC  rZ   _SubParsersActionr   r,   format_usager  )_action	subparserr   tokenss     r   _usage_for_errorz#run_slash.<locals>._usage_for_error
  s     	A(1 A Agx'ABB A ' 3 3F1I > >I ,(5577>>@@@@@))++22444r   >   Nr   u   ⚠ /kanban usage error
u   ⚠ /kanban usage errorr  zerror: r  z(no output)r   r   )ior+  rW   shlexr  _SLASH_KANBAN_HELPrZ   ArgumentParserexit_on_errorr   r  ri  rm  rC  rn  r   r  StringIOredirect_stdoutredirect_stderr
parse_args
SystemExitgetvaluer  codeArgumentErrorr_  rw   r'  r(  r)  )re  ru  r+  _wrap_top_subrp  _name_choicers  buf_outbuf_errrG   r\  outr  r6   r   rr  s                   @@r   	run_slashr  
  s    III"&?4::<<?U[RF  "VAY"???!! #%HHHEE###00H **M"M"'M ) . .gx9:: 	.")/"7"7"9"9 . .w1%11(-%%5 5 5 5 5 5 5 kkmmGkkmmGG'Z'00 	4 	42L*2LW2U2U 	4 	4 ++F33D	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 	4 Y Y Y  ''))  ''))8y  S JJJJJJzc59X14111?XXXXXXX! G G GF+;+;+=+=FFFFFFFFFFG 
$	#G	,	, 4 4.Hj.H.Q.Q 4 4	44     	 	 	D 	4 	4 	4/C//
333333333	44 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 




#
#
%
%C





#
#
%
%C
 s 133C0=1s   F .E8?E!E8!E%	%E8(E%	)E8,F 8E<<F ?E< F 
H*AG>&H*,G>8H*>H*H%H*%H*=KJ,I J, 
J*J,,	J5JJ,JJ, K,J0	0K3J0	4KK
K)r   r   r   r   )r    r!   r   r   )r    r!   r   r4   )rG   rH   r   rI   )rQ   r   r   rR   )rQ   rc   r   rc   )r   ro   )r~   r   r   r   )rG   rH   r   r   rt  )r   r   r   ro  )r   r   )r   r   r   r   )re  r   r   r   )T__doc__
__future__r   rZ   r+  r   r\   rv  r(  r   pathlibr   typingr   r   r@  r   r   r   r  rd  r	   r
   r   r+   r   r3   rF   rP   rb   rn   r}   r  r_  rf  r*  r}  rh  ri  rj  rk  rl  rm  rn  r  r3  rN  rO  r4  r5  r6  r7  r8  r9  r:  r;  r<  r=  r>  r?  r  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  rP  rQ  rR  rL  rM  rS  rT  rU  rV  rw  r  r  r   r   <module>r     s    # " " " " "       				  



                        & & & & & & ) ) ) ) ) ) ] ] ] ] ] ] ] ] ] ]  ? ? ? ?N N N N   20 0 0 0   2   3 3 3 3tP
 P
 P
 P
nt t t tv
 
 
 
"   8          F   <   (   *          ,\ \ \ \2. . . .b      &> > > >B   >* * * *Zi i i iX          .@ @ @ @F         ,    	 	 	 	*" *" *" *"Z   8" " " "," " " "," " " ",0" 0" 0" 0"f" " " "8   $h h h hVJ J J JZ. . . .b   (   "   "   	 	 	 	, , , ,^   F1 F1 F1 F1RN1 N1 N1 N1b& & & &Z .K2 K2 K2 K2 K2 K2r   