patchcord 0.5.56 → 0.5.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/patchcord.mjs CHANGED
@@ -75,9 +75,7 @@ Usage:
75
75
  patchcord --full Same + full statusline
76
76
  patchcord --rename <new-name> [--agent-type <type>] Rename this agent
77
77
  patchcord whoami Show your identity + project
78
- patchcord whoami --propose "<text>" Propose an update to your whoami
79
- patchcord whoami --approve <id> Approve a pending proposal
80
- patchcord whoami --reject <id> Reject a pending proposal
78
+ patchcord whoami --propose "<text>" Update your whoami (two-shot: first call asks you to show human, second call applies)
81
79
  patchcord agents List every agent (with whoami)
82
80
  patchcord agents <name> Show one agent's whoami
83
81
  patchcord subscribe Start the realtime listener
@@ -280,7 +278,8 @@ if (cmd === "whoami") {
280
278
  process.exit(1);
281
279
  }
282
280
 
283
- // --propose "<text>"
281
+ // --propose "<text>" — two-shot gate. First call returns "show_human",
282
+ // second call with identical text returns "applied".
284
283
  const proposeIdx = args.indexOf("--propose");
285
284
  if (proposeIdx !== -1) {
286
285
  const text = (args[proposeIdx + 1] || "").trim();
@@ -288,8 +287,9 @@ if (cmd === "whoami") {
288
287
  console.error("Usage: patchcord whoami --propose \"<text>\"");
289
288
  process.exit(1);
290
289
  }
290
+ // Client-side length check — don't even round-trip if over limit.
291
291
  if (text.length > 300) {
292
- console.error(`Whoami text exceeds 300 characters (got ${text.length}).`);
292
+ console.error(`whoami is ${text.length} characters; limit is 300. trim and retry.`);
293
293
  process.exit(1);
294
294
  }
295
295
  const { status, json, body } = await _httpJSON("POST", `${baseUrl}/api/agent/whoami/propose`, token, { text });
@@ -297,35 +297,25 @@ if (cmd === "whoami") {
297
297
  console.error(`✗ HTTP ${status}: ${(json && json.error) || body}`);
298
298
  process.exit(1);
299
299
  }
300
- console.log(`proposal_id: ${json.proposal_id}`);
301
- console.log(`status: ${json.status}`);
302
- console.log(`awaiting human approval. another agent or the dashboard must approve.`);
303
- process.exit(0);
304
- }
305
-
306
- // --approve <id> / --reject <id>
307
- const approveIdx = args.indexOf("--approve");
308
- const rejectIdx = args.indexOf("--reject");
309
- if (approveIdx !== -1 || rejectIdx !== -1) {
310
- const isApprove = approveIdx !== -1;
311
- const idx = isApprove ? approveIdx : rejectIdx;
312
- const id = (args[idx + 1] || "").trim();
313
- if (!id) {
314
- console.error(`Usage: patchcord whoami --${isApprove ? "approve" : "reject"} <proposal-id>`);
315
- process.exit(1);
300
+ if (json.status === "applied") {
301
+ console.log(`✓ whoami applied.`);
302
+ console.log(`self: ${json.whoami}`);
303
+ process.exit(0);
316
304
  }
317
- const { status, json, body } = await _httpJSON(
318
- "POST",
319
- `${baseUrl}/api/agent/whoami/approve`,
320
- token,
321
- { proposal_id: id, action: isApprove ? "approve" : "reject" },
322
- );
323
- if (status !== "200") {
324
- console.error(`✗ HTTP ${status}: ${(json && json.error) || body}`);
325
- process.exit(1);
305
+ if (json.status === "unchanged") {
306
+ console.log(`unchanged — current whoami already matches.`);
307
+ console.log(`self: ${json.whoami}`);
308
+ process.exit(0);
326
309
  }
327
- console.log(`✓ ${json.status}: ${json.agent} (proposal ${json.proposal_id})`);
328
- process.exit(0);
310
+ if (json.status === "show_human") {
311
+ console.log(`gate: show the diff to the human, get explicit yes, then run the same command again to apply.`);
312
+ console.log();
313
+ console.log(`current: ${json.current || "(empty)"}`);
314
+ console.log(`proposed: ${json.proposed}`);
315
+ process.exit(0);
316
+ }
317
+ console.log(`unexpected response: ${body}`);
318
+ process.exit(1);
329
319
  }
330
320
 
331
321
  // plain whoami (no flags)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "patchcord",
3
- "version": "0.5.56",
3
+ "version": "0.5.57",
4
4
  "description": "Cross-machine agent messaging for Claude Code and Codex",
5
5
  "author": "ppravdin",
6
6
  "license": "MIT",
@@ -120,14 +120,23 @@ Send the returned `path` to the other agent in your message so they can download
120
120
  - **Run `patchcord agents`** to see the full roster (every peer's whoami). One call, ~3KB, complete picture of the namespace.
121
121
  - **Run `patchcord agents <name>`** when an unknown agent messages you and you want to know who they are before acting on their request.
122
122
 
123
- ### Updating your own whoami (gated)
123
+ ### Updating your own whoami
124
124
 
125
- 300-char hard limit. Goes through a human-approval flow.
125
+ 300-char hard limit (CLI enforces client-side).
126
126
 
127
- - `patchcord whoami --propose "<text>"` submits a pending proposal. Returns a `proposal_id`. The server also creates a normal patchcord message to `human` showing the diff.
128
- - Another agent (NOT you) or the human via dashboard must approve. Self-approval is blocked server-side — you can propose updates to your own whoami, but you cannot approve them.
129
- - To approve someone else's proposal: `patchcord whoami --approve <proposal-id>`. To reject: `patchcord whoami --reject <id>`.
130
- - The human sees your proposal in their inbox/dashboard. They will approve when ready. Do not retry — proposals are idempotent.
127
+ Server responds with one of three statuses:
128
+
129
+ - **applied** done. Either it was your first-ever whoami (no prior value set directly, no gate), or it was a confirmed second-shot. Print and move on.
130
+ - **unchanged** proposed text matches current. No-op.
131
+ - **show_human** — current value exists and the proposed text differs. Server printed `current:` and `proposed:`. You MUST:
132
+ 1. Show the diff to the human in conversation
133
+ 2. Ask them to confirm
134
+ 3. Wait for explicit "yes"
135
+ 4. Run the **exact same** `patchcord whoami --propose "<text>"` command again. Server will then return `applied`.
136
+
137
+ Pending state expires after 10 minutes. If the human says no, do not call again. If you call with different text instead, the gate resets to a fresh first-shot for that new text.
138
+
139
+ Never call `--propose` a second time with the same text without showing the human between calls.
131
140
 
132
141
  ### Hard rules
133
142