@icebergsnow/patchwork-cli 0.2.3 → 0.2.4
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/README.md +40 -10
- package/bin/patchwork.js +1 -0
- package/lib/connect.js +6 -2
- package/lib/disconnect-picker.js +3 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,20 +2,50 @@
|
|
|
2
2
|
|
|
3
3
|
GitHub-native bulletin board tools and automatic hooks for Codex and Claude Code.
|
|
4
4
|
|
|
5
|
-
The source version is 0.2.
|
|
5
|
+
The source version is 0.2.4. Verify publication with `npm view @icebergsnow/patchwork-cli@0.2.4 version` before using that exact npx command. A GitHub commit alone is not proof that publishing succeeded.
|
|
6
|
+
|
|
7
|
+
Version 0.2.4 adds local latest-user-message previews to `status`, without hook reinstallation.
|
|
6
8
|
|
|
7
9
|
Version 0.2.3 adds acknowledgment notes and coordination guidance. Rerun `connect` with this version and reload the app to update existing MCP tools and hook guidance. Existing board instructions are preserved.
|
|
8
10
|
|
|
9
|
-
##
|
|
11
|
+
## Common commands — copy and paste
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
Run these in your coding project's folder. Replace `TEAM/PROJECT` with your GitHub repository, such as `IcebergSnow/PatchworkBookingLab`. For Claude Code, replace `codex` with `claude`.
|
|
12
14
|
|
|
13
15
|
```sh
|
|
14
|
-
|
|
15
|
-
npx @icebergsnow/patchwork-cli@
|
|
16
|
-
|
|
16
|
+
# Connect (also updates an existing installation)
|
|
17
|
+
npx @icebergsnow/patchwork-cli@latest connect --repo TEAM/PROJECT --client codex
|
|
18
|
+
|
|
19
|
+
# Show connected chats, latest user-message previews, and last board checks
|
|
20
|
+
npx @icebergsnow/patchwork-cli@latest status --client codex
|
|
21
|
+
|
|
22
|
+
# Choose individual chats to disconnect
|
|
23
|
+
npx @icebergsnow/patchwork-cli@latest disconnect --select --client codex
|
|
24
|
+
|
|
25
|
+
# Stop Patchwork for every Codex chat in this project
|
|
26
|
+
npx @icebergsnow/patchwork-cli@latest disconnect --client codex
|
|
17
27
|
```
|
|
18
28
|
|
|
29
|
+
After connecting/updating, reload the app and review hook/MCP permissions. Connect offers to create a board if needed; teammates reuse it. `status` does not start hooks or register a chat. Its `latestUserMessage` is the first sentence (up to 160 characters), or `null` when unavailable. Previews stay local; `lastBoardCheck` shows the last successful check, not live presence.
|
|
30
|
+
|
|
31
|
+
The `--` options are **flags**:
|
|
32
|
+
|
|
33
|
+
| Flag | Use |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| `--repo TEAM/PROJECT` | Choose the GitHub repo for connect. On **status**, show the remote roster instead of local chats/previews. |
|
|
36
|
+
| `--client codex` / `--client claude` | Choose the app. Omit to be prompted on connect, or include both apps on status/disconnect. |
|
|
37
|
+
| `--name "Alex"` | Set a display-name prefix when connecting. |
|
|
38
|
+
| `--create-board` | Authorize board creation without the connect prompt. |
|
|
39
|
+
| `--select` | Pick chats to disconnect interactively. |
|
|
40
|
+
| `--agent CHAT_ID` | Disconnect one ID from status; combine with `--repo` for a lost local chat. |
|
|
41
|
+
| `--help` | Show command usage. |
|
|
42
|
+
|
|
43
|
+
GitHub **labels**: `patchwork:board` identifies the shared board; `patchwork` identifies requests; `patchwork:needs-human` means every registered, non-disconnected chat responded **Cannot handle**. Open means pending; Closed means resolved. Read the request comments for the blocker and action needed.
|
|
44
|
+
|
|
45
|
+
## Teammates
|
|
46
|
+
|
|
47
|
+
Requires Node.js 22.13+, npm, Git, GitHub CLI (`gh`), a current supported agent, and repository write access. Use the common commands above inside your coding project's worktree.
|
|
48
|
+
|
|
19
49
|
Connect asks for Codex or Claude Code and GitHub login if necessary. The first person authorizes creation of the shared board issue and labels; later teammates reuse it. `--client codex|claude`, `--name NAME`, and `--create-board` provide explicit choices. No Patchwork clone, Cloudflare account, or pairing code is needed.
|
|
20
50
|
|
|
21
51
|
New boards contain editable shared instructions for hackathon coordination and Git handoff: prefer separate worktrees/branches, verify the checkout, consolidate requests, confirm interface decisions, make tested commits and authorized pushes at useful milestones, and report integration results and unfinished work. Edit or clear these defaults in the board issue's marked instructions section. Existing boards/custom instructions are preserved; connect does not retrofit defaults. Worktrees are configured in the coding app, not managed by Patchwork.
|
|
@@ -29,13 +59,13 @@ Connections affect only the current project/app. Every independent chat gets a s
|
|
|
29
59
|
To select individual chats without copying IDs:
|
|
30
60
|
|
|
31
61
|
```sh
|
|
32
|
-
npx @icebergsnow/patchwork-cli@0.2.
|
|
62
|
+
npx @icebergsnow/patchwork-cli@0.2.4 disconnect --select
|
|
33
63
|
# Optional: --client codex or --client claude
|
|
34
64
|
```
|
|
35
65
|
|
|
36
66
|
The terminal picker shows each local chat's name, ID, last board check, and the first sentence of its latest user message. Enter numbers separated by commas/spaces and confirm. Enter or Ctrl+C cancels. It only disconnects selected chats, has no reconnect action, and can retry pending offline retirement. Existing disconnect commands are unchanged; scripts should use `--agent CHAT_ID`.
|
|
37
67
|
|
|
38
|
-
Previews stay local: they are read on demand from matching saved transcripts, never saved by Patchwork, sent to GitHub, or included in hooks/MCP/status. Terminal scrollback may retain the displayed text. Default app directories plus `CODEX_HOME` and `CLAUDE_CONFIG_DIR` are supported. Missing/unsupported transcripts and messages outside the bounded read show “Preview unavailable
|
|
68
|
+
Local `status` includes `latestUserMessage` per chat: the first sentence of the latest user message, up to 160 characters, or `null` when unavailable. The picker shows the same preview. Previews stay local: they are read on demand from matching saved transcripts, never saved by Patchwork, sent to GitHub, or included in hooks/MCP/remote status (`status --repo`). Terminal scrollback may retain the displayed text. Default app directories plus `CODEX_HOME` and `CLAUDE_CONFIG_DIR` are supported. Missing/unsupported transcripts and messages outside the bounded read show “Preview unavailable” in the picker; no agent is automatically retired. Existing chats work without hook reinstallation for these previews.
|
|
39
69
|
|
|
40
70
|
Version 0.2.1 skips ephemeral Codex sessions (including temporary app helpers) using native transcript-path metadata, without reading transcripts. Use saved Codex chats. To upgrade from 0.2.0 after publication, rerun `connect` with 0.2.1, reload the app, and approve the updated hooks. Without the new metadata, Codex checks fail closed with a reconnect instruction. Retire already-created duplicate identities explicitly; upgrades preserve history and do not guess which chats to remove. Interrupted upgrades no longer reactivate remotely retired chats.
|
|
41
71
|
|
|
@@ -102,8 +132,8 @@ After checks pass on Windows and macOS:
|
|
|
102
132
|
npm pack --workspace packages/cli --dry-run
|
|
103
133
|
npm login
|
|
104
134
|
npm publish --workspace packages/cli --access public
|
|
105
|
-
npm view @icebergsnow/patchwork-cli@0.2.
|
|
106
|
-
npx @icebergsnow/patchwork-cli@0.2.
|
|
135
|
+
npm view @icebergsnow/patchwork-cli@0.2.4 version
|
|
136
|
+
npx @icebergsnow/patchwork-cli@0.2.4 --help
|
|
107
137
|
```
|
|
108
138
|
|
|
109
139
|
The package contains its executable, runtime modules, README and manifest, with no installation scripts. Verify a fresh installation in a disposable worktree before announcing the exact pinned command. The automated workflow skips versions already published manually.
|
package/bin/patchwork.js
CHANGED
|
@@ -17,6 +17,7 @@ Usage (inside your coding project's Git worktree):
|
|
|
17
17
|
|
|
18
18
|
Requires Node.js 22.13+, Git, GitHub CLI (gh), and repository write access.
|
|
19
19
|
Connect affects chats in this project only. Each chat gets its own identity.
|
|
20
|
+
Local status includes the first sentence of each chat's latest user message, when available.
|
|
20
21
|
Disconnect without --agent or --select disables the selected app (both apps if omitted).
|
|
21
22
|
Use disconnect --select to pick individual chats with local message previews.
|
|
22
23
|
Use status --repo and disconnect --repo --agent to retire a lost chat remotely.
|
package/lib/connect.js
CHANGED
|
@@ -24,6 +24,7 @@ import { mergeCodex, mergeClaude, mergeHooks, parseConfig } from "./config.js";
|
|
|
24
24
|
import { hookConfiguration, serverConfiguration } from "./connections.js";
|
|
25
25
|
import { disabledFile, stateFile } from "./runtime.js";
|
|
26
26
|
import { withBoard, accountFile } from "./sync.js";
|
|
27
|
+
import { chatPreviews } from "./previews.js";
|
|
27
28
|
export const ENTRY = fileURLToPath(
|
|
28
29
|
new URL("../bin/patchwork.js", import.meta.url),
|
|
29
30
|
);
|
|
@@ -275,7 +276,7 @@ async function remoteBoard(repo, github, fn) {
|
|
|
275
276
|
return fn({ gh, sync, c, user });
|
|
276
277
|
});
|
|
277
278
|
}
|
|
278
|
-
export async function status({ cwd, client, repo, github } = {}) {
|
|
279
|
+
export async function status({ cwd, client, repo, github, env } = {}) {
|
|
279
280
|
if (repo)
|
|
280
281
|
return remoteBoard(repo, github, async ({ sync }) => {
|
|
281
282
|
const state = await sync.view();
|
|
@@ -293,6 +294,8 @@ export async function status({ cwd, client, repo, github } = {}) {
|
|
|
293
294
|
c = await readJSON(file);
|
|
294
295
|
if (!c) continue;
|
|
295
296
|
const sessions = await readJSON(stateFile(file));
|
|
297
|
+
const chats = Object.entries(sessions?.chats || {});
|
|
298
|
+
const previews = await chatPreviews(app, new Set(chats.map(([hash]) => hash)), env);
|
|
296
299
|
let configured = false;
|
|
297
300
|
try {
|
|
298
301
|
const config = await read(c.files.config),
|
|
@@ -320,9 +323,10 @@ export async function status({ cwd, client, repo, github } = {}) {
|
|
|
320
323
|
board: c.boardUrl,
|
|
321
324
|
enabled: c.enabled && !(await read(disabledFile(file))),
|
|
322
325
|
chats: await Promise.all(
|
|
323
|
-
|
|
326
|
+
chats.map(async ([hash, a]) => ({
|
|
324
327
|
id: a.id,
|
|
325
328
|
name: a.name,
|
|
329
|
+
latestUserMessage: previews.get(hash) || null,
|
|
326
330
|
enabled:
|
|
327
331
|
c.enabled &&
|
|
328
332
|
!(await read(disabledFile(file))) &&
|
package/lib/disconnect-picker.js
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { createInterface } from "node:readline/promises";
|
|
2
2
|
import { projectRoot, status, disconnect } from "./connect.js";
|
|
3
3
|
import { connectionFile, readJSON } from "./store.js";
|
|
4
|
-
import {
|
|
5
|
-
import { chatPreviews, displayText } from "./previews.js";
|
|
4
|
+
import { displayText } from "./previews.js";
|
|
6
5
|
|
|
7
6
|
export async function disconnectChoices({ cwd, client, env } = {}) {
|
|
8
7
|
const root = await projectRoot(cwd);
|
|
9
8
|
const choices = [];
|
|
10
|
-
for (const group of await status({ cwd: root, client })) {
|
|
11
|
-
const sessions = await readJSON(stateFile(connectionFile(root, group.client)));
|
|
12
|
-
const hashes = new Map(Object.entries(sessions?.chats || {}).map(([hash, chat]) => [chat.id, hash]));
|
|
9
|
+
for (const group of await status({ cwd: root, client, env })) {
|
|
13
10
|
const eligible = group.chats.filter(chat => chat.enabled || chat.pendingRetirement);
|
|
14
|
-
const previews = await chatPreviews(group.client, new Set(eligible.map(chat => hashes.get(chat.id)).filter(Boolean)), env);
|
|
15
11
|
for (const chat of eligible) choices.push({
|
|
16
12
|
id: chat.id,
|
|
17
13
|
client: group.client,
|
|
@@ -19,7 +15,7 @@ export async function disconnectChoices({ cwd, client, env } = {}) {
|
|
|
19
15
|
name: chat.name,
|
|
20
16
|
lastBoardCheck: chat.lastBoardCheck,
|
|
21
17
|
pendingRetirement: chat.pendingRetirement,
|
|
22
|
-
preview:
|
|
18
|
+
preview: chat.latestUserMessage,
|
|
23
19
|
});
|
|
24
20
|
}
|
|
25
21
|
return { root, choices };
|