Commit Graph

4 Commits

Author SHA1 Message Date
xarmian 5c598a18d3 feat(plugin): no event monitor at session start; an opted-in session's watch starts from the mod, and an unarmed one shows nothing (TASK-3513) (#1925)
* feat(plugin): no event monitor at session start; an opted-in session's watch starts from the mod, and an unarmed one shows nothing (TASK-3513)

Every session with the plugin opened with "Monitor ... ended without
producing output", and Claude explaining it: the "always" monitor ran
pad-monitor.sh, which exits when the session has not consented, and
Claude Code reports any monitor that exits. Monitors take only "always"
or "on-skill-invoke", with no condition and no silent exit.

The plugin is already a mod (the pane). Its session.start now:
- records presence (`pad session register`), silently, as the monitor did;
- asks `pad session should-arm`, PLAN-2613's gate, unchanged (.pad.toml
  push.auto_arm stays the per-project opt-in);
- only when armed, spawns pad-monitor.sh ($.process.spawn) and relays
  its stdout lines with $.prompt.submit, coalescing a burst into one
  message per idle window.
An unarmed session runs nothing and shows nothing: no process, no line,
no notice. session.end stops the stream, except /clear and /resume,
which keep the process, the socket consent is keyed on, and do not
refire session.start.

Measured (Claude Code 2.1.295): CLAUDE_CODE_MESSAGING_SOCKET reaches a
mod's processes, so consent and the wrapper's lockfile key match the
connect monitor's; CLAUDE_PID and CLAUDECODE do not, so the mod passes
PAD_SESSION_PID (its children's parent is the session process) and
CLAUDECODE=1.

- monitors.json: pad-events-auto removed; /pad:connect keeps its
  on-skill-invoke monitor, the explicit path and the path where mods do
  not load. The lockfile still keeps the two from streaming twice.
- pad-monitor.sh: runs the stream as a child the traps can name, so a
  caller that stops the script stops the stream too.
- SKILL.md and README: no "always-on wrapper"; the two delivery forms.

Tests (claude plugin test plugin, 18 pass, the pane's included): unarmed
registers and starts/shows nothing; no CLI; the CLI calls carry the
session pid; armed relays one message per burst (stderr dropped);
survives /clear and /resume; any other end relays nothing after it.
Controls: dropping the gate fails 2, ending on /clear fails 1, and the
relay's ownership check was found by its test (a late chunk relayed).

Hand-check in an interactive session (tmux, --plugin-dir): unarmed start
shows nothing and registers with the right pid; armed start spawns the
wrapper and stream under the session process; a submitted line renders as
"The pad plugin sent a message:"; the stream survives /clear; /exit takes
the wrapper, the stream and the lockfile with it.

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS

* fix(plugin): a session that ends while the CLI answers starts no watch (TASK-3513, codex r1)

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS

* fix(plugin): a flush the session's end overtook relays nothing more (TASK-3513, codex r2)

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS

* fix(plugin): pad-monitor.sh frees its lock only once the stream has closed (TASK-3513, codex r3)

Measured with a stand-in pad whose stream takes 1s to close on TERM: the
lock stays held through the close and is gone after, with no process left.

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS

* fix(plugin): a burst of watch lines goes to Claude after it goes quiet, capped at 10s (TASK-3513, codex r4)

Claude-Session: https://claude.ai/code/session_01Q9WssCjFuHjSfLABoW4tmS
2026-10-08 22:06:11 -04:00
xarmian 9f9304b294 fix(plugin): the pane's copy link points at the server it talks to, not always Pad Cloud (BUG-3484) (#1899)
.pad.toml's url, else the CLI's configured server (pad server info), else the MCP server's
own URL (Pad Cloud's MCP host maps to the app, a self-hosted /mcp to its base), else Pad Cloud.

Claude-Session: https://claude.ai/code/session_01J9famMX8HvArgW2uo8mPRT
2026-10-08 14:20:49 -04:00
xarmian 09135d15c5 feat(plugin): the pane's Get started view: Pad Cloud, this machine, or your own server (PLAN-3490) (#1888)
* feat(plugin): the pane's Get started view: Pad Cloud, this machine, or your own server (PLAN-3490)

When the pane can't reach Pad it guides setup instead of showing an error: what this machine
has (the CLI, a linked folder), then three paths. Pad Cloud adds its MCP server to Claude Code
(claude mcp add, user scope) on a confirmed second press and fills /reload-plugins; it is never
listed in the plugin manifest, which would nag every session. This machine and your own server
hand the work to Claude in the prompt, so permission prompts apply.

Claude-Session: https://claude.ai/code/session_01J9famMX8HvArgW2uo8mPRT

* feat(plugin): Desktop: 6px of space between the pane's top line and the view tabs

Claude-Session: https://claude.ai/code/session_01J9famMX8HvArgW2uo8mPRT
2026-10-08 12:29:42 -04:00
xarmian b66af1e624 feat(plugin): the Pad pane ships in the pad plugin (/pad-pane) (TASK-3486) (#1883)
Folds the pad-mod pane (IDEA-3477) into plugin/ so one install gives the skills, the
monitor and the pane. plugin/hooks/register.js is the mod (Claude Code 2.1.287+; older
versions ignore it); plugin/tests run with `claude plugin test plugin` (9 pass).
The tool.call refresh can no longer disturb the call it watched.

Claude-Session: https://claude.ai/code/session_01J9famMX8HvArgW2uo8mPRT
2026-10-08 11:32:10 -04:00