Compare commits
2
Commits
9dd128b77a
...
8a1bcb03f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a1bcb03f5 | ||
|
|
d963bd0a4c |
@@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
name: Restarting your own host
|
||||||
|
description: Use before restarting, stopping or reloading any PM2 process, and whenever a change you made lives in a sidecar rather than in the main server. Names the one process that kills you, and what to do instead.
|
||||||
|
version: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
**You are a child of `officer-claude-code`.** Your process tree is:
|
||||||
|
|
||||||
|
```
|
||||||
|
zsh ← every Bash command you run
|
||||||
|
claude --output-format stream-json …
|
||||||
|
bun run src/servers/sidecar/claude/user-instance.ts ← officer-claude-code, a PM2 process
|
||||||
|
PM2 God Daemon
|
||||||
|
```
|
||||||
|
|
||||||
|
So **`pm2 restart officer-claude-code` kills you, mid-command.** PM2 tree-kills the sidecar, which takes
|
||||||
|
`claude` and your shell with it. The tool call never returns. What the user sees is the conversation
|
||||||
|
stopping dead — and what the harness records is an *interrupted* or *rejected* tool call, so the transcript
|
||||||
|
blames them for something they did not do. That misattribution is the worst part: it sends everyone
|
||||||
|
looking in the wrong place.
|
||||||
|
|
||||||
|
The same applies to `pm2 stop`, `pm2 delete`, `pm2 reload` and `pm2 restart all` or
|
||||||
|
`ecosystem.config.cjs`, which include you.
|
||||||
|
|
||||||
|
## What is safe
|
||||||
|
|
||||||
|
**`pm2 restart officer` is safe.** The sidecars are PM2 PEERS of the main server, not its children, so
|
||||||
|
restarting `officer` costs you a socket reconnect and nothing else. Every other sidecar —
|
||||||
|
`officer-pty`, `officer-email`, `officer-notify` and the rest — is equally safe for the same reason.
|
||||||
|
|
||||||
|
Only your own host is special.
|
||||||
|
|
||||||
|
## The trap this actually sets
|
||||||
|
|
||||||
|
A change under `src/servers/sidecar/claude/` — the session credential, the manager, the transcript
|
||||||
|
reader — **does not take effect when you restart `officer`.** It lives in the process you are running
|
||||||
|
inside. So the honest failure mode is not a crash, it is this:
|
||||||
|
|
||||||
|
> You edit the file, restart `officer`, report the change as live, and it is not. The old code keeps
|
||||||
|
> running for hours while everything you say about it is wrong.
|
||||||
|
|
||||||
|
That happened on 2026-08-25: a credential scope was widened, `officer` was restarted four times, and the
|
||||||
|
sidecar carried the previous build all day. The symptom was a legitimate refusal that read as a bug.
|
||||||
|
|
||||||
|
**So check which process owns your change before you claim it is live.** `pm2 jlist` gives each process's
|
||||||
|
uptime; if the sidecar's start time predates your edit, your edit is not running.
|
||||||
|
|
||||||
|
## What to do instead
|
||||||
|
|
||||||
|
**Ask the user to run it.** One line, and they are already there:
|
||||||
|
|
||||||
|
```
|
||||||
|
pm2 restart officer-claude-code
|
||||||
|
```
|
||||||
|
|
||||||
|
Say why it is theirs to run rather than yours — that it ends this session — so it does not read as
|
||||||
|
helplessness.
|
||||||
|
|
||||||
|
If it genuinely must happen without them, detaching it from your process group is the only form that
|
||||||
|
survives, and **it still ends this conversation** — the restart completes, you do not:
|
||||||
|
|
||||||
|
```
|
||||||
|
setsid nohup sh -c 'sleep 2; pm2 restart officer-claude-code' >/dev/null 2>&1 &
|
||||||
|
```
|
||||||
|
|
||||||
|
Never do that silently. Tell the user first that the session is about to end, or they will see exactly
|
||||||
|
what this affordance exists to explain.
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
name: Starting an app
|
||||||
|
description: Use when asked to create, scaffold or start a new app or project, and when asked to run one. There is a template to begin from, and a specific way the owner expects a dev server to be started.
|
||||||
|
version: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
**Do not scaffold a new app from scratch.** There is a template, it is the agreed starting point, and it
|
||||||
|
carries decisions that took a while to settle.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@gitea.officer.dev:templates/template-react.git <name>
|
||||||
|
```
|
||||||
|
|
||||||
|
Bun · Hono · React 19 · Tailwind v4 · shadcn/ui · Postgres with Drizzle. A JSON API at `/api` and a React
|
||||||
|
app at `/`, over one query layer.
|
||||||
|
|
||||||
|
**SSH, not HTTPS.** `https://gitea.officer.dev/…` prompts for a username and fails in a non-interactive
|
||||||
|
shell; the SSH remote is already authenticated. If SSH is being refused for a stretch — the public host is
|
||||||
|
behind a proxy that rate-limits it — `ssh://git@100.64.0.13:10023/templates/template-react.git` is the same
|
||||||
|
repository over the tailnet.
|
||||||
|
|
||||||
|
## Then read its own documentation, and do step 1
|
||||||
|
|
||||||
|
The template documents itself. **`README.md` step 1 is a rename** — everything project-specific is called
|
||||||
|
`app`, and a case-sensitive search for `app`, `App` and `APP` finds all of it. Thirty seconds at the start,
|
||||||
|
a chore forever after. Do it before the first commit.
|
||||||
|
|
||||||
|
Its `CLAUDE.md` points at `CONVENTIONS.md` (React patterns, feature folders, manager hooks),
|
||||||
|
`docs/DATABASE.md` and `docs/SURFACES.md`. Read those rather than inferring house style from the code —
|
||||||
|
they exist so the same argument is not had twice.
|
||||||
|
|
||||||
|
Drop the template's git history and start your own unless told otherwise: it is a starting point, not an
|
||||||
|
upstream to track.
|
||||||
|
|
||||||
|
## Running it — always as a background job
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Start it in the BACKGROUND, never in the foreground.** Two reasons, and either one is sufficient:
|
||||||
|
|
||||||
|
- **A dev server does not exit.** Run in the foreground it blocks the turn until the tool times out, and
|
||||||
|
the timeout is reported as a failure of a thing that was working perfectly.
|
||||||
|
- **The owner wants to watch it.** A background job gets Officer's live panel — the same one they would
|
||||||
|
see running it themselves — so they can read the output, see the port, and stop it. Run any other way it
|
||||||
|
is invisible, and stopping it means asking you.
|
||||||
|
|
||||||
|
`bun dev` prints steadily, so the panel fills immediately. `predev` regenerates the index first; that is
|
||||||
|
normal and takes a moment.
|
||||||
|
|
||||||
|
The general rule about background output still applies — see the background-jobs affordance. It matters
|
||||||
|
less here only because this particular command is already talkative.
|
||||||
|
|
||||||
|
**Say the URL when it comes up.** The port is in `.env` and the template's README, and the first thing
|
||||||
|
anybody wants after "it's running" is where to look.
|
||||||
Reference in New Issue
Block a user