Skip to content

refactor: move the helpers the CLI and the executor share out of internal/cmd - #19

Merged
mbalazy merged 5 commits into
mainfrom
refactor/extract-cli-shared-helpers
Oct 10, 2026
Merged

mbalazy merged 5 commits into
mainfrom
refactor/extract-cli-shared-helpers

Conversation

@mbalazy

@mbalazy mbalazy commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Stacked on #18.

Four helpers that both the CLI and the executor use move out of internal/cmd into small packages of their own, so the executor can leave internal/cmd without importing it:

  • internal/proc - the process-group runner (GroupCmd, RunGroupCmd, WaitDelay, KillGrace), also used by pm serve and pm runs.
  • internal/exitcode - the coded exit error and the codes 1-4. internal/cmd's ExitCode still classifies it.
  • internal/projectarg - resolving the optional [project] argument.
  • internal/ccpath - Claude Code's project-directory name for a path.

internal/proc must not import the executor. On a terminal signal it used to call the executor's crash journal directly; now it calls a proc.OnTerminalSignal hook, a no-op by default, which the executor sets in an init. Every pm binary links the executor, so the behaviour is the same.

Apart from comments, the moved code changes only in names: the exported names of the moved functions and fields, and the names they call (the renamed variables, the exit-code helper, the hook). The contract tests from #18 pass unchanged. CLAUDE.md and the current docs (not the dated docs/design-log.md) name internal/proc and internal/exitcode where they named the old helpers.

internal/cmd/work_proc.go moves whole to internal/proc (GroupCmd,
RunGroupCmd and the WaitDelay/KillGrace tunables), so the CLI and the
executor can share it without importing each other. The one call back
into the executor - journaling a forwarded terminal signal - becomes the
OnTerminalSignal hook, which the crash journal sets at init.
The codes and the error that pins one on a failure live in
internal/exitcode now; cmd keeps ExitCode, its Exit* constants (aliases
of the leaf's) and the usageErr/notFoundErr/conflictErr shorthands. The
acceptance claim's conflict errors in finish.go use the leaf directly,
since that code is not going to stay in cmd.
…nternal/cmd

Only these functions move, the rest of their files stays:
resolveProjectSlugArg and resolveProjectArg (executor_show.go) become
projectarg.Slug and projectarg.Load, detectProjectFromCwd (board.go)
becomes projectarg.FromCwd. The CLI commands and the executor commands
both resolve their [project] argument through them.
…rnal/cmd

Only encodeProjectPath and its test move out of sessionid.go and
sessionid_test.go, as ccpath.Encode: `pm session-id` and the worker
transcript lookup both use it.
@mbalazy
mbalazy changed the base branch from test/pin-executor-cli-contract to main October 10, 2026 16:46
@mbalazy
mbalazy merged commit 6b9cf43 into main Oct 10, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant