Skip to content

feat(agent): 'agent start' (daemonize) + 'agent serve' (foreground)#134

Merged
arimxyer merged 2 commits into
mainfrom
feat/agent-start-serve-116
Jul 1, 2026
Merged

feat(agent): 'agent start' (daemonize) + 'agent serve' (foreground)#134
arimxyer merged 2 commits into
mainfrom
feat/agent-start-serve-116

Conversation

@arimxyer

@arimxyer arimxyer commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Replaces the clunky pass-cli agent & with a real lifecycle, per your request.

New commands

  • pass-cli agent start — backgrounds the agent and returns as soon as it is unlocked and listening. No & needed. Spawns a detached agent serve (setsid, so it survives closing the terminal), keeping stdin+stderr on your terminal for the one-time unlock prompt (keychain unlock is silent), and polls for the socket before returning agent started (pid N).
  • pass-cli agent serve — explicit foreground alias for bare pass-cli agent (for supervisors, or when you want to & it yourself).

--idle/--max-ttl are now persistent flags shared by agent/serve/start (and start forwards them to the serve process). POSIX-only; Windows returns a clear not supported (unix-socket transport).

Real bug caught while building it

The detached child originally inherited the caller's stdout, so it held the pipe open forever — hanging any caller that captures it, e.g. out=\$(pass-cli agent start). I reproduced the hang (goroutine dump showed Cmd.Wait blocked on the stdout/stderr copy goroutines), then fixed it by pointing the child's stdout at /dev/null (stderr stays on the terminal for the prompt/errors). Verified out=\$(...) now returns in 0s.

Tests

  • TestIntegration_Agent_StartDaemonizes — drives agent start with the password on an OS pipe + a file-backed stderr (a bytes.Buffer stderr reproduces the same Wait-on-copy-goroutine hang the feature had to fix), then resolves through the detached agent.
  • All 7 agent integration tests green; unit + golangci-lint clean on linux/darwin/windows.

🤖 Generated with Claude Code

arimxyer and others added 2 commits July 1, 2026 13:48
…und)

Replaces the clunky 'pass-cli agent &' with a proper lifecycle:
- 'agent start' backgrounds the agent and returns once it is unlocked and
  listening. It spawns a detached 'agent serve' (setsid — survives closing the
  terminal), keeping stdin+stderr on the terminal for the one-time unlock prompt
  (keychain is silent), and polls for the socket before returning.
- 'agent serve' is an explicit foreground alias for bare 'pass-cli agent'.
- --idle/--max-ttl are now persistent flags so all three forms accept them, and
  'start' forwards them to the spawned serve. POSIX only; Windows returns a clear
  'not supported' (unix-socket transport).

Real bug fixed along the way: the detached child must NOT inherit the caller's
stdout, or it holds the pipe open forever and hangs any caller that captures it
(e.g. out=$(pass-cli agent start)) — verified it hung, then fixed by pointing the
child's stdout at /dev/null (stderr stays on the terminal for the prompt/errors).

Test: TestIntegration_Agent_StartDaemonizes drives 'agent start' with the password
on an OS pipe and a file-backed stderr (a bytes.Buffer stderr would reproduce the
same Wait-on-copy-goroutine hang the feature had to fix), then resolves through the
detached agent. All 7 agent integration tests pass; unit + lint green on
linux/darwin/windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kVLjbUL4F4CkoA7RbMYy8
agent.md (added in #130) never had Hugo front matter; the markdown validation
only flags files touched by a PR, so this surfaced when #134 edited it. Add
title/weight/toc matching the sibling operations docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kVLjbUL4F4CkoA7RbMYy8
@arimxyer arimxyer merged commit 0ce4abe into main Jul 1, 2026
11 checks passed
@arimxyer arimxyer deleted the feat/agent-start-serve-116 branch July 1, 2026 18:02
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